From 11ecdc7b5e461c744975deaec4e4ddf77bdf9c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Thu, 25 Feb 2021 14:49:41 +0100 Subject: [PATCH] Add grpc tests for the owncloud driver --- .../fixtures/storageprovider-owncloud.toml | 11 +++ tests/integration/grpc/grpc_suite_test.go | 45 +++++++-- .../integration/grpc/storageprovider_test.go | 94 +++++++++++++++++-- tests/integration/grpc/userprovider_test.go | 4 +- 4 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 tests/integration/grpc/fixtures/storageprovider-owncloud.toml diff --git a/tests/integration/grpc/fixtures/storageprovider-owncloud.toml b/tests/integration/grpc/fixtures/storageprovider-owncloud.toml new file mode 100644 index 00000000000..a65851c0053 --- /dev/null +++ b/tests/integration/grpc/fixtures/storageprovider-owncloud.toml @@ -0,0 +1,11 @@ +[grpc] +address = "{{grpc_address}}" + +[grpc.services.storageprovider] +driver = "owncloud" + +[grpc.services.storageprovider.drivers.owncloud] +enable_home = true +datadirectory = "{{root}}" +userprovidersvc = "{{users_address}}" +redis = "{{redis_address}}" diff --git a/tests/integration/grpc/grpc_suite_test.go b/tests/integration/grpc/grpc_suite_test.go index 800f93839a7..1dbbed4a9f9 100644 --- a/tests/integration/grpc/grpc_suite_test.go +++ b/tests/integration/grpc/grpc_suite_test.go @@ -38,7 +38,6 @@ import ( const timeoutMs = 30000 -var revads = map[string]*Revad{} var mutex = sync.Mutex{} var port = 19000 @@ -47,15 +46,37 @@ func TestGprc(t *testing.T) { RunSpecs(t, "Gprc Suite") } -type cleanupFunc func() error +type cleanupFunc func(bool) error +// Revad represents a running revad process type Revad struct { - TmpRoot string - GrpcAddress string - Cleanup cleanupFunc + TmpRoot string // Temporary directory on disk. Will be cleaned up by the Cleanup func. + GrpcAddress string // Address of the grpc service + Cleanup cleanupFunc // Function to kill the process and cleanup the temp. root. If the given parameter is true the files will be kept to make debugging failures easier. } -func startRevads(configs map[string]string) (map[string]*Revad, error) { +// stardRevads takes a list of revad configuration files plus a map of +// variables that need to be substituted in them and starts them. +// +// A unique port is assigned to each spawned instance. +// Placeholders in the config files can be replaced the variables from the +// `variables` map, e.g. the config +// +// redis = "{{redis_address}}" +// +// and the variables map +// +// variables = map[string]string{"redis_address": "localhost:6379"} +// +// will result in the config +// +// redis = "localhost:6379" +// +// Special variables are created for the revad addresses, e.g. having a +// `storage` and a `users` revad will make `storage_address` and +// `users_address` available wit the dynamically assigned ports so that +// the services can be made available to each other. +func startRevads(configs map[string]string, variables map[string]string) (map[string]*Revad, error) { mutex.Lock() defer mutex.Unlock() @@ -82,6 +103,9 @@ func startRevads(configs map[string]string) (map[string]*Revad, error) { cfg := string(rawCfg) cfg = strings.ReplaceAll(cfg, "{{root}}", tmpRoot) cfg = strings.ReplaceAll(cfg, "{{grpc_address}}", ownAddress) + for v, value := range variables { + cfg = strings.ReplaceAll(cfg, "{{"+v+"}}", value) + } for name, address := range addresses { cfg = strings.ReplaceAll(cfg, "{{"+name+"_address}}", address) } @@ -99,6 +123,7 @@ func startRevads(configs map[string]string) (map[string]*Revad, error) { } defer outfile.Close() cmd.Stdout = outfile + cmd.Stderr = outfile err = cmd.Start() if err != nil { @@ -116,13 +141,17 @@ func startRevads(configs map[string]string) (map[string]*Revad, error) { revad := &Revad{ TmpRoot: tmpRoot, GrpcAddress: ownAddress, - Cleanup: func() error { + Cleanup: func(keepLogs bool) error { err := cmd.Process.Signal(os.Kill) if err != nil { return errors.Wrap(err, "Could not kill revad") } waitForPort(ownAddress, "close") - os.RemoveAll(tmpRoot) + if keepLogs { + fmt.Println("Test failed, keeping root", tmpRoot, "around for debugging") + } else { + os.RemoveAll(tmpRoot) + } return nil }, } diff --git a/tests/integration/grpc/storageprovider_test.go b/tests/integration/grpc/storageprovider_test.go index b2ba157072e..cce656b3af1 100644 --- a/tests/integration/grpc/storageprovider_test.go +++ b/tests/integration/grpc/storageprovider_test.go @@ -22,6 +22,7 @@ import ( "bytes" "context" "io/ioutil" + "os" "google.golang.org/grpc/metadata" @@ -30,6 +31,7 @@ import ( storagep "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/cs3org/reva/pkg/storage/fs/ocis" + "github.com/cs3org/reva/pkg/storage/fs/owncloud" "github.com/cs3org/reva/pkg/token" jwt "github.com/cs3org/reva/pkg/token/manager/jwt" ruser "github.com/cs3org/reva/pkg/user" @@ -38,9 +40,17 @@ import ( . "github.com/onsi/gomega" ) +// This test suite tests the gprc storageprovider interface using different +// storage backends +// +// It uses the `startRevads` helper to spawn the according reva daemon and +// other dependencies like a userprovider if needed. +// It also sets up an authenticated context and a service client to the storage +// provider to be used in the assertion functions. var _ = Describe("storage providers", func() { var ( dependencies = map[string]string{} + variables = map[string]string{} revads = map[string]*Revad{} ctx context.Context @@ -53,17 +63,17 @@ var _ = Describe("storage providers", func() { } homeRef = &storagep.Reference{ - Spec: &storagep.Reference_Path{Path: "/home"}, + Spec: &storagep.Reference_Path{Path: "/"}, } - filePath = "/home/file" + filePath = "/file" fileRef = &storagep.Reference{ Spec: &storagep.Reference_Path{Path: filePath}, } - versionedFilePath = "/home/versionedFile" + versionedFilePath = "/versionedFile" versionedFileRef = &storagep.Reference{ Spec: &storagep.Reference_Path{Path: versionedFilePath}, } - subdirPath = "/home/subdir" + subdirPath = "/subdir" subdirRef = &storagep.Reference{ Spec: &storagep.Reference_Path{Path: subdirPath}, } @@ -86,7 +96,7 @@ var _ = Describe("storage providers", func() { ctx = metadata.AppendToOutgoingContext(ctx, token.TokenHeader, t) ctx = ruser.ContextSetUser(ctx, user) - revads, err = startRevads(dependencies) + revads, err = startRevads(dependencies, variables) Expect(err).ToNot(HaveOccurred()) serviceClient, err = pool.GetStorageProviderServiceClient(revads["storage"].GrpcAddress) Expect(err).ToNot(HaveOccurred()) @@ -94,7 +104,7 @@ var _ = Describe("storage providers", func() { AfterEach(func() { for _, r := range revads { - Expect(r.Cleanup()).To(Succeed()) + Expect(r.Cleanup(CurrentGinkgoTestDescription().Failed)).To(Succeed()) } }) @@ -111,6 +121,10 @@ var _ = Describe("storage providers", func() { statRes, err = serviceClient.Stat(ctx, &storagep.StatRequest{Ref: homeRef}) Expect(err).ToNot(HaveOccurred()) Expect(statRes.Status.Code).To(Equal(rpcv1beta1.Code_CODE_OK)) + + ghRes, err := serviceClient.GetHome(ctx, &storagep.GetHomeRequest{}) + Expect(err).ToNot(HaveOccurred()) + Expect(ghRes.Status.Code).To(Equal(rpcv1beta1.Code_CODE_OK)) }) } @@ -480,4 +494,72 @@ var _ = Describe("storage providers", func() { assertFileVersions() }) }) + + Describe("owncloud", func() { + BeforeEach(func() { + dependencies = map[string]string{ + "users": "userprovider-json.toml", + "storage": "storageprovider-owncloud.toml", + } + + redisAddress := os.Getenv("REDIS_ADDRESS") + if redisAddress == "" { + Fail("REDIS_ADDRESS not set") + } + variables = map[string]string{ + "redis_address": redisAddress, + } + }) + + assertCreateHome() + + Context("with a home and a subdirectory", func() { + JustBeforeEach(func() { + res, err := serviceClient.CreateHome(ctx, &storagep.CreateHomeRequest{}) + Expect(err).ToNot(HaveOccurred()) + Expect(res.Status.Code).To(Equal(rpcv1beta1.Code_CODE_OK)) + + subdirRes, err := serviceClient.CreateContainer(ctx, &storagep.CreateContainerRequest{Ref: subdirRef}) + Expect(err).ToNot(HaveOccurred()) + Expect(subdirRes.Status.Code).To(Equal(rpcv1beta1.Code_CODE_OK)) + }) + + assertCreateContainer() + assertListContainer() + assertGetPath() + assertDelete() + assertMove() + assertGrants() + assertUploads() + assertDownloads() + assertRecycle() + assertReferences() + assertMetadata() + }) + + Context("with an existing file /versioned_file", func() { + JustBeforeEach(func() { + fs, err := owncloud.New(map[string]interface{}{ + "datadirectory": revads["storage"].TmpRoot, + "userprovidersvc": revads["users"].GrpcAddress, + "enable_home": true, + }) + Expect(err).ToNot(HaveOccurred()) + + content1 := ioutil.NopCloser(bytes.NewReader([]byte("1"))) + content2 := ioutil.NopCloser(bytes.NewReader([]byte("22"))) + + ctx := ruser.ContextSetUser(context.Background(), user) + + err = fs.CreateHome(ctx) + Expect(err).ToNot(HaveOccurred()) + err = fs.Upload(ctx, versionedFileRef, content1) + Expect(err).ToNot(HaveOccurred()) + err = fs.Upload(ctx, versionedFileRef, content2) + Expect(err).ToNot(HaveOccurred()) + }) + + assertFileVersions() + }) + }) }) diff --git a/tests/integration/grpc/userprovider_test.go b/tests/integration/grpc/userprovider_test.go index 21a7d5b9160..24bb7a77a9e 100644 --- a/tests/integration/grpc/userprovider_test.go +++ b/tests/integration/grpc/userprovider_test.go @@ -64,7 +64,7 @@ var _ = Describe("user providers", func() { ctx = metadata.AppendToOutgoingContext(ctx, token.TokenHeader, t) ctx = ruser.ContextSetUser(ctx, user) - revads, err = startRevads(dependencies) + revads, err = startRevads(dependencies, map[string]string{}) Expect(err).ToNot(HaveOccurred()) serviceClient, err = pool.GetUserProviderServiceClient(revads["users"].GrpcAddress) Expect(err).ToNot(HaveOccurred()) @@ -72,7 +72,7 @@ var _ = Describe("user providers", func() { AfterEach(func() { for _, r := range revads { - r.Cleanup() + r.Cleanup(CurrentGinkgoTestDescription().Failed) } })