AuroraMeter.Test (Aurora Meter v0.3.1)

View Source

Helpers for testing an application that uses Aurora Meter.

defmodule MyApp.MeterCase do
  use ExUnit.CaseTemplate

  using do
    quote do
      use AuroraMeter.Test, reset: true
    end
  end
end

use AuroraMeter.Test imports every function below. With reset: true the ETS tables are cleared before each test (see reset!/0, which requires async: false); with sandbox: true an Ecto.Adapters.SQL.Sandbox owner is started on the configured repo for tests that do not already have one.

Set large :flush_interval / :broadcast_interval values in test config so the timers never fire mid-test, and drive them with flush!/0 and broadcast!/0.

Cross-node behaviour can be exercised on one node: simulate_node/3 applies deltas as if another node had gossiped them, and simulate_flush/2 applies totals as if another node had flushed.

Summary

Functions

Broadcasts touched counters to subscribed LiveViews (and gossips deltas) now.

Starts an Ecto.Adapters.SQL.Sandbox owner on the configured repo (shared unless the test is async) and stops it on exit. Use only when your own case template does not already do this.

Flushes dirty counters to the database now; returns the number of keys persisted.

Clears every Aurora Meter ETS table: counters, dirty and touched sets, and the subscription cache. Unflushed usage is discarded; the database is not touched. Because the tables are global, only use this in async: false tests (or give each test a unique tenant instead, see unique_tenant/1).

Applies totals ([{tenant, feature, total}]) as if node origin had flushed and announced them: this node re-bases each warm counter on the total plus its own unflushed increments.

Applies deltas ([{tenant, feature, delta}]) as if node origin had gossiped them: this node's view of each counter moves by the delta, exactly as it would in a cluster. period_start defaults to the tenant's current period. Only warm counters are affected, as in production; read the counter first if you need it seeded.

A process-unique tenant key, so tests can share the global ETS tables safely.

Functions

broadcast!()

@spec broadcast!() :: :ok

Broadcasts touched counters to subscribed LiveViews (and gossips deltas) now.

checkout(tags \\ %{})

@spec checkout(map()) :: :ok

Starts an Ecto.Adapters.SQL.Sandbox owner on the configured repo (shared unless the test is async) and stops it on exit. Use only when your own case template does not already do this.

flush!()

@spec flush!() :: non_neg_integer()

Flushes dirty counters to the database now; returns the number of keys persisted.

reset!()

@spec reset!() :: :ok

Clears every Aurora Meter ETS table: counters, dirty and touched sets, and the subscription cache. Unflushed usage is discarded; the database is not touched. Because the tables are global, only use this in async: false tests (or give each test a unique tenant instead, see unique_tenant/1).

simulate_flush(origin, totals, period_start \\ nil)

@spec simulate_flush(node(), [{term(), atom(), integer()}], DateTime.t() | nil) :: :ok

Applies totals ([{tenant, feature, total}]) as if node origin had flushed and announced them: this node re-bases each warm counter on the total plus its own unflushed increments.

simulate_node(origin, deltas, period_start \\ nil)

@spec simulate_node(node(), [{term(), atom(), integer()}], DateTime.t() | nil) :: :ok

Applies deltas ([{tenant, feature, delta}]) as if node origin had gossiped them: this node's view of each counter moves by the delta, exactly as it would in a cluster. period_start defaults to the tenant's current period. Only warm counters are affected, as in production; read the counter first if you need it seeded.

unique_tenant(prefix \\ "org")

@spec unique_tenant(String.t()) :: String.t()

A process-unique tenant key, so tests can share the global ETS tables safely.