asteris-llc/converge

View on GitHub
resource/systemd/unit/systemd_linux_test.go

Summary

Maintainability
F
3 wks
Test Coverage
// Copyright © 2016 Asteris, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build linux

package unit

import (
    "fmt"
    "reflect"
    "testing"

    "github.com/pkg/errors"

    "github.com/coreos/go-systemd/dbus"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestInterface(t *testing.T) {
    //    assert.Implements(t, (*SystemdExecutor)(nil), new(LinuxExecutor))
}

// TestListUnits runs a test
func TestListUnits(t *testing.T) {
    t.Parallel()

    t.Run("when-dbus-errors", func(t *testing.T) {
        t.Run("list-units-returns-error", func(t *testing.T) {
            t.Parallel()
            m := &DbusMock{}
            expected := errors.New("error1")
            m.On("ListUnits").Return([]dbus.UnitStatus{}, expected)
            l := LinuxExecutor{m}
            _, err := l.ListUnits()
            assert.Equal(t, expected, err)
        })

        t.Run("GetUnitProperties-fails", func(t *testing.T) {
            t.Parallel()
            m := &DbusMock{}
            expected := errors.New("error1")
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{}}, nil)
            m.On("GetUnitProperties", any).Return(map[string]interface{}{}, expected)
            l := LinuxExecutor{m}
            _, err := l.ListUnits()
            assert.Equal(t, expected, err)
        })
        t.Run("GetUnitTypeProperties-fails", func(t *testing.T) {
            t.Run("when-should-not-have-properties", func(t *testing.T) {
                t.Parallel()
                m := &DbusMock{}
                expected := errors.New("error1")
                m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{}}, nil)
                m.On("GetUnitProperties", any).Return(map[string]interface{}{}, nil)
                m.On("GetUnitTypeProperties", any).Return(map[string]interface{}{}, expected)
                l := LinuxExecutor{m}
                _, err := l.ListUnits()
                assert.NoError(t, err)
            })
            t.Run("when-should-have-type-properties", func(t *testing.T) {
                t.Parallel()
                m := &DbusMock{}
                expected := errors.New("error1")
                m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: "foo.service"}}, nil)
                m.On("GetUnitProperties", any).Return(map[string]interface{}{}, nil)
                m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, expected)
                l := LinuxExecutor{m}
                _, err := l.ListUnits()
                assert.Equal(t, expected, err)
            })
        })
    })

    t.Run("returns-a-unit-for-each-returned-unit", func(t *testing.T) {
        t.Parallel()
        var units []dbus.UnitStatus
        for i := 0; i < 10; i++ {
            units = append(units, dbus.UnitStatus{})
        }
        m := &DbusMock{}
        m.On("ListUnits").Return(units, nil)
        m.On("GetUnitProperties", any).Return(map[string]interface{}{}, nil)
        m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
        l := LinuxExecutor{m}
        actual, err := l.ListUnits()
        assert.NoError(t, err)
        assert.Equal(t, len(units), len(actual))
    })

    t.Run("sets-unit-fields", func(t *testing.T) {
        t.Parallel()

        expected := randomUnitStatus()
        units := []dbus.UnitStatus{expected}
        m := &DbusMock{}
        m.On("ListUnits").Return(units, nil)
        m.On("GetUnitProperties", any).Return(map[string]interface{}{}, nil)
        m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
        l := LinuxExecutor{m}
        actualSlice, err := l.ListUnits()
        require.NoError(t, err)
        require.Equal(t, 1, len(actualSlice))
        actual := actualSlice[0]
        assert.Equal(t, expected.Name, actual.Name)
        assert.Equal(t, expected.LoadState, actual.LoadState)
        assert.Equal(t, expected.Description, actual.Description)
        assert.Equal(t, expected.ActiveState, actual.ActiveState)
    })

    t.Run("sets-global-properties", func(t *testing.T) {
        t.Parallel()

        propMap := map[string]interface{}{
            "DefaultDependencies": true,
            "LoadState":           "loaded",
            "Names":               []string{"name1", "name2", "name3"},
            "StartLimitBurst":     uint32(7),
        }

        expected := Properties{
            DefaultDependencies: true,
            LoadState:           "loaded",
            Names:               []string{"name1", "name2", "name3"},
            StartLimitBurst:     uint32(7),
        }

        m := &DbusMock{}
        m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{}}, nil)
        m.On("GetUnitProperties", any).Return(propMap, nil)
        m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
        l := LinuxExecutor{m}
        actualSlice, err := l.ListUnits()
        require.NoError(t, err)
        require.Equal(t, 1, len(actualSlice))
        actual := actualSlice[0]
        assert.True(t, reflect.DeepEqual(expected, actual.Properties))
    })

    t.Run("sets-type-properties", func(t *testing.T) {
        t.Parallel()

        t.Run("service", func(t *testing.T) {
            typeName := "service"
            m := &DbusMock{}
            typeProps := map[string]interface{}{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: "name." + typeName}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.NotNil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("socket", func(t *testing.T) {
            typeName := "socket"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.NotNil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("device", func(t *testing.T) {
            typeName := "device"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.NotNil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("mount", func(t *testing.T) {
            typeName := "mount"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.NotNil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("automount", func(t *testing.T) {
            typeName := "automount"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.NotNil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("swap", func(t *testing.T) {
            typeName := "swap"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.NotNil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("target", func(t *testing.T) {
            typeName := "target"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("path", func(t *testing.T) {
            typeName := "path"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.NotNil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("timer", func(t *testing.T) {
            typeName := "timer"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.NotNil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("snapshot", func(t *testing.T) {
            typeName := "snapshot"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("slice", func(t *testing.T) {
            typeName := "slice"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.NotNil(t, actual.SliceProperties)
            assert.Nil(t, actual.ScopeProperties)
        })
        t.Run("scope", func(t *testing.T) {
            typeName := "scope"
            typeProps := map[string]interface{}{}
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{dbus.UnitStatus{Name: ("name." + typeName)}}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(typeProps, nil)
            l := LinuxExecutor{m}
            actualSlice, err := l.ListUnits()
            require.NoError(t, err)
            require.Equal(t, 1, len(actualSlice))
            actual := actualSlice[0]
            assert.Nil(t, actual.ServiceProperties)
            assert.Nil(t, actual.SocketProperties)
            assert.Nil(t, actual.DeviceProperties)
            assert.Nil(t, actual.MountProperties)
            assert.Nil(t, actual.AutomountProperties)
            assert.Nil(t, actual.SwapProperties)
            assert.Nil(t, actual.PathProperties)
            assert.Nil(t, actual.TimerProperties)
            assert.Nil(t, actual.SliceProperties)
            assert.NotNil(t, actual.ScopeProperties)
        })
    })
}

// TestQueryUnit runs a test
func TestQueryUnit(t *testing.T) {
    t.Parallel()
    t.Run("when-verify", func(t *testing.T) {
        t.Parallel()
        t.Run("when-unit-exists", func(t *testing.T) {
            t.Parallel()
            unit := randomUnitStatus()
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{unit}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
            l := LinuxExecutor{m}
            actual, err := l.QueryUnit(unit.Name, true)
            assert.NoError(t, err)
            assertUnitStatusEqUnit(t, unit, actual)
        })
        t.Run("when-unit-not-exists", func(t *testing.T) {
            t.Parallel()
            unit := randomUnitStatus()
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{randomUnitStatus()}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
            l := LinuxExecutor{m}
            _, err := l.QueryUnit(unit.Name, true)
            assert.Error(t, err)
        })
        t.Run("when-list-units-error", func(t *testing.T) {
            t.Parallel()
            err := errors.New("error1")
            m := &DbusMock{}
            m.On("ListUnits").Return([]dbus.UnitStatus{}, err)
            l := LinuxExecutor{m}
            _, actual := l.QueryUnit("name1", true)
            assert.Equal(t, err, errors.Cause(actual))
        })
    })

    t.Run("when-not-verify", func(t *testing.T) {
        t.Run("when-list-units-returns-value", func(t *testing.T) {
            t.Parallel()
            unit := randomUnitStatus()
            m := &DbusMock{}
            m.On("ListUnitsByNames", any).Return([]dbus.UnitStatus{unit}, nil)
            m.On("GetUnitProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("GetUnitTypeProperties", any, any).Return(map[string]interface{}{}, nil)
            m.On("ListUnits").Return([]dbus.UnitStatus{unit}, nil)
            l := LinuxExecutor{m}
            actual, err := l.QueryUnit(unit.Name, false)
            assert.NoError(t, err)
            assertUnitStatusEqUnit(t, unit, actual)
        })
        t.Run("when-list-units-returns-error", func(t *testing.T) {
            t.Parallel()
            expected := errors.New("error1")
            m := &DbusMock{}
            m.On("ListUnitsByNames", any).Return([]dbus.UnitStatus{}, expected)
            m.On("ListUnits").Return([]dbus.UnitStatus{}, expected)
            l := LinuxExecutor{m}
            _, actual := l.QueryUnit("name1", false)
            assert.Equal(t, expected, errors.Cause(actual))
        })
    })
}

// TestStartUnit runs a test
func TestStartUnit(t *testing.T) {
    t.Parallel()
    t.Run("call-start-unit", func(t *testing.T) {
        t.Parallel()
        u := randomUnit(UnitTypeService)
        m := &DbusMock{startResp: "done"}
        m.On("StartUnit", any, any, any).Return(1, nil)
        l := LinuxExecutor{m}
        err := l.StartUnit(u)
        assert.NoError(t, err)
        m.AssertCalled(t, "StartUnit", any, any, any)
    })
    t.Run("test-channel-return-values", func(t *testing.T) {
        t.Parallel()
        t.Run("done", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "done"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.NoError(t, err)
        })
        t.Run("canceled", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "canceled"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation was cancelled while starting: %s", u.Name))
        })
        t.Run("timeout", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "timeout"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation timed out while starting: %s", u.Name))
        })
        t.Run("failed", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "failed"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation failed while starting: %s", u.Name))
        })
        t.Run("dependency", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "dependency"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation depends on a failed unit when starting: %s", u.Name))
        })
        t.Run("skipped", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "skipped"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.NoError(t, err)
        })
        t.Run("bad-message", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{startResp: "msg1"}
            m.On("StartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StartUnit(u)
            assert.Equal(t, err, fmt.Errorf("unknown systemd status: msg1"))
        })
    })
    t.Run("start-unit-returns-error", func(t *testing.T) {
        t.Parallel()
        expected := errors.New("err1")
        u := randomUnit(UnitTypeService)
        m := &DbusMock{}
        m.On("StartUnit", any, any, any).Return(1, expected)
        l := LinuxExecutor{m}
        actual := l.StartUnit(u)
        assert.Equal(t, expected, actual)
    })
}

// TestStopUnit runs a test
func TestStopUnit(t *testing.T) {
    t.Parallel()
    t.Run("call-stop-unit", func(t *testing.T) {
        t.Parallel()
        u := randomUnit(UnitTypeService)
        m := &DbusMock{stopResp: "done"}
        m.On("StopUnit", any, any, any).Return(1, nil)
        l := LinuxExecutor{m}
        err := l.StopUnit(u)
        assert.NoError(t, err)
        m.AssertCalled(t, "StopUnit", any, any, any)
    })
    t.Run("test-channel-return-values", func(t *testing.T) {
        t.Parallel()
        t.Run("done", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "done"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.NoError(t, err)
        })
        t.Run("canceled", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "canceled"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation was cancelled while stopping: %s", u.Name))
        })
        t.Run("timeout", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "timeout"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation timed out while stopping: %s", u.Name))
        })
        t.Run("failed", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "failed"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation failed while stopping: %s", u.Name))
        })
        t.Run("dependency", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "dependency"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation depends on a failed unit when stopping: %s", u.Name))
        })
        t.Run("skipped", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "skipped"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.NoError(t, err)
        })
        t.Run("bad-message", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{stopResp: "msg1"}
            m.On("StopUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.StopUnit(u)
            assert.Equal(t, err, fmt.Errorf("unknown systemd status: msg1"))
        })
    })
    t.Run("stop-unit-returns-error", func(t *testing.T) {
        t.Parallel()
        expected := errors.New("err1")
        u := randomUnit(UnitTypeService)
        m := &DbusMock{}
        m.On("StopUnit", any, any, any).Return(1, expected)
        l := LinuxExecutor{m}
        actual := l.StopUnit(u)
        assert.Equal(t, expected, actual)
    })
}

// Test RestartUnit runs a test
func TestRestartUnit(t *testing.T) {
    t.Parallel()
    t.Run("call-restart-unit", func(t *testing.T) {
        t.Parallel()
        u := randomUnit(UnitTypeService)
        m := &DbusMock{restartResp: "done"}
        m.On("RestartUnit", any, any, any).Return(1, nil)
        l := LinuxExecutor{m}
        err := l.RestartUnit(u)
        assert.NoError(t, err)
        m.AssertCalled(t, "RestartUnit", any, any, any)
    })
    t.Run("test-channel-return-values", func(t *testing.T) {
        t.Parallel()
        t.Run("done", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "done"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.NoError(t, err)
        })
        t.Run("canceled", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "canceled"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation was cancelled while restarting: %s", u.Name))
        })
        t.Run("timeout", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "timeout"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation timed out while restarting: %s", u.Name))
        })
        t.Run("failed", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "failed"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation failed while restarting: %s", u.Name))
        })
        t.Run("dependency", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "dependency"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation depends on a failed unit when restarting: %s", u.Name))
        })
        t.Run("skipped", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "skipped"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.NoError(t, err)
        })
        t.Run("bad-message", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{restartResp: "msg1"}
            m.On("RestartUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.RestartUnit(u)
            assert.Equal(t, err, fmt.Errorf("unknown systemd status: msg1"))
        })
    })
    t.Run("restart-unit-returns-error", func(t *testing.T) {
        t.Parallel()
        expected := errors.New("err1")
        u := randomUnit(UnitTypeService)
        m := &DbusMock{}
        m.On("RestartUnit", any, any, any).Return(1, expected)
        l := LinuxExecutor{m}
        actual := l.RestartUnit(u)
        assert.Equal(t, expected, actual)
    })
}

// Test ReloadUnit runs a test
func TestReloadUnit(t *testing.T) {
    t.Parallel()
    t.Run("call-reload-unit", func(t *testing.T) {
        t.Parallel()
        u := randomUnit(UnitTypeService)
        m := &DbusMock{reloadResp: "done"}
        m.On("ReloadUnit", any, any, any).Return(1, nil)
        l := LinuxExecutor{m}
        err := l.ReloadUnit(u)
        assert.NoError(t, err)
        m.AssertCalled(t, "ReloadUnit", any, any, any)
    })
    t.Run("test-channel-return-values", func(t *testing.T) {
        t.Parallel()
        t.Run("done", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "done"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.NoError(t, err)
        })
        t.Run("canceled", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "canceled"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation was cancelled while reloading: %s", u.Name))
        })
        t.Run("timeout", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "timeout"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation timed out while reloading: %s", u.Name))
        })
        t.Run("failed", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "failed"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation failed while reloading: %s", u.Name))
        })
        t.Run("dependency", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "dependency"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.Equal(t, err, fmt.Errorf("operation depends on a failed unit when reloading: %s", u.Name))
        })
        t.Run("skipped", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "skipped"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.NoError(t, err)
        })
        t.Run("bad-message", func(t *testing.T) {
            t.Parallel()
            u := randomUnit(UnitTypeService)
            m := &DbusMock{reloadResp: "msg1"}
            m.On("ReloadUnit", any, any, any).Return(1, nil)
            l := LinuxExecutor{m}
            err := l.ReloadUnit(u)
            assert.Equal(t, err, fmt.Errorf("unknown systemd status: msg1"))
        })
    })
    t.Run("reload-unit-returns-error", func(t *testing.T) {
        t.Parallel()
        expected := errors.New("err1")
        u := randomUnit(UnitTypeService)
        m := &DbusMock{}
        m.On("ReloadUnit", any, any, any).Return(1, expected)
        l := LinuxExecutor{m}
        actual := l.ReloadUnit(u)
        assert.Equal(t, expected, actual)
    })
}

func TestSendSignal(t *testing.T) {
    t.Parallel()
    u := randomUnit(UnitTypeService)
    m := &DbusMock{}
    m.On("KillUnit", any, any).Return()
    l := LinuxExecutor{m}
    signals := []Signal{SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
        SIGEMT, SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM,
        SIGURG, SIGSTOP, SIGTSTP, SIGCONT, SIGCHLD, SIGTTIN, SIGTTOU, SIGIO,
        SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2}
    for _, signal := range signals {
        t.Run(signal.String(), func(t *testing.T) {
            t.Parallel()
            l.SendSignal(u, signal)
            m.AssertCalled(t, "KillUnit", u.Name, int32(signal))
        })
    }
}