package fstore import ( "errors" "net/http" "net/http/httptest" "testing" "time" ) type StoreTestCase struct { Name string Update func(t *testing.T, s *Store) error ExpectedError error State map[string]string } func TestRunnerTestCases(t *testing.T) { t.Helper() rootDir := t.TempDir() store, err := Open(Config{ RootDir: rootDir, Primary: true, }) if err != nil { t.Fatal(err) } defer store.Close() mux := http.NewServeMux() mux.HandleFunc("/rep/", store.Handle) testServer := httptest.NewServer(mux) defer testServer.Close() rootDir2 := t.TempDir() secondary, err := Open(Config{ RootDir: rootDir2, Primary: false, PrimaryEndpoint: testServer.URL + "/rep/", }) if err != nil { t.Fatal(err) } defer secondary.Close() for _, testCase := range storeTestCases { testCase := testCase t.Run(testCase.Name, func(t *testing.T) { testRunnerRunTestCase(t, store, secondary, testCase) }) } } func testRunnerRunTestCase(t *testing.T, store, secondary *Store, testCase StoreTestCase) { err := testCase.Update(t, store) if !errors.Is(err, testCase.ExpectedError) { t.Fatal(testCase.Name, err, testCase.ExpectedError) } store.AssertState(t, testCase.State) pInfo := store.rep.Info() for { sInfo := secondary.rep.Info() if sInfo.AppSeqNum == pInfo.AppSeqNum { break } time.Sleep(time.Millisecond) } secondary.AssertState(t, testCase.State) } var storeTestCases = []StoreTestCase{ { Name: "store a file", Update: func(t *testing.T, s *Store) error { return s.StoreString("hello world", "/a/b/c") }, ExpectedError: nil, State: map[string]string{ "/a/b/c": "hello world", }, }, { Name: "store more files", Update: func(t *testing.T, s *Store) error { if err := s.StoreString("good bye", "/a/b/x"); err != nil { return err } return s.StoreString("xxx", "/x") }, ExpectedError: nil, State: map[string]string{ "/a/b/c": "hello world", "/a/b/x": "good bye", "/x": "xxx", }, }, { Name: "remove a file", Update: func(t *testing.T, s *Store) error { return s.Remove("/x") }, ExpectedError: nil, State: map[string]string{ "/a/b/c": "hello world", "/a/b/x": "good bye", }, }, { Name: "remove another file", Update: func(t *testing.T, s *Store) error { return s.Remove("/a/b/c") }, ExpectedError: nil, State: map[string]string{ "/a/b/x": "good bye", }, }, }