From 6b3fd8091685c6c33f6132c89a5516aaab37aebe Mon Sep 17 00:00:00 2001 From: Luke Imhoff Date: Thu, 21 Jun 2018 11:10:43 -0500 Subject: [PATCH] Extract Explorer.Indexer to Indexer Resolves #304 --- apps/ethereum_jsonrpc/mix.exs | 6 +++- apps/ethereum_jsonrpc/test/test_helper.exs | 3 ++ apps/explorer/config/config.exs | 4 --- apps/explorer/lib/explorer/application.ex | 1 - apps/explorer/mix.exs | 4 +-- apps/explorer/test/test_helper.exs | 3 ++ apps/explorer_web/mix.exs | 8 ++++- apps/explorer_web/test/test_helper.exs | 7 +++-- apps/indexer/config/config.exs | 29 +++---------------- apps/indexer/lib/indexer.ex | 22 +++++++------- .../lib/indexer/address_balance_fetcher.ex | 8 ++--- .../indexer/lib/indexer/address_extraction.ex | 14 ++++----- apps/indexer/lib/indexer/application.ex | 22 +++++++------- apps/indexer/lib/indexer/block_fetcher.ex | 14 +++++---- apps/indexer/lib/indexer/buffered_task.ex | 4 +-- .../indexer/internal_transaction_fetcher.ex | 8 ++--- .../indexer/pending_transaction_fetcher.ex | 10 +++---- apps/indexer/lib/indexer/sequence.ex | 2 +- apps/indexer/mix.exs | 21 ++++++++++++-- .../indexer/address_balance_fetcher_test.exs | 6 ++-- .../test/indexer/address_extraction_test.exs | 16 +++++----- .../test/indexer/block_fetcher_test.exs | 16 +++++----- .../test/indexer/buffered_task_test.exs | 4 +-- .../internal_transaction_fetcher_test.exs | 12 ++++---- .../pending_transaction_fetcher_test.exs | 6 ++-- apps/indexer/test/indexer/sequence_test.exs | 4 +-- apps/indexer/test/indexer_test.exs | 4 +-- .../indexer/address_balance_fetcher_case.ex | 4 +-- .../internal_transaction_fetcher_case.ex | 4 +-- apps/indexer/test/test_helper.exs | 19 ++++++++++++ coveralls.json | 2 +- mix.exs | 12 ++++++-- 32 files changed, 165 insertions(+), 134 deletions(-) diff --git a/apps/ethereum_jsonrpc/mix.exs b/apps/ethereum_jsonrpc/mix.exs index 2984527c8c..cdd6428a9d 100644 --- a/apps/ethereum_jsonrpc/mix.exs +++ b/apps/ethereum_jsonrpc/mix.exs @@ -38,7 +38,11 @@ defmodule EthereumJsonrpc.MixProject do end defp aliases(env) do - env_aliases(env) + [ + # to match behavior of `mix test` from project root, which needs to not start applications for `indexer` to + # prevent its supervision tree from starting, which is undesirable in test + test: "test --no-start" + ] ++ env_aliases(env) end defp env_aliases(:dev), do: [] diff --git a/apps/ethereum_jsonrpc/test/test_helper.exs b/apps/ethereum_jsonrpc/test/test_helper.exs index 9fbe8ddc4c..1a944da0e7 100644 --- a/apps/ethereum_jsonrpc/test/test_helper.exs +++ b/apps/ethereum_jsonrpc/test/test_helper.exs @@ -3,5 +3,8 @@ junit_folder = Mix.Project.build_path() <> "/junit/#{Mix.Project.config()[:app]} File.mkdir_p!(junit_folder) :ok = Application.put_env(:junit_formatter, :report_dir, junit_folder) +# Counter `test --no-start`. `--no-start` is needed for `:indexer` compatibility +{:ok, _} = Application.ensure_all_started(:ethereum_jsonrpc) + ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) ExUnit.start() diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs index 623aa3b946..623945f5c5 100644 --- a/apps/explorer/config/config.exs +++ b/apps/explorer/config/config.exs @@ -7,10 +7,6 @@ use Mix.Config config :ecto, json_library: Jason -config :explorer, :indexer, - block_rate: 5_000, - debug_logs: !!System.get_env("DEBUG_INDEXER") - # General application configuration config :explorer, ecto_repos: [Explorer.Repo], diff --git a/apps/explorer/lib/explorer/application.ex b/apps/explorer/lib/explorer/application.ex index 777bbce359..9d3f8a5ce7 100644 --- a/apps/explorer/lib/explorer/application.ex +++ b/apps/explorer/lib/explorer/application.ex @@ -25,7 +25,6 @@ defmodule Explorer.Application do [ configure(Explorer.Chain.Statistics.Server), configure(Explorer.ExchangeRates), - configure(Explorer.Indexer.Supervisor), configure(Explorer.Market.History.Cataloger) ] |> List.flatten() diff --git a/apps/explorer/mix.exs b/apps/explorer/mix.exs index 9de0741f62..45f64f8110 100644 --- a/apps/explorer/mix.exs +++ b/apps/explorer/mix.exs @@ -75,8 +75,6 @@ defmodule Explorer.Mixfile do # Code coverage {:excoveralls, "~> 0.8.1", only: [:test]}, {:exvcr, "~> 0.10", only: :test}, - # JSONRPC access to Parity for `Explorer.Indexer` - {:ethereum_jsonrpc, in_umbrella: true}, {:httpoison, "~> 1.0", override: true}, {:jason, "~> 1.0"}, {:junit_formatter, ">= 0.0.0", only: [:test], runtime: false}, @@ -100,7 +98,7 @@ defmodule Explorer.Mixfile do [ "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], - test: ["ecto.create --quiet", "ecto.migrate", "test"] + test: ["ecto.create --quiet", "ecto.migrate", "test --no-start"] ] ++ env_aliases(env) end diff --git a/apps/explorer/test/test_helper.exs b/apps/explorer/test/test_helper.exs index df5634fd24..8730cafb4d 100644 --- a/apps/explorer/test/test_helper.exs +++ b/apps/explorer/test/test_helper.exs @@ -3,6 +3,9 @@ junit_folder = Mix.Project.build_path() <> "/junit/#{Mix.Project.config()[:app]} File.mkdir_p!(junit_folder) :ok = Application.put_env(:junit_formatter, :report_dir, junit_folder) +# Counter `test --no-start`. `--no-start` is needed for `:indexer` compatibility +{:ok, _} = Application.ensure_all_started(:explorer) + ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) ExUnit.start() diff --git a/apps/explorer_web/mix.exs b/apps/explorer_web/mix.exs index cf5bc140bc..b395cde13e 100644 --- a/apps/explorer_web/mix.exs +++ b/apps/explorer_web/mix.exs @@ -112,7 +112,13 @@ defmodule ExplorerWeb.Mixfile do compile: "compile --warnings-as-errors", "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], - test: ["ecto.create --quiet", "ecto.migrate", "test"] + test: [ + "ecto.create --quiet", + "ecto.migrate", + # to match behavior of `mix test` from project root, which needs to not start applications for `indexer` to + # prevent its supervision tree from starting, which is undesirable in test + "test --no-start" + ] ] end diff --git a/apps/explorer_web/test/test_helper.exs b/apps/explorer_web/test/test_helper.exs index f58ef1f9d1..0c8e8846e2 100644 --- a/apps/explorer_web/test/test_helper.exs +++ b/apps/explorer_web/test/test_helper.exs @@ -3,12 +3,15 @@ junit_folder = Mix.Project.build_path() <> "/junit/#{Mix.Project.config()[:app]} File.mkdir_p!(junit_folder) :ok = Application.put_env(:junit_formatter, :report_dir, junit_folder) -ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) -ExUnit.start() +# Counter `test --no-start`. `--no-start` is needed for `:indexer` compatibility +{:ok, _} = Application.ensure_all_started(:explorer_web) {:ok, _} = Application.ensure_all_started(:wallaby) Application.put_env(:wallaby, :base_url, ExplorerWeb.Endpoint.url()) {:ok, _} = Application.ensure_all_started(:ex_machina) +ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) +ExUnit.start() + Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, :manual) diff --git a/apps/indexer/config/config.exs b/apps/indexer/config/config.exs index e1d88eb57c..7999d8e40e 100644 --- a/apps/indexer/config/config.exs +++ b/apps/indexer/config/config.exs @@ -2,29 +2,8 @@ # and its dependencies with the aid of the Mix.Config module. use Mix.Config -# This configuration is loaded before any dependency and is restricted -# to this project. If another project depends on this project, this -# file won't be loaded nor affect the parent project. For this reason, -# if you want to provide default values for your application for -# 3rd-party users, it should be done in your "mix.exs" file. +config :indexer, + block_rate: 5_000, + debug_logs: !!System.get_env("DEBUG_INDEXER") -# You can configure your application as: -# -# config :indexer, key: :value -# -# and access this configuration in your application as: -# -# Application.get_env(:indexer, :key) -# -# You can also configure a 3rd-party app: -# -# config :logger, level: :info -# - -# It is also possible to import configuration files, relative to this -# directory. For example, you can emulate configuration per environment -# by uncommenting the line below and defining dev.exs, test.exs and such. -# Configuration from the imported file will override the ones defined -# here (which is why it is important to import them last). -# -# import_config "#{Mix.env}.exs" +config :indexer, ecto_repos: [Explorer.Repo] diff --git a/apps/indexer/lib/indexer.ex b/apps/indexer/lib/indexer.ex index 8f82749472..80e8bdc7cf 100644 --- a/apps/indexer/lib/indexer.ex +++ b/apps/indexer/lib/indexer.ex @@ -1,10 +1,10 @@ -defmodule Explorer.Indexer do +defmodule Indexer do @moduledoc """ Indexes an Ethereum-based chain using JSONRPC. """ require Logger - alias Explorer.{Chain, Indexer} + alias Explorer.Chain @doc """ The maximum `t:Explorer.Chain.Block.t/0` `number` that was indexed @@ -13,12 +13,12 @@ defmodule Explorer.Indexer do iex> insert(:block, number: 2) iex> insert(:block, number: 1) - iex> Explorer.Indexer.max_block_number() + iex> Indexer.max_block_number() 2 If there are no blocks, `0` is returned to indicate to index from genesis block. - iex> Explorer.Indexer.max_block_number() + iex> Indexer.max_block_number() 0 """ @@ -34,16 +34,16 @@ defmodule Explorer.Indexer do When there are no blocks the next block is the 0th block - iex> Explorer.Indexer.max_block_number() + iex> Indexer.max_block_number() 0 - iex> Explorer.Indexer.next_block_number() + iex> Indexer.next_block_number() 0 When there is a block, it is the successive block number iex> insert(:block, number: 2) iex> insert(:block, number: 1) - iex> Explorer.Indexer.next_block_number() + iex> Indexer.next_block_number() 3 """ @@ -69,14 +69,14 @@ defmodule Explorer.Indexer do Enables debug logs for indexing system. """ def enable_debug_logs do - Application.put_env(:explorer, :indexer, Keyword.put(config(), :debug_logs, true)) + Application.put_env(:indexer, :debug_logs, true) end @doc """ Disables debug logs for indexing system. """ def disable_debug_logs do - Application.put_env(:explorer, :indexer, Keyword.put(config(), :debug_logs, false)) + Application.put_env(:indexer, :debug_logs, false) end @doc """ @@ -90,8 +90,6 @@ defmodule Explorer.Indexer do end defp debug_logs_enabled? do - Keyword.fetch!(config(), :debug_logs) + Application.fetch_env!(:indexer, :debug_logs) end - - defp config, do: Application.fetch_env!(:explorer, :indexer) end diff --git a/apps/indexer/lib/indexer/address_balance_fetcher.ex b/apps/indexer/lib/indexer/address_balance_fetcher.ex index ae5e19186e..751fb46292 100644 --- a/apps/indexer/lib/indexer/address_balance_fetcher.ex +++ b/apps/indexer/lib/indexer/address_balance_fetcher.ex @@ -1,13 +1,13 @@ -defmodule Explorer.Indexer.AddressBalanceFetcher do +defmodule Indexer.AddressBalanceFetcher do @moduledoc """ Fetches `t:Explorer.Chain.Address.t/0` `fetched_balance`. """ import EthereumJSONRPC, only: [integer_to_quantity: 1] - alias Explorer.{BufferedTask, Chain} + alias Explorer.Chain alias Explorer.Chain.{Block, Hash} - alias Explorer.Indexer + alias Indexer.BufferedTask @behaviour BufferedTask @@ -16,7 +16,7 @@ defmodule Explorer.Indexer.AddressBalanceFetcher do max_batch_size: 500, max_concurrency: 4, init_chunk_size: 1000, - task_supervisor: Explorer.Indexer.TaskSupervisor + task_supervisor: Indexer.TaskSupervisor ] @doc """ diff --git a/apps/indexer/lib/indexer/address_extraction.ex b/apps/indexer/lib/indexer/address_extraction.ex index 0bad95fc3b..729238a1ee 100644 --- a/apps/indexer/lib/indexer/address_extraction.ex +++ b/apps/indexer/lib/indexer/address_extraction.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Indexer.AddressExtraction do +defmodule Indexer.AddressExtraction do @moduledoc """ Extract Addresses from data fetched from the Blockchain and structured as Blocks, InternalTransactions, Transactions and Logs. @@ -104,7 +104,7 @@ defmodule Explorer.Indexer.AddressExtraction do Blocks have their `miner_hash` extracted. - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> blocks: [ ...> %{ @@ -124,7 +124,7 @@ defmodule Explorer.Indexer.AddressExtraction do Internal transactions can have their `from_address_hash`, `to_address_hash` and/or `created_contract_address_hash` extracted. - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> internal_transactions: [ ...> %{ @@ -161,7 +161,7 @@ defmodule Explorer.Indexer.AddressExtraction do Transactions can have their `from_address_hash` and/or `to_address_hash` extracted. - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> transactions: [ ...> %{ @@ -193,7 +193,7 @@ defmodule Explorer.Indexer.AddressExtraction do Logs can have their `address_hash` extracted. - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> logs: [ ...> %{ @@ -212,7 +212,7 @@ defmodule Explorer.Indexer.AddressExtraction do When the same address is mentioned multiple times, the greatest `block_number` is used - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> blocks: [ ...> %{ @@ -262,7 +262,7 @@ defmodule Explorer.Indexer.AddressExtraction do When a contract is created and then used in internal transactions and transaction in the same fetched data, the `created_contract_code` is merged with the greatest `block_number` - iex> Explorer.Indexer.AddressExtraction.extract_addresses( + iex> Indexer.AddressExtraction.extract_addresses( ...> %{ ...> internal_transactions: [ ...> %{ diff --git a/apps/indexer/lib/indexer/application.ex b/apps/indexer/lib/indexer/application.ex index 4ecdd6d6b5..318cbe5fb7 100644 --- a/apps/indexer/lib/indexer/application.ex +++ b/apps/indexer/lib/indexer/application.ex @@ -1,26 +1,24 @@ -defmodule Explorer.Indexer.Supervisor do +defmodule Indexer.Application do @moduledoc """ - Supervising the fetchers for the `Explorer.Indexer` + This is the `Application` module for `Indexer`. """ - use Supervisor + use Application - alias Explorer.Indexer.{AddressBalanceFetcher, BlockFetcher, InternalTransactionFetcher, PendingTransactionFetcher} + alias Indexer.{AddressBalanceFetcher, BlockFetcher, InternalTransactionFetcher, PendingTransactionFetcher} - def start_link(opts) do - Supervisor.start_link(__MODULE__, opts, name: __MODULE__) - end - - @impl Supervisor - def init(_opts) do + @impl Application + def start(_type, _args) do children = [ - {Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}, + {Task.Supervisor, name: Indexer.TaskSupervisor}, {AddressBalanceFetcher, name: AddressBalanceFetcher}, {PendingTransactionFetcher, name: PendingTransactionFetcher}, {InternalTransactionFetcher, name: InternalTransactionFetcher}, {BlockFetcher, []} ] - Supervisor.init(children, strategy: :one_for_one) + opts = [strategy: :one_for_one, name: Indexer.Supervisor] + + Supervisor.start_link(children, opts) end end diff --git a/apps/indexer/lib/indexer/block_fetcher.ex b/apps/indexer/lib/indexer/block_fetcher.ex index cebf0408ef..b696cdc7e2 100644 --- a/apps/indexer/lib/indexer/block_fetcher.ex +++ b/apps/indexer/lib/indexer/block_fetcher.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Indexer.BlockFetcher do +defmodule Indexer.BlockFetcher do @moduledoc """ Fetches and indexes block ranges from gensis to realtime. """ @@ -7,12 +7,12 @@ defmodule Explorer.Indexer.BlockFetcher do require Logger - import Explorer.Indexer, only: [debug: 1] + import Indexer, only: [debug: 1] alias EthereumJSONRPC alias EthereumJSONRPC.Transactions - alias Explorer.{BufferedTask, Chain, Indexer} - alias Explorer.Indexer.{AddressBalanceFetcher, AddressExtraction, InternalTransactionFetcher, Sequence} + alias Explorer.Chain + alias Indexer.{AddressBalanceFetcher, AddressExtraction, BufferedTask, InternalTransactionFetcher, Sequence} # dialyzer thinks that Logger.debug functions always have no_local_return @dialyzer {:nowarn_function, import_range: 3} @@ -63,7 +63,11 @@ defmodule Explorer.Indexer.BlockFetcher do @impl GenServer def init(opts) do - opts = Keyword.merge(Application.fetch_env!(:explorer, :indexer), opts) + opts = + :indexer + |> Application.get_all_env() + |> Keyword.merge(opts) + :timer.send_interval(15_000, self(), :debug_count) state = %{ diff --git a/apps/indexer/lib/indexer/buffered_task.ex b/apps/indexer/lib/indexer/buffered_task.ex index 523639acda..8e95c541d3 100644 --- a/apps/indexer/lib/indexer/buffered_task.ex +++ b/apps/indexer/lib/indexer/buffered_task.ex @@ -1,4 +1,4 @@ -defmodule Explorer.BufferedTask do +defmodule Indexer.BufferedTask do @moduledoc """ Provides a behaviour for batched task running with retries. @@ -166,7 +166,7 @@ defmodule Explorer.BufferedTask do ]} ) :: {:ok, pid()} | {:error, {:already_started, pid()}} def start_link({module, base_opts}) do - default_opts = Application.fetch_env!(:explorer, :indexer) + default_opts = Application.get_all_env(:indexer) opts = Keyword.merge(default_opts, base_opts) GenServer.start_link(__MODULE__, {module, opts}, name: opts[:name]) diff --git a/apps/indexer/lib/indexer/internal_transaction_fetcher.ex b/apps/indexer/lib/indexer/internal_transaction_fetcher.ex index b460aeea98..233f466ba4 100644 --- a/apps/indexer/lib/indexer/internal_transaction_fetcher.ex +++ b/apps/indexer/lib/indexer/internal_transaction_fetcher.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Indexer.InternalTransactionFetcher do +defmodule Indexer.InternalTransactionFetcher do @moduledoc """ Fetches and indexes `t:Explorer.Chain.InternalTransaction.t/0`. @@ -7,8 +7,8 @@ defmodule Explorer.Indexer.InternalTransactionFetcher do require Logger - alias Explorer.{BufferedTask, Chain, Indexer} - alias Explorer.Indexer.{AddressBalanceFetcher, AddressExtraction} + alias Explorer.Chain + alias Indexer.{AddressBalanceFetcher, AddressExtraction, BufferedTask} alias Explorer.Chain.{Block, Hash} @behaviour BufferedTask @@ -20,7 +20,7 @@ defmodule Explorer.Indexer.InternalTransactionFetcher do max_concurrency: @max_concurrency, max_batch_size: @max_batch_size, init_chunk_size: 5000, - task_supervisor: Explorer.Indexer.TaskSupervisor + task_supervisor: Indexer.TaskSupervisor ] @doc """ diff --git a/apps/indexer/lib/indexer/pending_transaction_fetcher.ex b/apps/indexer/lib/indexer/pending_transaction_fetcher.ex index 0fd03b934b..ba8b808f38 100644 --- a/apps/indexer/lib/indexer/pending_transaction_fetcher.ex +++ b/apps/indexer/lib/indexer/pending_transaction_fetcher.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Indexer.PendingTransactionFetcher do +defmodule Indexer.PendingTransactionFetcher do @moduledoc """ Fetches pending transactions and imports them. @@ -11,8 +11,8 @@ defmodule Explorer.Indexer.PendingTransactionFetcher do import EthereumJSONRPC.Parity, only: [fetch_pending_transactions: 0] - alias Explorer.{Chain, Indexer} - alias Explorer.Indexer.{AddressExtraction, PendingTransactionFetcher} + alias Explorer.Chain + alias Indexer.{AddressExtraction, PendingTransactionFetcher} # milliseconds @default_interval 1_000 @@ -46,8 +46,8 @@ defmodule Explorer.Indexer.PendingTransactionFetcher do @impl GenServer def init(opts) do opts = - :explorer - |> Application.fetch_env!(:indexer) + :indexer + |> Application.get_all_env() |> Keyword.merge(opts) state = diff --git a/apps/indexer/lib/indexer/sequence.ex b/apps/indexer/lib/indexer/sequence.ex index 08965945ae..6f7757673c 100644 --- a/apps/indexer/lib/indexer/sequence.ex +++ b/apps/indexer/lib/indexer/sequence.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Indexer.Sequence do +defmodule Indexer.Sequence do @moduledoc false use Agent diff --git a/apps/indexer/mix.exs b/apps/indexer/mix.exs index 93ba230ff4..676fde9f09 100644 --- a/apps/indexer/mix.exs +++ b/apps/indexer/mix.exs @@ -3,6 +3,7 @@ defmodule Indexer.MixProject do def project do [ + aliases: aliases(), app: :indexer, version: "0.1.0", build_path: "../../_build", @@ -10,6 +11,7 @@ defmodule Indexer.MixProject do deps_path: "../../deps", lockfile: "../../mix.lock", elixir: "~> 1.6", + elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, deps: deps() ] @@ -23,12 +25,25 @@ defmodule Indexer.MixProject do ] end + defp aliases do + [ + # so that the supervision tree does not start, which would begin indexing, and so that the various fetchers can + # be started with `ExUnit`'s `start_supervised` for unit testing. + test: "test --no-start" + ] + end + # Run "mix help deps" to learn about dependencies. defp deps do [ - # {:dep_from_hexpm, "~> 0.3.0"}, - # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, - # {:sibling_app_in_umbrella, in_umbrella: true}, + # JSONRPC access to Parity for `Explorer.Indexer` + {:ethereum_jsonrpc, in_umbrella: true}, + # Importing to database + {:explorer, in_umbrella: true} ] end + + # Specifies which paths to compile per environment. + defp elixirc_paths(:test), do: ["test/support" | elixirc_paths(:dev)] + defp elixirc_paths(_), do: ["lib"] end diff --git a/apps/indexer/test/indexer/address_balance_fetcher_test.exs b/apps/indexer/test/indexer/address_balance_fetcher_test.exs index 58d1cb2f96..e54bc0544d 100644 --- a/apps/indexer/test/indexer/address_balance_fetcher_test.exs +++ b/apps/indexer/test/indexer/address_balance_fetcher_test.exs @@ -1,10 +1,10 @@ -defmodule Explorer.Indexer.AddressBalanceFetcherTest do +defmodule Indexer.AddressBalanceFetcherTest do # MUST be `async: false` so that {:shared, pid} is set for connection to allow AddressBalanceFetcher's self-send to have # connection allowed immediately. use Explorer.DataCase, async: false alias Explorer.Chain.{Address, Hash, Wei} - alias Explorer.Indexer.{AddressBalanceFetcher, AddressBalanceFetcherCase} + alias Indexer.{AddressBalanceFetcher, AddressBalanceFetcherCase} @block_number 2_932_838 @hash %Explorer.Chain.Hash{ @@ -13,7 +13,7 @@ defmodule Explorer.Indexer.AddressBalanceFetcherTest do } setup do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) :ok end diff --git a/apps/indexer/test/indexer/address_extraction_test.exs b/apps/indexer/test/indexer/address_extraction_test.exs index 3f9c788d66..29a822e6f9 100644 --- a/apps/indexer/test/indexer/address_extraction_test.exs +++ b/apps/indexer/test/indexer/address_extraction_test.exs @@ -1,13 +1,13 @@ -defmodule Explorer.Indexer.AddressExtractionTest do +defmodule Indexer.AddressExtractionTest do use Explorer.DataCase, async: true - alias Explorer.Indexer.AddressExtraction + alias Indexer.AddressExtraction doctest AddressExtraction describe "extract_addresses/1" do test "blocks without a `miner_hash` aren't extracted" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ blocks: [ %{ number: 34 @@ -17,7 +17,7 @@ defmodule Explorer.Indexer.AddressExtractionTest do end test "blocks without a `number` aren't extracted" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ blocks: [ %{ miner_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" @@ -27,7 +27,7 @@ defmodule Explorer.Indexer.AddressExtractionTest do end test "internal_transactions with a `from_address_hash` without a `block_number` aren't extracted" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ internal_transactions: [ %{ from_address_hash: "0x0000000000000000000000000000000000000001" @@ -37,7 +37,7 @@ defmodule Explorer.Indexer.AddressExtractionTest do end test "internal_transactions with a `to_address_hash` without a `block_number` aren't extracted" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ internal_transactions: [ %{ to_address_hash: "0x0000000000000000000000000000000000000002" @@ -48,7 +48,7 @@ defmodule Explorer.Indexer.AddressExtractionTest do test "internal_transactions with a `created_contract_address_hash` and `created_contract_code` " <> "without a `block_number` aren't extracted" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ internal_transactions: [ %{ created_contract_address_hash: "0x0000000000000000000000000000000000000003", @@ -59,7 +59,7 @@ defmodule Explorer.Indexer.AddressExtractionTest do end test "differing contract code is ignored" do - assert Explorer.Indexer.AddressExtraction.extract_addresses(%{ + assert Indexer.AddressExtraction.extract_addresses(%{ internal_transactions: [ %{ block_number: 1, diff --git a/apps/indexer/test/indexer/block_fetcher_test.exs b/apps/indexer/test/indexer/block_fetcher_test.exs index acdcc51c5b..82cf0f4ec2 100644 --- a/apps/indexer/test/indexer/block_fetcher_test.exs +++ b/apps/indexer/test/indexer/block_fetcher_test.exs @@ -1,16 +1,16 @@ -defmodule Explorer.Indexer.BlockFetcherTest do +defmodule Indexer.BlockFetcherTest do # `async: false` due to use of named GenServer use Explorer.DataCase, async: false import ExUnit.CaptureLog alias Explorer.Chain.{Address, Block, Log, Transaction, Wei} - alias Explorer.Indexer - alias Explorer.Indexer.{ + alias Indexer.{ AddressBalanceFetcher, AddressBalanceFetcherCase, BlockFetcher, + BufferedTask, InternalTransactionFetcher, InternalTransactionFetcherCase, Sequence @@ -46,7 +46,7 @@ defmodule Explorer.Indexer.BlockFetcherTest do assert Repo.aggregate(Block, :count, :hash) == 0 - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() InternalTransactionFetcherCase.start_supervised!() start_supervised!(BlockFetcher) @@ -89,7 +89,7 @@ defmodule Explorer.Indexer.BlockFetcherTest do @tag :capture_log @heading "persisted counts" test "without debug_logs", %{state: state} do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() InternalTransactionFetcherCase.start_supervised!() @@ -104,7 +104,7 @@ defmodule Explorer.Indexer.BlockFetcherTest do @tag :capture_log test "with debug_logs", %{state: state} do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() InternalTransactionFetcherCase.start_supervised!() @@ -129,7 +129,7 @@ defmodule Explorer.Indexer.BlockFetcherTest do setup :state setup do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() InternalTransactionFetcherCase.start_supervised!() {:ok, state} = BlockFetcher.init([]) @@ -293,7 +293,7 @@ defmodule Explorer.Indexer.BlockFetcherTest do defp wait_for_tasks(buffered_task) do wait_until(5000, fn -> - counts = Explorer.BufferedTask.debug_count(buffered_task) + counts = BufferedTask.debug_count(buffered_task) counts.buffer == 0 and counts.tasks == 0 end) end diff --git a/apps/indexer/test/indexer/buffered_task_test.exs b/apps/indexer/test/indexer/buffered_task_test.exs index 6e9e7ed261..228a8d1368 100644 --- a/apps/indexer/test/indexer/buffered_task_test.exs +++ b/apps/indexer/test/indexer/buffered_task_test.exs @@ -1,7 +1,7 @@ -defmodule Explorer.BufferedTaskTest do +defmodule Indexer.BufferedTaskTest do use ExUnit.Case, async: true - alias Explorer.BufferedTask + alias Indexer.BufferedTask @max_batch_size 2 diff --git a/apps/indexer/test/indexer/internal_transaction_fetcher_test.exs b/apps/indexer/test/indexer/internal_transaction_fetcher_test.exs index 0612e81a0f..8960545378 100644 --- a/apps/indexer/test/indexer/internal_transaction_fetcher_test.exs +++ b/apps/indexer/test/indexer/internal_transaction_fetcher_test.exs @@ -1,15 +1,15 @@ -defmodule Explorer.Indexer.InternalTransactionFetcherTest do +defmodule Indexer.InternalTransactionFetcherTest do use Explorer.DataCase, async: false import ExUnit.CaptureLog alias Explorer.Chain.Transaction - alias Explorer.Indexer.{AddressBalanceFetcherCase, InternalTransactionFetcher, PendingTransactionFetcher} + alias Indexer.{AddressBalanceFetcherCase, InternalTransactionFetcher, PendingTransactionFetcher} @moduletag :capture_log - test "does not try to fetch pending transactions from Explorer.Indexer.PendingTransactionFetcher" do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + test "does not try to fetch pending transactions from Indexer.PendingTransactionFetcher" do + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() start_supervised!(PendingTransactionFetcher) @@ -57,7 +57,7 @@ defmodule Explorer.Indexer.InternalTransactionFetcherTest do describe "run/2" do test "duplicate transaction hashes are logged" do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() insert(:transaction, hash: "0x03cd5899a63b6f6222afda8705d059fd5a7d126bcabe962fb654d9736e6bcafa") @@ -82,7 +82,7 @@ defmodule Explorer.Indexer.InternalTransactionFetcherTest do end test "duplicate transaction hashes only retry uniques" do - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) AddressBalanceFetcherCase.start_supervised!() # not a real transaction hash, so that it fails diff --git a/apps/indexer/test/indexer/pending_transaction_fetcher_test.exs b/apps/indexer/test/indexer/pending_transaction_fetcher_test.exs index 0616827c1b..26b4496b75 100644 --- a/apps/indexer/test/indexer/pending_transaction_fetcher_test.exs +++ b/apps/indexer/test/indexer/pending_transaction_fetcher_test.exs @@ -1,16 +1,16 @@ -defmodule Explorer.Indexer.PendingTransactionFetcherTest do +defmodule Indexer.PendingTransactionFetcherTest do # `async: false` due to use of named GenServer use Explorer.DataCase, async: false alias Explorer.Chain.Transaction - alias Explorer.Indexer.PendingTransactionFetcher + alias Indexer.PendingTransactionFetcher describe "start_link/1" do # this test may fail if Sokol so low volume that the pending transactions are empty for too long test "starts fetching pending transactions" do assert Repo.aggregate(Transaction, :count, :hash) == 0 - start_supervised!({Task.Supervisor, name: Explorer.Indexer.TaskSupervisor}) + start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor}) start_supervised!(PendingTransactionFetcher) wait_for_results(fn -> diff --git a/apps/indexer/test/indexer/sequence_test.exs b/apps/indexer/test/indexer/sequence_test.exs index d01194d4c4..31334a34d1 100644 --- a/apps/indexer/test/indexer/sequence_test.exs +++ b/apps/indexer/test/indexer/sequence_test.exs @@ -1,7 +1,7 @@ -defmodule Explorer.Indexer.SequenceTest do +defmodule Indexer.SequenceTest do use ExUnit.Case - alias Explorer.Indexer.Sequence + alias Indexer.Sequence test "start_link" do {:ok, pid} = Sequence.start_link([1..4], 5, 1) diff --git a/apps/indexer/test/indexer_test.exs b/apps/indexer/test/indexer_test.exs index 040d7adeb7..4badfd1907 100644 --- a/apps/indexer/test/indexer_test.exs +++ b/apps/indexer/test/indexer_test.exs @@ -1,8 +1,6 @@ -defmodule Explorer.IndexerTest do +defmodule IndexerTest do use Explorer.DataCase, async: true - alias Explorer.Indexer - import Explorer.Factory doctest Indexer diff --git a/apps/indexer/test/support/indexer/address_balance_fetcher_case.ex b/apps/indexer/test/support/indexer/address_balance_fetcher_case.ex index 5ec9a18a9f..e1af1430ad 100644 --- a/apps/indexer/test/support/indexer/address_balance_fetcher_case.ex +++ b/apps/indexer/test/support/indexer/address_balance_fetcher_case.ex @@ -1,5 +1,5 @@ -defmodule Explorer.Indexer.AddressBalanceFetcherCase do - alias Explorer.Indexer.AddressBalanceFetcher +defmodule Indexer.AddressBalanceFetcherCase do + alias Indexer.AddressBalanceFetcher def start_supervised!(options \\ []) when is_list(options) do options diff --git a/apps/indexer/test/support/indexer/internal_transaction_fetcher_case.ex b/apps/indexer/test/support/indexer/internal_transaction_fetcher_case.ex index bd514c6116..dd9abb862f 100644 --- a/apps/indexer/test/support/indexer/internal_transaction_fetcher_case.ex +++ b/apps/indexer/test/support/indexer/internal_transaction_fetcher_case.ex @@ -1,5 +1,5 @@ -defmodule Explorer.Indexer.InternalTransactionFetcherCase do - alias Explorer.Indexer.InternalTransactionFetcher +defmodule Indexer.InternalTransactionFetcherCase do + alias Indexer.InternalTransactionFetcher def start_supervised!(options \\ []) when is_list(options) do options diff --git a/apps/indexer/test/test_helper.exs b/apps/indexer/test/test_helper.exs index 869559e709..42f3af3fe4 100644 --- a/apps/indexer/test/test_helper.exs +++ b/apps/indexer/test/test_helper.exs @@ -1 +1,20 @@ +# https://github.com/CircleCI-Public/circleci-demo-elixir-phoenix/blob/a89de33a01df67b6773ac90adc74c34367a4a2d6/test/test_helper.exs#L1-L3 +junit_folder = Mix.Project.build_path() <> "/junit/#{Mix.Project.config()[:app]}" +File.mkdir_p!(junit_folder) +:ok = Application.put_env(:junit_formatter, :report_dir, junit_folder) + +# start all dependencies, but not Indexer itself as we need to unit test the supervision tree without and don't want the +# genesis task scanning in the background +Application.load(:indexer) + +for application <- Application.spec(:indexer, :applications) do + Application.ensure_all_started(application) +end + +# no declared in :applications since it is test-only +{:ok, _} = Application.ensure_all_started(:ex_machina) + +ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter]) ExUnit.start() + +Ecto.Adapters.SQL.Sandbox.mode(Explorer.Repo, :manual) diff --git a/coveralls.json b/coveralls.json index 38a52b8eb8..186c305327 100644 --- a/coveralls.json +++ b/coveralls.json @@ -1,7 +1,7 @@ { "coverage_options": { "treat_no_relevant_lines_as_covered": true, - "minimum_coverage": 93.7 + "minimum_coverage": 94.4 }, "terminal_options": { "file_column_width": 120 diff --git a/mix.exs b/mix.exs index ff0723faca..4ad4fa19c2 100644 --- a/mix.exs +++ b/mix.exs @@ -28,11 +28,19 @@ defmodule ExplorerUmbrella.Mixfile do ## Private Functions - defp aliases(:dev) do + defp aliases(env) do + [ + # to match behavior of `mix test` in `apps/indexer`, which needs to not start applications for `indexer` to + # prevent its supervision tree from starting, which is undesirable in test + test: "test --no-start" + ] ++ env_aliases(env) + end + + defp env_aliases(:dev) do [] end - defp aliases(_env) do + defp env_aliases(_env) do [ compile: "compile --warnings-as-errors" ]