github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/overlord/servicestate/quotas_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 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 servicestate_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 "github.com/snapcore/snapd/gadget/quantity" 26 "github.com/snapcore/snapd/overlord/servicestate" 27 "github.com/snapcore/snapd/overlord/servicestate/servicestatetest" 28 "github.com/snapcore/snapd/snap/quota" 29 ) 30 31 type servicestateQuotasSuite struct { 32 baseServiceMgrTestSuite 33 } 34 35 var _ = Suite(&servicestateQuotasSuite{}) 36 37 func (s *servicestateQuotasSuite) SetUpTest(c *C) { 38 s.baseServiceMgrTestSuite.SetUpTest(c) 39 40 // we don't need the EnsureSnapServices ensure loop to run by default 41 servicestate.MockEnsuredSnapServices(s.mgr, true) 42 } 43 44 func (s *servicestateQuotasSuite) TestQuotas(c *C) { 45 st := s.state 46 st.Lock() 47 defer st.Unlock() 48 49 // with nothing in state we don't get any quotas 50 quotaMap, err := servicestate.AllQuotas(st) 51 c.Assert(err, IsNil) 52 c.Assert(quotaMap, HasLen, 0) 53 54 // we can add some basic quotas to state 55 grp := "a.Group{ 56 Name: "foogroup", 57 MemoryLimit: quantity.SizeGiB, 58 } 59 newGrps, err := servicestatetest.PatchQuotas(st, grp) 60 c.Assert(err, IsNil) 61 c.Assert(newGrps, DeepEquals, map[string]*quota.Group{ 62 "foogroup": grp, 63 }) 64 65 // now we get back the same quota 66 quotaMap, err = servicestate.AllQuotas(st) 67 c.Assert(err, IsNil) 68 c.Assert(quotaMap, DeepEquals, map[string]*quota.Group{ 69 "foogroup": grp, 70 }) 71 72 // adding a sub-group quota only works when we update the parent group to 73 // reference the sub-group at the same time 74 grp2 := "a.Group{ 75 Name: "group-2", 76 MemoryLimit: quantity.SizeGiB, 77 ParentGroup: "foogroup", 78 } 79 _, err = servicestatetest.PatchQuotas(st, grp2) 80 c.Assert(err, ErrorMatches, `cannot update quota "group-2": group "foogroup" does not reference necessary child group "group-2"`) 81 82 // we also can't add a sub-group to the parent without adding the sub-group 83 // itself 84 grp.SubGroups = append(grp.SubGroups, "group-2") 85 _, err = servicestatetest.PatchQuotas(st, grp) 86 c.Assert(err, ErrorMatches, `cannot update quota "foogroup": missing group "group-2" referenced as the sub-group of group "foogroup"`) 87 88 // but if we update them both at the same time we succeed 89 newGrps, err = servicestatetest.PatchQuotas(st, grp, grp2) 90 c.Assert(err, IsNil) 91 c.Assert(newGrps, DeepEquals, map[string]*quota.Group{ 92 "foogroup": grp, 93 "group-2": grp2, 94 }) 95 96 // and now we see both in the state 97 quotaMap, err = servicestate.AllQuotas(st) 98 c.Assert(err, IsNil) 99 c.Assert(quotaMap, DeepEquals, map[string]*quota.Group{ 100 "foogroup": grp, 101 "group-2": grp2, 102 }) 103 104 // and we can get individual quotas too 105 res, err := servicestate.GetQuota(st, "foogroup") 106 c.Assert(err, IsNil) 107 c.Assert(res, DeepEquals, grp) 108 109 res2, err := servicestate.GetQuota(st, "group-2") 110 c.Assert(err, IsNil) 111 c.Assert(res2, DeepEquals, grp2) 112 113 _, err = servicestate.GetQuota(st, "unknown") 114 c.Assert(err, Equals, servicestate.ErrQuotaNotFound) 115 }