github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/snapd/main_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 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 main_test 21 22 import ( 23 "fmt" 24 "os" 25 "path/filepath" 26 "sync" 27 "testing" 28 "time" 29 30 . "gopkg.in/check.v1" 31 32 "github.com/snapcore/snapd/client" 33 snapd "github.com/snapcore/snapd/cmd/snapd" 34 "github.com/snapcore/snapd/dirs" 35 "github.com/snapcore/snapd/interfaces/apparmor" 36 "github.com/snapcore/snapd/interfaces/seccomp" 37 "github.com/snapcore/snapd/logger" 38 "github.com/snapcore/snapd/osutil" 39 "github.com/snapcore/snapd/testutil" 40 ) 41 42 // Hook up check.v1 into the "go test" runner 43 func Test(t *testing.T) { TestingT(t) } 44 45 type snapdSuite struct { 46 tmpdir string 47 testutil.BaseTest 48 } 49 50 var _ = Suite(&snapdSuite{}) 51 52 func (s *snapdSuite) SetUpTest(c *C) { 53 s.tmpdir = c.MkDir() 54 for _, d := range []string{"/var/lib/snapd", "/run"} { 55 err := os.MkdirAll(filepath.Join(s.tmpdir, d), 0755) 56 c.Assert(err, IsNil) 57 } 58 dirs.SetRootDir(s.tmpdir) 59 60 restore := osutil.MockMountInfo("") 61 s.AddCleanup(restore) 62 } 63 64 func (s *snapdSuite) TestSanityFailGoesIntoDegradedMode(c *C) { 65 logbuf, restore := logger.MockLogger() 66 defer restore() 67 restore = apparmor.MockIsHomeUsingNFS(func() (bool, error) { return false, nil }) 68 defer restore() 69 restore = seccomp.MockSnapSeccompVersionInfo("abcdef 1.2.3 1234abcd -") 70 defer restore() 71 72 sanityErr := fmt.Errorf("foo failed") 73 sanityCalled := make(chan bool) 74 sanityRan := 0 75 restore = snapd.MockSanityCheck(func() error { 76 sanityRan++ 77 // Ensure this ran at least *twice* to avoid a race here: 78 // If we close the channel and this wakes up the "select" 79 // below immediately and stops this go-routine then the 80 // check that the logbuf contains the error will fail. 81 // By running this at least twice we know the error made 82 // it to the log. 83 if sanityRan == 2 { 84 close(sanityCalled) 85 } 86 return sanityErr 87 }) 88 defer restore() 89 90 restore = snapd.MockCheckRunningConditionsRetryDelay(10 * time.Millisecond) 91 defer restore() 92 93 // run the daemon 94 ch := make(chan os.Signal) 95 wg := sync.WaitGroup{} 96 wg.Add(1) 97 go func() { 98 defer wg.Done() 99 err := snapd.Run(ch) 100 c.Check(err, IsNil) 101 }() 102 103 sanityCheckWasRun := false 104 select { 105 case <-time.After(5 * time.Second): 106 case _, stillOpen := <-sanityCalled: 107 c.Assert(stillOpen, Equals, false) 108 sanityCheckWasRun = true 109 } 110 c.Check(sanityCheckWasRun, Equals, true) 111 c.Check(logbuf.String(), testutil.Contains, "system does not fully support snapd: foo failed") 112 113 // verify that talking to the daemon yields the sanity error 114 // message 115 // disable keepliave as it would sometimes cause the daemon to be 116 // blocked when closing connections during graceful shutdown 117 cli := client.New(&client.Config{DisableKeepAlive: true}) 118 _, err := cli.Abort("123") 119 c.Check(err, ErrorMatches, "system does not fully support snapd: foo failed") 120 121 // verify that the sysinfo command is still available 122 _, err = cli.SysInfo() 123 c.Check(err, IsNil) 124 125 // stop the daemon 126 close(ch) 127 wg.Wait() 128 }