The Check protobuf has a `oneof config` field which generates separate
fields in the Elixir struct: :http, :tcp, :dns, :ssl. However,
check_type_config/2 was returning [config: {:http, ...}] which doesn't
match the struct definition, causing a KeyError crash in
build_and_push_check_jobs/1.
This bug was originally fixed in e0a74e2f but was accidentally
reintroduced in f703e61b when attempting to use "tagged tuple config".
Fix: Return field-specific keyword lists (e.g., [http: %HttpCheckConfig{}])
instead of [config: {:http, ...}].
Also added comprehensive test that creates all 4 check types and verifies
no KeyError crash occurs when sending check jobs to agent.
Reviewed-on: graham/towerops-web#141
186 lines
6.4 KiB
Elixir
186 lines
6.4 KiB
Elixir
defmodule Towerops.SettingsTest do
|
|
use Towerops.DataCase
|
|
|
|
alias Towerops.Settings
|
|
alias Towerops.Settings.ApplicationSetting
|
|
|
|
# Ensure the migration-seeded setting exists (CI may have stale test DB)
|
|
setup do
|
|
if !Settings.get_setting_record("global_default_cloud_poller_id") do
|
|
{:ok, _} = create_setting("global_default_cloud_poller_id", nil, "uuid")
|
|
end
|
|
|
|
:ok
|
|
end
|
|
|
|
describe "get_setting/1" do
|
|
test "returns parsed value for existing setting" do
|
|
assert Settings.get_setting("global_default_cloud_poller_id") == nil
|
|
end
|
|
|
|
test "returns nil for non-existent setting" do
|
|
assert Settings.get_setting("nonexistent_key") == nil
|
|
end
|
|
|
|
test "parses string values correctly" do
|
|
{:ok, _setting} = create_setting("test_string", "hello", "string")
|
|
assert Settings.get_setting("test_string") == "hello"
|
|
end
|
|
|
|
test "parses integer values correctly" do
|
|
{:ok, _setting} = create_setting("test_integer", "42", "integer")
|
|
assert Settings.get_setting("test_integer") == 42
|
|
end
|
|
|
|
test "parses boolean values correctly" do
|
|
{:ok, _setting} = create_setting("test_bool_true", "true", "boolean")
|
|
{:ok, _setting} = create_setting("test_bool_false", "false", "boolean")
|
|
{:ok, _setting} = create_setting("test_bool_one", "1", "boolean")
|
|
{:ok, _setting} = create_setting("test_bool_zero", "0", "boolean")
|
|
|
|
assert Settings.get_setting("test_bool_true") == true
|
|
assert Settings.get_setting("test_bool_false") == false
|
|
assert Settings.get_setting("test_bool_one") == true
|
|
assert Settings.get_setting("test_bool_zero") == false
|
|
end
|
|
|
|
test "parses json values correctly" do
|
|
{:ok, _setting} = create_setting("test_json", ~s({"key": "value"}), "json")
|
|
assert Settings.get_setting("test_json") == %{"key" => "value"}
|
|
end
|
|
|
|
test "returns nil for invalid integer" do
|
|
{:ok, _setting} = create_setting("test_invalid_int", "not_a_number", "integer")
|
|
assert Settings.get_setting("test_invalid_int") == nil
|
|
end
|
|
|
|
test "returns nil for invalid json" do
|
|
{:ok, _setting} = create_setting("test_invalid_json", "not json", "json")
|
|
assert Settings.get_setting("test_invalid_json") == nil
|
|
end
|
|
|
|
test "parses decimal values correctly" do
|
|
{:ok, _setting} = create_setting("test_decimal", "123.45", "decimal")
|
|
|
|
result = Settings.get_setting("test_decimal")
|
|
assert result == Decimal.new("123.45")
|
|
assert %Decimal{} = result
|
|
end
|
|
|
|
test "returns nil for invalid decimal" do
|
|
{:ok, _setting} = create_setting("test_invalid_decimal", "not_a_number", "decimal")
|
|
|
|
assert Settings.get_setting("test_invalid_decimal") == nil
|
|
end
|
|
|
|
test "parses decimal with remainder correctly" do
|
|
{:ok, _setting} = create_setting("test_decimal_remainder", "123.45abc", "decimal")
|
|
|
|
# Decimal.parse stops at invalid chars, returns parsed portion
|
|
assert Settings.get_setting("test_decimal_remainder") == Decimal.new("123.45")
|
|
end
|
|
end
|
|
|
|
describe "get_setting_record/1" do
|
|
test "returns the raw ApplicationSetting record" do
|
|
record = Settings.get_setting_record("global_default_cloud_poller_id")
|
|
assert %ApplicationSetting{} = record
|
|
assert record.key == "global_default_cloud_poller_id"
|
|
assert record.value_type == "uuid"
|
|
end
|
|
|
|
test "returns nil for non-existent setting" do
|
|
assert Settings.get_setting_record("nonexistent") == nil
|
|
end
|
|
end
|
|
|
|
describe "update_setting/2" do
|
|
test "updates an existing setting value" do
|
|
agent_token_id = Ecto.UUID.generate()
|
|
{:ok, updated} = Settings.update_setting("global_default_cloud_poller_id", agent_token_id)
|
|
|
|
assert updated.value == agent_token_id
|
|
assert Settings.get_setting("global_default_cloud_poller_id") == agent_token_id
|
|
end
|
|
|
|
test "updates setting to nil" do
|
|
agent_token_id = Ecto.UUID.generate()
|
|
{:ok, _} = Settings.update_setting("global_default_cloud_poller_id", agent_token_id)
|
|
{:ok, updated} = Settings.update_setting("global_default_cloud_poller_id", nil)
|
|
|
|
assert updated.value == nil
|
|
assert Settings.get_setting("global_default_cloud_poller_id") == nil
|
|
end
|
|
|
|
test "creates setting if it doesn't exist" do
|
|
assert {:ok, setting} = Settings.update_setting("nonexistent_key", "value")
|
|
assert setting.key == "nonexistent_key"
|
|
assert setting.value == "value"
|
|
assert setting.value_type == "string"
|
|
end
|
|
|
|
test "converts non-string values to strings" do
|
|
{:ok, _setting} = create_setting("test_number", "0", "integer")
|
|
{:ok, updated} = Settings.update_setting("test_number", 123)
|
|
|
|
assert updated.value == "123"
|
|
assert Settings.get_setting("test_number") == 123
|
|
end
|
|
end
|
|
|
|
describe "get_global_default_cloud_poller/0" do
|
|
test "returns nil when not configured" do
|
|
assert Settings.get_global_default_cloud_poller() == nil
|
|
end
|
|
|
|
test "returns agent token ID when configured" do
|
|
agent_token_id = Ecto.UUID.generate()
|
|
{:ok, _} = Settings.set_global_default_cloud_poller(agent_token_id)
|
|
|
|
assert Settings.get_global_default_cloud_poller() == agent_token_id
|
|
end
|
|
end
|
|
|
|
describe "set_global_default_cloud_poller/1" do
|
|
test "sets the global default cloud poller" do
|
|
agent_token_id = Ecto.UUID.generate()
|
|
{:ok, setting} = Settings.set_global_default_cloud_poller(agent_token_id)
|
|
|
|
assert setting.value == agent_token_id
|
|
assert Settings.get_global_default_cloud_poller() == agent_token_id
|
|
end
|
|
|
|
test "clears the global default cloud poller when set to nil" do
|
|
agent_token_id = Ecto.UUID.generate()
|
|
{:ok, _} = Settings.set_global_default_cloud_poller(agent_token_id)
|
|
{:ok, setting} = Settings.set_global_default_cloud_poller(nil)
|
|
|
|
assert setting.value == nil
|
|
assert Settings.get_global_default_cloud_poller() == nil
|
|
end
|
|
end
|
|
|
|
describe "list_all_settings/0" do
|
|
test "returns all application settings" do
|
|
# Create a test setting first
|
|
{:ok, _} = create_setting("test_setting", "test_value", "string")
|
|
|
|
settings = Settings.list_all_settings()
|
|
|
|
assert is_list(settings)
|
|
refute Enum.empty?(settings)
|
|
assert Enum.any?(settings, &(&1.key == "test_setting"))
|
|
end
|
|
end
|
|
|
|
# Helper function to create test settings
|
|
defp create_setting(key, value, value_type) do
|
|
%ApplicationSetting{}
|
|
|> ApplicationSetting.changeset(%{
|
|
key: key,
|
|
value: value,
|
|
value_type: value_type
|
|
})
|
|
|> Repo.insert()
|
|
end
|
|
end
|