335 lines
10 KiB
Elixir
335 lines
10 KiB
Elixir
defmodule Mix.Tasks.GenVendorTestsTest do
|
|
use ExUnit.Case, async: false
|
|
|
|
import ExUnit.CaptureIO
|
|
|
|
alias Mix.Tasks.GenVendorTests
|
|
|
|
@moduletag :mix_task
|
|
|
|
setup do
|
|
# Save original directory
|
|
original_dir = File.cwd!()
|
|
|
|
# Create temporary directories for vendor modules and tests
|
|
temp_dir = Path.join(System.tmp_dir!(), "vendor_tests_#{System.unique_integer([:positive])}")
|
|
vendors_dir = Path.join(temp_dir, "lib/towerops/snmp/profiles/vendors")
|
|
tests_dir = Path.join(temp_dir, "test/towerops/snmp/profiles/vendors")
|
|
File.mkdir_p!(vendors_dir)
|
|
File.mkdir_p!(tests_dir)
|
|
|
|
on_exit(fn ->
|
|
File.cd!(original_dir)
|
|
File.rm_rf!(temp_dir)
|
|
end)
|
|
|
|
{:ok, temp_dir: temp_dir, vendors_dir: vendors_dir, tests_dir: tests_dir}
|
|
end
|
|
|
|
describe "run/1 with dry-run" do
|
|
test "reports vendors without tests in dry-run mode", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: _tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module
|
|
File.write!(Path.join(vendors_dir, "mikrotik.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Mikrotik do
|
|
@behaviour Towerops.Snmp.Profiles.Vendors.Vendor
|
|
|
|
@impl true
|
|
def profile_names, do: ["mikrotik"]
|
|
end
|
|
""")
|
|
|
|
# Change to temp directory to run task
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run(["--dry-run"])
|
|
end)
|
|
|
|
assert output =~ "Found 1 vendor modules"
|
|
assert output =~ "Found 0 existing tests"
|
|
assert output =~ "1 vendors need tests"
|
|
assert output =~ "Would generate: test/towerops/snmp/profiles/vendors/mikrotik_test.exs"
|
|
end)
|
|
end
|
|
|
|
test "reports no work needed when all vendors have tests", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module
|
|
File.write!(Path.join(vendors_dir, "mikrotik.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Mikrotik do
|
|
def profile_names, do: ["mikrotik"]
|
|
end
|
|
""")
|
|
|
|
# Create corresponding test
|
|
File.write!(Path.join(tests_dir, "mikrotik_test.exs"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.MikrotikTest do
|
|
use ExUnit.Case
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run(["--dry-run"])
|
|
end)
|
|
|
|
assert output =~ "All vendor modules have tests!"
|
|
end)
|
|
end
|
|
end
|
|
|
|
describe "run/1 without dry-run" do
|
|
test "generates test file for vendor without test", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module with profile_names
|
|
File.write!(Path.join(vendors_dir, "cisco.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Cisco do
|
|
@behaviour Towerops.Snmp.Profiles.Vendors.Vendor
|
|
|
|
@impl true
|
|
def profile_names, do: ["cisco-ios", "cisco-nxos"]
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
assert output =~ "Generated: test/towerops/snmp/profiles/vendors/cisco_test.exs"
|
|
assert output =~ "Generated 1 test files"
|
|
|
|
# Verify test file was created
|
|
test_file = Path.join(tests_dir, "cisco_test.exs")
|
|
assert File.exists?(test_file)
|
|
|
|
content = File.read!(test_file)
|
|
assert content =~ "defmodule Towerops.Snmp.Profiles.Vendors.CiscoTest do"
|
|
assert content =~ "use Towerops.DataCase, async: true"
|
|
assert content =~ "alias Towerops.Snmp.Profiles.Vendors.Cisco"
|
|
assert content =~ ~s{profile_names() == ["cisco-ios", "cisco-nxos"]}
|
|
assert content =~ "describe \"profile_names/0\" do"
|
|
assert content =~ "describe \"detect_hardware/1\" do"
|
|
assert content =~ "describe \"wireless_oid_defs/0\" do"
|
|
assert content =~ "describe \"discover_wireless_sensors/1\" do"
|
|
end)
|
|
end
|
|
|
|
test "generates tests for multiple vendors", %{vendors_dir: vendors_dir, tests_dir: tests_dir, temp_dir: temp_dir} do
|
|
# Create multiple vendor modules
|
|
File.write!(Path.join(vendors_dir, "mikrotik.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Mikrotik do
|
|
def profile_names, do: ["mikrotik"]
|
|
end
|
|
""")
|
|
|
|
File.write!(Path.join(vendors_dir, "ubiquiti.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Ubiquiti do
|
|
def profile_names, do: ["ubnt"]
|
|
end
|
|
""")
|
|
|
|
File.write!(Path.join(vendors_dir, "cisco.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Cisco do
|
|
def profile_names, do: ["cisco"]
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
assert output =~ "Generated 3 test files"
|
|
assert File.exists?(Path.join(tests_dir, "mikrotik_test.exs"))
|
|
assert File.exists?(Path.join(tests_dir, "ubiquiti_test.exs"))
|
|
assert File.exists?(Path.join(tests_dir, "cisco_test.exs"))
|
|
end)
|
|
end
|
|
|
|
test "skips vendors that already have tests", %{vendors_dir: vendors_dir, tests_dir: tests_dir, temp_dir: temp_dir} do
|
|
# Create vendor modules
|
|
File.write!(Path.join(vendors_dir, "mikrotik.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Mikrotik do
|
|
def profile_names, do: ["mikrotik"]
|
|
end
|
|
""")
|
|
|
|
File.write!(Path.join(vendors_dir, "cisco.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Cisco do
|
|
def profile_names, do: ["cisco"]
|
|
end
|
|
""")
|
|
|
|
# Create test for mikrotik (but not cisco)
|
|
File.write!(Path.join(tests_dir, "mikrotik_test.exs"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.MikrotikTest do
|
|
use ExUnit.Case
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
assert output =~ "Found 2 vendor modules"
|
|
assert output =~ "Found 1 existing tests"
|
|
assert output =~ "1 vendors need tests"
|
|
assert output =~ "Generated 1 test files"
|
|
|
|
# Only cisco test should be generated
|
|
assert File.exists?(Path.join(tests_dir, "cisco_test.exs"))
|
|
|
|
# Mikrotik test should be the old one (not regenerated)
|
|
mikrotik_test = File.read!(Path.join(tests_dir, "mikrotik_test.exs"))
|
|
assert mikrotik_test =~ "use ExUnit.Case"
|
|
refute mikrotik_test =~ "use Towerops.DataCase"
|
|
end)
|
|
end
|
|
|
|
test "excludes registry and vendor files from generation", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor modules
|
|
File.write!(Path.join(vendors_dir, "registry.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Registry do
|
|
end
|
|
""")
|
|
|
|
File.write!(Path.join(vendors_dir, "vendor.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Vendor do
|
|
end
|
|
""")
|
|
|
|
File.write!(Path.join(vendors_dir, "mikrotik.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Mikrotik do
|
|
def profile_names, do: ["mikrotik"]
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
# Should only count mikrotik as vendor module
|
|
assert output =~ "Found 1 vendor modules"
|
|
assert output =~ "Generated 1 test files"
|
|
|
|
# Only mikrotik test should be generated
|
|
assert File.exists?(Path.join(tests_dir, "mikrotik_test.exs"))
|
|
refute File.exists?(Path.join(tests_dir, "registry_test.exs"))
|
|
refute File.exists?(Path.join(tests_dir, "vendor_test.exs"))
|
|
end)
|
|
end
|
|
|
|
test "handles vendor module without profile_names function", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module without profile_names
|
|
File.write!(Path.join(vendors_dir, "custom.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.Custom do
|
|
# No profile_names function
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
assert output =~ "Generated 1 test files"
|
|
|
|
# Test should be generated with empty profile list
|
|
test_file = Path.join(tests_dir, "custom_test.exs")
|
|
assert File.exists?(test_file)
|
|
|
|
content = File.read!(test_file)
|
|
assert content =~ "assert Custom.profile_names() == []"
|
|
end)
|
|
end
|
|
|
|
test "generates proper module name for snake_case files", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module with snake_case filename
|
|
File.write!(Path.join(vendors_dir, "palo_alto.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.PaloAlto do
|
|
def profile_names, do: ["panos"]
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
_output =
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
# Test file should be palo_alto_test.exs
|
|
test_file = Path.join(tests_dir, "palo_alto_test.exs")
|
|
assert File.exists?(test_file)
|
|
|
|
# Module should be PaloAltoTest
|
|
content = File.read!(test_file)
|
|
assert content =~ "defmodule Towerops.Snmp.Profiles.Vendors.PaloAltoTest do"
|
|
assert content =~ "alias Towerops.Snmp.Profiles.Vendors.PaloAlto"
|
|
end)
|
|
end
|
|
|
|
test "generates tests with proper expect counts for wireless_oid_defs", %{
|
|
vendors_dir: vendors_dir,
|
|
tests_dir: tests_dir,
|
|
temp_dir: temp_dir
|
|
} do
|
|
# Create vendor module with multiple OID defs
|
|
File.write!(Path.join(vendors_dir, "test_vendor.ex"), """
|
|
defmodule Towerops.Snmp.Profiles.Vendors.TestVendor do
|
|
def profile_names, do: ["test"]
|
|
|
|
def wireless_oid_defs do
|
|
[
|
|
%{oid: "1.2.3.4.0", sensor_descr: "Temp", sensor_type: "temperature", sensor_unit: "C", sensor_divisor: 1},
|
|
%{oid: "1.2.3.5.0", sensor_descr: "Voltage", sensor_type: "voltage", sensor_unit: "V", sensor_divisor: 1},
|
|
%{oid: "1.2.3.6.0", sensor_descr: "Power", sensor_type: "power", sensor_unit: "W", sensor_divisor: 1}
|
|
]
|
|
end
|
|
end
|
|
""")
|
|
|
|
File.cd!(temp_dir, fn ->
|
|
capture_io(fn ->
|
|
GenVendorTests.run([])
|
|
end)
|
|
|
|
test_file = Path.join(tests_dir, "test_vendor_test.exs")
|
|
content = File.read!(test_file)
|
|
|
|
# Should verify list has >= 1 items (not hardcoded count)
|
|
assert content =~ "assert length(defs) >= 1"
|
|
end)
|
|
end
|
|
end
|
|
end
|