diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 49422e4b..cb605ef4 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -16,6 +16,7 @@ handleTest = path: args: nixosTesting.simpleTest (import path (pkgs // args)); in { archiver-appliance = handleTest ./archiver-appliance {}; + ca-gateway = handleTest ./ca-gateway.nix {}; phoebus-alarm = handleTest ./phoebus/alarm.nix {}; phoebus-olog = handleTest ./phoebus/olog.nix {}; } diff --git a/nixos/tests/ca-gateway.nix b/nixos/tests/ca-gateway.nix new file mode 100644 index 00000000..fbc60400 --- /dev/null +++ b/nixos/tests/ca-gateway.nix @@ -0,0 +1,92 @@ +{ + epnixLib, + pkgs, + ... +}: { + name = "ca-gateway-simple-check"; + meta.maintainers = with epnixLib.maintainers; [minijackson]; + + nodes = let + softIoc = vlans: db: let + dbfile = pkgs.writeText "softIoc.db" db; + in { + systemd.services.ioc = { + wantedBy = ["multi-user.target"]; + wants = ["network-online.target"]; + after = ["network-online.target"]; + + serviceConfig = { + ExecStart = "${pkgs.epnix.epics-base}/bin/softIoc -S -d ${dbfile}"; + DynamicUser = true; + }; + }; + environment.systemPackages = [pkgs.epnix.epics-base]; + + networking.firewall.allowedTCPPorts = [5064 5065]; + networking.firewall.allowedUDPPorts = [5064 5065]; + + virtualisation.vlans = vlans; + }; + in { + # Test two IOC on their own network, but only one in the ADDR_LIST of the gateway + ioc = softIoc [1] '' + record(ai, "PV_CLIENT") { } + record(ai, "PV_CLIENT_IGNORED") { } + ''; + invisible_ioc = softIoc [1] '' + record(ai, "PV_INVISIBLE_CLIENT") { } + ''; + + # Test one IOC in its own network, but put the broadcast address + # in the ADDR_LIST of the gateway. + # Useful for testing the openFirewall option + ioc_broadcast = softIoc [2] '' + record(ai, "PV_FROM_BROADCAST") { } + ''; + + gateway = { + environment.systemPackages = [pkgs.epnix.epics-base]; + services.ca-gateway = { + enable = true; + openFirewall = true; + settings = { + # One unicast, one broadcast + cip = ["ioc" "192.168.2.255"]; + pvlist = pkgs.writeText "gateway.pvlist" '' + EVALUATION ORDER DENY, ALLOW + + .* DENY + PV_CLIENT ALLOW + PV_FROM_BROADCAST ALLOW + ''; + }; + }; + + # Put 3 first here so that the /etc/hosts file in VMs + # has the gateway IP from vlan 3 + virtualisation.vlans = [3 1 2]; + }; + + client = { + environment.systemPackages = [pkgs.epnix.epics-base]; + virtualisation.vlans = [3]; + }; + }; + + testScript = '' + start_all() + + gateway.wait_for_unit("ca-gateway.service") + ioc.wait_for_unit("ioc.service") + invisible_ioc.wait_for_unit("ioc.service") + client.wait_for_unit("multi-user.target") + + def caget(pv: str) -> str: + return f"EPICS_CA_AUTO_ADDR_LIST=NO EPICS_CA_ADDR_LIST=gateway caget {pv}" + + client.wait_until_succeeds(caget("PV_CLIENT")) + client.wait_until_succeeds(caget("PV_FROM_BROADCAST")) + client.fail(caget("PV_INVISIBLE_CLIENT")) + client.fail(caget("PV_CLIENT_IGNORED")) + ''; +}