github.com/divyam234/rclone@v1.64.1/cmd/serve/restic/restic_test.go (about) 1 // Serve restic tests set up a server and run the integration tests 2 // for restic against it. 3 4 package restic 5 6 import ( 7 "context" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "os/exec" 12 "testing" 13 14 _ "github.com/divyam234/rclone/backend/all" 15 "github.com/divyam234/rclone/fstest" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 ) 19 20 const ( 21 testBindAddress = "localhost:0" 22 resticSource = "../../../../../restic/restic" 23 ) 24 25 func newOpt() Options { 26 opt := DefaultOpt 27 opt.HTTP.ListenAddr = []string{testBindAddress} 28 return opt 29 } 30 31 // TestRestic runs the restic server then runs the unit tests for the 32 // restic remote against it. 33 // 34 // Requires the restic source code in the location indicated by resticSource. 35 func TestResticIntegration(t *testing.T) { 36 ctx := context.Background() 37 _, err := os.Stat(resticSource) 38 if err != nil { 39 t.Skipf("Skipping test as restic source not found: %v", err) 40 } 41 42 opt := newOpt() 43 44 fstest.Initialise() 45 46 fremote, _, clean, err := fstest.RandomRemote() 47 assert.NoError(t, err) 48 defer clean() 49 50 err = fremote.Mkdir(context.Background(), "") 51 assert.NoError(t, err) 52 53 // Start the server 54 s, err := newServer(ctx, fremote, &opt) 55 require.NoError(t, err) 56 testURL := s.Server.URLs()[0] 57 defer func() { 58 _ = s.Shutdown() 59 }() 60 61 // Change directory to run the tests 62 err = os.Chdir(resticSource) 63 require.NoError(t, err, "failed to cd to restic source code") 64 65 // Run the restic tests 66 runTests := func(path string) { 67 args := []string{"test", "./internal/backend/rest", "-run", "TestBackendRESTExternalServer", "-count=1"} 68 if testing.Verbose() { 69 args = append(args, "-v") 70 } 71 cmd := exec.Command("go", args...) 72 cmd.Env = append(os.Environ(), 73 "RESTIC_TEST_REST_REPOSITORY=rest:"+testURL+path, 74 "GO111MODULE=on", 75 ) 76 out, err := cmd.CombinedOutput() 77 if len(out) != 0 { 78 t.Logf("\n----------\n%s----------\n", string(out)) 79 } 80 assert.NoError(t, err, "Running restic integration tests") 81 } 82 83 // Run the tests with no path 84 runTests("") 85 //... and again with a path 86 runTests("potato/sausage/") 87 88 } 89 90 func TestMakeRemote(t *testing.T) { 91 for _, test := range []struct { 92 in, want string 93 }{ 94 {"/", ""}, 95 {"/data", "data"}, 96 {"/data/", "data"}, 97 {"/data/1", "data/1"}, 98 {"/data/12", "data/12/12"}, 99 {"/data/123", "data/12/123"}, 100 {"/data/123/", "data/12/123"}, 101 {"/keys", "keys"}, 102 {"/keys/1", "keys/1"}, 103 {"/keys/12", "keys/12"}, 104 {"/keys/123", "keys/123"}, 105 } { 106 r := httptest.NewRequest("GET", test.in, nil) 107 w := httptest.NewRecorder() 108 next := http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) { 109 remote, ok := request.Context().Value(ContextRemoteKey).(string) 110 assert.True(t, ok, "Failed to get remote from context") 111 assert.Equal(t, test.want, remote, test.in) 112 }) 113 got := WithRemote(next) 114 got.ServeHTTP(w, r) 115 } 116 }