| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- package wifi
- import (
- "os"
- "path/filepath"
- "runtime"
- "testing"
- db "imuslab.com/arozos/mod/database"
- )
- // newTestDatabase creates a temporary bolt database for use in tests.
- // The caller is responsible for calling the returned cleanup function.
- func newTestDatabase(t *testing.T) (*db.Database, func()) {
- t.Helper()
- tmpDir := t.TempDir()
- dbPath := filepath.Join(tmpDir, "test.db")
- // Create the file so the database opener can find it.
- f, err := os.Create(dbPath)
- if err != nil {
- t.Fatalf("failed to create temp db file: %v", err)
- }
- f.Close()
- database, err := db.NewDatabase(dbPath, false)
- if err != nil {
- t.Fatalf("NewDatabase() error: %v", err)
- }
- cleanup := func() {
- // Nothing extra needed; t.TempDir() handles directory removal.
- _ = database
- }
- return database, cleanup
- }
- // ---------------------------------------------------------------------------
- // NewWiFiManager
- // ---------------------------------------------------------------------------
- // TestNewWiFiManager verifies that the constructor returns a non-nil manager
- // and creates the expected database table.
- func TestNewWiFiManager(t *testing.T) {
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "/etc/wpa_supplicant/wpa_supplicant.conf", "wlan0")
- if wm == nil {
- t.Fatal("NewWiFiManager() returned nil")
- }
- // Verify the wifi table was created.
- if !database.TableExists("wifi") {
- t.Error("NewWiFiManager() did not create 'wifi' table in the database")
- }
- }
- // TestNewWiFiManagerSudoMode verifies that sudo_mode is stored correctly.
- func TestNewWiFiManagerSudoMode(t *testing.T) {
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, true, "/tmp/wpa.conf", "wlan1")
- if wm == nil {
- t.Fatal("NewWiFiManager() returned nil")
- }
- if !wm.sudo_mode {
- t.Error("sudo_mode should be true")
- }
- }
- // TestNewWiFiManagerFields verifies that all constructor arguments are stored.
- func TestNewWiFiManagerFields(t *testing.T) {
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wpaPath := "/etc/wpa_supplicant.conf"
- wlanName := "wlan2"
- wm := NewWiFiManager(database, false, wpaPath, wlanName)
- if wm.wpa_supplicant_path != wpaPath {
- t.Errorf("wpa_supplicant_path = %q, expected %q", wm.wpa_supplicant_path, wpaPath)
- }
- if wm.wan_interface_name != wlanName {
- t.Errorf("wan_interface_name = %q, expected %q", wm.wan_interface_name, wlanName)
- }
- if wm.database != database {
- t.Error("database pointer not stored correctly")
- }
- }
- // ---------------------------------------------------------------------------
- // GetWirelessInterfaces
- // ---------------------------------------------------------------------------
- // TestGetWirelessInterfaces verifies that GetWirelessInterfaces does not error
- // on the current platform. On Linux it may return an empty list if no wireless
- // hardware is present (common in CI); on Darwin/FreeBSD it always returns an
- // empty list (stub implementation). On Windows it calls netsh; errors from
- // missing netsh are tolerated.
- func TestGetWirelessInterfaces(t *testing.T) {
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- switch runtime.GOOS {
- case "linux":
- ifaces, err := wm.GetWirelessInterfaces()
- if err != nil {
- t.Logf("GetWirelessInterfaces() returned error (may be expected in CI without iw): %v", err)
- return
- }
- // ifaces may be empty (no wireless hardware) or contain interface names.
- for _, iface := range ifaces {
- if iface == "" {
- t.Error("GetWirelessInterfaces() returned an empty string in the interface list")
- }
- }
- case "darwin", "freebsd":
- // Stub implementations always return an empty slice with no error.
- ifaces, err := wm.GetWirelessInterfaces()
- if err != nil {
- t.Errorf("GetWirelessInterfaces() unexpected error on %s: %v", runtime.GOOS, err)
- }
- if len(ifaces) != 0 {
- t.Errorf("GetWirelessInterfaces() on %s should return empty slice, got %v", runtime.GOOS, ifaces)
- }
- case "windows":
- // May fail in CI if running without wireless hardware; that's acceptable.
- _, err := wm.GetWirelessInterfaces()
- if err != nil {
- t.Logf("GetWirelessInterfaces() on Windows returned error (may be expected in CI): %v", err)
- }
- default:
- t.Skipf("GetWirelessInterfaces not tested on %s", runtime.GOOS)
- }
- }
- // ---------------------------------------------------------------------------
- // Platform-specific capability tests
- // ---------------------------------------------------------------------------
- // TestSetInterfacePowerUnsupported verifies that SetInterfacePower returns an
- // error on platforms that do not support the operation (Darwin, FreeBSD, Windows).
- func TestSetInterfacePowerUnsupported(t *testing.T) {
- switch runtime.GOOS {
- case "darwin", "freebsd", "windows":
- // Intentionally left without t.Skip: these platforms should return an error.
- case "linux":
- t.Skip("skipping unsupported-platform test on Linux")
- default:
- t.Skipf("platform %s not tested", runtime.GOOS)
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- err := wm.SetInterfacePower("wlan0", true)
- if err == nil {
- t.Errorf("SetInterfacePower() on %s should return an error, got nil", runtime.GOOS)
- }
- }
- // TestGetInterfacePowerStatusUnsupported verifies that GetInterfacePowerStatuts
- // returns an error on Darwin, FreeBSD, and Windows.
- func TestGetInterfacePowerStatusUnsupported(t *testing.T) {
- switch runtime.GOOS {
- case "darwin", "freebsd", "windows":
- // These platforms should return an error.
- case "linux":
- t.Skip("skipping unsupported-platform test on Linux")
- default:
- t.Skipf("platform %s not tested", runtime.GOOS)
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- _, err := wm.GetInterfacePowerStatuts("wlan0")
- if err == nil {
- t.Errorf("GetInterfacePowerStatuts() on %s should return an error, got nil", runtime.GOOS)
- }
- }
- // TestScanNearbyWiFiUnsupported verifies that ScanNearbyWiFi returns an error
- // on Darwin and FreeBSD (stub implementations).
- func TestScanNearbyWiFiUnsupported(t *testing.T) {
- switch runtime.GOOS {
- case "darwin", "freebsd":
- // These platforms should return an error.
- default:
- t.Skipf("skipping ScanNearbyWiFi unsupported test on %s", runtime.GOOS)
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- results, err := wm.ScanNearbyWiFi("wlan0")
- if err == nil {
- t.Errorf("ScanNearbyWiFi() on %s should return an error, got nil", runtime.GOOS)
- }
- if results == nil {
- t.Error("ScanNearbyWiFi() should return an empty (non-nil) slice on error")
- }
- }
- // TestConnectWiFiUnsupported verifies that ConnectWiFi returns an error on
- // Darwin, FreeBSD, and Windows stub implementations.
- func TestConnectWiFiUnsupported(t *testing.T) {
- switch runtime.GOOS {
- case "darwin", "freebsd", "windows":
- // These platforms should return an error.
- case "linux":
- t.Skip("skipping unsupported platform ConnectWiFi test on Linux")
- default:
- t.Skipf("platform %s not tested", runtime.GOOS)
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- result, err := wm.ConnectWiFi("TestSSID", "password", "", "")
- if err == nil {
- t.Errorf("ConnectWiFi() on %s should return an error, got nil", runtime.GOOS)
- }
- if result == nil {
- t.Error("ConnectWiFi() should return a non-nil result even on error")
- }
- }
- // TestRemoveWifiUnsupported verifies that RemoveWifi returns an error on
- // Darwin, FreeBSD, and Windows stub implementations.
- func TestRemoveWifiUnsupported(t *testing.T) {
- switch runtime.GOOS {
- case "darwin", "freebsd", "windows":
- // These platforms should return an error.
- case "linux":
- t.Skip("skipping unsupported platform RemoveWifi test on Linux")
- default:
- t.Skipf("platform %s not tested", runtime.GOOS)
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- err := wm.RemoveWifi("TestSSID")
- if err == nil {
- t.Errorf("RemoveWifi() on %s should return an error, got nil", runtime.GOOS)
- }
- }
- // ---------------------------------------------------------------------------
- // Linux-specific helper function tests
- // ---------------------------------------------------------------------------
- // TestFileExistsLinux verifies the fileExists helper.
- func TestFileExistsLinux(t *testing.T) {
- if runtime.GOOS != "linux" {
- t.Skip("fileExists helper is in linux-only source; test runs on Linux")
- }
- // A path that exists.
- if !fileExists("/proc/version") {
- t.Error("fileExists(\"/proc/version\") should return true on Linux")
- }
- // A path that does not exist.
- if fileExists("/nonexistent_path_xyz_12345") {
- t.Error("fileExists(\"/nonexistent_path_xyz_12345\") should return false")
- }
- }
- // TestFileInDirLinux verifies the fileInDir helper.
- func TestFileInDirLinux(t *testing.T) {
- if runtime.GOOS != "linux" {
- t.Skip("fileInDir helper is in linux-only source; test runs on Linux")
- }
- // The file is inside the directory.
- if !fileInDir("/tmp/foo/bar.txt", "/tmp/foo") {
- t.Error("fileInDir should return true when file is inside directory")
- }
- // The file is outside the directory.
- if fileInDir("/etc/passwd", "/tmp") {
- t.Error("fileInDir should return false when file is outside directory")
- }
- }
- // TestPkgExistsLinux verifies the pkg_exists helper.
- func TestPkgExistsLinux(t *testing.T) {
- if runtime.GOOS != "linux" {
- t.Skip("pkg_exists helper is in linux-only source; test runs on Linux")
- }
- // "sh" should always exist on Linux.
- if !pkg_exists("sh") {
- t.Error("pkg_exists(\"sh\") should return true on Linux")
- }
- // A package that almost certainly doesn't exist.
- if pkg_exists("this_package_does_not_exist_xyz") {
- t.Error("pkg_exists(\"this_package_does_not_exist_xyz\") should return false")
- }
- }
- // TestGetSignalLevelEstimation verifies the bar-to-dBm mapping.
- func TestGetSignalLevelEstimation(t *testing.T) {
- if runtime.GOOS != "linux" {
- t.Skip("getSignalLevelEstimation is in linux-only source; test runs on Linux")
- }
- database, cleanup := newTestDatabase(t)
- defer cleanup()
- wm := NewWiFiManager(database, false, "", "")
- cases := []struct {
- bar string
- expected string
- }{
- {"▂▄▆█", "-45 dBm[Estimated]"},
- {"▂▄▆_", "-55 dBm[Estimated]"},
- {"▂▄__", "-75 dBm[Estimated]"},
- {"▂___", "-85 dBm[Estimated]"},
- {"____", "-95 dBm[Estimated]"},
- {"", "-95 dBm[Estimated]"},
- }
- for _, tc := range cases {
- got := wm.getSignalLevelEstimation(tc.bar)
- if got != tc.expected {
- t.Errorf("getSignalLevelEstimation(%q) = %q, expected %q", tc.bar, got, tc.expected)
- }
- }
- }
|