defmodule SnmpKit.SnmpLib.ConfigTest do use ExUnit.Case, async: false alias SnmpKit.SnmpLib.Config doctest Config @moduletag :config_test setup do # Ensure config process is stopped before each test if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end :timer.sleep(10) :ok end describe "Config.start_link/1" do test "starts with default configuration" do assert {:ok, pid} = Config.start_link() assert Process.alive?(pid) # Test default values (test environment has different defaults) assert Config.get(:snmp, :default_version) == :v2c assert Config.get(:pool, :default_size) == 2 # Environment defaults to :test in test environment assert Config.environment() == :test try do GenServer.stop(Config) catch :exit, _ -> :ok end end test "starts with custom environment" do assert {:ok, _pid} = Config.start_link(environment: :prod) # Production environment should have different defaults assert Config.get(:pool, :default_size) == 25 assert Config.environment() == :prod try do GenServer.stop(Config) catch :exit, _ -> :ok end end end describe "Config.get/3 and Config.put/3" do setup do {:ok, _pid} = Config.start_link() on_exit(fn -> if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end end) :ok end test "gets and sets configuration values" do # Test simple get with default timeout = Config.get(:snmp, :default_timeout, 1000) assert is_integer(timeout) # Test put and get :ok = Config.put(:snmp, :custom_value, "test") assert Config.get(:snmp, :custom_value) == "test" end test "gets nested configuration values" do # Test nested path access threshold = Config.get(:monitoring, [:alert_thresholds, :error_rate]) assert is_float(threshold) # Test nested put :ok = Config.put(:monitoring, [:alert_thresholds, :custom], 0.15) assert Config.get(:monitoring, [:alert_thresholds, :custom]) == 0.15 end test "returns default for missing keys" do assert Config.get(:nonexistent, :key, :default) == :default assert Config.get(:snmp, :nonexistent, 42) == 42 end end describe "Config.validate/0" do setup do {:ok, _pid} = Config.start_link() on_exit(fn -> if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end end) :ok end test "validates correct configuration" do assert {:ok, _config} = Config.validate() end end describe "Config.all/0" do setup do {:ok, _pid} = Config.start_link() on_exit(fn -> if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end end) :ok end test "returns complete configuration map" do config = Config.all() assert Map.has_key?(config, :snmp) assert Map.has_key?(config, :pool) assert Map.has_key?(config, :monitoring) end end describe "Config.watch/2" do setup do {:ok, _pid} = Config.start_link() on_exit(fn -> if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end end) :ok end test "registers configuration watchers" do # Register a watcher test_pid = self() callback = fn _old, _new -> send(test_pid, :config_changed) end assert :ok = Config.watch(:snmp, callback) # Change configuration to trigger watcher assert :ok = Config.put(:snmp, :test_value, "changed") # Note: In a real implementation, this would trigger the callback # For now, we just test that the watcher registration succeeds end end describe "environment detection" do test "detects test environment by default" do {:ok, _pid} = Config.start_link() # Environment should be :test in test environment assert Config.environment() == :test try do GenServer.stop(Config) catch :exit, _ -> :ok end end test "respects explicit environment setting" do {:ok, _pid} = Config.start_link(environment: :dev) assert Config.environment() == :dev try do GenServer.stop(Config) catch :exit, _ -> :ok end end end describe "Config.reload/0" do setup do {:ok, _pid} = Config.start_link() on_exit(fn -> if Process.whereis(Config) do try do GenServer.stop(Config, :normal, 1000) catch :exit, _ -> :ok end end end) :ok end test "reloads configuration successfully" do # Change a value :ok = Config.put(:snmp, :test_reload, "before") assert Config.get(:snmp, :test_reload) == "before" # Reload should reset to defaults (since no external config file) assert :ok = Config.reload() # Value should be reset assert Config.get(:snmp, :test_reload, :missing) == :missing end end end