github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/state/bakerystorage/storage_test.go (about)

     1  // Copyright 2014-2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package bakerystorage
     5  
     6  import (
     7  	"errors"
     8  	"time" // Only used for time types.
     9  
    10  	gitjujutesting "github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/macaroon-bakery.v1/bakery"
    14  	"gopkg.in/mgo.v2"
    15  
    16  	"github.com/juju/juju/mongo"
    17  	"github.com/juju/juju/testing"
    18  )
    19  
    20  type StorageSuite struct {
    21  	testing.BaseSuite
    22  	gitjujutesting.Stub
    23  	collection      mockCollection
    24  	closeCollection func()
    25  	config          Config
    26  }
    27  
    28  var _ = gc.Suite(&StorageSuite{})
    29  
    30  func (s *StorageSuite) SetUpTest(c *gc.C) {
    31  	s.BaseSuite.SetUpTest(c)
    32  	s.Stub.ResetCalls()
    33  	s.collection = mockCollection{Stub: &s.Stub}
    34  	s.closeCollection = func() {
    35  		s.AddCall("Close")
    36  		s.PopNoErr()
    37  	}
    38  	s.config = Config{
    39  		GetCollection: func() (mongo.Collection, func()) {
    40  			s.AddCall("GetCollection")
    41  			s.PopNoErr()
    42  			return &s.collection, s.closeCollection
    43  		},
    44  	}
    45  }
    46  
    47  func (s *StorageSuite) TestValidateConfigGetCollection(c *gc.C) {
    48  	s.config.GetCollection = nil
    49  	_, err := New(s.config)
    50  	c.Assert(err, gc.ErrorMatches, "validating config: nil GetCollection not valid")
    51  }
    52  
    53  func (s *StorageSuite) TestPut(c *gc.C) {
    54  	store, err := New(s.config)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  
    57  	err = store.Put("foo", "bar")
    58  	c.Assert(err, jc.ErrorIsNil)
    59  	s.CheckCalls(c, []gitjujutesting.StubCall{
    60  		{"GetCollection", nil},
    61  		{"Writeable", nil},
    62  		{"UpsertId", []interface{}{"foo", storageDoc{
    63  			Location: "foo",
    64  			Item:     "bar",
    65  		}}},
    66  		{"Close", nil},
    67  	})
    68  }
    69  
    70  func (s *StorageSuite) TestExpireAt(c *gc.C) {
    71  	store, err := New(s.config)
    72  	c.Assert(err, jc.ErrorIsNil)
    73  
    74  	expiryTime := testing.NonZeroTime().Add(24 * time.Hour)
    75  	store = store.ExpireAt(expiryTime)
    76  
    77  	err = store.Put("foo", "bar")
    78  	c.Assert(err, jc.ErrorIsNil)
    79  	s.CheckCalls(c, []gitjujutesting.StubCall{
    80  		{"GetCollection", nil},
    81  		{"Writeable", nil},
    82  		{"UpsertId", []interface{}{"foo", storageDoc{
    83  			Location: "foo",
    84  			Item:     "bar",
    85  			ExpireAt: expiryTime.Add(-1 * time.Second),
    86  		}}},
    87  		{"Close", nil},
    88  	})
    89  }
    90  
    91  func (s *StorageSuite) TestPutError(c *gc.C) {
    92  	store, err := New(s.config)
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	s.SetErrors(nil, nil, errors.New("failed to upsert"))
    95  	err = store.Put("foo", "bar")
    96  	c.Assert(err, gc.ErrorMatches, `cannot store item for location "foo": failed to upsert`)
    97  }
    98  
    99  func (s *StorageSuite) TestGet(c *gc.C) {
   100  	store, err := New(s.config)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	item, err := store.Get("foo")
   103  	c.Assert(err, jc.ErrorIsNil)
   104  	c.Assert(item, gc.Equals, "item-value")
   105  	s.CheckCalls(c, []gitjujutesting.StubCall{
   106  		{"GetCollection", nil},
   107  		{"FindId", []interface{}{"foo"}},
   108  		{"One", []interface{}{&storageDoc{
   109  			// Set by mock, not in input. Unimportant anyway.
   110  			Location: "foo",
   111  			Item:     "item-value",
   112  		}}},
   113  		{"Close", nil},
   114  	})
   115  }
   116  
   117  func (s *StorageSuite) TestGetNotFound(c *gc.C) {
   118  	store, err := New(s.config)
   119  	c.Assert(err, jc.ErrorIsNil)
   120  	s.SetErrors(nil, nil, mgo.ErrNotFound)
   121  	_, err = store.Get("foo")
   122  	c.Assert(err, gc.Equals, bakery.ErrNotFound)
   123  }
   124  
   125  func (s *StorageSuite) TestGetError(c *gc.C) {
   126  	store, err := New(s.config)
   127  	c.Assert(err, jc.ErrorIsNil)
   128  	s.SetErrors(nil, nil, errors.New("failed to read"))
   129  	_, err = store.Get("foo")
   130  	c.Assert(err, gc.ErrorMatches, `cannot get item for location "foo": failed to read`)
   131  }
   132  
   133  func (s *StorageSuite) TestDel(c *gc.C) {
   134  	store, err := New(s.config)
   135  	c.Assert(err, jc.ErrorIsNil)
   136  
   137  	err = store.Del("foo")
   138  	c.Assert(err, jc.ErrorIsNil)
   139  	s.CheckCalls(c, []gitjujutesting.StubCall{
   140  		{"GetCollection", nil},
   141  		{"Writeable", nil},
   142  		{"RemoveId", []interface{}{"foo"}},
   143  		{"Close", nil},
   144  	})
   145  }
   146  
   147  func (s *StorageSuite) TestDelNotFound(c *gc.C) {
   148  	store, err := New(s.config)
   149  	c.Assert(err, jc.ErrorIsNil)
   150  	s.SetErrors(nil, nil, mgo.ErrNotFound)
   151  	err = store.Del("foo")
   152  	c.Assert(err, jc.ErrorIsNil)
   153  }
   154  
   155  func (s *StorageSuite) TestDelError(c *gc.C) {
   156  	store, err := New(s.config)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	s.SetErrors(nil, nil, errors.New("failed to remove"))
   159  	err = store.Del("foo")
   160  	c.Assert(err, gc.ErrorMatches, `cannot remove item for location "foo": failed to remove`)
   161  }
   162  
   163  type mockCollection struct {
   164  	mongo.WriteCollection
   165  	*gitjujutesting.Stub
   166  }
   167  
   168  func (c *mockCollection) FindId(id interface{}) mongo.Query {
   169  	c.MethodCall(c, "FindId", id)
   170  	c.PopNoErr()
   171  	return &mockQuery{Stub: c.Stub, id: id}
   172  }
   173  
   174  func (c *mockCollection) UpsertId(id, update interface{}) (*mgo.ChangeInfo, error) {
   175  	c.MethodCall(c, "UpsertId", id, update)
   176  	return &mgo.ChangeInfo{}, c.NextErr()
   177  }
   178  
   179  func (c *mockCollection) RemoveId(id interface{}) error {
   180  	c.MethodCall(c, "RemoveId", id)
   181  	return c.NextErr()
   182  }
   183  
   184  func (c *mockCollection) Writeable() mongo.WriteCollection {
   185  	c.MethodCall(c, "Writeable")
   186  	c.PopNoErr()
   187  	return c
   188  }
   189  
   190  type mockQuery struct {
   191  	mongo.Query
   192  	*gitjujutesting.Stub
   193  	id interface{}
   194  }
   195  
   196  func (q *mockQuery) One(result interface{}) error {
   197  	q.MethodCall(q, "One", result)
   198  	*result.(*storageDoc) = storageDoc{
   199  		Location: q.id.(string),
   200  		Item:     "item-value",
   201  	}
   202  	return q.NextErr()
   203  }