github.com/rigado/snapd@v2.42.5-go-mod+incompatible/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  	"os"
    26  	"os/exec"
    27  
    28  	"github.com/godbus/dbus"
    29  
    30  	. "gopkg.in/check.v1"
    31  )
    32  
    33  func dbusSessionBus() (*dbus.Conn, error) {
    34  	// the test suite *must* use a private connection to the bus to avoid
    35  	// breaking things for code that might use a shared connection
    36  	conn, err := dbus.SessionBusPrivate()
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	if err := conn.Auth(nil); err != nil {
    41  		conn.Close()
    42  		return nil, err
    43  	}
    44  	if err := conn.Hello(); err != nil {
    45  		conn.Close()
    46  		return nil, err
    47  	}
    48  	return conn, nil
    49  }
    50  
    51  // DBusTest provides a separate dbus session bus for running tests
    52  type DBusTest struct {
    53  	tmpdir           string
    54  	dbusDaemon       *exec.Cmd
    55  	oldSessionBusEnv string
    56  
    57  	// the dbus.Conn to the session bus that tests can use
    58  	SessionBus *dbus.Conn
    59  }
    60  
    61  func (s *DBusTest) SetUpSuite(c *C) {
    62  	if _, err := exec.LookPath("dbus-daemon"); err != nil {
    63  		c.Skip(fmt.Sprintf("cannot run test without dbus-daemon: %s", err))
    64  		return
    65  	}
    66  	if _, err := exec.LookPath("dbus-launch"); err != nil {
    67  		c.Skip(fmt.Sprintf("cannot run test without dbus-launch: %s", err))
    68  		return
    69  	}
    70  
    71  	s.tmpdir = c.MkDir()
    72  	s.dbusDaemon = exec.Command("dbus-daemon", "--session", "--print-address", fmt.Sprintf("--address=unix:path=%s/user_bus_socket", s.tmpdir))
    73  	pout, err := s.dbusDaemon.StdoutPipe()
    74  	c.Assert(err, IsNil)
    75  	err = s.dbusDaemon.Start()
    76  	c.Assert(err, IsNil)
    77  
    78  	scanner := bufio.NewScanner(pout)
    79  	scanner.Scan()
    80  	c.Assert(scanner.Err(), IsNil)
    81  	s.oldSessionBusEnv = os.Getenv("DBUS_SESSION_BUS_ADDRESS")
    82  	os.Setenv("DBUS_SESSION_BUS_ADDRESS", scanner.Text())
    83  
    84  	s.SessionBus, err = dbusSessionBus()
    85  	c.Assert(err, IsNil)
    86  }
    87  
    88  func (s *DBusTest) TearDownSuite(c *C) {
    89  	if s.SessionBus != nil {
    90  		s.SessionBus.Close()
    91  	}
    92  
    93  	os.Setenv("DBUS_SESSION_BUS_ADDRESS", s.oldSessionBusEnv)
    94  	if s.dbusDaemon != nil && s.dbusDaemon.Process != nil {
    95  		err := s.dbusDaemon.Process.Kill()
    96  		c.Assert(err, IsNil)
    97  		err = s.dbusDaemon.Wait() // do cleanup
    98  		c.Assert(err, ErrorMatches, `(?i)signal: killed`)
    99  	}
   100  }
   101  
   102  func (s *DBusTest) SetUpTest(c *C)    {}
   103  func (s *DBusTest) TearDownTest(c *C) {}
   104  
   105  func DBusGetConnectionUnixProcessID(conn *dbus.Conn, name string) (pid int, err error) {
   106  	obj := conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
   107  
   108  	err = obj.Call("org.freedesktop.DBus.GetConnectionUnixProcessID", 0, name).Store(&pid)
   109  	return pid, err
   110  }