package aerotun import ( "os" "path/filepath" "testing" ) func TestManagerPersistenceValidationAndStartupErrors(t *testing.T) { m := &Manager{instances: map[string]TunnelInstance{}, runners: map[string]*TunnelRunner{}, errors: map[string]string{}, filePath: filepath.Join(t.TempDir(), "instances.json")} cfg := TunnelInstance{Name: "atest", Mode: "client", LocalAddress: "10.99.0.1/24", PeerAddress: "10.99.0.2/24", RemoteEndpoint: "192.0.2.1:51830", PSK: testPSK, Disabled: true} saved, err := m.Save(cfg) if err != nil { t.Fatal(err) } info, err := os.Stat(m.filePath) if err != nil || info.Mode().Perm() != 0600 { t.Fatalf("config permissions: %v %v", info, err) } m2 := &Manager{instances: map[string]TunnelInstance{}, filePath: m.filePath} if err = m2.load(); err != nil { t.Fatal(err) } if got := m2.instances[saved.ID]; got.PSK != testPSK || !got.Disabled { t.Fatal("configuration did not roundtrip") } duplicate := cfg duplicate.ID = "duplicate" if _, err = m.Save(duplicate); err == nil { t.Fatal("duplicate interface name accepted") } // A bad endpoint fails before any interface creation, and surfaces to the UI. m.instances[saved.ID] = saved saved.RemoteEndpoint = "bad endpoint" m.instances[saved.ID] = saved if err = m.StartTunnel(saved.ID); err == nil { t.Fatal("startup failure hidden") } if got, _ := m.Get(saved.ID); got.Running || got.LastError == "" { t.Fatal("startup failure not exposed in telemetry") } } func TestManagerFailedPersistenceDoesNotChangeConfig(t *testing.T) { dir := t.TempDir() m := &Manager{instances: map[string]TunnelInstance{}, runners: map[string]*TunnelRunner{}, errors: map[string]string{}, filePath: filepath.Join(dir, "missing", "instances.json")} cfg := TunnelInstance{ID: "test", Name: "atest", Mode: "server", LocalAddress: "10.99.0.1/24", PSK: testPSK, Disabled: true} m.instances[cfg.ID] = cfg changed := cfg changed.Comment = "new" if _, err := m.Save(changed); err == nil { t.Fatal("expected persistence error") } if m.instances[cfg.ID].Comment != "" { t.Fatal("failed save changed in-memory configuration") } if err := m.ToggleState(cfg.ID, false); err == nil { t.Fatal("expected persistence error") } if !m.instances[cfg.ID].Disabled { t.Fatal("failed persistence enabled the tunnel") } }