1{ system ? builtins.currentSystem
2, config ? {}
3, pkgs ? import ../.. { inherit system config; }
4}:
5
6with import ../../lib/testing-python.nix { inherit system pkgs; };
7
8let
9 lib = pkgs.lib;
10 # this is intended as a client test since you shouldn't use NetworkManager for a router or server
11 # so using systemd-networkd for the router vm is fine in these tests.
12 router = import ./router.nix { networkd = true; };
13 qemu-common = import ../../lib/qemu-common.nix { inherit (pkgs) lib pkgs; };
14 clientConfig = extraConfig: lib.recursiveUpdate {
15 networking.useDHCP = false;
16
17 # Make sure that only NetworkManager configures the interface
18 networking.interfaces = lib.mkForce {
19 eth1 = {};
20 };
21 networking.networkmanager = {
22 enable = true;
23 # this is needed so NM doesn't generate 'Wired Connection' profiles and instead uses the default one
24 settings.main.no-auto-default = "*";
25 ensureProfiles.profiles.default = {
26 connection = {
27 id = "default";
28 type = "ethernet";
29 interface-name = "eth1";
30 autoconnect = true;
31 };
32 };
33 };
34 } extraConfig;
35 testCases = {
36 static = {
37 name = "static";
38 nodes = {
39 inherit router;
40 client = clientConfig {
41 networking.networkmanager.ensureProfiles.profiles.default = {
42 ipv4.method = "manual";
43 ipv4.addresses = "192.168.1.42/24";
44 ipv4.gateway = "192.168.1.1";
45 ipv6.method = "manual";
46 ipv6.addresses = "fd00:1234:5678:1::42/64";
47 ipv6.gateway = "fd00:1234:5678:1::1";
48 };
49 };
50 };
51 testScript = ''
52 start_all()
53 router.systemctl("start network-online.target")
54 router.wait_for_unit("network-online.target")
55 client.wait_for_unit("NetworkManager.service")
56
57 with subtest("Wait until we have an ip address on each interface"):
58 client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
59 client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
60
61 with subtest("Test if icmp echo works"):
62 client.wait_until_succeeds("ping -c 1 192.168.3.1")
63 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1")
64 router.wait_until_succeeds("ping -c 1 192.168.1.42")
65 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::42")
66 '';
67 };
68 auto = {
69 name = "auto";
70 nodes = {
71 inherit router;
72 client = clientConfig {
73 networking.networkmanager.ensureProfiles.profiles.default = {
74 ipv4.method = "auto";
75 ipv6.method = "auto";
76 };
77 };
78 };
79 testScript = ''
80 start_all()
81 router.systemctl("start network-online.target")
82 router.wait_for_unit("network-online.target")
83 client.wait_for_unit("NetworkManager.service")
84
85 with subtest("Wait until we have an ip address on each interface"):
86 client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
87 client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
88
89 with subtest("Test if icmp echo works"):
90 client.wait_until_succeeds("ping -c 1 192.168.1.1")
91 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
92 router.wait_until_succeeds("ping -c 1 192.168.1.2")
93 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2")
94 '';
95 };
96 dns = {
97 name = "dns";
98 nodes = {
99 inherit router;
100 dynamic = clientConfig {
101 networking.networkmanager.ensureProfiles.profiles.default = {
102 ipv4.method = "auto";
103 };
104 };
105 static = clientConfig {
106 networking.networkmanager.ensureProfiles.profiles.default = {
107 ipv4 = {
108 method = "auto";
109 ignore-auto-dns = "true";
110 dns = "10.10.10.10";
111 dns-search = "";
112 };
113 };
114 };
115 };
116 testScript = ''
117 start_all()
118 router.systemctl("start network-online.target")
119 router.wait_for_unit("network-online.target")
120 dynamic.wait_for_unit("NetworkManager.service")
121 static.wait_for_unit("NetworkManager.service")
122
123 dynamic.wait_until_succeeds("cat /etc/resolv.conf | grep -q '192.168.1.1'")
124 static.wait_until_succeeds("cat /etc/resolv.conf | grep -q '10.10.10.10'")
125 static.wait_until_fails("cat /etc/resolv.conf | grep -q '192.168.1.1'")
126 '';
127 };
128 dispatcherScripts = {
129 name = "dispatcherScripts";
130 nodes.client = clientConfig {
131 networking.networkmanager.dispatcherScripts = [{
132 type = "pre-up";
133 source = pkgs.writeText "testHook" ''
134 touch /tmp/dispatcher-scripts-are-working
135 '';
136 }];
137 };
138 testScript = ''
139 start_all()
140 client.wait_for_unit("NetworkManager.service")
141 client.wait_until_succeeds("stat /tmp/dispatcher-scripts-are-working")
142 '';
143 };
144 envsubst = {
145 name = "envsubst";
146 nodes.client = let
147 # you should never write secrets in to your nixos configuration, please use tools like sops-nix or agenix
148 secretFile = pkgs.writeText "my-secret.env" ''
149 MY_SECRET_IP=fd00:1234:5678:1::23/64
150 '';
151 in clientConfig {
152 networking.networkmanager.ensureProfiles.environmentFiles = [ secretFile ];
153 networking.networkmanager.ensureProfiles.profiles.default = {
154 ipv6.method = "manual";
155 ipv6.addresses = "$MY_SECRET_IP";
156 };
157 };
158 testScript = ''
159 start_all()
160 client.wait_for_unit("NetworkManager.service")
161 client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
162 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::23")
163 '';
164 };
165 };
166in lib.mapAttrs (lib.const (attrs: makeTest (attrs // {
167 name = "${attrs.name}-Networking-NetworkManager";
168 meta = {
169 maintainers = with lib.maintainers; [ janik ];
170 };
171
172}))) testCases