blob: 41b266a807c993baea6f37d4408a4846c0218a23 [file] [log] [blame]
// Copyright 2018 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package command
import (
"bytes"
"context"
"io"
"io/ioutil"
"sort"
"strings"
"time"
"cloud.google.com/go/storage"
"github.com/googleapis/google-cloud-go-testing/storage/stiface"
"google.golang.org/api/iterator"
)
type fakeObject struct {
stiface.ObjectHandle
data []byte
updated time.Time
}
func (o *fakeObject) NewReader(context.Context) (stiface.Reader, error) {
return &fakeObjectReader{
size: len(o.data),
rc: ioutil.NopCloser(bytes.NewReader(o.data)),
}, nil
}
type fakeObjectReader struct {
stiface.Reader
size int
rc io.ReadCloser
}
func (r *fakeObjectReader) Size() int64 { return int64(r.size) }
func (r *fakeObjectReader) Read(p []byte) (int, error) {
return r.rc.Read(p)
}
func (r *fakeObjectReader) Close() error {
return r.rc.Close()
}
type fakeObjIter struct {
stiface.ObjectIterator
attrs []*storage.ObjectAttrs
}
func (o *fakeObjIter) Next() (*storage.ObjectAttrs, error) {
if len(o.attrs) == 0 {
return nil, iterator.Done
}
oa, attrs := o.attrs[0], o.attrs[1:]
o.attrs = attrs
return oa, nil
}
type fakeStorageBucket struct {
stiface.BucketHandle
objs map[string]*fakeObject
}
func newFakeStorageBucket() *fakeStorageBucket {
return &fakeStorageBucket{
objs: make(map[string]*fakeObject),
}
}
func (sb *fakeStorageBucket) store(obj string, data []byte, ts time.Time) {
sb.objs[obj] = &fakeObject{
data: data,
updated: ts,
}
}
func (sb *fakeStorageBucket) storeString(obj string, value string, ts time.Time) {
sb.store(obj, []byte(value), ts)
}
func (sb *fakeStorageBucket) Object(name string) stiface.ObjectHandle {
if sb.objs[name] == nil {
// Return explicit nil as interface value.
return nil
}
return sb.objs[name]
}
func (sb *fakeStorageBucket) Objects(ctx context.Context, query *storage.Query) stiface.ObjectIterator {
// Get stored objects in sorted order.
names := []string{}
for name := range sb.objs {
names = append(names, name)
}
sort.Strings(names)
iter := &fakeObjIter{}
for _, name := range names {
if !strings.HasPrefix(name, query.Prefix) {
continue
}
obj := sb.objs[name]
iter.attrs = append(iter.attrs, &storage.ObjectAttrs{
Name: name,
Updated: obj.updated,
})
}
return iter
}
type fakeStorage struct {
stiface.Client
buckets map[string]*fakeStorageBucket
}
func newFakeStorage() *fakeStorage {
return &fakeStorage{
buckets: make(map[string]*fakeStorageBucket),
}
}
func (s *fakeStorage) createBucket(bucket string) *fakeStorageBucket {
// Only create bucket if none exists. If it exists, just return existing bucket.
if s.buckets[bucket] == nil {
s.buckets[bucket] = newFakeStorageBucket()
}
return s.buckets[bucket]
}
func (s *fakeStorage) Bucket(name string) stiface.BucketHandle {
if s.buckets[name] == nil {
// Return explicit nil as interface value.
return nil
}
return s.buckets[name]
}