120 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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",
 | |
| 		},
 | |
| 	},
 | |
| }
 |