github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/testutil/dbustest.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2015 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 testutil 21 22 import ( 23 "bufio" 24 "fmt" 25 "io/ioutil" 26 "os" 27 "os/exec" 28 "path/filepath" 29 30 "github.com/godbus/dbus" 31 . "gopkg.in/check.v1" 32 33 "github.com/snapcore/snapd/dbusutil" 34 ) 35 36 // DBusTest provides a separate dbus session bus for running tests 37 type DBusTest struct { 38 tmpdir string 39 dbusDaemon *exec.Cmd 40 oldSessionBusEnv string 41 42 // the dbus.Conn to the session bus that tests can use 43 SessionBus *dbus.Conn 44 } 45 46 // sessionBusConfigTemplate is a minimal session dbus daemon 47 // configuration template for use in the unit tests. In comparison to 48 // the typical disto session config, it contains no <servicedir> 49 // directives to avoid activating services installed on the test 50 // system. 51 const sessionBusConfigTemplate = `<busconfig> 52 <type>session</type> 53 <listen>unix:path=%s/user_bus_socket</listen> 54 <auth>EXTERNAL</auth> 55 <policy context="default"> 56 <!-- Allow everything to be sent --> 57 <allow send_destination="*" eavesdrop="true"/> 58 <!-- Allow everything to be received --> 59 <allow eavesdrop="true"/> 60 <!-- Allow anyone to own anything --> 61 <allow own="*"/> 62 </policy> 63 </busconfig> 64 ` 65 66 func (s *DBusTest) SetUpSuite(c *C) { 67 if _, err := exec.LookPath("dbus-daemon"); err != nil { 68 c.Skip(fmt.Sprintf("cannot run test without dbus-daemon: %s", err)) 69 return 70 } 71 if _, err := exec.LookPath("dbus-launch"); err != nil { 72 c.Skip(fmt.Sprintf("cannot run test without dbus-launch: %s", err)) 73 return 74 } 75 76 s.tmpdir = c.MkDir() 77 configFile := filepath.Join(s.tmpdir, "session.conf") 78 err := ioutil.WriteFile(configFile, []byte(fmt.Sprintf(sessionBusConfigTemplate, s.tmpdir)), 0644) 79 c.Assert(err, IsNil) 80 s.dbusDaemon = exec.Command("dbus-daemon", "--print-address", fmt.Sprintf("--config-file=%s", configFile)) 81 s.dbusDaemon.Stderr = os.Stderr 82 pout, err := s.dbusDaemon.StdoutPipe() 83 c.Assert(err, IsNil) 84 err = s.dbusDaemon.Start() 85 c.Assert(err, IsNil) 86 87 scanner := bufio.NewScanner(pout) 88 scanner.Scan() 89 c.Assert(scanner.Err(), IsNil) 90 s.oldSessionBusEnv = os.Getenv("DBUS_SESSION_BUS_ADDRESS") 91 os.Setenv("DBUS_SESSION_BUS_ADDRESS", scanner.Text()) 92 93 s.SessionBus, err = dbusutil.SessionBusPrivate() 94 c.Assert(err, IsNil) 95 } 96 97 func (s *DBusTest) TearDownSuite(c *C) { 98 if s.SessionBus != nil { 99 s.SessionBus.Close() 100 } 101 102 os.Setenv("DBUS_SESSION_BUS_ADDRESS", s.oldSessionBusEnv) 103 if s.dbusDaemon != nil && s.dbusDaemon.Process != nil { 104 err := s.dbusDaemon.Process.Kill() 105 c.Assert(err, IsNil) 106 err = s.dbusDaemon.Wait() // do cleanup 107 c.Assert(err, ErrorMatches, `(?i)signal: killed`) 108 } 109 } 110 111 func (s *DBusTest) SetUpTest(c *C) {} 112 func (s *DBusTest) TearDownTest(c *C) {} 113 114 func DBusGetConnectionUnixProcessID(conn *dbus.Conn, name string) (pid int, err error) { 115 obj := conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus") 116 117 err = obj.Call("org.freedesktop.DBus.GetConnectionUnixProcessID", 0, name).Store(&pid) 118 return pid, err 119 }