Skip to content

Commit

Permalink
Add network module tests
Browse files Browse the repository at this point in the history
- add automated tests for netvm
- add check for managed interfaces in wifimanager
- add go tools to devshell/shell.nix

Signed-off-by: Manuel Bluhm <[email protected]>
  • Loading branch information
mbssrc committed Aug 31, 2024
1 parent ee286dd commit 078fbf1
Show file tree
Hide file tree
Showing 5 changed files with 309 additions and 3 deletions.
11 changes: 9 additions & 2 deletions devshell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
devshell = {
name = "GIVC";
motd = ''
❄️ Welcome to the {14}{bold}Welcome to givc-devshell{reset} devshell ❄️
{14}{bold}❄️ Welcome to the givc devshell ❄️{reset}
$(type -p menu &>/dev/null && menu)
$(type -p update-pre-commit-hooks &>/dev/null && update-pre-commit-hooks)
'';
Expand All @@ -21,8 +21,10 @@
config.treefmt.build.wrapper
reuse
go
gotests
gopls
gosec
gotests
go-tools
golangci-lint
rustc
rustfmt
Expand Down Expand Up @@ -50,6 +52,11 @@
name = "gcl";
command = "grpcurl";
}
{
help = "Check golang vulnerabilities";
name = "go-checksec";
command = "gosec ./...";
}
{
help = "Update go dependencies";
name = "go-update";
Expand Down
7 changes: 7 additions & 0 deletions internal/pkgs/wifimanager/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,13 @@ func (c *WifiController) GetWifiDevices() ([]dbus.BusObject, error) {

for _, devicePath := range devicePaths {
device := c.conn.Object("org.freedesktop.NetworkManager", devicePath)
deviceManaged, err := device.GetProperty("org.freedesktop.NetworkManager.Device.Managed")
if err != nil {
return nil, fmt.Errorf("failed to get device type: %s", err)
}
if !deviceManaged.Value().(bool) {
continue // skip unmanaged devices
}
deviceTypeVriant, err := device.GetProperty("org.freedesktop.NetworkManager.Device.DeviceType")
if err != nil {
return nil, fmt.Errorf("failed to get device type: %s", err)
Expand Down
7 changes: 6 additions & 1 deletion nixos/tests/default.nix
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
{ imports = [ ./admin.nix ]; }
{
imports = [
./admin.nix
./netvm.nix
];
}
286 changes: 286 additions & 0 deletions nixos/tests/netvm.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
{
self,
lib,
inputs,
...
}:
let
tls = false;
snakeoil = ./snakeoil;
addrs = {
netvm = "192.168.101.1";
adminvm = "192.168.101.2";
};
adminSettings = {
name = "admin-vm";
addr = addrs.adminvm;
port = "9001";
protocol = "tcp"; # go version expect word "tcp" here, but it unused
};
mkTls = name: {
enable = tls;
caCertPath = "${snakeoil}/${name}/ca-cert.pem";
certPath = "${snakeoil}/${name}/${name}-cert.pem";
keyPath = "${snakeoil}/${name}/${name}-key.pem";
};
in
{
perSystem = _: {
vmTests.tests.netvm = {
module = {
nodes = {
adminvm =
{ pkgs, ... }:
{
imports = [ self.nixosModules.admin ];

networking.interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [
{
address = addrs.adminvm;
prefixLength = 24;
}
];
environment.systemPackages = [ pkgs.grpcurl ];
givc.admin = {
enable = true;
name = "admin-vm";
addr = addrs.adminvm;
port = "9001";
tls = mkTls "admin-vm";
};
};

netvm =
{ pkgs, ... }:
let
inherit (import "${inputs.nixpkgs.outPath}/nixos/tests/ssh-keys.nix" pkgs)
snakeOilPublicKey
;
in
{
imports = [ self.nixosModules.sysvm ];

# Setup users and keys
users.groups.ghaf = { };
users.users = {
ghaf = {
isNormalUser = true;
group = "ghaf";
openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
};
};
services.getty.autologinUser = "ghaf";
# End of users

# Emulate wireless interfaces
boot.kernelModules = [ "mac80211_hwsim" ];
# boot.kernelParams = [ "mac80211_hwsim.radios=3" ];

# Setup fake access point
services.hostapd = {
enable = true;
radios.wlan0 = {
wifi6.enable = true;
networks = {
wlan0 = {
bssid = "02:00:00:00:00:01";
ssid = "Test Network 1";
authentication = {
mode = "wpa3-sae";
saePasswords = [ { password = "secret-password"; } ];
};
};
wlan0-1 = {
bssid = "02:00:00:00:00:02";
ssid = "Test Network 2";
authentication = {
mode = "wpa2-sha256";
wpaPassword = "secret-password2";
};
};
};
};
};

# Configure DHCP server
services.dnsmasq = {
enable = true;
settings = {
dhcp-range = [
"interface:wlan0,192.168.1.10,192.168.1.200,255.255.255.0,1h"
"interface:wlan0-1,192.168.2.10,192.168.2.200,255.255.255.0,1h"
];
port = 0;
};
};
systemd.services.dnsmasq = {
after = [ "multi-user.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.restart = "always";
};

# Network settings
networking = {
firewall.enable = false;
interfaces = {
eth1.ipv4.addresses = [
{
address = addrs.netvm;
prefixLength = 24;
}
];
wlan0 = {
useDHCP = false;
ipv4.addresses = [
{
address = "192.168.1.1";
prefixLength = 24;
}
];
};
wlan0-1 = {
useDHCP = false;
ipv4.addresses = [
{
address = "192.168.2.1";
prefixLength = 24;
}
];
};
wlan1.useDHCP = true;
};

# Enable NetworkManager
networkmanager = {
enable = true;
unmanaged = [
"eth0"
"eth1"
"hwsim0"
"wlan0"
"wlan0-1"
];
};
enableIPv6 = false;
wireless.enable = lib.mkForce false;
};

givc.sysvm = {
enable = true;
admin = adminSettings;
addr = addrs.netvm;
name = "net-vm";
tls = mkTls "net-vm";
wifiManager = true;
hwidService = true;
hwidIface = "wlan1";
debug = true;
};
};
};
testScript =
{ nodes, ... }:
let
grpcurl_cmd = "/run/current-system/sw/bin/grpcurl ";
grpcurl_args =
if tls then
"-cacert ${nodes.netvm.givc.sysvm.tls.caCertPath} -cert ${nodes.netvm.givc.sysvm.tls.certPath} -key ${nodes.netvm.givc.sysvm.tls.keyPath}"
else
"-plaintext";
grpcurl_addr = "${nodes.netvm.givc.sysvm.addr}:${nodes.netvm.givc.sysvm.port} ";
in
''
import time
with subtest("boot_completed"):
adminvm.wait_for_unit("multi-user.target")
netvm.wait_for_unit("multi-user.target")
print(netvm.succeed("systemd-analyze critical-chain"))
print(netvm.succeed("systemd-analyze blame"))
with subtest("wifimanager_listnetworks"):
nwlistMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.ListNetwork")
print(nwlistMsg)
if not "networks" in nwlistMsg:
print("RPC 'wifimanager.WifiService.ListNetworks' failed, no networks found")
exit(1)
with subtest("wifimanager_connect"):
# Test connection to network 1
connectMsg = adminvm.succeed("${grpcurl_cmd} -d \'{\"SSID\":\"Test Network 1\",\"Password\":\"secret-password\"}\' ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.ConnectNetwork")
print(connectMsg)
if not "Connected" in connectMsg:
print("RPC 'wifimanager.WifiService.ConnectNetwork' failed")
exit(1)
activeNetworkMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.GetActiveConnection")
print(activeNetworkMsg)
if not "\"Connection\": true" in activeNetworkMsg:
print("RPC 'wifimanager.WifiService.GetActiveConnection' failed")
exit(1)
disconnectMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.DisconnectNetwork")
print(disconnectMsg)
if not "disconnected" in disconnectMsg:
print("RPC 'wifimanager.WifiService.DisconnectNetwork' failed")
exit(1)
# Test connection to network 2
connectMsg = adminvm.succeed("${grpcurl_cmd} -d \'{\"SSID\":\"Test Network 2\",\"Password\":\"secret-password2\"}\' ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.ConnectNetwork")
print(connectMsg)
if not "Connected" in connectMsg:
print("RPC 'wifimanager.WifiService.ConnectNetwork' failed")
exit(1)
activeNetworkMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.GetActiveConnection")
print(activeNetworkMsg)
if not "\"Connection\": true" in activeNetworkMsg:
print("RPC 'wifimanager.WifiService.GetActiveConnection' failed")
exit(1)
disconnectMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.DisconnectNetwork")
print(disconnectMsg)
if not "disconnected" in disconnectMsg:
print("RPC 'wifimanager.WifiService.DisconnectNetwork' failed")
exit(1)
with subtest("wifimanager_turnoff"):
# Test turn off wifi
turnoffMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.TurnOff")
print(turnoffMsg)
if not "Wireless disabled successfully" in turnoffMsg:
print("RPC 'wifimanager.WifiService.TurnOff' failed")
exit(1)
nwlistMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.ListNetwork")
print(nwlistMsg)
if "networks" in nwlistMsg:
print("RPC 'wifimanager.WifiService.ListNetworks' failed, networks found")
exit(1)
# Test turn on wifi
turnonMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.TurnOn")
print(turnonMsg)
if not "Wireless enabled successfully" in turnonMsg:
print("RPC 'wifimanager.WifiService.TurnOn' failed")
exit(1)
time.sleep(5)
nwlistMsg = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} wifimanager.WifiService.ListNetwork")
print(nwlistMsg)
if not "networks" in nwlistMsg:
print("RPC 'wifimanager.WifiService.ListNetworks' failed, no networks found")
exit(1)
with subtest("test_hwid_manager"):
# Test hwid manager service
hwId = adminvm.succeed("${grpcurl_cmd} ${grpcurl_args} ${grpcurl_addr} hwid.HwidService.GetHwId")
print(hwId)
if not "Identifier" in hwId:
print("RPC 'hwid.HwidService.GetHwId' failed")
exit(1)
'';
};
};
};
}
1 change: 1 addition & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pkgs.mkShell {
packages = with pkgs; [
go
gopls
gosec
gotests
go-tools
golangci-lint
Expand Down

0 comments on commit 078fbf1

Please sign in to comment.