Skip to content

Commit 5c2319b

Browse files
authored
Merge pull request #50 from eigr/feat/tests_continuation
Centralize protos and cluster, test helper structure and ecto sandbox
2 parents 7cd0d04 + aee090b commit 5c2319b

File tree

52 files changed

+309
-182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+309
-182
lines changed

apps/activator/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ defmodule Activators.MixProject do
2727
# Run "mix help deps" to learn about dependencies.
2828
defp deps do
2929
[
30-
{:protos, "~> 0.1", in_umbrella: true},
30+
{:spawn, "~> 0.1", in_umbrella: true},
3131
{:actors, "~> 0.1", in_umbrella: true},
3232
{:cloudevents, "~> 0.6.1"},
3333
{:hackney, "~> 1.9"}

apps/activator_grpc/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule ActivatorGRPC.MixProject do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
3232
{:actors, "~> 0.1", in_umbrella: true},
33-
{:cluster, "~> 0.1", in_umbrella: true},
33+
{:spawn, "~> 0.1", in_umbrella: true},
3434
{:metrics_endpoint, "~> 0.1", in_umbrella: true}
3535
]
3636
end

apps/activator_http/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule ActivatorHTTP.MixProject do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
3232
{:actors, "~> 0.1", in_umbrella: true},
33-
{:cluster, "~> 0.1", in_umbrella: true},
33+
{:spawn, "~> 0.1", in_umbrella: true},
3434
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3535
{:bakeware, "~> 0.2"},
3636
{:bandit, "~> 0.5"}

apps/activator_kafka/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule ActivatorKafka.MixProject do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
3232
{:actors, "~> 0.1", in_umbrella: true},
33-
{:cluster, "~> 0.1", in_umbrella: true},
33+
{:spawn, "~> 0.1", in_umbrella: true},
3434
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3535
{:broadway_kafka, "~> 0.3"},
3636
{:bakeware, "~> 0.2"},

apps/activator_pubsub/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule ActivatorPubSub.MixProject do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
3232
{:actors, "~> 0.1", in_umbrella: true},
33-
{:cluster, "~> 0.1", in_umbrella: true},
33+
{:spawn, "~> 0.1", in_umbrella: true},
3434
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3535
{:bakeware, "~> 0.2"},
3636
{:bandit, "~> 0.5"}

apps/activator_rabbitmq/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ defmodule ActivatorRabbitMQ.MixProject do
2929
defp deps do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
32-
{:cluster, "~> 0.1", in_umbrella: true},
32+
{:spawn, "~> 0.1", in_umbrella: true},
3333
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3434
{:bakeware, "~> 0.2"},
3535
{:bandit, "~> 0.5"},

apps/activator_sqs/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule ActivatorSQS.MixProject do
3030
[
3131
{:activator, "~> 0.1", in_umbrella: true},
3232
{:actors, "~> 0.1", in_umbrella: true},
33-
{:cluster, "~> 0.1", in_umbrella: true},
33+
{:spawn, "~> 0.1", in_umbrella: true},
3434
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3535
{:bakeware, "~> 0.2"},
3636
{:bandit, "~> 0.5"},

apps/actors/mix.exs

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ defmodule Actors.MixProject do
2828
# Run "mix help deps" to learn about dependencies.
2929
defp deps do
3030
[
31-
{:cluster, "~> 0.1", in_umbrella: true},
32-
{:protos, "~> 0.1", in_umbrella: true},
31+
{:spawn, "~> 0.1", in_umbrella: true},
3332
{:statestores, "~> 0.1", in_umbrella: true},
3433
{:cowlib, "~> 2.9", override: true},
3534
{:decimal, "~> 2.0", override: true},

apps/actors/test/actors/actors_test.exs

+92-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
defmodule ActorsTest do
2-
use ExUnit.Case, async: false
3-
use Actors.MockTest
4-
import Actors.FactoryTest
2+
use Actors.DataCase, async: false
53

64
alias Eigr.Functions.Protocol.ActorInvocationResponse
75
alias Eigr.Functions.Protocol.Actors.ActorState
86
alias Eigr.Functions.Protocol.RegistrationResponse
97

10-
doctest Actors
8+
setup_all do
9+
actor_name = "global_actor_test"
10+
11+
actor = build_actor(name: actor_name)
12+
actor_entry = build_actor_entry(name: actor_name)
13+
registry = build_registry_with_actors(actors: [actor_entry])
14+
system = build_system(name: "global_sytem_name", registry: registry)
15+
16+
request = build_registration_request(actor_system: system)
17+
{:ok, %RegistrationResponse{}} = Actors.register(request)
18+
19+
%{system: system, actor: actor}
20+
end
1121

1222
describe "register/1" do
1323
test "register actors for a system" do
@@ -39,7 +49,7 @@ defmodule ActorsTest do
3949
end
4050

4151
describe "invoke/2" do
42-
test "invoke function for a newly registered actor" do
52+
test "invoke actor function for a newly registered actor" do
4353
actor_name = "actor_test_" <> Ecto.UUID.generate()
4454

4555
actor = build_actor(name: actor_name)
@@ -62,5 +72,82 @@ defmodule ActorsTest do
6272
assert {:ok, %ActorInvocationResponse{actor_name: ^actor_name}} =
6373
Actors.invoke(invoke_request)
6474
end
75+
76+
test "invoke actor function for a already registered actor in another node", ctx do
77+
%{system: system, actor: actor} = ctx
78+
actor_name = actor.name
79+
80+
invoke_request = build_invocation_request(system: system, actor: actor)
81+
82+
host_invoke_response =
83+
build_host_invoke_response(actor_name: actor_name, system_name: system.name)
84+
85+
mock_invoke_host_actor_with_ok_response(host_invoke_response)
86+
87+
assert {:ok, %ActorInvocationResponse{actor_name: ^actor_name}} =
88+
Actors.invoke(invoke_request)
89+
90+
state =
91+
Actors.Protos.ChangeNameResponseTest.new(
92+
status: :NAME_ALREADY_TAKEN,
93+
new_name: "new_name"
94+
)
95+
|> any_pack!
96+
97+
host_invoke_response =
98+
build_host_invoke_response(actor_name: actor_name, system_name: system.name, state: state)
99+
100+
mock_invoke_host_actor_with_ok_response(host_invoke_response)
101+
102+
# wait for nodes to sync
103+
Process.sleep(100)
104+
105+
assert {:ok,
106+
%ActorInvocationResponse{actor_name: ^actor_name, updated_context: updated_context}} =
107+
Spawn.NodeHelper.rpc(:"[email protected]", Actors, :invoke, [
108+
invoke_request
109+
])
110+
111+
assert %Actors.Protos.ChangeNameResponseTest{status: :NAME_ALREADY_TAKEN} =
112+
any_unpack!(updated_context.state, Actors.Protos.ChangeNameResponseTest)
113+
end
114+
115+
test "invoke function for a new actor without persistence in another node", _ctx do
116+
actor_name = "actor_not_persistent"
117+
118+
actor = build_actor(name: actor_name, persistent: false)
119+
actor_entry = build_actor_entry(name: actor_name, actor: actor)
120+
registry = build_registry_with_actors(actors: [actor_entry])
121+
system = build_system(name: "any_system_whatever", registry: registry)
122+
123+
request = build_registration_request(actor_system: system)
124+
{:ok, %RegistrationResponse{}} = Actors.register(request)
125+
126+
invoke_request = build_invocation_request(system: system, actor: actor)
127+
128+
state =
129+
Actors.Protos.ChangeNameResponseTest.new(
130+
status: :OK,
131+
new_name: "new_name"
132+
)
133+
|> any_pack!
134+
135+
host_invoke_response =
136+
build_host_invoke_response(actor_name: actor_name, system_name: system.name, state: state)
137+
138+
mock_invoke_host_actor_with_ok_response(host_invoke_response)
139+
140+
# wait for nodes to sync
141+
Process.sleep(100)
142+
143+
assert {:ok,
144+
%ActorInvocationResponse{actor_name: ^actor_name, updated_context: updated_context}} =
145+
Spawn.NodeHelper.rpc(:"[email protected]", Actors, :invoke, [
146+
invoke_request
147+
])
148+
149+
assert %Actors.Protos.ChangeNameResponseTest{status: :OK} =
150+
any_unpack!(updated_context.state, Actors.Protos.ChangeNameResponseTest)
151+
end
65152
end
66153
end

apps/actors/test/support/data_case.ex

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
defmodule Actors.DataCase do
2+
@moduledoc false
3+
4+
use ExUnit.CaseTemplate
5+
6+
using do
7+
quote do
8+
use Spawn.SandboxHelper, repos: [Statestores.Util.load_repo()]
9+
10+
use Actors.MockTest
11+
import Actors.FactoryTest
12+
13+
import Spawn.DataCase
14+
end
15+
end
16+
end

apps/actors/test/support/factory.ex

+14-13
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ defmodule Actors.FactoryTest do
8181
def build_actor(attrs \\ []) do
8282
Actor.new(
8383
name: attrs[:name] || "#{Faker.Superhero.name()} #{Faker.StarWars.character()}",
84-
persistent: attrs[:persistent] || false,
84+
persistent: Keyword.get(attrs, :persistent, true),
8585
state: attrs[:state] || build_actor_state(),
8686
snapshot_strategy: attrs[:snapshot_strategy] || build_actor_snapshot_strategy(),
8787
deactivate_strategy: attrs[:deactivate_strategy] || build_actor_deactivate_strategy()
@@ -90,12 +90,7 @@ defmodule Actors.FactoryTest do
9090

9191
def build_actor_state(attrs \\ []) do
9292
state =
93-
Any.new(
94-
type_url: get_type_url(Actors.Protos.StateTest),
95-
value:
96-
Actors.Protos.StateTest.new(name: "example_state_name_#{Faker.Superhero.name()}")
97-
|> Actors.Protos.StateTest.encode()
98-
)
93+
any_pack!(Actors.Protos.StateTest.new(name: "example_state_name_#{Faker.Superhero.name()}"))
9994

10095
ActorState.new(state: Any.new(attrs[:state] || state))
10196
end
@@ -128,12 +123,7 @@ defmodule Actors.FactoryTest do
128123

129124
def build_host_invoke_response(attrs \\ []) do
130125
state =
131-
Any.new(
132-
type_url: get_type_url(Actors.Protos.ChangeNameTest),
133-
value:
134-
Actors.Protos.ChangeNameResponseTest.new(status: :OK, new_name: "new_name")
135-
|> Actors.Protos.ChangeNameTest.encode()
136-
)
126+
Actors.Protos.ChangeNameResponseTest.new(status: :OK, new_name: "new_name") |> any_pack!
137127

138128
context = Eigr.Functions.Protocol.Context.new(state: attrs[:state] || state)
139129

@@ -145,6 +135,17 @@ defmodule Actors.FactoryTest do
145135
)
146136
end
147137

138+
def any_pack!(record) do
139+
Any.new(
140+
type_url: get_type_url(record.__struct__),
141+
value: apply(record.__struct__, :encode, [record])
142+
)
143+
end
144+
145+
def any_unpack!(any_record, builder) do
146+
builder.decode(any_record.value)
147+
end
148+
148149
defp get_type_url(type) do
149150
parts =
150151
type

apps/actors/test/test_helper.exs

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,15 @@ Mimic.copy(Actors.Node.Client)
33
ExUnit.start()
44
Faker.start()
55

6-
Spawn.Cluster.Node.Registry.start_link(%{})
6+
Spawn.InitializerHelper.setup()
7+
8+
Actors.Supervisors.ProtocolSupervisor.start_link(%{})
9+
Actors.Supervisors.EntitySupervisor.start_link(%{})
10+
11+
node = Spawn.NodeHelper.spawn_peer("spawn_actors_node")
12+
13+
Spawn.NodeHelper.rpc(node, Spawn.InitializerHelper, :setup, [])
14+
Spawn.NodeHelper.rpc(node, Actors.Supervisors.ProtocolSupervisor, :start_link, [%{}])
15+
Spawn.NodeHelper.rpc(node, Actors.Supervisors.EntitySupervisor, :start_link, [%{}])
16+
17+
IO.puts("Nodes connected: #{inspect(Node.list())}")

apps/cluster/lib/cluster.ex

-5
This file was deleted.

apps/cluster/test/cluster_test.exs

-4
This file was deleted.

apps/cluster/test/test_helper.exs

-1
This file was deleted.

apps/operator/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ defmodule Operator.MixProject do
2828
# Run "mix help deps" to learn about dependencies.
2929
defp deps do
3030
[
31-
{:cluster, "~> 0.1", in_umbrella: true},
31+
{:spawn, "~> 0.1", in_umbrella: true},
3232
{:metrics_endpoint, "~> 0.1", in_umbrella: true},
3333
{:bandit, "~> 0.5"},
3434
{:bonny, "~> 0.5"},

apps/protos/.formatter.exs

-4
This file was deleted.

apps/protos/.gitignore

-26
This file was deleted.

apps/protos/README.md

-21
This file was deleted.

apps/protos/compile-pb.sh

-11
This file was deleted.

apps/protos/lib/protos.ex

-5
This file was deleted.

0 commit comments

Comments
 (0)