github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/lease/fixture_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package lease_test
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	jujutesting "github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	jujutxn "github.com/juju/txn"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/mgo.v2"
    15  
    16  	corelease "github.com/juju/juju/core/lease"
    17  	"github.com/juju/juju/state/lease"
    18  )
    19  
    20  var (
    21  	defaultClient     = "default-client"
    22  	defaultNamespace  = "default-namespace"
    23  	defaultCollection = "default-collection"
    24  	defaultClockStart time.Time
    25  )
    26  
    27  func init() {
    28  	// We pick a time with a comfortable h:m:s component but:
    29  	//  (1) past the int32 unix epoch limit;
    30  	//  (2) at a 5ns offset to make sure we're not discarding precision;
    31  	//  (3) in a weird time zone.
    32  	value := "2073-03-03T01:00:00.000000005-08:40"
    33  	var err error
    34  	defaultClockStart, err = time.Parse(time.RFC3339Nano, value)
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  }
    39  
    40  type FixtureParams struct {
    41  	Id         string
    42  	Namespace  string
    43  	Collection string
    44  	ClockStart time.Time
    45  	ClockStep  time.Duration
    46  }
    47  
    48  // Fixture collects together a running client and a bunch of useful data.
    49  type Fixture struct {
    50  	Client corelease.Client
    51  	Config lease.ClientConfig
    52  	Runner jujutxn.Runner
    53  	Clock  *Clock
    54  	Zero   time.Time
    55  }
    56  
    57  func NewFixture(c *gc.C, database *mgo.Database, params FixtureParams) *Fixture {
    58  	mongo := NewMongo(database)
    59  	clockStart := params.ClockStart
    60  	if clockStart.IsZero() {
    61  		clockStart = defaultClockStart
    62  	}
    63  	clock := NewClock(clockStart, params.ClockStep)
    64  	config := lease.ClientConfig{
    65  		Id:         or(params.Id, "default-client"),
    66  		Namespace:  or(params.Namespace, "default-namespace"),
    67  		Collection: or(params.Collection, "default-collection"),
    68  		Mongo:      mongo,
    69  		Clock:      clock,
    70  	}
    71  	client, err := lease.NewClient(config)
    72  	c.Assert(err, jc.ErrorIsNil)
    73  	return &Fixture{
    74  		Client: client,
    75  		Config: config,
    76  		Runner: mongo.runner,
    77  		Clock:  clock,
    78  		Zero:   clockStart,
    79  	}
    80  }
    81  
    82  func or(u, v string) string {
    83  	if u != "" {
    84  		return u
    85  	}
    86  	return v
    87  }
    88  
    89  func (fix *Fixture) badge() string {
    90  	return fmt.Sprintf("%s %s", fix.Config.Id, fix.Config.Namespace)
    91  }
    92  
    93  func (fix *Fixture) Holder() gc.Checker {
    94  	return &callbackChecker{
    95  		CheckerInfo: &gc.CheckerInfo{
    96  			Name:   fmt.Sprintf("Holder[%s]", fix.badge()),
    97  			Params: []string{"name", "holder"},
    98  		},
    99  		callback: fix.infoChecker(checkHolder),
   100  	}
   101  }
   102  
   103  func (fix *Fixture) Expiry() gc.Checker {
   104  	return &callbackChecker{
   105  		CheckerInfo: &gc.CheckerInfo{
   106  			Name:   fmt.Sprintf("Expiry[%s]", fix.badge()),
   107  			Params: []string{"name", "expiry"},
   108  		},
   109  		callback: fix.infoChecker(checkExpiry),
   110  	}
   111  }
   112  
   113  func (fix *Fixture) infoChecker(checkInfo checkInfoFunc) checkFunc {
   114  
   115  	return func(params []interface{}, names []string) (result bool, error string) {
   116  		defer func() {
   117  			if v := recover(); v != nil {
   118  				result = false
   119  				error = fmt.Sprint(v)
   120  			}
   121  		}()
   122  		name := params[0].(string)
   123  		info := fix.Client.Leases()[name]
   124  		return checkInfo(info, params[1])
   125  	}
   126  }
   127  
   128  type callbackChecker struct {
   129  	*gc.CheckerInfo
   130  	callback checkFunc
   131  }
   132  
   133  func (c *callbackChecker) Check(params []interface{}, names []string) (bool, string) {
   134  	return c.callback(params, names)
   135  }
   136  
   137  type checkFunc func(params []interface{}, names []string) (bool, string)
   138  
   139  type checkInfoFunc func(info corelease.Info, param interface{}) (bool, string)
   140  
   141  func checkHolder(info corelease.Info, holder interface{}) (bool, string) {
   142  	actual := info.Holder
   143  	expect := holder.(string)
   144  	if actual == expect {
   145  		return true, ""
   146  	}
   147  	return false, fmt.Sprintf("lease held by %q; expected %q", actual, expect)
   148  }
   149  
   150  func checkExpiry(info corelease.Info, expiry interface{}) (bool, string) {
   151  	actual := info.Expiry
   152  	expect := expiry.(time.Time)
   153  	if actual.Equal(expect) {
   154  		return true, ""
   155  	}
   156  	return false, fmt.Sprintf("expiry is %s; expected %s", actual, expect)
   157  }
   158  
   159  type FixtureSuite struct {
   160  	jujutesting.IsolationSuite
   161  	jujutesting.MgoSuite
   162  	db *mgo.Database
   163  }
   164  
   165  func (s *FixtureSuite) SetUpSuite(c *gc.C) {
   166  	s.IsolationSuite.SetUpSuite(c)
   167  	s.MgoSuite.SetUpSuite(c)
   168  }
   169  
   170  func (s *FixtureSuite) TearDownSuite(c *gc.C) {
   171  	s.MgoSuite.TearDownSuite(c)
   172  	s.IsolationSuite.TearDownSuite(c)
   173  }
   174  
   175  func (s *FixtureSuite) SetUpTest(c *gc.C) {
   176  	s.IsolationSuite.SetUpTest(c)
   177  	s.MgoSuite.SetUpTest(c)
   178  	s.db = s.Session.DB("juju")
   179  }
   180  
   181  func (s *FixtureSuite) TearDownTest(c *gc.C) {
   182  	s.MgoSuite.TearDownTest(c)
   183  	s.IsolationSuite.TearDownTest(c)
   184  }
   185  
   186  func (s *FixtureSuite) NewFixture(c *gc.C, fp FixtureParams) *Fixture {
   187  	return NewFixture(c, s.db, fp)
   188  }
   189  
   190  func (s *FixtureSuite) EasyFixture(c *gc.C) *Fixture {
   191  	return s.NewFixture(c, FixtureParams{})
   192  }