github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/storage/gcs_test.go (about)

     1  // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
     2  
     3  package storage
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  
    11  	"github.com/fsouza/fake-gcs-server/fakestorage"
    12  	. "github.com/pingcap/check"
    13  	backuppb "github.com/pingcap/kvproto/pkg/backup"
    14  )
    15  
    16  func (r *testStorageSuite) TestGCS(c *C) {
    17  	ctx := context.Background()
    18  
    19  	opts := fakestorage.Options{
    20  		NoListener: true,
    21  	}
    22  	server, err := fakestorage.NewServerWithOptions(opts)
    23  	c.Assert(err, IsNil)
    24  	bucketName := "testbucket"
    25  	server.CreateBucketWithOpts(fakestorage.CreateBucketOpts{Name: bucketName})
    26  
    27  	gcs := &backuppb.GCS{
    28  		Bucket:          bucketName,
    29  		Prefix:          "a/b/",
    30  		StorageClass:    "NEARLINE",
    31  		PredefinedAcl:   "private",
    32  		CredentialsBlob: "Fake Credentials",
    33  	}
    34  	stg, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
    35  		SendCredentials:  false,
    36  		CheckPermissions: []Permission{AccessBuckets},
    37  		HTTPClient:       server.HTTPClient(),
    38  	})
    39  	c.Assert(err, IsNil)
    40  
    41  	err = stg.WriteFile(ctx, "key", []byte("data"))
    42  	c.Assert(err, IsNil)
    43  
    44  	err = stg.WriteFile(ctx, "key1", []byte("data1"))
    45  	c.Assert(err, IsNil)
    46  
    47  	err = stg.WriteFile(ctx, "key2", []byte("data22223346757222222222289722222"))
    48  	c.Assert(err, IsNil)
    49  
    50  	rc, err := server.Client().Bucket(bucketName).Object("a/b/key").NewReader(ctx)
    51  	c.Assert(err, IsNil)
    52  	d, err := io.ReadAll(rc)
    53  	rc.Close()
    54  	c.Assert(err, IsNil)
    55  	c.Assert(d, DeepEquals, []byte("data"))
    56  
    57  	d, err = stg.ReadFile(ctx, "key")
    58  	c.Assert(err, IsNil)
    59  	c.Assert(d, DeepEquals, []byte("data"))
    60  
    61  	exist, err := stg.FileExists(ctx, "key")
    62  	c.Assert(err, IsNil)
    63  	c.Assert(exist, IsTrue)
    64  
    65  	exist, err = stg.FileExists(ctx, "key_not_exist")
    66  	c.Assert(err, IsNil)
    67  	c.Assert(exist, IsFalse)
    68  
    69  	list := ""
    70  	var totalSize int64 = 0
    71  	err = stg.WalkDir(ctx, nil, func(name string, size int64) error {
    72  		list += name
    73  		totalSize += size
    74  		return nil
    75  	})
    76  	c.Assert(err, IsNil)
    77  	c.Assert(list, Equals, "keykey1key2")
    78  	c.Assert(totalSize, Equals, int64(42))
    79  
    80  	// test 1003 files
    81  	totalSize = 0
    82  	for i := 0; i < 1000; i += 1 {
    83  		err = stg.WriteFile(ctx, fmt.Sprintf("f%d", i), []byte("data"))
    84  		c.Assert(err, IsNil)
    85  	}
    86  	filesSet := make(map[string]struct{}, 1003)
    87  	err = stg.WalkDir(ctx, nil, func(name string, size int64) error {
    88  		filesSet[name] = struct{}{}
    89  		totalSize += size
    90  		return nil
    91  	})
    92  	c.Assert(err, IsNil)
    93  	c.Assert(totalSize, Equals, int64(42+4000))
    94  	_, ok := filesSet["key"]
    95  	c.Assert(ok, IsTrue)
    96  	_, ok = filesSet["key1"]
    97  	c.Assert(ok, IsTrue)
    98  	_, ok = filesSet["key2"]
    99  	c.Assert(ok, IsTrue)
   100  	for i := 0; i < 1000; i += 1 {
   101  		_, ok = filesSet[fmt.Sprintf("f%d", i)]
   102  		c.Assert(ok, IsTrue)
   103  	}
   104  
   105  	efr, err := stg.Open(ctx, "key2")
   106  	c.Assert(err, IsNil)
   107  
   108  	p := make([]byte, 10)
   109  	n, err := efr.Read(p)
   110  	c.Assert(err, IsNil)
   111  	c.Assert(n, Equals, 10)
   112  	c.Assert(string(p), Equals, "data222233")
   113  
   114  	p = make([]byte, 40)
   115  	n, err = efr.Read(p)
   116  	c.Assert(err, IsNil)
   117  	c.Assert(n, Equals, 23)
   118  	c.Assert(string(p[:23]), Equals, "46757222222222289722222")
   119  
   120  	p = make([]byte, 5)
   121  	offs, err := efr.Seek(3, io.SeekStart)
   122  	c.Assert(err, IsNil)
   123  	c.Assert(offs, Equals, int64(3))
   124  
   125  	n, err = efr.Read(p)
   126  	c.Assert(err, IsNil)
   127  	c.Assert(n, Equals, 5)
   128  	c.Assert(string(p), Equals, "a2222")
   129  
   130  	p = make([]byte, 5)
   131  	offs, err = efr.Seek(3, io.SeekCurrent)
   132  	c.Assert(err, IsNil)
   133  	c.Assert(offs, Equals, int64(11))
   134  
   135  	n, err = efr.Read(p)
   136  	c.Assert(err, IsNil)
   137  	c.Assert(n, Equals, 5)
   138  	c.Assert(string(p), Equals, "67572")
   139  
   140  	/* Since fake_gcs_server hasn't support for negative offset yet.
   141  	p = make([]byte, 5)
   142  	offs, err = efr.Seek(int64(-7), io.SeekEnd)
   143  	c.Assert(err, IsNil)
   144  	c.Assert(offs, Equals, int64(-7))
   145  
   146  	n, err = efr.Read(p)
   147  	c.Assert(err, IsNil)
   148  	c.Assert(n, Equals, 5)
   149  	c.Assert(string(p), Equals, "97222")
   150  	*/
   151  
   152  	err = efr.Close()
   153  	c.Assert(err, IsNil)
   154  
   155  	c.Assert(stg.URI(), Equals, "gcs://testbucket/a/b/")
   156  }
   157  
   158  func (r *testStorageSuite) TestNewGCSStorage(c *C) {
   159  	ctx := context.Background()
   160  
   161  	opts := fakestorage.Options{
   162  		NoListener: true,
   163  	}
   164  	server, err1 := fakestorage.NewServerWithOptions(opts)
   165  	c.Assert(err1, IsNil)
   166  	bucketName := "testbucket"
   167  	server.CreateBucketWithOpts(fakestorage.CreateBucketOpts{Name: bucketName})
   168  	testDir := c.MkDir()
   169  
   170  	{
   171  		gcs := &backuppb.GCS{
   172  			Bucket:          bucketName,
   173  			Prefix:          "a/b/",
   174  			StorageClass:    "NEARLINE",
   175  			PredefinedAcl:   "private",
   176  			CredentialsBlob: "FakeCredentials",
   177  		}
   178  		_, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   179  			SendCredentials:  true,
   180  			CheckPermissions: []Permission{AccessBuckets},
   181  			HTTPClient:       server.HTTPClient(),
   182  		})
   183  		c.Assert(err, IsNil)
   184  		c.Assert(gcs.CredentialsBlob, Equals, "FakeCredentials")
   185  	}
   186  
   187  	{
   188  		gcs := &backuppb.GCS{
   189  			Bucket:          bucketName,
   190  			Prefix:          "a/b/",
   191  			StorageClass:    "NEARLINE",
   192  			PredefinedAcl:   "private",
   193  			CredentialsBlob: "FakeCredentials",
   194  		}
   195  		_, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   196  			SendCredentials:  false,
   197  			CheckPermissions: []Permission{AccessBuckets},
   198  			HTTPClient:       server.HTTPClient(),
   199  		})
   200  		c.Assert(err, IsNil)
   201  		c.Assert(gcs.CredentialsBlob, Equals, "")
   202  	}
   203  
   204  	{
   205  		fakeCredentialsFile, err := os.CreateTemp(testDir, "fakeCredentialsFile")
   206  		c.Assert(err, IsNil)
   207  		defer func() {
   208  			fakeCredentialsFile.Close()
   209  			os.Remove(fakeCredentialsFile.Name())
   210  		}()
   211  		_, err = fakeCredentialsFile.Write([]byte(`{"type": "service_account"}`))
   212  		c.Assert(err, IsNil)
   213  		err = os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", fakeCredentialsFile.Name())
   214  		defer os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS")
   215  		c.Assert(err, IsNil)
   216  
   217  		gcs := &backuppb.GCS{
   218  			Bucket:          bucketName,
   219  			Prefix:          "a/b/",
   220  			StorageClass:    "NEARLINE",
   221  			PredefinedAcl:   "private",
   222  			CredentialsBlob: "",
   223  		}
   224  		_, err = newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   225  			SendCredentials:  true,
   226  			CheckPermissions: []Permission{AccessBuckets},
   227  			HTTPClient:       server.HTTPClient(),
   228  		})
   229  		c.Assert(err, IsNil)
   230  		c.Assert(gcs.CredentialsBlob, Equals, `{"type": "service_account"}`)
   231  	}
   232  
   233  	{
   234  		fakeCredentialsFile, err := os.CreateTemp(testDir, "fakeCredentialsFile")
   235  		c.Assert(err, IsNil)
   236  		defer func() {
   237  			fakeCredentialsFile.Close()
   238  			os.Remove(fakeCredentialsFile.Name())
   239  		}()
   240  		_, err = fakeCredentialsFile.Write([]byte(`{"type": "service_account"}`))
   241  		c.Assert(err, IsNil)
   242  		err = os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", fakeCredentialsFile.Name())
   243  		defer os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS")
   244  		c.Assert(err, IsNil)
   245  
   246  		gcs := &backuppb.GCS{
   247  			Bucket:          bucketName,
   248  			Prefix:          "a/b/",
   249  			StorageClass:    "NEARLINE",
   250  			PredefinedAcl:   "private",
   251  			CredentialsBlob: "",
   252  		}
   253  		s, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   254  			SendCredentials:  false,
   255  			CheckPermissions: []Permission{AccessBuckets},
   256  			HTTPClient:       server.HTTPClient(),
   257  		})
   258  		c.Assert(err, IsNil)
   259  		c.Assert(gcs.CredentialsBlob, Equals, "")
   260  		c.Assert(s.objectName("x"), Equals, "a/b/x")
   261  	}
   262  
   263  	{
   264  		os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS")
   265  		gcs := &backuppb.GCS{
   266  			Bucket:          bucketName,
   267  			Prefix:          "a/b/",
   268  			StorageClass:    "NEARLINE",
   269  			PredefinedAcl:   "private",
   270  			CredentialsBlob: "",
   271  		}
   272  		_, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   273  			SendCredentials:  true,
   274  			CheckPermissions: []Permission{AccessBuckets},
   275  			HTTPClient:       server.HTTPClient(),
   276  		})
   277  		c.Assert(err, NotNil)
   278  	}
   279  
   280  	{
   281  		gcs := &backuppb.GCS{
   282  			Bucket:          bucketName,
   283  			Prefix:          "a/b",
   284  			StorageClass:    "NEARLINE",
   285  			PredefinedAcl:   "private",
   286  			CredentialsBlob: "FakeCredentials",
   287  		}
   288  		s, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{
   289  			SendCredentials:  false,
   290  			CheckPermissions: []Permission{AccessBuckets},
   291  			HTTPClient:       server.HTTPClient(),
   292  		})
   293  		c.Assert(err, IsNil)
   294  		c.Assert(gcs.CredentialsBlob, Equals, "")
   295  		c.Assert(s.objectName("x"), Equals, "a/b/x")
   296  	}
   297  }