github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/asset/backend_dummy.go (about)

     1  // Copyright 2022 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package asset
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/google/syzkaller/pkg/gcs"
    12  )
    13  
    14  type objectUploadCallback func(req *uploadRequest) (*uploadResponse, error)
    15  type objectRemoveCallback func(url string) error
    16  
    17  type dummyObject struct {
    18  	createdAt       time.Time
    19  	contentType     string
    20  	contentEncoding string
    21  }
    22  
    23  type dummyStorageBackend struct {
    24  	currentTime  time.Time
    25  	objects      map[string]*dummyObject
    26  	objectUpload objectUploadCallback
    27  	objectRemove objectRemoveCallback
    28  }
    29  
    30  func makeDummyStorageBackend() *dummyStorageBackend {
    31  	return &dummyStorageBackend{
    32  		currentTime: time.Now(),
    33  		objects:     make(map[string]*dummyObject),
    34  	}
    35  }
    36  
    37  type dummyWriteCloser struct {
    38  }
    39  
    40  func (dwc *dummyWriteCloser) Write(p []byte) (int, error) {
    41  	return len(p), nil
    42  }
    43  
    44  func (dwc *dummyWriteCloser) Close() error {
    45  	return nil
    46  }
    47  
    48  func (be *dummyStorageBackend) upload(req *uploadRequest) (*uploadResponse, error) {
    49  	be.objects[req.savePath] = &dummyObject{
    50  		createdAt:       be.currentTime,
    51  		contentType:     req.contentType,
    52  		contentEncoding: req.contentEncoding,
    53  	}
    54  	if be.objectUpload != nil {
    55  		return be.objectUpload(req)
    56  	}
    57  	return &uploadResponse{writer: &dummyWriteCloser{}, path: req.savePath}, nil
    58  }
    59  
    60  func (be *dummyStorageBackend) downloadURL(path string, publicURL bool) (string, error) {
    61  	return "http://download/" + path, nil
    62  }
    63  
    64  func (be *dummyStorageBackend) getPath(url string) (string, error) {
    65  	if strings.HasPrefix(url, "http://unknown-bucket/") {
    66  		return "", ErrUnknownBucket
    67  	}
    68  	if strings.HasPrefix(url, "http://download/") {
    69  		return strings.TrimPrefix(url, "http://download/"), nil
    70  	}
    71  	return "", fmt.Errorf("unknown URL format")
    72  }
    73  
    74  func (be *dummyStorageBackend) list() ([]*gcs.Object, error) {
    75  	ret := []*gcs.Object{}
    76  	for path, obj := range be.objects {
    77  		ret = append(ret, &gcs.Object{
    78  			Path:      path,
    79  			CreatedAt: obj.createdAt,
    80  		})
    81  	}
    82  	return ret, nil
    83  }
    84  
    85  func (be *dummyStorageBackend) remove(path string) error {
    86  	if be.objectRemove != nil {
    87  		if err := be.objectRemove(path); err != nil {
    88  			return err
    89  		}
    90  	}
    91  	if _, ok := be.objects[path]; !ok {
    92  		return ErrAssetDoesNotExist
    93  	}
    94  	delete(be.objects, path)
    95  	return nil
    96  }
    97  
    98  func (be *dummyStorageBackend) hasOnly(paths []string) error {
    99  	makeError := func() error {
   100  		return fmt.Errorf("object sets are not equal; needed: %#v; uploaded: %#v", paths, be.objects)
   101  	}
   102  	if len(paths) != len(be.objects) {
   103  		return makeError()
   104  	}
   105  	for _, path := range paths {
   106  		if be.objects[path] == nil {
   107  			return makeError()
   108  		}
   109  	}
   110  	return nil
   111  }