Skip to content

Commit

Permalink
Fix tests for network config change
Browse files Browse the repository at this point in the history
  • Loading branch information
jsonmaur committed Apr 23, 2023
1 parent 62296e7 commit 571024a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 32 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ NETWORK="private"
IPV="ipv4"

# Droplet hostname is only needed if `:node_basename` is not defined in your strategy config.
# Otherwise, replace this with the value defined in `:node_basename`.
# Otherwise, replace this curl command with the value defined in `:node_basename`.
HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)

IP_ADDRESS=$(curl -s http://169.254.169.254/metadata/v1/interfaces/$NETWORK/0/$IPV/address)

export RELEASE_DISTRIBUTION=name
Expand All @@ -83,17 +84,18 @@ Erlang's [epmd](https://www.erlang.org/doc/man/epmd.html) communicates on port 4
If you want to tighten security even further and only allow specific ports, you can customize the ports used by epmd by adding this to your `env.sh.eex` file:

```sh
#
# This port will be used by epmd instead of port 4369.
ERL_EPMD_PORT=9000
ERL_NODE_PORT=9001

# This port will be used by epmd instead of a random port for each node.
# Note that if you set this value, you can only run one app instance in each Droplet.
NODE_PORT=9001

case $RELEASE_COMMAND in
start*|daemon*)
export ELIXIR_ERL_OPTIONS="-kernel inet_dist_listen_min $ERL_NODE_PORT inet_dist_listen_max $ERL_NODE_PORT"
export ELIXIR_ERL_OPTIONS="-kernel inet_dist_listen_min $NODE_PORT inet_dist_listen_max $NODE_PORT"
;;
*)
;;
esac
```

*Note that if you use a single node port, you can only run one app instance in each Droplet.*
2 changes: 1 addition & 1 deletion test/fixtures/custom_cassettes/droplets.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"headers": {
"content-type": "application/json; charset=utf-8"
},
"body": "{\"droplets\":[{\"id\":\"3164444\",\"name\":\"example\",\"status\":\"active\",\"networks\":{\"v4\":[{\"ip_address\":\"192.241.165.154\",\"type\":\"public\"}]}}]}\n"
"body": "{\"droplets\":[{\"id\":\"3164444\",\"name\":\"example\",\"status\":\"active\",\"networks\":{\"v4\":[{\"ip_address\":\"10.128.192.124\",\"type\":\"private\"}]}}]}\n"
}
},
{
Expand Down
60 changes: 35 additions & 25 deletions test/strategy/droplet_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,23 @@ defmodule Cluster.Strategy.DropletTest do
"id" => 2,
"name" => "foobar",
"status" => "off",
"networks" => %{"v4" => [%{"type" => "public", "ip_address" => "2.2.2.2"}]}
"networks" => %{
"v4" => [
%{"type" => "public", "ip_address" => "2.2.2.2"},
%{"type" => "private", "ip_address" => "127.0.0.2"}
]
}
},
%{
"id" => 3,
"name" => "foobar",
"status" => "active",
"networks" => %{"v4" => [%{"type" => "public", "ip_address" => "3.3.3.3"}]}
"networks" => %{
"v4" => [
%{"type" => "public", "ip_address" => "3.3.3.3"},
%{"type" => "private", "ip_address" => "127.0.0.3"}
]
}
}
]

Expand All @@ -58,8 +68,7 @@ defmodule Cluster.Strategy.DropletTest do
config: [
polling_interval: 100,
token: "dop_v1_abc123",
tag_name: "foobar",
network: :public
tag_name: "foobar"
]
}

Expand All @@ -71,25 +80,25 @@ defmodule Cluster.Strategy.DropletTest do
capture_log(fn -> Droplet.start_link([ctx.state]) end)
end

assert_receive {:connect, :"example@192.241.165.154"}, 100
assert_receive {:connect, :"example@10.128.192.124"}, 100
end

test "should remove nodes", ctx do
use_cassette "droplets", custom: true do
nodes = [:"example@192.241.165.154", :"example@1.2.3.4"]
nodes = [:"example@1.2.3.4", :"example@10.128.192.124"]
state = Map.put(ctx.state, :meta, MapSet.new(nodes))
state = Map.put(state, :list_nodes, {__MODULE__, :list_nodes, [nodes]})

capture_log(fn -> Droplet.start_link([state]) end)
end

assert_receive {:disconnect, :"example@1.2.3.4"}, 100
refute_receive {:connect, :"example@192.241.165.154"}, 100
refute_receive {:connect, :"example@10.128.192.124"}, 100
end

test "should not do anything if nodes have not changed", ctx do
use_cassette "droplets", custom: true do
nodes = [:"example@192.241.165.154"]
nodes = [:"example@10.128.192.124"]
state = Map.put(ctx.state, :meta, MapSet.new(nodes))
state = Map.put(state, :list_nodes, {__MODULE__, :list_nodes, [nodes]})

Expand Down Expand Up @@ -134,16 +143,16 @@ defmodule Cluster.Strategy.DropletTest do

use_cassette "droplets", custom: true, match_requests_on: [:query], custom_matchers: [auth] do
assert Droplet.get_nodes(%State{}, "https://api.digitalocean.com/v2/droplets", "dop_v1_abc123", nil) == [
:"example@192.241.165.154",
:"example@162.243.0.4"
:"example@10.128.192.124",
:"example@10.128.192.138"
]
end
end

test "should not return self in list of nodes" do
use_cassette "droplets", custom: true, match_requests_on: [:query] do
assert Droplet.get_nodes(%State{}, "https://api.digitalocean.com/v2/droplets", "dop_v1_abc123", "3164444") == [
:"example@162.243.0.4"
:"example@10.128.192.138"
]
end
end
Expand Down Expand Up @@ -174,19 +183,19 @@ defmodule Cluster.Strategy.DropletTest do

describe "to_node_names/3" do
test "should return list of names", ctx do
assert Droplet.to_node_names(%State{}, ctx.droplets) == [:"foobar@1.1.1.1", :"foobar@3.3.3.3"]
assert Droplet.to_node_names(%State{}, ctx.droplets) == [:"foobar@127.0.0.1", :"foobar@127.0.0.3"]
end

test "should return list of names without self", ctx do
assert Droplet.to_node_names(%State{}, ctx.droplets, 1) == [:"foobar@3.3.3.3"]
assert Droplet.to_node_names(%State{}, ctx.droplets, 1) == [:"foobar@127.0.0.3"]
end

test "should not return name for droplet with no ip address", ctx do
droplets = ctx.droplets ++ [%{"id" => 4, "name" => "foobar", "status" => "active", "networks" => %{}}]

assert capture_log(fn ->
assert Droplet.to_node_names(%State{}, droplets) == [:"foobar@1.1.1.1", :"foobar@3.3.3.3"]
end) =~ "No public ipv4 network was found for droplet #4"
assert Droplet.to_node_names(%State{}, droplets) == [:"foobar@127.0.0.1", :"foobar@127.0.0.3"]
end) =~ "No private ipv4 network was found for droplet #4"
end
end

Expand All @@ -195,30 +204,31 @@ defmodule Cluster.Strategy.DropletTest do
%{droplet: Enum.at(ctx.droplets, 0)}
end

test "should return name from ipv4 public address", ctx do
assert Droplet.to_node_name(%State{}, ctx.droplet) == :"foobar@1.1.1.1"
end

test "should return name from ipv4 private address", ctx do
assert Droplet.to_node_name(%State{config: [network: :private]}, ctx.droplet) == :"foobar@127.0.0.1"
assert Droplet.to_node_name(%State{}, ctx.droplet) == :"foobar@127.0.0.1"
end

test "should return name from ipv6 public address", ctx do
assert Droplet.to_node_name(%State{config: [ipv6: true]}, ctx.droplet) == :"foobar@2606:4700:4700::1111"
test "should return name from ipv4 public address", ctx do
assert Droplet.to_node_name(%State{config: [network: :public]}, ctx.droplet) == :"foobar@1.1.1.1"
end

test "should return name from ipv6 private address", ctx do
assert Droplet.to_node_name(%State{config: [ipv6: true, network: :private]}, ctx.droplet) == :"foobar@::1"
assert Droplet.to_node_name(%State{config: [ipv6: true]}, ctx.droplet) == :"foobar@::1"
end

test "should return name from ipv6 public address", ctx do
assert Droplet.to_node_name(%State{config: [ipv6: true, network: :public]}, ctx.droplet) ==
:"foobar@2606:4700:4700::1111"
end

test "should return name with a base name", ctx do
assert Droplet.to_node_name(%State{config: [node_basename: "yo"]}, ctx.droplet) == :"yo@1.1.1.1"
assert Droplet.to_node_name(%State{config: [node_basename: "yo"]}, ctx.droplet) == :"yo@127.0.0.1"
end

test "should not return name for droplet with no ip address" do
assert capture_log(fn ->
refute Droplet.to_node_name(%State{}, %{"id" => 1, "networks" => %{}})
end) =~ "No public ipv4 network was found for droplet #1"
end) =~ "No private ipv4 network was found for droplet #1"
end
end

Expand Down

0 comments on commit 571024a

Please sign in to comment.