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
25{
26 airgap =
27 { config, ... }:
28 {
29 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
30 {
31 address = "192.168.1.2";
32 prefixLength = 24;
33 }
34 ];
35 services.vwifi = {
36 server = {
37 enable = true;
38 ports.tcp = 8212;
39 # uncomment if you want to enable monitor mode on another node
40 # ports.spy = 8213;
41 openFirewall = true;
42 };
43 };
44 };
45}
46```
47
48### AP {#sec-nixos-test-wifi-ap}
49
50A node like this will act as a wireless access point in infrastructure mode.
51
52```nix
53{
54 ap =
55 { config, ... }:
56 {
57 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
58 {
59 address = "192.168.1.3";
60 prefixLength = 24;
61 }
62 ];
63 services.hostapd = {
64 enable = true;
65 radios.wlan0 = {
66 channel = 1;
67 networks.wlan0 = {
68 ssid = "NixOS Test Wi-Fi Network";
69 authentication = {
70 mode = "wpa3-sae";
71 saePasswords = [ { password = "supersecret"; } ];
72 enableRecommendedPairwiseCiphers = true;
73 };
74 };
75 };
76 };
77 services.vwifi = {
78 module = {
79 enable = true;
80 macPrefix = "74:F8:F6:00:01";
81 };
82 client = {
83 enable = true;
84 serverAddress = "192.168.1.2";
85 };
86 };
87 };
88}
89```
90
91### Station {#sec-nixos-test-wifi-station}
92
93A node like this acts as a wireless client.
94
95```nix
96{
97 station =
98 { config, ... }:
99 {
100 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
101 {
102 address = "192.168.1.3";
103 prefixLength = 24;
104 }
105 ];
106 networking.wireless = {
107 # No, really, we want it enabled!
108 enable = lib.mkOverride 0 true;
109 interfaces = [ "wlan0" ];
110 networks = {
111 "NixOS Test Wi-Fi Network" = {
112 psk = "supersecret";
113 authProtocols = [ "SAE" ];
114 };
115 };
116 };
117 services.vwifi = {
118 module = {
119 enable = true;
120 macPrefix = "74:F8:F6:00:02";
121 };
122 client = {
123 enable = true;
124 serverAddress = "192.168.1.2";
125 };
126 };
127 };
128}
129```
130
131### Monitor {#sec-nixos-test-wifi-monitor}
132
133When the monitor mode interface is enabled, this node will receive
134all packets broadcast by all other nodes through the spy interface.
135
136```nix
137{
138 monitor =
139 { config, ... }:
140 {
141 networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
142 {
143 address = "192.168.1.4";
144 prefixLength = 24;
145 }
146 ];
147
148 services.vwifi = {
149 module = {
150 enable = true;
151 macPrefix = "74:F8:F6:00:03";
152 };
153 client = {
154 enable = true;
155 spy = true;
156 serverAddress = "192.168.1.2";
157 };
158 };
159 };
160}
161```