github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/featuretests/bakerystorage_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package featuretests
     5  
     6  import (
     7  	"time"
     8  
     9  	gitjujutesting "github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  	"gopkg.in/macaroon-bakery.v2-unstable/bakery"
    13  	"gopkg.in/macaroon-bakery.v2-unstable/bakery/mgostorage"
    14  	"gopkg.in/macaroon.v2-unstable"
    15  	"gopkg.in/mgo.v2"
    16  
    17  	"github.com/juju/juju/mongo"
    18  	"github.com/juju/juju/state/bakerystorage"
    19  )
    20  
    21  // This suite is not about a feature tests per se, but tests the integration
    22  // of the mongo-based bakery storage with the macaroon bakery service.
    23  type BakeryStorageSuite struct {
    24  	gitjujutesting.MgoSuite
    25  	gitjujutesting.LoggingSuite
    26  
    27  	store   bakerystorage.ExpirableStorage
    28  	service *bakery.Service
    29  	db      *mgo.Database
    30  	coll    *mgo.Collection
    31  }
    32  
    33  func (s *BakeryStorageSuite) SetUpTest(c *gc.C) {
    34  	s.MgoSuite.SetUpTest(c)
    35  	s.LoggingSuite.SetUpTest(c)
    36  	s.db = s.Session.DB("bakerydb")
    37  	s.coll = s.db.C("bakedgoods")
    38  	s.ensureIndexes(c)
    39  	s.initService(c, false)
    40  }
    41  
    42  func (s *BakeryStorageSuite) TearDownTest(c *gc.C) {
    43  	s.LoggingSuite.TearDownTest(c)
    44  	s.MgoSuite.TearDownTest(c)
    45  }
    46  
    47  func (s *BakeryStorageSuite) SetUpSuite(c *gc.C) {
    48  	s.LoggingSuite.SetUpSuite(c)
    49  	s.MgoSuite.SetUpSuite(c)
    50  }
    51  
    52  func (s *BakeryStorageSuite) TearDownSuite(c *gc.C) {
    53  	s.MgoSuite.TearDownSuite(c)
    54  	s.LoggingSuite.TearDownSuite(c)
    55  }
    56  
    57  func (s *BakeryStorageSuite) initService(c *gc.C, enableExpiry bool) {
    58  	store, err := bakerystorage.New(bakerystorage.Config{
    59  		GetCollection: func() (mongo.Collection, func()) {
    60  			return mongo.CollectionFromName(s.db, s.coll.Name)
    61  		},
    62  		GetStorage: func(rootKeys *mgostorage.RootKeys, coll mongo.Collection, expireAfter time.Duration) bakery.Storage {
    63  			return rootKeys.NewStorage(coll.Writeable().Underlying(), mgostorage.Policy{
    64  				ExpiryDuration: expireAfter,
    65  			})
    66  		},
    67  	})
    68  	c.Assert(err, jc.ErrorIsNil)
    69  	if enableExpiry {
    70  		store = store.ExpireAfter(10 * time.Second)
    71  	}
    72  	s.store = store
    73  
    74  	service, err := bakery.NewService(bakery.NewServiceParams{
    75  		Location: "straya",
    76  		Store:    s.store,
    77  	})
    78  	c.Assert(err, jc.ErrorIsNil)
    79  	s.service = service
    80  }
    81  
    82  func (s *BakeryStorageSuite) ensureIndexes(c *gc.C) {
    83  	for _, index := range bakerystorage.MongoIndexes() {
    84  		err := s.coll.EnsureIndex(index)
    85  		c.Assert(err, jc.ErrorIsNil)
    86  	}
    87  }
    88  
    89  func (s *BakeryStorageSuite) TestCheckNewMacaroon(c *gc.C) {
    90  	mac, err := s.service.NewMacaroon(nil)
    91  	c.Assert(err, jc.ErrorIsNil)
    92  	_, err = s.service.CheckAny([]macaroon.Slice{{mac}}, nil, nil)
    93  	c.Assert(err, gc.ErrorMatches, "verification failed: macaroon not found in storage")
    94  
    95  	store := s.store.ExpireAfter(10 * time.Second)
    96  	mac, err = s.service.WithStore(store).NewMacaroon(nil)
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	_, err = s.service.CheckAny([]macaroon.Slice{{mac}}, nil, nil)
    99  	c.Assert(err, jc.ErrorIsNil)
   100  }
   101  
   102  func (s *BakeryStorageSuite) TestExpiryTime(c *gc.C) {
   103  	// Reinitialise bakery service with storage that will expire
   104  	// items immediately.
   105  	s.initService(c, true)
   106  
   107  	mac, err := s.service.NewMacaroon(nil)
   108  	c.Assert(err, jc.ErrorIsNil)
   109  
   110  	// The background thread that removes records runs every 60s.
   111  	// Give a little bit of leeway for loaded systems.
   112  	for i := 0; i < 90; i++ {
   113  		_, err = s.service.CheckAny([]macaroon.Slice{{mac}}, nil, nil)
   114  		if err == nil {
   115  			time.Sleep(time.Second)
   116  			continue
   117  		}
   118  		c.Assert(err, gc.ErrorMatches, "verification failed: macaroon not found in storage")
   119  		return
   120  	}
   121  	c.Fatal("timed out waiting for storage expiry")
   122  }