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