Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
cmd_test.go 3.14 KiB
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Huawei Inc.

package raucpreinstallhandler_test

import (
	"context"
	"os"
	"testing"

	"github.com/godbus/dbus/v5"
	"gitlab.com/zygoon/go-cmdr"
	. "gopkg.in/check.v1"

	raucpreinstallhandler "booting.oniroproject.org/distro/components/sysota/cmd/rauc-pre-install-handler"
	"booting.oniroproject.org/distro/components/sysota/cmd/sysotad/raucinstallhosted"
	svcspec "booting.oniroproject.org/distro/components/sysota/cmd/sysotad/spec"
	"booting.oniroproject.org/distro/components/sysota/pkg/dbusutil"
	"booting.oniroproject.org/distro/components/sysota/pkg/dbusutil/dbustest"
	"booting.oniroproject.org/distro/components/sysota/pkg/testutil"
	"booting.oniroproject.org/distro/components/sysota/rauc/installhandler"
	"booting.oniroproject.org/distro/components/sysota/rauc/installhandler/installtest"
)

func Test(t *testing.T) { TestingT(t) }

type cmdSuite struct {
	dbustest.Suite
	conn        *dbus.Conn
	serviceHost *dbusutil.ServiceHost
	handler     installtest.Handler
	cmd         cmdr.Cmd
}

var _ = Suite(&cmdSuite{})

func (s *cmdSuite) SetUpTest(_ *C) {
	s.cmd = raucpreinstallhandler.Cmd{}
}

func (s *cmdSuite) TearDownTest(c *C) {
	if s.serviceHost != nil {
		err := s.serviceHost.Unexport()
		c.Check(err, IsNil)

		s.serviceHost = nil
	}

	if s.conn != nil {
		err := s.conn.Close()
		c.Check(err, IsNil)

		s.conn = nil
	}
}

func (s *cmdSuite) EnsureConn(c *C) *dbus.Conn {
	if s.conn == nil {
		var err error
		s.conn, err = dbusutil.SystemBus()
		c.Assert(err, IsNil)
	}

	return s.conn
}

func (s *cmdSuite) EnsureService(c *C) {
	if s.serviceHost == nil {
		conn := s.EnsureConn(c)
		s.serviceHost = dbusutil.NewServiceHost(conn)
		s.serviceHost.AddHostedService(raucinstallhosted.New(&s.handler))

		err := s.serviceHost.Export()
		c.Assert(err, IsNil)

		reply, err := conn.RequestName(svcspec.BusName, dbus.NameFlagDoNotQueue)
		c.Assert(err, IsNil)
		c.Assert(reply, Equals, dbus.RequestNameReplyPrimaryOwner)
	}
}

func (s *cmdSuite) TestRunButBrokenEnvironment(c *C) {
	s.EnsureService(c)
	s.handler.MockPreInstallFn(func(env *installhandler.Environment) error {
		return nil
	})

	c.Assert(os.Setenv("RAUC_SLOTS", "potato"), IsNil)

	defer func() { c.Assert(os.Unsetenv("RAUC_SLOTS"), IsNil) }()

	err := s.cmd.Run(context.TODO(), []string{})
	c.Assert(err, ErrorMatches, `cannot create handler environment: variable RAUC_SLOTS refers to undefined slot potato`)
}

func (s *cmdSuite) TestRunPreInstallHandler(c *C) {
	s.EnsureService(c)

	var called testutil.CallWitness

	s.handler.MockPreInstallFn(func(env *installhandler.Environment) error {
		called.Witness()

		return nil
	})

	err := s.cmd.Run(context.TODO(), []string{})
	c.Assert(err, IsNil)

	c.Check(called.Once(), Equals, true)
}

type brokenDBusSuite struct{}

var _ = Suite(&brokenDBusSuite{})

func (s *brokenDBusSuite) TestRunButNoSystemBus(c *C) {
	restore, err := dbustest.SetDBusSystemBusAddress("unix:path=potato")
	c.Assert(err, IsNil)

	defer func() { c.Assert(restore(), IsNil) }()

	cmd := raucpreinstallhandler.Cmd{}
	err = cmd.Run(context.TODO(), []string{})
	c.Assert(err, ErrorMatches, `dial .*potato: connect: no such file or directory`)
}