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