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