Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Measure :ets tables #125

Merged
merged 7 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
timeout-minutes: 30
name: Internal Typespecs
env:
OTP: "25.3"
ELIXIR: "1.13"
OTP: "26.2"
ELIXIR: "1.14"
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
Expand Down Expand Up @@ -50,8 +50,8 @@ jobs:
runs-on: ubuntu-20.04
name: Code Style
env:
OTP: "25.3"
ELIXIR: "1.13"
OTP: "26.2"
ELIXIR: "1.14"
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
Expand All @@ -78,8 +78,8 @@ jobs:
runs-on: ubuntu-20.04
name: Code Formatting
env:
OTP: "25.3"
ELIXIR: "1.13"
OTP: "26.2"
ELIXIR: "1.14"
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
Expand Down Expand Up @@ -107,8 +107,8 @@ jobs:
timeout-minutes: 30
name: External Typespecs
env:
OTP: "25.3"
ELIXIR: "1.13"
OTP: "26.2"
ELIXIR: "1.14"
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
Expand Down Expand Up @@ -151,11 +151,9 @@ jobs:
# NOTE: We are going to support 4 version from the official list of 5
# https://hexdocs.pm/elixir/compatibility-and-deprecations.html
matrix:
otp: ["25.3"]
elixir: ["1.13.4"]
otp: ["26.2"]
elixir: ["1.14.5"]
include:
- otp: "26.2"
elixir: "1.14.5"
- otp: "26.2"
elixir: "1.15.8"
- otp: "26.2"
Expand Down
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ config :avrora,
convert_null_values: true,
names_cache_ttl: :infinity

config :logger, :console, format: "$time $metadata[$level] $levelpad$message\n"
config :logger, :console, format: "$time $metadata[$level] $message\n"
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Avrora.MixProject do
[
app: :avrora,
version: @version,
elixir: "~> 1.12",
elixir: "~> 1.14",
description: description(),
package: package(),
docs: docs(),
Expand Down
11 changes: 11 additions & 0 deletions test/avrora/storage/file_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule Avrora.Storage.FileTest do
use ExUnit.Case, async: true
doctest Avrora.Storage.File

import Mox
import Support.Config
import ExUnit.CaptureLog
alias Avrora.Storage.File
Expand Down Expand Up @@ -45,6 +46,16 @@ defmodule Avrora.Storage.FileTest do
assert output =~ "schema file with version is not allowed"
end

test "when references reuse same ets table" do
_ = start_link_supervised!(Support.AvroSchemaStore)
stub(Avrora.ConfigMock, :ets_lib, fn -> Support.AvroSchemaStore end)

existing_ets_tables = Support.AvroSchemaStore.count()
{:ok, _} = File.get("io.acme.PaymentHistory")

assert Support.AvroSchemaStore.count() - existing_ets_tables == 1
end

test "when schema file contains invalid json" do
assert File.get("io.acme.Wrong") == {:error, "argument error"}
end
Expand Down
52 changes: 46 additions & 6 deletions test/avrora/storage/registry_test.exs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
defmodule Avrora.Storage.RegistryTest do
# NOTE: Remove when Elixir 1.6 support ends
use ExUnit.Case
# use ExUnit.Case, async: true
use ExUnit.Case, async: true
doctest Avrora.Storage.Registry

import Mox
import Support.Config
import ExUnit.CaptureLog
alias Avrora.Storage.Registry

# NOTE: Remove when Elixir 1.6 support ends
setup :set_mox_from_context

setup :verify_on_exit!
setup :support_config

Expand Down Expand Up @@ -283,6 +278,51 @@ defmodule Avrora.Storage.RegistryTest do

assert Registry.get("anything") == {:error, :unconfigured_registry_url}
end

@tag skip: "This test will fail because Registry creates new table on each reference"
test "when references reuse same ets table" do
_ = start_link_supervised!(Support.AvroSchemaStore)
stub(Avrora.ConfigMock, :ets_lib, fn -> Support.AvroSchemaStore end)

existing_ets_tables = Support.AvroSchemaStore.count()

Avrora.HTTPClientMock
|> expect(:get, fn url, _ ->
assert url == "http://reg.loc/schemas/ids/43"

{
:ok,
%{
"subject" => "io.acme.Account",
"id" => 43,
"version" => 1,
"schema" => json_schema_with_reference(),
"references" => [
%{"name" => "io.acme.User", "subject" => "io.acme.User", "version" => 1}
]
}
}
end)

Avrora.HTTPClientMock
|> expect(:get, fn url, _ ->
assert url == "http://reg.loc/subjects/io.acme.User/versions/1"

{
:ok,
%{
"subject" => "io.acme.User",
"id" => 44,
"version" => 1,
"schema" => json_schema_referenced()
}
}
end)

{:ok, _} = Registry.get(43)

assert Support.AvroSchemaStore.count() - existing_ets_tables == 1
end
end

describe "put/2" do
Expand Down
71 changes: 71 additions & 0 deletions test/support/avro_schema_store.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
defmodule Support.AvroSchemaStore do
@moduledoc """
A host process and a wrapper for :avro_schema_store produced tables.
Used only in tests

See more: `Avrora.AvroSchemaStore`

## Examples:

test "when we need test schema store creation" do
{:ok, _} = start_link_supervised!(Support.AvroSchemaStore)
stub(Avrora.ConfigMock, :ets_lib, fn -> Support.AvroSchemaStore end)

assert Support.AvroSchemaStore.count() == 0

Support.AvroSchemaStore.new()
assert Support.AvroSchemaStore.count() == 1
end
"""

@prefix "avrora__test"

use GenServer

def start_link(opts \\ []) do
{name_opts, _} = Keyword.split(opts, [:name])
opts = Keyword.merge([name: __MODULE__], name_opts)

GenServer.start_link(__MODULE__, [], opts)
end

@impl true
def init(_state \\ []), do: {:ok, []}

@impl true
def handle_call({:new}, _from, state),
do: {:reply, :avro_schema_store.new(name: String.to_atom("#{@prefix}-#{rand()}")), state}

def handle_call({:count}, _from, state),
do: {:reply, Enum.count(:ets.all(), &is_test_store/1), state}

@doc """
Creates a new Erlang Term Store.

## Examples:

iex> {:ok, _} = Support.AvroSchemaStore.start_link()
iex> Support.AvroSchemaStore.new() |> :ets.info() |> Keyword.get(:size)
0
"""
@spec new() :: reference()
def new, do: GenServer.call(__MODULE__, {:new})

@doc """
Returns a number of `:ets` tables matching the test prefix.

## Examples:

iex> {:ok, _} = Support.AvroSchemaStore.start_link()
iex> Support.AvroSchemaStore.count()
0
iex> Support.AvroSchemaStore.new()
iex> Support.AvroSchemaStore.count()
1
"""
@spec count() :: non_neg_integer()
def count, do: GenServer.call(__MODULE__, {:count})

defp rand, do: :rand.uniform(1_000_000) + System.os_time()
defp is_test_store(id), do: !is_reference(id) && Atom.to_string(id) =~ @prefix
end
Loading