Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions features/etag-propagation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ Feature: Etag and Treesize propagation
Scenario: Change etag of personal home and move subtree
Given user "admin" has created a folder "a-folder/a-sub-folder-B" in the home directory with the alias "a-sub-folder-B"
And user "admin" has created a folder "a-folder/a-sub-folder/testFolder" in the home directory with the alias "testFolder"
And user "admin" remembers the fileinfo of the resource with the alias "Admin Home"
And user "admin" has created a folder "a-folder/a-sub-folder/testFolder/test2" in the home directory with the alias "test2"
# This is needed to make sure that the propagation has happened to the testing file tree before we move the folder
And for user "admin" the etag of the resource with the alias "Admin Home" should have changed
And user "admin" remembers the fileinfo of the resource with the alias "Admin Home"
And user "admin" has uploaded a file "a-folder/a-sub-folder/testfile.txt" with content "text" in the home directory with the alias "testfile.txt"
# This is needed to make sure that the propagation has happened to the testing file tree before we move the folder
And for user "admin" the etag of the resource with the alias "Admin Home" should have changed
# Now we have a clean state and can start the actual test
And user "admin" remembers the fileinfo of the resource with the alias "Admin Home"
And user "admin" remembers the fileinfo of the resource with the alias "a-folder"
And user "admin" remembers the fileinfo of the resource with the alias "a-sub-folder"
Expand Down
17 changes: 17 additions & 0 deletions helpers/retry.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package helpers

import (
"context"
"time"

providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
)

// Retry retries a function f max times with a delay between each attempt
Expand All @@ -17,3 +20,17 @@ func Retry(f func() error, max int, delay time.Duration) error {
time.Sleep(delay)
return f()
}

// RetryResource retries a function f max times with a delay between each attempt
func RetryResource(f func(*providerv1beta1.Reference, context.Context) error, ref *providerv1beta1.Reference, ctx context.Context, max int, delay time.Duration) error {
// retry the function f max-1 times with a delay between each attempt
for i := 0; i < max-1; i++ {
time.Sleep(delay)
if f(ref, ctx) == nil {
return nil
}
}
// last attempt
time.Sleep(delay)
return f(ref, ctx)
}
36 changes: 23 additions & 13 deletions steps/resources/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package resources

import (
"context"
"errors"

rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cucumber/godog"
"github.com/owncloud/cs3api-validator/helpers"
)

// deleteResourcesAfterScenario deletes resources which have been created after running the scenario
Expand All @@ -15,7 +17,6 @@ func (f *ResourcesFeatureContext) DeleteResourcesAfterScenario(ctx context.Conte

// we don't now which user has access to which reference,
// therefore we just try to delete each reference with all users

for u := range f.Users {
reqctx, err := f.GetAuthContext(u)
if err != nil {
Expand All @@ -25,18 +26,9 @@ func (f *ResourcesFeatureContext) DeleteResourcesAfterScenario(ctx context.Conte
notYetDeleted := []*providerv1beta1.Reference{}

for _, ref := range resourcesToDelete {
resp, err := f.Client.Delete(
reqctx,
&providerv1beta1.DeleteRequest{
Ref: ref,
},
)
if err != nil {
continue
}

// non-existing resources are not errors
if resp.Status.Code != rpc.Code_CODE_OK && resp.Status.Code != rpc.Code_CODE_NOT_FOUND {
// we need to retry the deletion because the resource might be in postprocessing
e := helpers.RetryResource(f.deleteResource, ref, reqctx, 3, f.Config.AsyncPropagationDelay)
if e != nil {
notYetDeleted = append(notYetDeleted, ref)
}
}
Expand All @@ -47,6 +39,24 @@ func (f *ResourcesFeatureContext) DeleteResourcesAfterScenario(ctx context.Conte
return ctx, nil
}

func (f *ResourcesFeatureContext) deleteResource(ref *providerv1beta1.Reference, reqctx context.Context) error {
resp, err := f.Client.Delete(
reqctx,
&providerv1beta1.DeleteRequest{
Ref: ref,
},
)
if err != nil {
return err
}

// non-existing resources are not errors
if resp.Status.Code != rpc.Code_CODE_OK && resp.Status.Code != rpc.Code_CODE_NOT_FOUND {
return errors.New(resp.GetStatus().GetMessage())
}
return nil
}

// emptyTrashAfterScenario empties the trash for all users after running the scenario
func (f *ResourcesFeatureContext) EmptyTrashAfterScenario(ctx context.Context, sc *godog.Scenario, errsctx error) (context.Context, error) {
for u := range f.Users {
Expand Down