github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/overlord/snapstate/refreshhints_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017-2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package snapstate_test 21 22 import ( 23 "context" 24 "time" 25 26 . "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/overlord/auth" 29 "github.com/snapcore/snapd/overlord/snapstate" 30 "github.com/snapcore/snapd/overlord/state" 31 "github.com/snapcore/snapd/release" 32 "github.com/snapcore/snapd/snap" 33 "github.com/snapcore/snapd/store" 34 "github.com/snapcore/snapd/store/storetest" 35 ) 36 37 type recordingStore struct { 38 storetest.Store 39 40 ops []string 41 } 42 43 func (r *recordingStore) SnapAction(ctx context.Context, currentSnaps []*store.CurrentSnap, actions []*store.SnapAction, assertQuery store.AssertionQuery, user *auth.UserState, opts *store.RefreshOptions) ([]store.SnapActionResult, []store.AssertionResult, error) { 44 if assertQuery != nil { 45 panic("no assertion query support") 46 } 47 if ctx == nil || !auth.IsEnsureContext(ctx) { 48 panic("Ensure marked context required") 49 } 50 if len(currentSnaps) != len(actions) || len(currentSnaps) == 0 { 51 panic("expected in test one action for each current snaps, and at least one snap") 52 } 53 for _, a := range actions { 54 if a.Action != "refresh" { 55 panic("expected refresh actions") 56 } 57 } 58 r.ops = append(r.ops, "list-refresh") 59 return nil, nil, nil 60 } 61 62 type refreshHintsTestSuite struct { 63 state *state.State 64 65 store *recordingStore 66 } 67 68 var _ = Suite(&refreshHintsTestSuite{}) 69 70 func (s *refreshHintsTestSuite) SetUpTest(c *C) { 71 s.state = state.New(nil) 72 73 s.store = &recordingStore{} 74 s.state.Lock() 75 defer s.state.Unlock() 76 snapstate.ReplaceStore(s.state, s.store) 77 78 snapstate.Set(s.state, "some-snap", &snapstate.SnapState{ 79 Active: true, 80 Sequence: []*snap.SideInfo{ 81 {RealName: "some-snap", Revision: snap.R(5), SnapID: "some-snap-id"}, 82 }, 83 Current: snap.R(5), 84 SnapType: "app", 85 UserID: 1, 86 }) 87 88 snapstate.CanAutoRefresh = func(*state.State) (bool, error) { return true, nil } 89 snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) { 90 return nil, nil 91 } 92 93 s.state.Set("refresh-privacy-key", "privacy-key") 94 } 95 96 func (s *refreshHintsTestSuite) TearDownTest(c *C) { 97 snapstate.CanAutoRefresh = nil 98 snapstate.AutoAliases = nil 99 } 100 101 func (s *refreshHintsTestSuite) TestLastRefresh(c *C) { 102 rh := snapstate.NewRefreshHints(s.state) 103 err := rh.Ensure() 104 c.Check(err, IsNil) 105 c.Check(s.store.ops, DeepEquals, []string{"list-refresh"}) 106 } 107 108 func (s *refreshHintsTestSuite) TestLastRefreshNoRefreshNeeded(c *C) { 109 s.state.Lock() 110 s.state.Set("last-refresh-hints", time.Now().Add(-23*time.Hour)) 111 s.state.Unlock() 112 113 rh := snapstate.NewRefreshHints(s.state) 114 err := rh.Ensure() 115 c.Check(err, IsNil) 116 c.Check(s.store.ops, HasLen, 0) 117 } 118 119 func (s *refreshHintsTestSuite) TestLastRefreshNoRefreshNeededBecauseOfFullAutoRefresh(c *C) { 120 s.state.Lock() 121 s.state.Set("last-refresh-hints", time.Now().Add(-48*time.Hour)) 122 s.state.Unlock() 123 124 s.state.Lock() 125 s.state.Set("last-refresh", time.Now().Add(-23*time.Hour)) 126 s.state.Unlock() 127 128 rh := snapstate.NewRefreshHints(s.state) 129 err := rh.Ensure() 130 c.Check(err, IsNil) 131 c.Check(s.store.ops, HasLen, 0) 132 } 133 134 func (s *refreshHintsTestSuite) TestAtSeedPolicy(c *C) { 135 r := release.MockOnClassic(false) 136 defer r() 137 138 s.state.Lock() 139 defer s.state.Unlock() 140 141 rh := snapstate.NewRefreshHints(s.state) 142 143 // on core, does nothing 144 err := rh.AtSeed() 145 c.Assert(err, IsNil) 146 var t1 time.Time 147 err = s.state.Get("last-refresh-hints", &t1) 148 c.Check(err, Equals, state.ErrNoState) 149 150 release.MockOnClassic(true) 151 // on classic it sets last-refresh-hints to now, 152 // postponing it of 24h 153 err = rh.AtSeed() 154 c.Assert(err, IsNil) 155 err = s.state.Get("last-refresh-hints", &t1) 156 c.Check(err, IsNil) 157 158 // nop if tried again 159 err = rh.AtSeed() 160 c.Assert(err, IsNil) 161 var t2 time.Time 162 err = s.state.Get("last-refresh-hints", &t2) 163 c.Check(err, IsNil) 164 c.Check(t1.Equal(t2), Equals, true) 165 }