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 }