1# Testing Hardware Features {#sec-nixos-test-testing-hardware-features}
2
3This section covers how to test various features using NixOS tests that would
4normally only be possible with hardware. It is designed to showcase the NixOS test
5framework's flexibility when combined with various hardware simulation libraries
6or kernel modules.
7
8## Wi-Fi {#sec-nixos-test-wifi}
9
10Use `services.vwifi` to set up a virtual Wi-Fi physical layer. Create at least two nodes
11for this kind of test: one with vwifi active, and either a station or an access point.
12Give each a static IP address on the test network so they will never collide.
13This module likely supports other topologies too; document them if you make one.
14
15This NixOS module leverages [vwifi](https://github.com/Raizo62/vwifi). Read the
16upstream repository's documentation for more information.
17
18### vwifi server {#sec-nixos-test-wifi-vwifi-server}
19
20This node runs the vwifi server, and otherwise does not interact with the network.
21You can run `vwifi-ctrl` on this node to control characteristics of the simulated
22physical layer.
23
24```nix
25airgap =
26 { config, ... }:
27 {
28 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
29 {
30 address = "192.168.1.2";
31 prefixLength = 24;
32 }
33 ];
34 services.vwifi = {
35 server = {
36 enable = true;
37 ports.tcp = 8212;
38 # uncomment if you want to enable monitor mode on another node
39 # ports.spy = 8213;
40 openFirewall = true;
41 };
42 };
43 };
44```
45
46### AP {#sec-nixos-test-wifi-ap}
47
48A node like this will act as a wireless access point in infrastructure mode.
49
50```nix
51ap =
52 { config, ... }:
53 {
54 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
55 {
56 address = "192.168.1.3";
57 prefixLength = 24;
58 }
59 ];
60 services.hostapd = {
61 enable = true;
62 radios.wlan0 = {
63 channel = 1;
64 networks.wlan0 = {
65 ssid = "NixOS Test Wi-Fi Network";
66 authentication = {
67 mode = "wpa3-sae";
68 saePasswords = [ { password = "supersecret"; } ];
69 enableRecommendedPairwiseCiphers = true;
70 };
71 };
72 };
73 };
74 services.vwifi = {
75 module = {
76 enable = true;
77 macPrefix = "74:F8:F6:00:01";
78 };
79 client = {
80 enable = true;
81 serverAddress = "192.168.1.2";
82 };
83 };
84 };
85```
86
87### Station {#sec-nixos-test-wifi-station}
88
89A node like this acts as a wireless client.
90
91```nix
92station =
93 { config, ... }:
94 {
95 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
96 {
97 address = "192.168.1.3";
98 prefixLength = 24;
99 }
100 ];
101 networking.wireless = {
102 # No, really, we want it enabled!
103 enable = lib.mkOverride 0 true;
104 interfaces = [ "wlan0" ];
105 networks = {
106 "NixOS Test Wi-Fi Network" = {
107 psk = "supersecret";
108 authProtocols = [ "SAE" ];
109 };
110 };
111 };
112 services.vwifi = {
113 module = {
114 enable = true;
115 macPrefix = "74:F8:F6:00:02";
116 };
117 client = {
118 enable = true;
119 serverAddress = "192.168.1.2";
120 };
121 };
122 };
123```
124
125### Monitor {#sec-nixos-test-wifi-monitor}
126
127When the monitor mode interface is enabled, this node will receive
128all packets broadcast by all other nodes through the spy interface.
129
130```nix
131monitor =
132 { config, ... }:
133 {
134 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
135 {
136 address = "192.168.1.4";
137 prefixLength = 24;
138 }
139 ];
140
141 services.vwifi = {
142 module = {
143 enable = true;
144 macPrefix = "74:F8:F6:00:03";
145 };
146 client = {
147 enable = true;
148 spy = true;
149 serverAddress = "192.168.1.2";
150 };
151 };
152```