diff --git a/base/database/database_test.go b/base/database/database_test.go index be4971dd..b7acd610 100644 --- a/base/database/database_test.go +++ b/base/database/database_test.go @@ -18,6 +18,7 @@ import ( _ "github.com/safing/portmaster/base/database/storage/bbolt" _ "github.com/safing/portmaster/base/database/storage/fstree" _ "github.com/safing/portmaster/base/database/storage/hashmap" + _ "github.com/safing/portmaster/base/database/storage/sqlite" ) func TestMain(m *testing.M) { @@ -166,7 +167,7 @@ func testDatabase(t *testing.T, storageType string, shadowDelete bool) { //nolin } // run maintenance - err = dbController.MaintainRecordStates(context.TODO(), now.Add(-60*time.Second)) + err = dbController.MaintainRecordStates(t.Context(), now.Add(-60*time.Second)) if err != nil { t.Fatal(err) } @@ -181,12 +182,22 @@ func testDatabase(t *testing.T, storageType string, shadowDelete bool) { //nolin if !errors.Is(err, storage.ErrNotFound) { t.Errorf("A should be deleted and purged, err=%s", err) } - B1, err := dbController.storage.Get("B") - if err != nil { - t.Fatalf("should exist: %s, original meta: %+v", err, B.Meta()) - } - if B1.Meta().Deleted == 0 { - t.Errorf("B should be deleted") + + if !shadowDelete { + // previous call MaintainRecordStates() must purge all expired and deleted records + _, err := dbController.storage.Get("B") + if !errors.Is(err, storage.ErrNotFound) { + t.Errorf("B should be deleted and purged, err=%s", err) + } + } else { + B1, err := dbController.storage.Get("B") + if err != nil { + t.Fatalf("should exist: %s, original meta: %+v", err, B.Meta()) + } + + if B1.Meta().Deleted == 0 { + t.Errorf("B should be deleted") + } } // delete last entry @@ -197,7 +208,9 @@ func testDatabase(t *testing.T, storageType string, shadowDelete bool) { //nolin } // run maintenance - err = dbController.MaintainRecordStates(context.TODO(), now) + // Since previous call MaintainRecordStates() saved actual timestamp for deleted records, + // use 'now + 1sec' just to guarantee that time is bigger) + err = dbController.MaintainRecordStates(t.Context(), time.Now().Add(time.Second).UTC()) if err != nil { t.Fatal(err) } @@ -251,6 +264,7 @@ func TestDatabaseSystem(t *testing.T) { //nolint:tparallel }() for _, shadowDelete := range []bool{false, true} { + testDatabase(t, "sqlite", shadowDelete) testDatabase(t, "bbolt", shadowDelete) testDatabase(t, "hashmap", shadowDelete) testDatabase(t, "fstree", shadowDelete) diff --git a/base/utils/structure_test.go b/base/utils/structure_test.go index d3debcf7..abf758c3 100644 --- a/base/utils/structure_test.go +++ b/base/utils/structure_test.go @@ -28,12 +28,12 @@ func ExampleDirStructure() { return } - ds := NewDirStructure(basePath, PublicReadPermission) - secret := ds.ChildDir("secret", AdminOnlyPermission) - repo := ds.ChildDir("repo", PublicWritePermission) - _ = repo.ChildDir("a", AdminOnlyPermission) - b := repo.ChildDir("b", PublicReadPermission) - c := b.ChildDir("c", PublicWritePermission) + ds := NewDirStructure(basePath, PublicReadExecPermission) + secret := ds.ChildDir("secret", AdminOnlyExecPermission) + repo := ds.ChildDir("repo", PublicWriteExecPermission) + _ = repo.ChildDir("a", AdminOnlyExecPermission) + b := repo.ChildDir("b", PublicReadExecPermission) + c := b.ChildDir("c", PublicWriteExecPermission) err = ds.Ensure() if err != nil { diff --git a/service/intel/geoip/init_test.go b/service/intel/geoip/init_test.go index 9d0288f2..b3202f81 100644 --- a/service/intel/geoip/init_test.go +++ b/service/intel/geoip/init_test.go @@ -3,67 +3,67 @@ package geoip import ( "fmt" "os" + "path/filepath" "testing" "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" "github.com/safing/portmaster/base/notifications" + "github.com/safing/portmaster/service/configure" + "github.com/safing/portmaster/service/ui" "github.com/safing/portmaster/service/updates" ) type testInstance struct { - db *dbmodule.DBModule - api *api.API - config *config.Config - updates *updates.Updater + db *dbmodule.DBModule + api *api.API + config *config.Config + intelUpdates *updates.Updater } var _ instance = &testInstance{} -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} +func (stub *testInstance) IntelUpdates() *updates.Updater { return stub.intelUpdates } +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) Notifications() *notifications.Notifications { return nil } +func (stub *testInstance) Ready() bool { return true } +func (stub *testInstance) Restart() {} +func (stub *testInstance) Shutdown() {} +func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) BinaryUpdates() *updates.Updater { return nil } +func (stub *testInstance) UI() *ui.UI { return nil } +func (stub *testInstance) DataDir() string { return _dataDir } -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - -func (stub *testInstance) SetCmdLineOperation(f func() error) {} +var _dataDir string func runTest(m *testing.M) error { - api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-geoip") + var err error + + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) + return fmt.Errorf("failed to create temporary data directory: %w", err) } - defer func() { _ = os.RemoveAll(ds) }() - installDir, err := os.MkdirTemp("", "geoip_installdir") - if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Initialize the Intel update configuration + intelUpdateConfig := updates.Config{ + Name: configure.DefaultIntelIndexName, + Directory: filepath.Join(_dataDir, "test_intel"), + DownloadDirectory: filepath.Join(_dataDir, "test_download_intel"), + PurgeDirectory: filepath.Join(_dataDir, "test_upgrade_obsolete_intel"), + IndexURLs: configure.DefaultIntelIndexURLs, + IndexFile: "index.json", + AutoCheck: true, + AutoDownload: true, + AutoApply: true, } + // Set the default API listen address + api.SetDefaultAPIListenAddress("0.0.0.0:8080") + + // Initialize the instance with the necessary components stub := &testInstance{} stub.db, err = dbmodule.New(stub) if err != nil { @@ -77,10 +77,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to create api: %w", err) } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) + stub.intelUpdates, err = updates.New(stub, "Intel Updater", intelUpdateConfig) if err != nil { return fmt.Errorf("failed to create updates: %w", err) } @@ -88,7 +85,6 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to initialize module: %w", err) } - err = stub.db.Start() if err != nil { return fmt.Errorf("Failed to start database: %w", err) @@ -101,7 +97,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("Failed to start api: %w", err) } - err = stub.updates.Start() + err = stub.intelUpdates.Start() if err != nil { return fmt.Errorf("Failed to start updates: %w", err) } diff --git a/service/intel/geoip/lookup_test.go b/service/intel/geoip/lookup_test.go index 4f882377..e9aad275 100644 --- a/service/intel/geoip/lookup_test.go +++ b/service/intel/geoip/lookup_test.go @@ -21,7 +21,8 @@ func TestLocationLookup(t *testing.T) { worker.triggerUpdate() select { case <-waiter: - case <-time.After(15 * time.Second): + case <-time.After(50 * time.Second): + t.Error("timeout waiting for geoip database to be initialized (updated)") } ip1 := net.ParseIP("81.2.69.142") diff --git a/service/netenv/init_test.go b/service/netenv/init_test.go index 39c0febd..c8a56f9c 100644 --- a/service/netenv/init_test.go +++ b/service/netenv/init_test.go @@ -3,67 +3,67 @@ package netenv import ( "fmt" "os" + "path/filepath" "testing" "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" "github.com/safing/portmaster/base/notifications" + "github.com/safing/portmaster/service/configure" + "github.com/safing/portmaster/service/ui" "github.com/safing/portmaster/service/updates" ) type testInstance struct { - db *dbmodule.DBModule - api *api.API - config *config.Config - updates *updates.Updater + db *dbmodule.DBModule + api *api.API + config *config.Config + intelUpdates *updates.Updater } var _ instance = &testInstance{} -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} +func (stub *testInstance) IntelUpdates() *updates.Updater { return stub.intelUpdates } +func (stub *testInstance) API() *api.API { return stub.api } +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) Notifications() *notifications.Notifications { return nil } +func (stub *testInstance) Ready() bool { return true } +func (stub *testInstance) Restart() {} +func (stub *testInstance) Shutdown() {} +func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) UI() *ui.UI { return nil } +func (stub *testInstance) DataDir() string { return _dataDir } -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - -func (stub *testInstance) SetCmdLineOperation(f func() error) {} +var _dataDir string func runTest(m *testing.M) error { - api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-netenv") + var err error + + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) + return fmt.Errorf("failed to create temporary data directory: %w", err) } - defer func() { _ = os.RemoveAll(ds) }() - installDir, err := os.MkdirTemp("", "netenv_installdir") - if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Initialize the Intel update configuration + intelUpdateConfig := updates.Config{ + Name: configure.DefaultIntelIndexName, + Directory: filepath.Join(_dataDir, "test_intel"), + DownloadDirectory: filepath.Join(_dataDir, "test_download_intel"), + PurgeDirectory: filepath.Join(_dataDir, "test_upgrade_obsolete_intel"), + IndexURLs: configure.DefaultIntelIndexURLs, + IndexFile: "index.json", + AutoCheck: true, + AutoDownload: true, + AutoApply: true, } + // Set the default API listen address + api.SetDefaultAPIListenAddress("0.0.0.0:8080") + + // Initialize the instance with the necessary components stub := &testInstance{} stub.db, err = dbmodule.New(stub) if err != nil { @@ -77,10 +77,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to create api: %w", err) } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) + stub.intelUpdates, err = updates.New(stub, "Intel Updater", intelUpdateConfig) if err != nil { return fmt.Errorf("failed to create updates: %w", err) } @@ -96,7 +93,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("Failed to start api: %w", err) } - err = stub.updates.Start() + err = stub.intelUpdates.Start() if err != nil { return fmt.Errorf("Failed to start updates: %w", err) } diff --git a/service/profile/endpoints/endpoints_test.go b/service/profile/endpoints/endpoints_test.go index 7f29cedc..e33822f0 100644 --- a/service/profile/endpoints/endpoints_test.go +++ b/service/profile/endpoints/endpoints_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "os" + "path/filepath" "runtime" "testing" @@ -14,63 +15,62 @@ import ( "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" "github.com/safing/portmaster/base/notifications" + "github.com/safing/portmaster/service/configure" "github.com/safing/portmaster/service/intel" "github.com/safing/portmaster/service/intel/geoip" + "github.com/safing/portmaster/service/ui" "github.com/safing/portmaster/service/updates" ) type testInstance struct { - db *dbmodule.DBModule - api *api.API - config *config.Config - updates *updates.Updater - geoip *geoip.GeoIP + db *dbmodule.DBModule + api *api.API + config *config.Config + intelUpdates *updates.Updater + geoip *geoip.GeoIP } -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} +func (stub *testInstance) IntelUpdates() *updates.Updater { return stub.intelUpdates } +func (stub *testInstance) API() *api.API { return stub.api } +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) Notifications() *notifications.Notifications { return nil } +func (stub *testInstance) Ready() bool { return true } +func (stub *testInstance) Restart() {} +func (stub *testInstance) Shutdown() {} +func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) BinaryUpdates() *updates.Updater { return nil } +func (stub *testInstance) UI() *ui.UI { return nil } +func (stub *testInstance) DataDir() string { return _dataDir } -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - -func (stub *testInstance) SetCmdLineOperation(f func() error) {} +var _dataDir string func runTest(m *testing.M) error { + var err error + + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") + if err != nil { + return fmt.Errorf("failed to create temporary data directory: %w", err) + } + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Initialize the Intel update configuration + intelUpdateConfig := updates.Config{ + Name: configure.DefaultIntelIndexName, + Directory: filepath.Join(_dataDir, "test_intel"), + DownloadDirectory: filepath.Join(_dataDir, "test_download_intel"), + PurgeDirectory: filepath.Join(_dataDir, "test_upgrade_obsolete_intel"), + IndexURLs: configure.DefaultIntelIndexURLs, + IndexFile: "index.json", + AutoCheck: true, + AutoDownload: true, + AutoApply: true, + } + + // Set the default API listen address api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-endpoints") - if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) - } - defer func() { _ = os.RemoveAll(ds) }() - - installDir, err := os.MkdirTemp("", "endpoints_installdir") - if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) - } + // Initialize the instance with the necessary components stub := &testInstance{} stub.db, err = dbmodule.New(stub) if err != nil { @@ -84,10 +84,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to create api: %w", err) } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) + stub.intelUpdates, err = updates.New(stub, "Intel Updater", intelUpdateConfig) if err != nil { return fmt.Errorf("failed to create updates: %w", err) } @@ -108,7 +105,7 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("Failed to start api: %w", err) } - err = stub.updates.Start() + err = stub.intelUpdates.Start() if err != nil { return fmt.Errorf("Failed to start updates: %w", err) } diff --git a/service/resolver/main_test.go b/service/resolver/main_test.go index 048ab4b5..62c7a7c8 100644 --- a/service/resolver/main_test.go +++ b/service/resolver/main_test.go @@ -8,76 +8,50 @@ import ( "github.com/safing/portmaster/base/api" "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" - "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/service/core/base" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/service/netenv" + "github.com/safing/portmaster/service/ui" "github.com/safing/portmaster/service/updates" ) var domainFeed = make(chan string) type testInstance struct { - db *dbmodule.DBModule - base *base.Base - api *api.API - config *config.Config - updates *updates.Updater - netenv *netenv.NetEnv + db *dbmodule.DBModule + base *base.Base + config *config.Config + netenv *netenv.NetEnv } -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} - -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) NetEnv() *netenv.NetEnv { - return stub.netenv -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - -func (stub *testInstance) SetCmdLineOperation(f func() error) {} - func (stub *testInstance) GetEventSPNConnected() *mgr.EventMgr[struct{}] { return mgr.NewEventMgr[struct{}]("spn connect", nil) } +func (stub *testInstance) IntelUpdates() *updates.Updater { return nil } +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) NetEnv() *netenv.NetEnv { return stub.netenv } +func (stub *testInstance) Ready() bool { return true } +func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) UI() *ui.UI { return nil } +func (stub *testInstance) DataDir() string { return _dataDir } + +var _dataDir string func runTest(m *testing.M) error { + var err error + + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") + if err != nil { + fmt.Printf("failed to create temporary data directory: %s", err) + os.Exit(0) + } + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Set the default API listen address api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-resolver") - if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) - } - defer func() { _ = os.RemoveAll(ds) }() - - installDir, err := os.MkdirTemp("", "resolver_installdir") - if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) - } + // Initialize the instance with the necessary components stub := &testInstance{} stub.db, err = dbmodule.New(stub) if err != nil { @@ -91,26 +65,14 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to create base: %w", err) } - stub.api, err = api.New(stub) - if err != nil { - return fmt.Errorf("failed to create api: %w", err) - } stub.netenv, err = netenv.New(stub) if err != nil { return fmt.Errorf("failed to create netenv: %w", err) } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) - if err != nil { - return fmt.Errorf("failed to create updates: %w", err) - } module, err := New(stub) if err != nil { return fmt.Errorf("failed to create module: %w", err) } - err = stub.db.Start() if err != nil { return fmt.Errorf("Failed to start database: %w", err) @@ -123,14 +85,6 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("Failed to start base: %w", err) } - err = stub.api.Start() - if err != nil { - return fmt.Errorf("Failed to start api: %w", err) - } - err = stub.updates.Start() - if err != nil { - return fmt.Errorf("Failed to start updates: %w", err) - } err = stub.netenv.Start() if err != nil { return fmt.Errorf("Failed to start netenv: %w", err) diff --git a/service/updates/updates_test.go b/service/updates/updates_test.go index 9dea5886..f70ac535 100644 --- a/service/updates/updates_test.go +++ b/service/updates/updates_test.go @@ -10,22 +10,17 @@ import ( "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/ui" ) type testInstance struct{} -func (i *testInstance) Restart() {} -func (i *testInstance) Shutdown() {} - -func (i *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (i *testInstance) Ready() bool { - return true -} - -func (i *testInstance) SetCmdLineOperation(f func() error) {} +func (i *testInstance) Restart() {} +func (i *testInstance) Shutdown() {} +func (i *testInstance) Notifications() *notifications.Notifications { return nil } +func (i *testInstance) Ready() bool { return true } +func (i *testInstance) SetCmdLineOperation(f func() error) {} +func (i *testInstance) UI() *ui.UI { return nil } func TestPerformUpdate(t *testing.T) { t.Parallel() @@ -39,11 +34,13 @@ func TestPerformUpdate(t *testing.T) { t.Fatal(err) } defer func() { _ = os.RemoveAll(installedDir) }() + updateDir, err := os.MkdirTemp("", "updates_new_") if err != nil { t.Fatal(err) } defer func() { _ = os.RemoveAll(updateDir) }() + purgeDir, err := os.MkdirTemp("", "updates_purge_") if err != nil { t.Fatal(err) @@ -109,7 +106,7 @@ func TestPerformUpdate(t *testing.T) { // GenerateMockFolder generates mock index folder for testing. func GenerateMockFolder(dir, name, version string, published time.Time) error { // Make sure dir exists - _ = os.MkdirAll(dir, defaultDirMode) + _ = os.MkdirAll(dir, 0o750) // Create empty files file, err := os.Create(filepath.Join(dir, "portmaster")) @@ -147,7 +144,7 @@ func GenerateMockFolder(dir, name, version string, published time.Time) error { fmt.Fprintf(os.Stderr, "failed to marshal index: %s\n", err) } - err = os.WriteFile(filepath.Join(dir, "index.json"), indexJSON, defaultFileMode) + err = os.WriteFile(filepath.Join(dir, "index.json"), indexJSON, 0o600) if err != nil { return err } diff --git a/spn/access/module_test.go b/spn/access/module_test.go index 5b018010..b459ecb8 100644 --- a/spn/access/module_test.go +++ b/spn/access/module_test.go @@ -6,6 +6,8 @@ import ( "testing" "github.com/safing/portmaster/base/config" + "github.com/safing/portmaster/base/database" + _ "github.com/safing/portmaster/base/database/storage/hashmap" "github.com/safing/portmaster/service/mgr" "github.com/safing/portmaster/spn/conf" ) @@ -14,44 +16,75 @@ type testInstance struct { config *config.Config } -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { - return nil -} - -func (stub *testInstance) Stopping() bool { - return false -} +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { return nil } +func (stub *testInstance) Stopping() bool { return false } +func (stub *testInstance) IsShuttingDown() bool { return false } func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) DataDir() string { return _dataDir } + +var _dataDir string func TestMain(m *testing.M) { - instance := &testInstance{} + exitCode := 1 + defer func() { + if exitCode != 0 { + os.Exit(exitCode) + } + }() + var err error + // Create a temporary directory for the data + _dataDir, err = os.MkdirTemp("", "") + if err != nil { + fmt.Printf("failed to create temporary data directory: %s", err) + return // Exit with error + } + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Initialize the database module + err = database.Initialize(_dataDir) + if err != nil { + fmt.Printf("failed to initialize database module: %s", err) + return // Exit with error + } + _, err = database.Register(&database.Database{ + Name: "core", + Description: "Holds core data, such as settings and profiles", + StorageType: "hashmap", + }) + if err != nil { + fmt.Printf("failed to register core database: %s", err) + return // Exit with error + } + + // Initialize the instance + instance := &testInstance{} + instance.config, err = config.New(instance) if err != nil { fmt.Printf("failed to create config module: %s", err) - os.Exit(0) + return // Exit with error } module, err = New(instance) if err != nil { fmt.Printf("failed to create access module: %s", err) - os.Exit(0) + return // Exit with error } err = instance.config.Start() if err != nil { fmt.Printf("failed to start config module: %s", err) - os.Exit(0) + return // Exit with error } err = module.Start() if err != nil { fmt.Printf("failed to start access module: %s", err) - os.Exit(0) + return // Exit with error } conf.EnableClient(true) m.Run() + + exitCode = 0 // success } diff --git a/spn/cabin/module_test.go b/spn/cabin/module_test.go index bf342849..ccb8c6df 100644 --- a/spn/cabin/module_test.go +++ b/spn/cabin/module_test.go @@ -22,31 +22,24 @@ type testInstance struct { base *base.Base } -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { - return nil -} - -func (stub *testInstance) Stopping() bool { - return false -} - -func (stub *testInstance) Ready() bool { - return true -} +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { return nil } +func (stub *testInstance) Stopping() bool { return false } +func (stub *testInstance) Ready() bool { return true } func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) DataDir() string { return _dataDir } + +var _dataDir string func runTest(m *testing.M) error { api.SetDefaultAPIListenAddress("0.0.0.0:8080") - // Initialize dataroot - ds, err := config.InitializeUnitTestDataroot("test-cabin") + var err error + // Create a temporary directory for the data + _dataDir, err = os.MkdirTemp("", "") if err != nil { return fmt.Errorf("failed to initialize dataroot: %w", err) } - defer func() { _ = os.RemoveAll(ds) }() + defer func() { _ = os.RemoveAll(_dataDir) }() // Init instance := &testInstance{} diff --git a/spn/crew/module_test.go b/spn/crew/module_test.go index d31184f8..8426716e 100644 --- a/spn/crew/module_test.go +++ b/spn/crew/module_test.go @@ -41,15 +41,24 @@ func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { func (stub *testInstance) Stopping() bool { return false } + func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) DataDir() string { + return _dataDir +} + +var _dataDir string + func runTest(m *testing.M) error { conf.EnablePublicHub(true) // Make hub config available. - ds, err := config.InitializeUnitTestDataroot("test-crew") + var err error + // Create a temporary directory for the data + _dataDir, err = os.MkdirTemp("", "") if err != nil { return fmt.Errorf("failed to initialize dataroot: %w", err) } - defer func() { _ = os.RemoveAll(ds) }() + defer func() { _ = os.RemoveAll(_dataDir) }() instance := &testInstance{} // Init diff --git a/spn/docks/module_test.go b/spn/docks/module_test.go index 2f333b93..5febbca9 100644 --- a/spn/docks/module_test.go +++ b/spn/docks/module_test.go @@ -29,31 +29,25 @@ type testInstance struct { cabin *cabin.Cabin } -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Metrics() *metrics.Metrics { - return stub.metrics -} - -func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { - return nil -} - -func (stub *testInstance) Stopping() bool { - return false -} +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) SPNGroup() *mgr.ExtendedGroup { return nil } func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) IsShuttingDown() bool { return false } +func (stub *testInstance) DataDir() string { return _dataDir } + +var _dataDir string func runTest(m *testing.M) error { _ = log.Start("info", true, "") - ds, err := config.InitializeUnitTestDataroot("test-docks") + var err error + + // Create a temporary directory for the data + _dataDir, err = os.MkdirTemp("", "") if err != nil { return fmt.Errorf("failed to initialize dataroot: %w", err) } - defer func() { _ = os.RemoveAll(ds) }() + defer func() { _ = os.RemoveAll(_dataDir) }() instance := &testInstance{} runningTests = true diff --git a/spn/hub/hub_test.go b/spn/hub/hub_test.go index 09425e72..491e93ad 100644 --- a/spn/hub/hub_test.go +++ b/spn/hub/hub_test.go @@ -8,91 +8,37 @@ import ( "github.com/stretchr/testify/assert" - "github.com/safing/portmaster/base/api" - "github.com/safing/portmaster/base/config" "github.com/safing/portmaster/base/database/dbmodule" - "github.com/safing/portmaster/base/notifications" "github.com/safing/portmaster/service/core/base" - "github.com/safing/portmaster/service/updates" ) type testInstance struct { - db *dbmodule.DBModule - api *api.API - config *config.Config - updates *updates.Updater - base *base.Base + db *dbmodule.DBModule + base *base.Base } -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} - -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Base() *base.Base { - return stub.base -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) DataDir() string { return _dataDir } + +var _dataDir string func runTest(m *testing.M) error { - api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-hub") - if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) - } - defer func() { _ = os.RemoveAll(ds) }() + var err error - installDir, err := os.MkdirTemp("", "hub_installdir") + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) + return fmt.Errorf("failed to create temporary data directory: %w", err) } + defer func() { _ = os.RemoveAll(_dataDir) }() + // Initialize the instance with the necessary components stub := &testInstance{} // Init stub.db, err = dbmodule.New(stub) if err != nil { return fmt.Errorf("failed to create database: %w", err) } - stub.api, err = api.New(stub) - if err != nil { - return fmt.Errorf("failed to create api: %w", err) - } - stub.config, err = config.New(stub) - if err != nil { - return fmt.Errorf("failed to create config: %w", err) - } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) - if err != nil { - return fmt.Errorf("failed to create updates: %w", err) - } stub.base, err = base.New(stub) if err != nil { return fmt.Errorf("failed to base updates: %w", err) @@ -103,18 +49,6 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to start database: %w", err) } - err = stub.api.Start() - if err != nil { - return fmt.Errorf("failed to start api: %w", err) - } - err = stub.config.Start() - if err != nil { - return fmt.Errorf("failed to start config: %w", err) - } - err = stub.updates.Start() - if err != nil { - return fmt.Errorf("failed to start updates: %w", err) - } err = stub.base.Start() if err != nil { return fmt.Errorf("failed to start base: %w", err) diff --git a/spn/navigator/module_test.go b/spn/navigator/module_test.go index a35cf9f6..ae254ea7 100644 --- a/spn/navigator/module_test.go +++ b/spn/navigator/module_test.go @@ -3,6 +3,7 @@ package navigator import ( "fmt" "os" + "path/filepath" "testing" "github.com/safing/portmaster/base/api" @@ -10,68 +11,59 @@ import ( "github.com/safing/portmaster/base/database/dbmodule" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/base/notifications" - "github.com/safing/portmaster/service/core/base" + "github.com/safing/portmaster/service/configure" "github.com/safing/portmaster/service/intel/geoip" + "github.com/safing/portmaster/service/ui" "github.com/safing/portmaster/service/updates" ) type testInstance struct { - db *dbmodule.DBModule - api *api.API - config *config.Config - updates *updates.Updater - base *base.Base - geoip *geoip.GeoIP + db *dbmodule.DBModule + config *config.Config + intelUpdates *updates.Updater + geoip *geoip.GeoIP } -func (stub *testInstance) IntelUpdates() *updates.Updater { - return stub.updates -} +func (stub *testInstance) IntelUpdates() *updates.Updater { return stub.intelUpdates } +func (stub *testInstance) Config() *config.Config { return stub.config } +func (stub *testInstance) Notifications() *notifications.Notifications { return nil } +func (stub *testInstance) Ready() bool { return true } +func (stub *testInstance) Restart() {} +func (stub *testInstance) Shutdown() {} +func (stub *testInstance) SetCmdLineOperation(f func() error) {} +func (stub *testInstance) BinaryUpdates() *updates.Updater { return nil } +func (stub *testInstance) UI() *ui.UI { return nil } +func (stub *testInstance) DataDir() string { return _dataDir } -func (stub *testInstance) API() *api.API { - return stub.api -} - -func (stub *testInstance) Config() *config.Config { - return stub.config -} - -func (stub *testInstance) Base() *base.Base { - return stub.base -} - -func (stub *testInstance) Notifications() *notifications.Notifications { - return nil -} - -func (stub *testInstance) Ready() bool { - return true -} - -func (stub *testInstance) Restart() {} - -func (stub *testInstance) Shutdown() {} - -func (stub *testInstance) SetCmdLineOperation(f func() error) {} +var _dataDir string func runTest(m *testing.M) error { + var err error + + // Create a temporary directory for testing + _dataDir, err = os.MkdirTemp("", "") + if err != nil { + return fmt.Errorf("failed to create temporary data directory: %w", err) + } + defer func() { _ = os.RemoveAll(_dataDir) }() + + // Initialize the Intel update configuration + intelUpdateConfig := updates.Config{ + Name: configure.DefaultIntelIndexName, + Directory: filepath.Join(_dataDir, "test_intel"), + DownloadDirectory: filepath.Join(_dataDir, "test_download_intel"), + PurgeDirectory: filepath.Join(_dataDir, "test_upgrade_obsolete_intel"), + IndexURLs: configure.DefaultIntelIndexURLs, + IndexFile: "index.json", + AutoCheck: true, + AutoDownload: true, + AutoApply: true, + } + + // Set the default API listen address api.SetDefaultAPIListenAddress("0.0.0.0:8080") - ds, err := config.InitializeUnitTestDataroot("test-navigator") - if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) - } - defer func() { _ = os.RemoveAll(ds) }() - - installDir, err := os.MkdirTemp("", "geoip_installdir") - if err != nil { - return fmt.Errorf("failed to create tmp install dir: %w", err) - } - defer func() { _ = os.RemoveAll(installDir) }() - err = updates.GenerateMockFolder(installDir, "Test Intel", "1.0.0") - if err != nil { - return fmt.Errorf("failed to generate mock installation: %w", err) - } + // Initialize the instance with the necessary components stub := &testInstance{} log.SetLogLevel(log.DebugLevel) @@ -80,25 +72,14 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to create db: %w", err) } - stub.api, err = api.New(stub) - if err != nil { - return fmt.Errorf("failed to create api: %w", err) - } stub.config, err = config.New(stub) if err != nil { return fmt.Errorf("failed to create config: %w", err) } - stub.updates, err = updates.New(stub, "Test Intel", updates.Config{ - Directory: installDir, - IndexFile: "index.json", - }) + stub.intelUpdates, err = updates.New(stub, "Intel Updater", intelUpdateConfig) if err != nil { return fmt.Errorf("failed to create updates: %w", err) } - stub.base, err = base.New(stub) - if err != nil { - return fmt.Errorf("failed to create base: %w", err) - } stub.geoip, err = geoip.New(stub) if err != nil { return fmt.Errorf("failed to create geoip: %w", err) @@ -112,22 +93,14 @@ func runTest(m *testing.M) error { if err != nil { return fmt.Errorf("failed to start db module: %w", err) } - err = stub.api.Start() - if err != nil { - return fmt.Errorf("failed to start api: %w", err) - } err = stub.config.Start() if err != nil { return fmt.Errorf("failed to start config: %w", err) } - err = stub.updates.Start() + err = stub.intelUpdates.Start() if err != nil { return fmt.Errorf("failed to start updates: %w", err) } - err = stub.base.Start() - if err != nil { - return fmt.Errorf("failed to start base module: %w", err) - } err = stub.geoip.Start() if err != nil { return fmt.Errorf("failed to start geoip module: %w", err) diff --git a/spn/terminal/module_test.go b/spn/terminal/module_test.go index d7e6f1d4..759fe863 100644 --- a/spn/terminal/module_test.go +++ b/spn/terminal/module_test.go @@ -22,6 +22,18 @@ type testInstance struct { rng *rng.Rng base *base.Base cabin *cabin.Cabin + dataDir string +} + +func (stub *testInstance) DataDir() string { + if len(stub.dataDir) == 0 { + var err error + stub.dataDir, err = os.MkdirTemp("", "") + if err != nil { + panic(fmt.Sprintf("failed to create temp dir: %v", err)) + } + } + return stub.dataDir } func (stub *testInstance) Config() *config.Config { @@ -42,11 +54,7 @@ func (stub *testInstance) Stopping() bool { func (stub *testInstance) SetCmdLineOperation(f func() error) {} func runTest(m *testing.M) error { - ds, err := config.InitializeUnitTestDataroot("test-terminal") - if err != nil { - return fmt.Errorf("failed to initialize dataroot: %w", err) - } - defer func() { _ = os.RemoveAll(ds) }() + var err error conf.EnablePublicHub(true) // Make hub config available.