Repository: fsouza/fake-gcs-server
Pull request #1158 (2023-05-10 00:16:52)

fakestorage: don't expose the Backend field
Make it available via a method instead. This way at least the reference is readonly.

Technically a breaking change, but it's short-lived :)


Patch:
diff --git a/fakestorage/bucket.go b/fakestorage/bucket.go
index eb31166..72bd702 100644
--- a/fakestorage/bucket.go
+++ b/fakestorage/bucket.go
@@ -24,7 +24,7 @@ var bucketRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$`)
 //
 // Deprecated: use CreateBucketWithOpts.
 func (s *Server) CreateBucket(name string) {
-	err := s.Backend.CreateBucket(name, false)
+	err := s.backend.CreateBucket(name, false)
 	if err != nil {
 		panic(err)
 	}
@@ -43,7 +43,7 @@ type CreateBucketOpts struct {
 //
 // If the underlying backend returns an error, this method panics.
 func (s *Server) CreateBucketWithOpts(opts CreateBucketOpts) {
-	err := s.Backend.CreateBucket(opts.Name, opts.VersioningEnabled)
+	err := s.backend.CreateBucket(opts.Name, opts.VersioningEnabled)
 	if err != nil {
 		panic(err)
 	}
@@ -71,7 +71,7 @@ func (s *Server) createBucketByPost(r *http.Request) jsonResponse {
 		return jsonResponse{errorMessage: err.Error(), status: http.StatusBadRequest}
 	}
 
-	_, err := s.Backend.GetBucket(name)
+	_, err := s.backend.GetBucket(name)
 	if err == nil {
 		return jsonResponse{
 			errorMessage: fmt.Sprintf(
@@ -84,12 +84,12 @@ func (s *Server) createBucketByPost(r *http.Request) jsonResponse {
 	}
 
 	// Create the named bucket
-	if err := s.Backend.CreateBucket(name, versioning); err != nil {
+	if err := s.backend.CreateBucket(name, versioning); err != nil {
 		return jsonResponse{errorMessage: err.Error()}
 	}
 
 	// Return the created bucket:
-	bucket, err := s.Backend.GetBucket(name)
+	bucket, err := s.backend.GetBucket(name)
 	if err != nil {
 		return jsonResponse{errorMessage: err.Error()}
 	}
@@ -97,7 +97,7 @@ func (s *Server) createBucketByPost(r *http.Request) jsonResponse {
 }
 
 func (s *Server) listBuckets(r *http.Request) jsonResponse {
-	buckets, err := s.Backend.ListBuckets()
+	buckets, err := s.backend.ListBuckets()
 	if err != nil {
 		return jsonResponse{errorMessage: err.Error()}
 	}
@@ -106,7 +106,7 @@ func (s *Server) listBuckets(r *http.Request) jsonResponse {
 
 func (s *Server) getBucket(r *http.Request) jsonResponse {
 	bucketName := unescapeMuxVars(mux.Vars(r))["bucketName"]
-	bucket, err := s.Backend.GetBucket(bucketName)
+	bucket, err := s.backend.GetBucket(bucketName)
 	if err != nil {
 		return jsonResponse{status: http.StatusNotFound}
 	}
@@ -115,7 +115,7 @@ func (s *Server) getBucket(r *http.Request) jsonResponse {
 
 func (s *Server) deleteBucket(r *http.Request) jsonResponse {
 	bucketName := unescapeMuxVars(mux.Vars(r))["bucketName"]
-	err := s.Backend.DeleteBucket(bucketName)
+	err := s.backend.DeleteBucket(bucketName)
 	if err == backend.BucketNotFound {
 		return jsonResponse{status: http.StatusNotFound}
 	}
diff --git a/fakestorage/object.go b/fakestorage/object.go
index 3cae86d..ddeb299 100644
--- a/fakestorage/object.go
+++ b/fakestorage/object.go
@@ -281,7 +281,7 @@ func (s *Server) CreateObjectStreaming(obj StreamingObject) error {
 }
 
 func (s *Server) createObject(obj StreamingObject, conditions backend.Conditions) (StreamingObject, error) {
-	oldBackendObj, err := s.Backend.GetObject(obj.BucketName, obj.Name)
+	oldBackendObj, err := s.backend.GetObject(obj.BucketName, obj.Name)
 	// Calling Close before checking err is okay on objects, and the object
 	// may need to be closed whether or not there's an error.
 	defer oldBackendObj.Close() //lint:ignore SA5001 // see above
@@ -289,7 +289,7 @@ func (s *Server) createObject(obj StreamingObject, conditions backend.Conditions
 	prevVersionExisted := err == nil
 
 	// The caller is responsible for closing the created object.
-	newBackendObj, err := s.Backend.CreateObject(toBackendObjects([]StreamingObject{obj})[0], conditions)
+	newBackendObj, err := s.backend.CreateObject(toBackendObjects([]StreamingObject{obj})[0], conditions)
 	if err != nil {
 		return StreamingObject{}, err
 	}
@@ -304,7 +304,7 @@ func (s *Server) createObject(obj StreamingObject, conditions backend.Conditions
 			"overwrittenByGeneration": strconv.FormatInt(newBackendObj.Generation, 10),
 		}
 
-		bucket, _ := s.Backend.GetBucket(obj.BucketName)
+		bucket, _ := s.backend.GetBucket(obj.BucketName)
 		if bucket.VersioningEnabled {
 			s.eventManager.Trigger(&oldBackendObj, notification.EventArchive, oldObjEventAttr)
 		} else {
@@ -339,7 +339,7 @@ func (s *Server) ListObjects(bucketName, prefix, delimiter string, versions bool
 }
 
 func (s *Server) ListObjectsWithOptions(bucketName string, options ListOptions) ([]ObjectAttrs, []string, error) {
-	backendObjects, err := s.Backend.ListObjects(bucketName, options.Prefix, options.Versions)
+	backendObjects, err := s.backend.ListObjects(bucketName, options.Prefix, options.Versions)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -514,7 +514,7 @@ func (s *Server) GetObject(bucketName, objectName string) (Object, error) {
 // GetObjectStreaming returns the object with the given name in the given
 // bucket, or an error if the object doesn't exist.
 func (s *Server) GetObjectStreaming(bucketName, objectName string) (StreamingObject, error) {
-	backendObj, err := s.Backend.GetObject(bucketName, objectName)
+	backendObj, err := s.backend.GetObject(bucketName, objectName)
 	if err != nil {
 		return StreamingObject{}, err
 	}
@@ -538,7 +538,7 @@ func (s *Server) GetObjectWithGeneration(bucketName, objectName string, generati
 //
 // If versioning is enabled, archived versions are considered.
 func (s *Server) GetObjectWithGenerationStreaming(bucketName, objectName string, generation int64) (StreamingObject, error) {
-	backendObj, err := s.Backend.GetObjectWithGeneration(bucketName, objectName, generation)
+	backendObj, err := s.backend.GetObjectWithGeneration(bucketName, objectName, generation)
 	if err != nil {
 		return StreamingObject{}, err
 	}
@@ -669,12 +669,12 @@ func (s *Server) deleteObject(r *http.Request) jsonResponse {
 	// may need to be closed whether or not there's an error.
 	defer obj.Close() //lint:ignore SA5001 // see above
 	if err == nil {
-		err = s.Backend.DeleteObject(vars["bucketName"], vars["objectName"])
+		err = s.backend.DeleteObject(vars["bucketName"], vars["objectName"])
 	}
 	if err != nil {
 		return jsonResponse{status: http.StatusNotFound}
 	}
-	bucket, _ := s.Backend.GetBucket(obj.BucketName)
+	bucket, _ := s.backend.GetBucket(obj.BucketName)
 	backendObj := toBackendObjects([]StreamingObject{obj})[0]
 	if bucket.VersioningEnabled {
 		s.eventManager.Trigger(&backendObj, notification.EventArchive, nil)
@@ -1027,7 +1027,7 @@ func (s *Server) patchObject(r *http.Request) jsonResponse {
 		}
 	}
 
-	backendObj, err := s.Backend.PatchObject(bucketName, objectName, attrsToUpdate)
+	backendObj, err := s.backend.PatchObject(bucketName, objectName, attrsToUpdate)
 	if err != nil {
 		return jsonResponse{
 			status:       http.StatusNotFound,
@@ -1076,7 +1076,7 @@ func (s *Server) updateObject(r *http.Request) jsonResponse {
 			attrsToUpdate.ACL = append(attrsToUpdate.ACL, newAcl)
 		}
 	}
-	backendObj, err := s.Backend.UpdateObject(bucketName, objectName, attrsToUpdate)
+	backendObj, err := s.backend.UpdateObject(bucketName, objectName, attrsToUpdate)
 	if err != nil {
 		return jsonResponse{
 			status:       http.StatusNotFound,
@@ -1119,7 +1119,7 @@ func (s *Server) composeObject(r *http.Request) jsonResponse {
 		sourceNames = append(sourceNames, n.Name)
 	}
 
-	backendObj, err := s.Backend.ComposeObject(bucketName, sourceNames, destinationObject, composeRequest.Destination.Metadata, composeRequest.Destination.ContentType)
+	backendObj, err := s.backend.ComposeObject(bucketName, sourceNames, destinationObject, composeRequest.Destination.Metadata, composeRequest.Destination.ContentType)
 	if err != nil {
 		return jsonResponse{
 			status:       http.StatusInternalServerError,
diff --git a/fakestorage/server.go b/fakestorage/server.go
index 43e24c0..7e9c822 100644
--- a/fakestorage/server.go
+++ b/fakestorage/server.go
@@ -42,7 +42,7 @@ const defaultPublicHost = "storage.googleapis.com"
 //
 // It provides a fake implementation of the Google Cloud Storage API.
 type Server struct {
-	Backend      backend.Storage
+	backend      backend.Storage
 	uploads      sync.Map
 	transport    http.RoundTripper
 	ts           *httptest.Server
@@ -211,7 +211,7 @@ func newServer(options Options) (*Server, error) {
 	}
 
 	s := Server{
-		Backend:      backendStorage,
+		backend:      backendStorage,
 		uploads:      sync.Map{},
 		externalURL:  options.ExternalURL,
 		publicHost:   publicHost,
@@ -313,9 +313,9 @@ func (s *Server) reseedServer(r *http.Request) jsonResponse {
 
 	var err error
 	if s.options.StorageRoot != "" {
-		s.Backend, err = backend.NewStorageFS(backendObjects, s.options.StorageRoot)
+		s.backend, err = backend.NewStorageFS(backendObjects, s.options.StorageRoot)
 	} else {
-		s.Backend, err = backend.NewStorageMemory(backendObjects)
+		s.backend, err = backend.NewStorageMemory(backendObjects)
 	}
 	if err != nil {
 		return errToJsonResponse(err)
@@ -425,6 +425,10 @@ func (s *Server) PublicURL() string {
 	return fmt.Sprintf("%s://%s", s.scheme(), s.publicHost)
 }
 
+func (s *Server) Backend() backend.Storage {
+	return s.backend
+}
+
 func (s *Server) scheme() string {
 	if s.options.Scheme == "http" {
 		return "http"
diff --git a/fakestorage/upload.go b/fakestorage/upload.go
index 40ae01d..4b3d859 100644
--- a/fakestorage/upload.go
+++ b/fakestorage/upload.go
@@ -67,7 +67,7 @@ func (c generationCondition) ConditionsMet(activeGeneration int64) bool {
 func (s *Server) insertObject(r *http.Request) jsonResponse {
 	bucketName := unescapeMuxVars(mux.Vars(r))["bucketName"]
 
-	if _, err := s.Backend.GetBucket(bucketName); err != nil {
+	if _, err := s.backend.GetBucket(bucketName); err != nil {
 		return jsonResponse{status: http.StatusNotFound}
 	}
 	uploadType := r.URL.Query().Get("uploadType")
diff --git a/main.go b/main.go
index 3771faf..10458a2 100644
--- a/main.go
+++ b/main.go
@@ -64,7 +64,7 @@ func main() {
 	}
 
 	go func() {
-		err := grpc.NewServerWithBackend(server.Backend, grpcListener)
+		err := grpc.NewServerWithBackend(server.Backend(), grpcListener)
 		println("Error while starting grpc server: ", err)
 	}()
 


Test patch:
diff --git a/fakestorage/server_test.go b/fakestorage/server_test.go
index 447b490..6cd9a30 100644
--- a/fakestorage/server_test.go
+++ b/fakestorage/server_test.go
@@ -1012,7 +1012,7 @@ func TestServerEventNotification(t *testing.T) {
 			}
 			eventManager := &fakeEventManager{}
 			server.eventManager = eventManager
-			err = server.Backend.CreateBucket(obj.BucketName, test.versioningEnabled)
+			err = server.backend.CreateBucket(obj.BucketName, test.versioningEnabled)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -1051,7 +1051,7 @@ func TestServerBatchRequest(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	err = server.Backend.CreateBucket("some-bucket", true)
+	err = server.backend.CreateBucket("some-bucket", true)
 	if err != nil {
 		t.Fatal(err)
 	}