1
// Copyright 2015 Canonical Ltd.
2
// Copyright 2015 Cloudbase Solutions SRL
3
// Licensed under the LGPLv3, see LICENCE file for details.
12
"github.com/juju/testing"
13
jc "github.com/juju/testing/checkers"
14
"github.com/juju/utils/proxy"
15
gc "gopkg.in/check.v1"
17
"github.com/juju/utils/packaging/commands"
18
"github.com/juju/utils/packaging/manager"
21
var _ = gc.Suite(&ManagerSuite{})
23
type ManagerSuite struct {
24
apt, yum manager.PackageManager
25
testing.IsolationSuite
29
func (s *ManagerSuite) SetUpSuite(c *gc.C) {
30
s.IsolationSuite.SetUpSuite(c)
31
s.apt = manager.NewAptPackageManager()
32
s.yum = manager.NewYumPackageManager()
35
func (s *ManagerSuite) SetUpTest(c *gc.C) {
36
s.IsolationSuite.SetUpTest(c)
39
func (s *ManagerSuite) TearDownTest(c *gc.C) {
40
s.IsolationSuite.TearDownTest(c)
43
func (s *ManagerSuite) TearDownSuite(c *gc.C) {
44
s.IsolationSuite.TearDownSuite(c)
48
// aptCmder is the commands.PackageCommander for apt-based
49
// systems whose commands will be checked against.
50
aptCmder = commands.NewAptPackageCommander()
52
// yumCmder is the commands.PackageCommander for yum-based
53
// systems whose commands will be checked against.
54
yumCmder = commands.NewYumPackageCommander()
56
// testedPackageName is the package name used in all
57
// single-package testing scenarios.
58
testedPackageName = "test-package"
60
// testedRepoName is the repository name used in all
61
// repository-related tests.
62
testedRepoName = "some-repo"
64
// testedProxySettings is the set of proxy settings used in
65
// all proxy-related tests.
66
testedProxySettings = proxy.Settings{
67
Http: "http://some-proxy.domain",
68
Https: "https://some-proxy.domain",
69
Ftp: "ftp://some-proxy.domain",
72
// testedPackageNames is a list of package names used in all
73
// multiple-package testing scenarions.
74
testedPackageNames = []string{
76
"second-test-package",
81
// getMockRunCommandWithRetry returns a function with the same signature as
82
// RunCommandWithRetry which saves the command it recieves in the provided
83
// string whilst always returning no output, 0 error code and nil error.
84
func getMockRunCommandWithRetry(stor *string) func(string, func(string) error) (string, int, error) {
85
return func(cmd string, fatalErr func(string) error) (string, int, error) {
91
// getMockRunCommand returns a function with the same signature as RunCommand
92
// which saves the command it revieves in the provided string whilst always
93
// returning empty output and no error.
94
func getMockRunCommand(stor *string) func(string, ...string) (string, error) {
95
return func(cmd string, args ...string) (string, error) {
96
*stor = strings.Join(append([]string{cmd}, args...), " ")
101
// simpleTestCase is a struct containing all the information required for
102
// running a simple error/no error test case.
103
type simpleTestCase struct {
104
// description of the test:
107
// the expected apt command which will get executed:
108
expectedAptCmd string
110
// the expected result of the given apt operation:
111
expectedAptResult interface{}
113
// the expected yum command which will get executed:
114
expectedYumCmd string
116
// the expected result of the given yum operation:
117
expectedYumResult interface{}
119
// the function to be applied on the package manager.
120
// returns the result of the operation and the error.
121
operation func(manager.PackageManager) (interface{}, error)
124
var simpleTestCases = []*simpleTestCase{
126
"Test install prerequisites.",
127
aptCmder.InstallPrerequisiteCmd(),
129
yumCmder.InstallPrerequisiteCmd(),
131
func(pacman manager.PackageManager) (interface{}, error) {
132
return nil, pacman.InstallPrerequisite()
136
"Test system update.",
137
aptCmder.UpdateCmd(),
139
yumCmder.UpdateCmd(),
141
func(pacman manager.PackageManager) (interface{}, error) {
142
return nil, pacman.Update()
146
"Test system upgrade.",
147
aptCmder.UpgradeCmd(),
149
yumCmder.UpgradeCmd(),
151
func(pacman manager.PackageManager) (interface{}, error) {
152
return nil, pacman.Upgrade()
156
"Test install packages.",
157
aptCmder.InstallCmd(testedPackageNames...),
159
yumCmder.InstallCmd(testedPackageNames...),
161
func(pacman manager.PackageManager) (interface{}, error) {
162
return nil, pacman.Install(testedPackageNames...)
166
"Test remove packages.",
167
aptCmder.RemoveCmd(testedPackageNames...),
169
yumCmder.RemoveCmd(testedPackageNames...),
171
func(pacman manager.PackageManager) (interface{}, error) {
172
return nil, pacman.Remove(testedPackageNames...)
176
"Test purge packages.",
177
aptCmder.PurgeCmd(testedPackageNames...),
179
yumCmder.PurgeCmd(testedPackageNames...),
181
func(pacman manager.PackageManager) (interface{}, error) {
182
return nil, pacman.Purge(testedPackageNames...)
186
"Test repository addition.",
187
aptCmder.AddRepositoryCmd(testedRepoName),
189
yumCmder.AddRepositoryCmd(testedRepoName),
191
func(pacman manager.PackageManager) (interface{}, error) {
192
return nil, pacman.AddRepository(testedRepoName)
196
"Test repository removal.",
197
aptCmder.RemoveRepositoryCmd(testedRepoName),
199
yumCmder.RemoveRepositoryCmd(testedRepoName),
201
func(pacman manager.PackageManager) (interface{}, error) {
202
return nil, pacman.RemoveRepository(testedRepoName)
206
"Test running cleanup.",
207
aptCmder.CleanupCmd(),
209
yumCmder.CleanupCmd(),
211
func(pacman manager.PackageManager) (interface{}, error) {
212
return nil, pacman.Cleanup()
217
// searchingTestCases are a couple of simple test cases which search for a
218
// given package; either localy or remotely, and need to be tested seperately
219
// on the case of their return value being a boolean.
220
var searchingTestCases = []*simpleTestCase{
222
"Test package search.",
223
aptCmder.SearchCmd(testedPackageName),
225
yumCmder.SearchCmd(testedPackageName),
227
func(pacman manager.PackageManager) (interface{}, error) {
228
return pacman.Search(testedPackageName)
232
"Test local package search.",
233
aptCmder.IsInstalledCmd(testedPackageName),
235
yumCmder.IsInstalledCmd(testedPackageName),
237
func(pacman manager.PackageManager) (interface{}, error) {
238
return pacman.IsInstalled(testedPackageName), nil
243
func (s *ManagerSuite) TestSimpleCases(c *gc.C) {
244
s.PatchValue(&manager.RunCommand, getMockRunCommand(&s.calledCommand))
245
s.PatchValue(&manager.RunCommandWithRetry, getMockRunCommandWithRetry(&s.calledCommand))
247
testCases := append(simpleTestCases, searchingTestCases...)
248
for i, testCase := range testCases {
249
c.Logf("Simple test %d: %s", i+1, testCase.desc)
251
// run for the apt PackageManager implementation:
252
res, err := testCase.operation(s.apt)
253
c.Assert(err, jc.ErrorIsNil)
254
c.Assert(s.calledCommand, gc.Equals, testCase.expectedAptCmd)
255
c.Assert(res, jc.DeepEquals, testCase.expectedAptResult)
257
// run for the yum PackageManager implementation.
258
res, err = testCase.operation(s.yum)
259
c.Assert(err, jc.ErrorIsNil)
260
c.Assert(s.calledCommand, gc.Equals, testCase.expectedYumCmd)
261
c.Assert(res, jc.DeepEquals, testCase.expectedYumResult)
265
func (s *ManagerSuite) TestSimpleErrorCases(c *gc.C) {
267
expectedErr = "packaging command failed: exit status 0"
268
expectedErrMsg = `E: I done failed :(`
270
state := os.ProcessState{}
271
cmdError := &exec.ExitError{ProcessState: &state}
273
cmdChan := s.HookCommandOutput(&manager.CommandOutput, []byte(expectedErrMsg), error(cmdError))
275
for i, testCase := range simpleTestCases {
276
c.Logf("Error'd test %d: %s", i+1, testCase.desc)
277
s.PatchValue(&manager.ProcessStateSys, func(*os.ProcessState) interface{} {
278
return mockExitStatuser(i + 1)
281
// run for the apt PackageManager implementation:
282
_, err := testCase.operation(s.apt)
283
c.Assert(err, gc.ErrorMatches, expectedErr)
286
c.Assert(strings.Join(cmd.Args, " "), gc.DeepEquals, testCase.expectedAptCmd)
288
// run for the yum PackageManager implementation:
289
_, err = testCase.operation(s.yum)
290
c.Assert(err, gc.ErrorMatches, expectedErr)
293
c.Assert(strings.Join(cmd.Args, " "), gc.DeepEquals, testCase.expectedYumCmd)