// SPDX-License-Identifier: MIT package state import ( "os" "path/filepath" "testing" ) func TestRoundTrip(t *testing.T) { path := filepath.Join(t.TempDir(), "run", "prx", "state.json") s := &State{ Enabled: true, WANInterface: "wlan0", Gateway4: "192.168.1.1", Mark: 0x100, TableV4: 100, TableV6: 101, PriorityV4: 100, PriorityV6: 100, } if err := Save(path, s); err != nil { t.Fatalf("Save: %v", err) } got, err := Load(path) if err != nil { t.Fatalf("Load: %v", err) } if !got.Enabled || got.WANInterface != "wlan0" || got.Mark != 0x100 { t.Fatalf("round trip mismatch: %+v", got) } if err := Remove(path); err != nil { t.Fatalf("Remove: %v", err) } empty, err := Load(path) if err != nil { t.Fatalf("Load after remove: %v", err) } if empty.Enabled { t.Fatal("expected disabled state after removal") } if err := Remove(path); err != nil { t.Fatalf("second Remove should be a no-op: %v", err) } } // TestLoadCorruptNeverReturnsNil guards against the nil-pointer panic that a // caller ignoring the error would otherwise hit on a corrupt state file. func TestLoadCorruptNeverReturnsNil(t *testing.T) { path := filepath.Join(t.TempDir(), "state.json") if err := os.WriteFile(path, []byte("{ not json"), 0o644); err != nil { t.Fatal(err) } st, err := Load(path) if err == nil { t.Fatal("expected a parse error for a corrupt state file") } if st == nil { t.Fatal("Load must never return a nil state alongside an error") } if st.Enabled { t.Fatal("expected a zero-value state") } }