github.com/advanderveer/restic@v0.8.1-0.20171209104529-42a8c19aaea6/internal/backend/rest/rest_test.go (about) 1 package rest_test 2 3 import ( 4 "context" 5 "io/ioutil" 6 "net" 7 "net/url" 8 "os" 9 "os/exec" 10 "testing" 11 "time" 12 13 "github.com/restic/restic/internal/backend" 14 "github.com/restic/restic/internal/backend/rest" 15 "github.com/restic/restic/internal/backend/test" 16 "github.com/restic/restic/internal/restic" 17 rtest "github.com/restic/restic/internal/test" 18 ) 19 20 func runRESTServer(ctx context.Context, t testing.TB, dir string) func() { 21 srv, err := exec.LookPath("rest-server") 22 if err != nil { 23 t.Skip(err) 24 } 25 26 cmd := exec.CommandContext(ctx, srv, "--path", dir) 27 cmd.Stdout = os.Stdout 28 cmd.Stderr = os.Stdout 29 if err := cmd.Start(); err != nil { 30 t.Fatal(err) 31 } 32 33 // wait until the TCP port is reachable 34 var success bool 35 for i := 0; i < 10; i++ { 36 time.Sleep(200 * time.Millisecond) 37 38 c, err := net.Dial("tcp", "localhost:8000") 39 if err != nil { 40 continue 41 } 42 43 success = true 44 if err := c.Close(); err != nil { 45 t.Fatal(err) 46 } 47 } 48 49 if !success { 50 t.Fatal("unable to connect to rest server") 51 return nil 52 } 53 54 return func() { 55 if err := cmd.Process.Kill(); err != nil { 56 t.Fatal(err) 57 } 58 59 // ignore errors, we've killed the process 60 _ = cmd.Wait() 61 } 62 } 63 64 func newTestSuite(ctx context.Context, t testing.TB) *test.Suite { 65 tr, err := backend.Transport(nil) 66 if err != nil { 67 t.Fatalf("cannot create transport for tests: %v", err) 68 } 69 70 return &test.Suite{ 71 // NewConfig returns a config for a new temporary backend that will be used in tests. 72 NewConfig: func() (interface{}, error) { 73 dir, err := ioutil.TempDir(rtest.TestTempDir, "restic-test-rest-") 74 if err != nil { 75 t.Fatal(err) 76 } 77 78 t.Logf("create new backend at %v", dir) 79 80 url, err := url.Parse("http://localhost:8000/restic-test") 81 if err != nil { 82 t.Fatal(err) 83 } 84 85 cfg := rest.NewConfig() 86 cfg.URL = url 87 return cfg, nil 88 }, 89 90 // CreateFn is a function that creates a temporary repository for the tests. 91 Create: func(config interface{}) (restic.Backend, error) { 92 cfg := config.(rest.Config) 93 return rest.Create(cfg, tr) 94 }, 95 96 // OpenFn is a function that opens a previously created temporary repository. 97 Open: func(config interface{}) (restic.Backend, error) { 98 cfg := config.(rest.Config) 99 return rest.Open(cfg, tr) 100 }, 101 102 // CleanupFn removes data created during the tests. 103 Cleanup: func(config interface{}) error { 104 return nil 105 }, 106 } 107 } 108 109 func TestBackendREST(t *testing.T) { 110 defer func() { 111 if t.Skipped() { 112 rtest.SkipDisallowed(t, "restic/backend/rest.TestBackendREST") 113 } 114 }() 115 116 ctx, cancel := context.WithCancel(context.Background()) 117 defer cancel() 118 119 dir, cleanup := rtest.TempDir(t) 120 defer cleanup() 121 122 cleanup = runRESTServer(ctx, t, dir) 123 defer cleanup() 124 125 newTestSuite(ctx, t).RunTests(t) 126 } 127 128 func BenchmarkBackendREST(t *testing.B) { 129 ctx, cancel := context.WithCancel(context.Background()) 130 defer cancel() 131 132 dir, cleanup := rtest.TempDir(t) 133 defer cleanup() 134 135 cleanup = runRESTServer(ctx, t, dir) 136 defer cleanup() 137 138 newTestSuite(ctx, t).RunBenchmarks(t) 139 }