github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/pkg/test/fakeindex.go (about)

     1  /*
     2  Copyright 2011 Google Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package test
    18  
    19  import (
    20  	"fmt"
    21  	"log"
    22  	"math"
    23  	"os"
    24  	"strings"
    25  	"sync"
    26  	"time"
    27  
    28  	"camlistore.org/pkg/blob"
    29  	"camlistore.org/pkg/context"
    30  	"camlistore.org/pkg/types/camtypes"
    31  )
    32  
    33  var ClockOrigin = time.Unix(1322443956, 123456)
    34  
    35  // A FakeIndex implements parts of search.Index and provides methods
    36  // to controls the results, such as AddMeta, AddClaim,
    37  // AddSignerAttrValue.
    38  type FakeIndex struct {
    39  	lk              sync.Mutex
    40  	meta            map[blob.Ref]camtypes.BlobMeta
    41  	claims          map[blob.Ref][]camtypes.Claim // permanode -> claims
    42  	signerAttrValue map[string]blob.Ref           // "<signer>\0<attr>\0<value>" -> blobref
    43  	path            map[string]*camtypes.Path     // "<signer>\0<base>\0<suffix>" -> path
    44  
    45  	cllk  sync.RWMutex
    46  	clock time.Time
    47  }
    48  
    49  func NewFakeIndex() *FakeIndex {
    50  	return &FakeIndex{
    51  		meta:            make(map[blob.Ref]camtypes.BlobMeta),
    52  		claims:          make(map[blob.Ref][]camtypes.Claim),
    53  		signerAttrValue: make(map[string]blob.Ref),
    54  		path:            make(map[string]*camtypes.Path),
    55  		clock:           ClockOrigin,
    56  	}
    57  }
    58  
    59  //
    60  // Test methods
    61  //
    62  
    63  func (fi *FakeIndex) nextDate() time.Time {
    64  	fi.cllk.Lock()
    65  	defer fi.cllk.Unlock()
    66  	fi.clock = fi.clock.Add(1 * time.Second)
    67  	return fi.clock.UTC()
    68  }
    69  
    70  func (fi *FakeIndex) LastTime() time.Time {
    71  	fi.cllk.RLock()
    72  	defer fi.cllk.RUnlock()
    73  	return fi.clock
    74  }
    75  
    76  func camliTypeFromMime(mime string) string {
    77  	if v := strings.TrimPrefix(mime, "application/json; camliType="); v != mime {
    78  		return v
    79  	}
    80  	return ""
    81  }
    82  
    83  func (fi *FakeIndex) AddMeta(br blob.Ref, camliType string, size int64) {
    84  	if size < 0 || size > math.MaxUint32 {
    85  		panic("bad size")
    86  	}
    87  	fi.lk.Lock()
    88  	defer fi.lk.Unlock()
    89  	fi.meta[br] = camtypes.BlobMeta{
    90  		Ref:       br,
    91  		Size:      uint32(size),
    92  		CamliType: camliType,
    93  	}
    94  }
    95  
    96  func (fi *FakeIndex) AddClaim(owner, permanode blob.Ref, claimType, attr, value string) {
    97  	fi.lk.Lock()
    98  	defer fi.lk.Unlock()
    99  	date := fi.nextDate()
   100  
   101  	claim := camtypes.Claim{
   102  		Permanode: permanode,
   103  		Signer:    owner,
   104  		BlobRef:   blob.Ref{},
   105  		Date:      date,
   106  		Type:      claimType,
   107  		Attr:      attr,
   108  		Value:     value,
   109  	}
   110  	fi.claims[permanode] = append(fi.claims[permanode], claim)
   111  
   112  	if claimType == "set-attribute" && strings.HasPrefix(attr, "camliPath:") {
   113  		suffix := attr[len("camliPath:"):]
   114  		path := &camtypes.Path{
   115  			Target: blob.MustParse(value),
   116  			Suffix: suffix,
   117  		}
   118  		fi.path[fmt.Sprintf("%s\x00%s\x00%s", owner, permanode, suffix)] = path
   119  	}
   120  }
   121  
   122  func (fi *FakeIndex) AddSignerAttrValue(signer blob.Ref, attr, val string, latest blob.Ref) {
   123  	fi.lk.Lock()
   124  	defer fi.lk.Unlock()
   125  	fi.signerAttrValue[fmt.Sprintf("%s\x00%s\x00%s", signer, attr, val)] = latest
   126  }
   127  
   128  //
   129  // Interface implementation
   130  //
   131  
   132  func (fi *FakeIndex) KeyId(blob.Ref) (string, error) {
   133  	panic("NOIMPL")
   134  }
   135  
   136  func (fi *FakeIndex) GetRecentPermanodes(dest chan<- camtypes.RecentPermanode, owner blob.Ref, limit int, before time.Time) error {
   137  	panic("NOIMPL")
   138  }
   139  
   140  // TODO(mpl): write real tests
   141  func (fi *FakeIndex) SearchPermanodesWithAttr(dest chan<- blob.Ref, request *camtypes.PermanodeByAttrRequest) error {
   142  	panic("NOIMPL")
   143  }
   144  
   145  func (fi *FakeIndex) AppendClaims(dst []camtypes.Claim, permaNode blob.Ref,
   146  	signerFilter blob.Ref,
   147  	attrFilter string) ([]camtypes.Claim, error) {
   148  	fi.lk.Lock()
   149  	defer fi.lk.Unlock()
   150  
   151  	for _, cl := range fi.claims[permaNode] {
   152  		if signerFilter.Valid() && cl.Signer != signerFilter {
   153  			continue
   154  		}
   155  		if attrFilter != "" && cl.Attr != attrFilter {
   156  			continue
   157  		}
   158  		dst = append(dst, cl)
   159  	}
   160  	return dst, nil
   161  }
   162  
   163  func (fi *FakeIndex) GetBlobMeta(br blob.Ref) (camtypes.BlobMeta, error) {
   164  	fi.lk.Lock()
   165  	defer fi.lk.Unlock()
   166  	bm, ok := fi.meta[br]
   167  	if !ok {
   168  		return camtypes.BlobMeta{}, os.ErrNotExist
   169  	}
   170  	return bm, nil
   171  }
   172  
   173  func (fi *FakeIndex) ExistingFileSchemas(bytesRef blob.Ref) ([]blob.Ref, error) {
   174  	panic("NOIMPL")
   175  }
   176  
   177  func (fi *FakeIndex) GetFileInfo(fileRef blob.Ref) (camtypes.FileInfo, error) {
   178  	panic("NOIMPL")
   179  }
   180  
   181  func (fi *FakeIndex) GetImageInfo(fileRef blob.Ref) (camtypes.ImageInfo, error) {
   182  	panic("NOIMPL")
   183  }
   184  
   185  func (fi *FakeIndex) GetDirMembers(dir blob.Ref, dest chan<- blob.Ref, limit int) error {
   186  	panic("NOIMPL")
   187  }
   188  
   189  func (fi *FakeIndex) PermanodeOfSignerAttrValue(signer blob.Ref, attr, val string) (blob.Ref, error) {
   190  	fi.lk.Lock()
   191  	defer fi.lk.Unlock()
   192  	if b, ok := fi.signerAttrValue[fmt.Sprintf("%s\x00%s\x00%s", signer, attr, val)]; ok {
   193  		return b, nil
   194  	}
   195  	return blob.Ref{}, os.ErrNotExist
   196  }
   197  
   198  func (fi *FakeIndex) PathsOfSignerTarget(signer, target blob.Ref) ([]*camtypes.Path, error) {
   199  	panic("NOIMPL")
   200  }
   201  
   202  func (fi *FakeIndex) PathsLookup(signer, base blob.Ref, suffix string) ([]*camtypes.Path, error) {
   203  	panic("NOIMPL")
   204  }
   205  
   206  func (fi *FakeIndex) PathLookup(signer, base blob.Ref, suffix string, at time.Time) (*camtypes.Path, error) {
   207  	if !at.IsZero() {
   208  		panic("PathLookup with non-zero 'at' time not supported")
   209  	}
   210  	fi.lk.Lock()
   211  	defer fi.lk.Unlock()
   212  	if p, ok := fi.path[fmt.Sprintf("%s\x00%s\x00%s", signer, base, suffix)]; ok {
   213  		return p, nil
   214  	}
   215  	log.Printf("PathLookup miss for signer %q, base %q, suffix %q", signer, base, suffix)
   216  	return nil, os.ErrNotExist
   217  }
   218  
   219  func (fi *FakeIndex) EdgesTo(ref blob.Ref, opts *camtypes.EdgesToOpts) ([]*camtypes.Edge, error) {
   220  	panic("NOIMPL")
   221  }
   222  
   223  func (fi *FakeIndex) EnumerateBlobMeta(ctx *context.Context, ch chan<- camtypes.BlobMeta) error {
   224  	panic("NOIMPL")
   225  }