github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/leaseexpiry/worker_test.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package leaseexpiry_test 5 6 import ( 7 "sync" 8 "time" 9 10 "github.com/juju/clock" 11 "github.com/juju/errors" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils/v3" 14 "github.com/juju/worker/v3" 15 "github.com/juju/worker/v3/workertest" 16 "go.uber.org/mock/gomock" 17 gc "gopkg.in/check.v1" 18 19 "github.com/juju/juju/database/testing" 20 "github.com/juju/juju/worker/leaseexpiry" 21 ) 22 23 type workerSuite struct { 24 testing.ControllerSuite 25 } 26 27 var _ = gc.Suite(&workerSuite{}) 28 29 func (s *workerSuite) TestConfigValidate(c *gc.C) { 30 validCfg := leaseexpiry.Config{ 31 Clock: clock.WallClock, 32 Logger: leaseexpiry.StubLogger{}, 33 TrackedDB: s.TrackedDB(), 34 } 35 36 cfg := validCfg 37 cfg.Clock = nil 38 c.Check(errors.Is(cfg.Validate(), errors.NotValid), jc.IsTrue) 39 40 cfg = validCfg 41 cfg.Logger = nil 42 c.Check(errors.Is(cfg.Validate(), errors.NotValid), jc.IsTrue) 43 44 cfg = validCfg 45 cfg.TrackedDB = nil 46 c.Check(errors.Is(cfg.Validate(), errors.NotValid), jc.IsTrue) 47 } 48 49 func (s *workerSuite) TestWorkerDeletesExpiredLeases(c *gc.C) { 50 ctrl := gomock.NewController(c) 51 defer ctrl.Finish() 52 53 clk := NewMockClock(ctrl) 54 timer := NewMockTimer(ctrl) 55 56 var w worker.Worker 57 var wmutex sync.Mutex 58 59 clk.EXPECT().NewTimer(time.Second).Return(timer) 60 61 // Kill the worker on the first pass through the loop, 62 // after we've processed one expiration. 63 ch := make(chan time.Time, 1) 64 ch <- time.Now() 65 timer.EXPECT().Chan().Return(ch).MinTimes(1) 66 timer.EXPECT().Reset(time.Second).Do(func(any) { 67 wmutex.Lock() 68 defer wmutex.Unlock() 69 w.Kill() 70 }) 71 timer.EXPECT().Stop().Return(true) 72 73 // Insert 2 leases, one with an expiry time in the past, 74 // another in the future. 75 q := ` 76 INSERT INTO lease (uuid, lease_type_id, model_uuid, name, holder, start, expiry) 77 VALUES (?, 1, 'some-model-uuid', ?, ?, datetime('now'), datetime('now', ?))`[1:] 78 79 stmt, err := s.DB().Prepare(q) 80 c.Assert(err, jc.ErrorIsNil) 81 82 _, err = stmt.Exec(utils.MustNewUUID().String(), "postgresql", "postgresql/0", "+2 minutes") 83 c.Assert(err, jc.ErrorIsNil) 84 85 _, err = stmt.Exec(utils.MustNewUUID().String(), "redis", "redis/0", "-2 minutes") 86 c.Assert(err, jc.ErrorIsNil) 87 88 wmutex.Lock() 89 w, err = leaseexpiry.NewWorker(leaseexpiry.Config{ 90 Clock: clk, 91 Logger: leaseexpiry.StubLogger{}, 92 TrackedDB: s.TrackedDB(), 93 }) 94 wmutex.Unlock() 95 c.Assert(err, jc.ErrorIsNil) 96 97 err = workertest.CheckKilled(c, w) 98 c.Assert(err, jc.ErrorIsNil) 99 100 // Only the postgresql lease (expiring in the future) should remain. 101 row := s.DB().QueryRow("SELECT name FROM LEASE") 102 var name string 103 err = row.Scan(&name) 104 c.Assert(err, jc.ErrorIsNil) 105 c.Assert(row.Err(), jc.ErrorIsNil) 106 107 c.Check(name, gc.Equals, "postgresql") 108 }