github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/backend/filestate/bucket_test.go (about) 1 package filestate 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 11 "gocloud.dev/blob" 12 ) 13 14 func mustNotHaveError(t *testing.T, context string, err error) { 15 t.Helper() 16 if err != nil { 17 t.Fatalf("Error in testcase %q, aborting: %v", context, err) 18 } 19 } 20 21 // The wrappedBucket type exists so that when we use the blob.Bucket type we can present a consistent 22 // view of file paths. Since it will assume that backslashes (file separators on Windows) are part of 23 // file names, and this causes "problems". 24 func TestWrappedBucket(t *testing.T) { 25 t.Parallel() 26 27 // wrappedBucket will only massage file paths IFF it is needed, as filepath.ToSlash is a noop. 28 if filepath.Separator == '/' { 29 assert.Equal(t, `foo\bar\baz`, filepath.ToSlash(`foo\bar\baz`)) 30 t.Skip("Skipping wrappedBucket tests because file paths won't be modified.") 31 } 32 33 // Initialize a filestate backend, using the default Pulumi directory. 34 cloudURL := FilePathPrefix + "~" 35 b, err := New(nil, cloudURL) 36 if err != nil { 37 t.Fatalf("Initializing new filestate backend: %v", err) 38 } 39 localBackend, ok := b.(*localBackend) 40 if !ok { 41 t.Fatalf("backend wasn't of type localBackend?") 42 } 43 44 wrappedBucket, ok := localBackend.bucket.(*wrappedBucket) 45 if !ok { 46 t.Fatalf("localBackend.bucket wasn't of type wrappedBucket?") 47 } 48 49 ctx := context.Background() 50 // Perform basic file operations using wrappedBucket and verify that it will 51 // successfully handle both "/" and "\" as file separators. (And probably fail in 52 // exciting ways if you try to give it a file on a system that supports "\" or "/" as 53 // a valid character in a filename.) 54 //nolint:paralleltest // uses shared state with parent 55 t.Run("SanityCheck", func(t *testing.T) { 56 randomData := []byte("Just some random data") 57 58 err := wrappedBucket.WriteAll(ctx, ".pulumi/bucket-test/foo", randomData, &blob.WriterOptions{}) 59 mustNotHaveError(t, "WriteAll", err) 60 61 readData, err := wrappedBucket.ReadAll(ctx, `.pulumi\bucket-test\foo`) 62 mustNotHaveError(t, "ReadAll", err) 63 assert.EqualValues(t, randomData, readData, "data read from bucket doesn't match what was written") 64 65 // Verify the leading slash isn't necessary. 66 err = wrappedBucket.Delete(ctx, ".pulumi/bucket-test/foo") 67 mustNotHaveError(t, "Delete", err) 68 69 exists, err := wrappedBucket.Exists(ctx, ".pulumi/bucket-test/foo") 70 mustNotHaveError(t, "Exists", err) 71 assert.False(t, exists, "Deleted file still found?") 72 }) 73 74 // Verify ListObjects / listBucket works with regard to differeing file separators too. 75 //nolint:paralleltest // uses shared state with parent 76 t.Run("ListObjects", func(t *testing.T) { 77 randomData := []byte("Just some random data") 78 filenames := []string{"a.json", "b.json", "c.json"} 79 80 // Write some data. 81 for _, filename := range filenames { 82 key := fmt.Sprintf(`.pulumi\bucket-test\%s`, filename) 83 err := wrappedBucket.WriteAll(ctx, key, randomData, &blob.WriterOptions{}) 84 mustNotHaveError(t, "WriteAll", err) 85 } 86 87 // Verify it is found. NOTE: This requires that any files created 88 // during other tests have successfully been cleaned up too. 89 objects, err := listBucket(wrappedBucket, `.pulumi\bucket-test`) 90 mustNotHaveError(t, "listBucket", err) 91 if len(objects) != len(filenames) { 92 assert.Equal(t, 3, len(objects), "listBucket returned unexpected number of objects.") 93 for _, object := range objects { 94 t.Logf("Got object: %+v", object) 95 } 96 } 97 }) 98 }