github.com/rigado/snapd@v2.42.5-go-mod+incompatible/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, user *auth.UserState, opts *store.RefreshOptions) ([]*snap.Info, error) { 44 if ctx == nil || !auth.IsEnsureContext(ctx) { 45 panic("Ensure marked context required") 46 } 47 if len(currentSnaps) != len(actions) || len(currentSnaps) == 0 { 48 panic("expected in test one action for each current snaps, and at least one snap") 49 } 50 for _, a := range actions { 51 if a.Action != "refresh" { 52 panic("expected refresh actions") 53 } 54 } 55 r.ops = append(r.ops, "list-refresh") 56 return nil, nil 57 } 58 59 type refreshHintsTestSuite struct { 60 state *state.State 61 62 store *recordingStore 63 } 64 65 var _ = Suite(&refreshHintsTestSuite{}) 66 67 func (s *refreshHintsTestSuite) SetUpTest(c *C) { 68 s.state = state.New(nil) 69 70 s.store = &recordingStore{} 71 s.state.Lock() 72 defer s.state.Unlock() 73 snapstate.ReplaceStore(s.state, s.store) 74 75 snapstate.Set(s.state, "some-snap", &snapstate.SnapState{ 76 Active: true, 77 Sequence: []*snap.SideInfo{ 78 {RealName: "some-snap", Revision: snap.R(5), SnapID: "some-snap-id"}, 79 }, 80 Current: snap.R(5), 81 SnapType: "app", 82 UserID: 1, 83 }) 84 85 snapstate.CanAutoRefresh = func(*state.State) (bool, error) { return true, nil } 86 snapstate.AutoAliases = func(*state.State, *snap.Info) (map[string]string, error) { 87 return nil, nil 88 } 89 90 s.state.Set("refresh-privacy-key", "privacy-key") 91 } 92 93 func (s *refreshHintsTestSuite) TearDownTest(c *C) { 94 snapstate.CanAutoRefresh = nil 95 snapstate.AutoAliases = nil 96 } 97 98 func (s *refreshHintsTestSuite) TestLastRefresh(c *C) { 99 rh := snapstate.NewRefreshHints(s.state) 100 err := rh.Ensure() 101 c.Check(err, IsNil) 102 c.Check(s.store.ops, DeepEquals, []string{"list-refresh"}) 103 } 104 105 func (s *refreshHintsTestSuite) TestLastRefreshNoRefreshNeeded(c *C) { 106 s.state.Lock() 107 s.state.Set("last-refresh-hints", time.Now().Add(-23*time.Hour)) 108 s.state.Unlock() 109 110 rh := snapstate.NewRefreshHints(s.state) 111 err := rh.Ensure() 112 c.Check(err, IsNil) 113 c.Check(s.store.ops, HasLen, 0) 114 } 115 116 func (s *refreshHintsTestSuite) TestLastRefreshNoRefreshNeededBecauseOfFullAutoRefresh(c *C) { 117 s.state.Lock() 118 s.state.Set("last-refresh-hints", time.Now().Add(-48*time.Hour)) 119 s.state.Unlock() 120 121 s.state.Lock() 122 s.state.Set("last-refresh", time.Now().Add(-23*time.Hour)) 123 s.state.Unlock() 124 125 rh := snapstate.NewRefreshHints(s.state) 126 err := rh.Ensure() 127 c.Check(err, IsNil) 128 c.Check(s.store.ops, HasLen, 0) 129 } 130 131 func (s *refreshHintsTestSuite) TestAtSeedPolicy(c *C) { 132 r := release.MockOnClassic(false) 133 defer r() 134 135 s.state.Lock() 136 defer s.state.Unlock() 137 138 rh := snapstate.NewRefreshHints(s.state) 139 140 // on core, does nothing 141 err := rh.AtSeed() 142 c.Assert(err, IsNil) 143 var t1 time.Time 144 err = s.state.Get("last-refresh-hints", &t1) 145 c.Check(err, Equals, state.ErrNoState) 146 147 release.MockOnClassic(true) 148 // on classic it sets last-refresh-hints to now, 149 // postponing it of 24h 150 err = rh.AtSeed() 151 c.Assert(err, IsNil) 152 err = s.state.Get("last-refresh-hints", &t1) 153 c.Check(err, IsNil) 154 155 // nop if tried again 156 err = rh.AtSeed() 157 c.Assert(err, IsNil) 158 var t2 time.Time 159 err = s.state.Get("last-refresh-hints", &t2) 160 c.Check(err, IsNil) 161 c.Check(t1.Equal(t2), Equals, true) 162 }