| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | package rest_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-05-11 22:40:50 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 	"net/url" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 20:04:23 +02:00
										 |  |  | 	"github.com/restic/restic/internal/backend" | 
					
						
							| 
									
										
										
										
											2017-07-23 14:21:03 +02:00
										 |  |  | 	"github.com/restic/restic/internal/backend/rest" | 
					
						
							|  |  |  | 	"github.com/restic/restic/internal/backend/test" | 
					
						
							| 
									
										
										
										
											2017-07-24 17:42:25 +02:00
										 |  |  | 	"github.com/restic/restic/internal/restic" | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 	rtest "github.com/restic/restic/internal/test" | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | func runRESTServer(ctx context.Context, t testing.TB, dir string) (*url.URL, func()) { | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 	srv, err := exec.LookPath("rest-server") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Skip(err) | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-24 18:06:21 +01:00
										 |  |  | 	cmd := exec.CommandContext(ctx, srv, "--no-auth", "--path", dir) | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 	cmd.Stdout = os.Stdout | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 	cmd.Stderr = os.Stdout | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 	if err := cmd.Start(); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 	// wait until the TCP port is reachable | 
					
						
							|  |  |  | 	var success bool | 
					
						
							|  |  |  | 	for i := 0; i < 10; i++ { | 
					
						
							| 
									
										
										
										
											2017-05-12 21:45:18 +02:00
										 |  |  | 		time.Sleep(200 * time.Millisecond) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 		c, err := net.Dial("tcp", "localhost:8000") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-05-12 21:33:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		success = true | 
					
						
							|  |  |  | 		if err := c.Close(); err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !success { | 
					
						
							|  |  |  | 		t.Fatal("unable to connect to rest server") | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 		return nil, nil | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-15 18:16:17 +02:00
										 |  |  | 	url, err := url.Parse("http://localhost:8000/restic-test/") | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cleanup := func() { | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 		if err := cmd.Process.Kill(); err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// ignore errors, we've killed the process | 
					
						
							|  |  |  | 		_ = cmd.Wait() | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return url, cleanup | 
					
						
							| 
									
										
										
										
											2016-02-20 22:05:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 19:18:09 +02:00
										 |  |  | func newTestSuite(_ context.Context, t testing.TB, url *url.URL, minimalData bool) *test.Suite { | 
					
						
							| 
									
										
										
										
											2018-01-27 13:57:43 +01:00
										 |  |  | 	tr, err := backend.Transport(backend.TransportOptions{}) | 
					
						
							| 
									
										
										
										
											2017-09-24 20:04:23 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("cannot create transport for tests: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | 	return &test.Suite{ | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 		MinimalData: minimalData, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 		// NewConfig returns a config for a new temporary backend that will be used in tests. | 
					
						
							|  |  |  | 		NewConfig: func() (interface{}, error) { | 
					
						
							| 
									
										
										
										
											2017-06-06 00:25:22 +02:00
										 |  |  | 			cfg := rest.NewConfig() | 
					
						
							|  |  |  | 			cfg.URL = url | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 			return cfg, nil | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// CreateFn is a function that creates a temporary repository for the tests. | 
					
						
							|  |  |  | 		Create: func(config interface{}) (restic.Backend, error) { | 
					
						
							|  |  |  | 			cfg := config.(rest.Config) | 
					
						
							| 
									
										
										
										
											2020-04-10 12:08:52 +02:00
										 |  |  | 			return rest.Create(context.TODO(), cfg, tr) | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// OpenFn is a function that opens a previously created temporary repository. | 
					
						
							|  |  |  | 		Open: func(config interface{}) (restic.Backend, error) { | 
					
						
							|  |  |  | 			cfg := config.(rest.Config) | 
					
						
							| 
									
										
										
										
											2017-09-24 20:04:23 +02:00
										 |  |  | 			return rest.Open(cfg, tr) | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// CleanupFn removes data created during the tests. | 
					
						
							|  |  |  | 		Cleanup: func(config interface{}) error { | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestBackendREST(t *testing.T) { | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if t.Skipped() { | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 			rtest.SkipDisallowed(t, "restic/backend/rest.TestBackendREST") | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-09 13:42:33 +01:00
										 |  |  | 	dir := rtest.TempDir(t) | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 	serverURL, cleanup := runRESTServer(ctx, t, dir) | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 	newTestSuite(ctx, t, serverURL, false).RunTests(t) | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 10:25:47 +01:00
										 |  |  | func TestBackendRESTExternalServer(t *testing.T) { | 
					
						
							|  |  |  | 	repostr := os.Getenv("RESTIC_TEST_REST_REPOSITORY") | 
					
						
							|  |  |  | 	if repostr == "" { | 
					
						
							|  |  |  | 		t.Skipf("environment variable %v not set", "RESTIC_TEST_REST_REPOSITORY") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cfg, err := rest.ParseConfig(repostr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c := cfg.(rest.Config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	newTestSuite(ctx, t, c.URL, true).RunTests(t) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | func BenchmarkBackendREST(t *testing.B) { | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-09 13:42:33 +01:00
										 |  |  | 	dir := rtest.TempDir(t) | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 	serverURL, cleanup := runRESTServer(ctx, t, dir) | 
					
						
							| 
									
										
										
										
											2017-05-13 21:56:18 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 10:16:50 +01:00
										 |  |  | 	newTestSuite(ctx, t, serverURL, false).RunBenchmarks(t) | 
					
						
							| 
									
										
										
										
											2017-05-01 23:08:16 +02:00
										 |  |  | } |