Merge lp:~fgimenez/snappy/integration-tests-verbosity-flag into lp:~snappy-dev/snappy/snappy-moved-to-github
- integration-tests-verbosity-flag
- Merge into snappy-moved-to-github
Status: | Needs review |
---|---|
Proposed branch: | lp:~fgimenez/snappy/integration-tests-verbosity-flag |
Merge into: | lp:~snappy-dev/snappy/snappy-moved-to-github |
Diff against target: |
766 lines (+345/-35) 16 files modified
_integration-tests/main.go (+8/-1) _integration-tests/tests/base_test.go (+16/-0) _integration-tests/testutils/autopkgtest/autopkgtest.go (+2/-2) _integration-tests/testutils/autopkgtest/autopkgtest_test.go (+26/-1) _integration-tests/testutils/autopkgtest/ssh.go (+14/-2) _integration-tests/testutils/build/build.go (+4/-4) _integration-tests/testutils/build/build_test.go (+0/-1) _integration-tests/testutils/cli/cli.go (+4/-3) _integration-tests/testutils/common/common.go (+8/-7) _integration-tests/testutils/config/config.go (+7/-5) _integration-tests/testutils/config/config_test.go (+5/-3) _integration-tests/testutils/image/image.go (+2/-2) _integration-tests/testutils/partition/partition.go (+0/-2) _integration-tests/testutils/testutils.go (+3/-2) _integration-tests/testutils/tlog/tlog.go (+101/-0) _integration-tests/testutils/tlog/tlog_test.go (+145/-0) |
To merge this branch: | bzr merge lp:~fgimenez/snappy/integration-tests-verbosity-flag |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Leo Arias (community) | Needs Information | ||
Review via email: mp+273670@code.launchpad.net |
Commit message
Integration tests verbosity flag
Description of the change
Integration tests verbosity flag.
There are currently only two levels implemented, DebugLevel (the default) and InfoLevel. The level can be set with:
tlog.
There are functions for logging at each level, tlog.Debugf and tlog.Infof. Currently all the previous fmt.Print have been changed into tlog.Debugf, which makes that, being DebugLevel the default, without flags the test run logs the same output as before. To get a less verbose output:
$ go run _integration-
There are currently no messages sent with tlog.Infof, the previous command only logs gocheck and adt-run related output.
Michael Vogt (mvo) wrote : | # |
Thanks for this branch! Its a bit unfortunate IMO that the native go logger is so limited, no support for log levels is really limiting and means that everyone has to reimplement a logger:/
We have a logger in snappy/logger already, I wonder if we could reuse that here instead of having a additional one? The one we have is a little more limited right now, i.e. you can suppress log messages right now, but it looks like it would be worthwhile to add there instead of having two versions. What do you think? Or is there something in the tests that makes sharing the logger unsuitable?
Federico Gimenez (fgimenez) wrote : | # |
@Michael I totally agree, it would be nice if we could use a single logger.
I had a look at the logger package before beginning with this and it seemed to me that it was oriented to a cli tool, with two "channels" to output messages but without giving the user the option to decide which kind of messages to show. In the case of the test logger there should be just one way of output (it shouldn't use syslog), but with different levels, and the level to be used should be selectable at invocation time. If we can make both things work at once it would be great :)
When we'll execute the tests on CI, for instance, we would like always the more verbose output on stdout, while perhaps a developer executing the suite locally would prefer to have a less verbose output, and enable the verbose one if there's an error.
Leo, what do you think?
Unmerged revisions
- 746. By Federico Gimenez
-
boot log also affected by the flag
- 745. By Federico Gimenez
-
set level in testbed moved to base_test's init
- 744. By Federico Gimenez
-
loglevel flag; passing the loglevel to the testbedd in config
- 743. By Federico Gimenez
-
removed calls to fmt.Print; added new line
- 742. By Federico Gimenez
-
tlog package
Preview Diff
1 | === modified file '_integration-tests/main.go' |
2 | --- _integration-tests/main.go 2015-09-02 03:12:43 +0000 |
3 | +++ _integration-tests/main.go 2015-10-07 15:29:59 +0000 |
4 | @@ -31,6 +31,7 @@ |
5 | "launchpad.net/snappy/_integration-tests/testutils/build" |
6 | "launchpad.net/snappy/_integration-tests/testutils/config" |
7 | "launchpad.net/snappy/_integration-tests/testutils/image" |
8 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
9 | ) |
10 | |
11 | const ( |
12 | @@ -39,6 +40,7 @@ |
13 | defaultChannel = "edge" |
14 | defaultSSHPort = 22 |
15 | dataOutputDir = "_integration-tests/data/output/" |
16 | + defaultLogLevel = "debug" |
17 | ) |
18 | |
19 | var configFileName = filepath.Join(dataOutputDir, "testconfig.json") |
20 | @@ -70,10 +72,15 @@ |
21 | rollback = flag.Bool("rollback", false, |
22 | "If this flag is used, the image will be updated and then rolled back before running the tests.") |
23 | outputDir = flag.String("output-dir", defaultOutputDir, "Directory where test artifacts will be stored.") |
24 | + logLevel = flag.String("loglevel", defaultLogLevel, "Log verbosity level, info or debug.") |
25 | ) |
26 | |
27 | flag.Parse() |
28 | |
29 | + if err := tlog.SetTextLevel(*logLevel); err != nil { |
30 | + log.Panic(err.Error()) |
31 | + } |
32 | + |
33 | build.Assets(*useSnappyFromBranch, *arch) |
34 | |
35 | // TODO: generate the files out of the source tree. --elopio - 2015-07-15 |
36 | @@ -85,7 +92,7 @@ |
37 | // TODO: pass the config as arguments to the test binaries. |
38 | // --elopio - 2015-07-15 |
39 | cfg := config.NewConfig( |
40 | - configFileName, *imgRelease, *imgChannel, *targetRelease, *targetChannel, |
41 | + configFileName, *imgRelease, *imgChannel, *targetRelease, *targetChannel, *logLevel, |
42 | remoteTestbed, *update, *rollback) |
43 | cfg.Write() |
44 | |
45 | |
46 | === modified file '_integration-tests/tests/base_test.go' |
47 | --- _integration-tests/tests/base_test.go 2015-09-03 11:35:59 +0000 |
48 | +++ _integration-tests/tests/base_test.go 2015-10-07 15:29:59 +0000 |
49 | @@ -21,13 +21,29 @@ |
50 | |
51 | import ( |
52 | "io" |
53 | + "log" |
54 | "os" |
55 | "testing" |
56 | |
57 | + "launchpad.net/snappy/_integration-tests/testutils/config" |
58 | "launchpad.net/snappy/_integration-tests/testutils/report" |
59 | "launchpad.net/snappy/_integration-tests/testutils/runner" |
60 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
61 | ) |
62 | |
63 | +func init() { |
64 | + cfg, err := config.ReadConfig( |
65 | + "_integration-tests/data/output/testconfig.json") |
66 | + |
67 | + if err != nil { |
68 | + log.Panic(err.Error()) |
69 | + } |
70 | + |
71 | + if err = tlog.SetTextLevel(cfg.LogLevel); err != nil { |
72 | + log.Panic(err.Error()) |
73 | + } |
74 | +} |
75 | + |
76 | // Hook up gocheck into the "go test" runner. |
77 | func Test(t *testing.T) { |
78 | output := io.MultiWriter( |
79 | |
80 | === modified file '_integration-tests/testutils/autopkgtest/autopkgtest.go' |
81 | --- _integration-tests/testutils/autopkgtest/autopkgtest.go 2015-08-24 17:43:59 +0000 |
82 | +++ _integration-tests/testutils/autopkgtest/autopkgtest.go 2015-10-07 15:29:59 +0000 |
83 | @@ -20,11 +20,11 @@ |
84 | package autopkgtest |
85 | |
86 | import ( |
87 | - "fmt" |
88 | "path/filepath" |
89 | "strings" |
90 | |
91 | "launchpad.net/snappy/_integration-tests/testutils" |
92 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
93 | "launchpad.net/snappy/_integration-tests/testutils/tpl" |
94 | ) |
95 | |
96 | @@ -75,7 +75,7 @@ |
97 | return |
98 | } |
99 | |
100 | - fmt.Println("Calling adt-run...") |
101 | + tlog.Debugf("Calling adt-run...") |
102 | outputDir := filepath.Join(a.testArtifactsPath, "output") |
103 | prepareTargetDir(outputDir) |
104 | |
105 | |
106 | === modified file '_integration-tests/testutils/autopkgtest/autopkgtest_test.go' |
107 | --- _integration-tests/testutils/autopkgtest/autopkgtest_test.go 2015-09-30 04:39:25 +0000 |
108 | +++ _integration-tests/testutils/autopkgtest/autopkgtest_test.go 2015-10-07 15:29:59 +0000 |
109 | @@ -29,6 +29,8 @@ |
110 | "testing" |
111 | |
112 | "gopkg.in/check.v1" |
113 | + |
114 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
115 | ) |
116 | |
117 | // Hook up check.v1 into the "go test" runner |
118 | @@ -183,6 +185,22 @@ |
119 | c.Assert(err, check.NotNil, check.Commentf("Expected error from tpl not received!")) |
120 | } |
121 | |
122 | +func (s *AutopkgtestSuite) TestAdtRunLocalHonoursLogLevel(c *check.C) { |
123 | + backTlogGetLevel := tlogGetLevel |
124 | + defer func() { tlogGetLevel = backTlogGetLevel }() |
125 | + tlogGetLevel = func() tlog.Level { |
126 | + return tlog.InfoLevel |
127 | + } |
128 | + s.subject.AdtRunLocal(imgPath) |
129 | + |
130 | + outputDir := outputDir(testArtifactsPath) |
131 | + expectedExecCommadCall := adtrunLocalCmd(controlFile, sourceCodePath, outputDir, imgPath) |
132 | + |
133 | + c.Assert(s.execCalls[expectedExecCommadCall], |
134 | + check.Equals, 1, |
135 | + check.Commentf("Expected call %s not executed 1 time", expectedExecCommadCall)) |
136 | +} |
137 | + |
138 | func tplExecuteCmd(tplFile, outputFile string, data interface{}) string { |
139 | return fmt.Sprint(tplFile, outputFile, data) |
140 | } |
141 | @@ -192,7 +210,14 @@ |
142 | } |
143 | |
144 | func adtrunLocalCmd(controlFile, sourceCodePath, outputDir, imgPath string) string { |
145 | - options := fmt.Sprintf("--- ssh -s /usr/share/autopkgtest/ssh-setup/snappy -- -b -i %s", imgPath) |
146 | + var showBoot string |
147 | + |
148 | + if tlogGetLevel() == tlog.DebugLevel { |
149 | + showBoot = " -b" |
150 | + } |
151 | + |
152 | + options := fmt.Sprintf("--- ssh -s /usr/share/autopkgtest/ssh-setup/snappy --%s -i %s", |
153 | + showBoot, imgPath) |
154 | return adtrunCommonCmd(controlFile, sourceCodePath, outputDir, options) |
155 | } |
156 | |
157 | |
158 | === modified file '_integration-tests/testutils/autopkgtest/ssh.go' |
159 | --- _integration-tests/testutils/autopkgtest/ssh.go 2015-09-30 04:39:25 +0000 |
160 | +++ _integration-tests/testutils/autopkgtest/ssh.go 2015-10-07 15:29:59 +0000 |
161 | @@ -24,6 +24,8 @@ |
162 | "os" |
163 | "path/filepath" |
164 | "strconv" |
165 | + |
166 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
167 | ) |
168 | |
169 | const ( |
170 | @@ -31,9 +33,19 @@ |
171 | sshTimeout = 600 |
172 | ) |
173 | |
174 | +var ( |
175 | + // dependency aliasing |
176 | + tlogGetLevel = tlog.GetLevel |
177 | +) |
178 | + |
179 | func kvmSSHOptions(imagePath string) string { |
180 | - return fmt.Sprint(commonSSHOptions, |
181 | - "-s /usr/share/autopkgtest/ssh-setup/snappy -- -b -i ", imagePath) |
182 | + var showBoot string |
183 | + |
184 | + if tlogGetLevel() == tlog.DebugLevel { |
185 | + showBoot = " -b" |
186 | + } |
187 | + return fmt.Sprintf(commonSSHOptions+ |
188 | + "-s /usr/share/autopkgtest/ssh-setup/snappy --%s -i "+imagePath, showBoot) |
189 | } |
190 | |
191 | func remoteTestbedSSHOptions(testbedIP string, testbedPort int) string { |
192 | |
193 | === modified file '_integration-tests/testutils/build/build.go' |
194 | --- _integration-tests/testutils/build/build.go 2015-09-14 09:38:49 +0000 |
195 | +++ _integration-tests/testutils/build/build.go 2015-10-07 15:29:59 +0000 |
196 | @@ -20,12 +20,12 @@ |
197 | package build |
198 | |
199 | import ( |
200 | - "fmt" |
201 | "os" |
202 | "path/filepath" |
203 | "strings" |
204 | |
205 | "launchpad.net/snappy/_integration-tests/testutils" |
206 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
207 | ) |
208 | |
209 | const ( |
210 | @@ -71,17 +71,17 @@ |
211 | } |
212 | |
213 | func buildSnappyCLI(arch string) { |
214 | - fmt.Println("Building snappy CLI...") |
215 | + tlog.Debugf("Building snappy CLI...") |
216 | goCall(arch, buildSnappyCliCmd) |
217 | } |
218 | |
219 | func buildSnapd(arch string) { |
220 | - fmt.Println("Building snapd...") |
221 | + tlog.Debugf("Building snapd...") |
222 | goCall(arch, buildSnapdCmd) |
223 | } |
224 | |
225 | func buildTests(arch string) { |
226 | - fmt.Println("Building tests...") |
227 | + tlog.Debugf("Building tests...") |
228 | |
229 | goCall(arch, buildTestCmd) |
230 | // XXX Go test 1.3 does not have the output flag, so we move the |
231 | |
232 | === modified file '_integration-tests/testutils/build/build_test.go' |
233 | --- _integration-tests/testutils/build/build_test.go 2015-09-09 13:12:16 +0000 |
234 | +++ _integration-tests/testutils/build/build_test.go 2015-10-07 15:29:59 +0000 |
235 | @@ -127,7 +127,6 @@ |
236 | |
237 | buildCall := s.execCalls[buildTestCmd] |
238 | |
239 | - fmt.Println(s.execCalls) |
240 | c.Assert(buildCall, check.Equals, 1, |
241 | check.Commentf("Expected 1 call to execCommand with %s, got %d", |
242 | buildTestCmd, buildCall)) |
243 | |
244 | === modified file '_integration-tests/testutils/cli/cli.go' |
245 | --- _integration-tests/testutils/cli/cli.go 2015-10-02 12:02:16 +0000 |
246 | +++ _integration-tests/testutils/cli/cli.go 2015-10-07 15:29:59 +0000 |
247 | @@ -20,12 +20,13 @@ |
248 | package cli |
249 | |
250 | import ( |
251 | - "fmt" |
252 | "os" |
253 | "os/exec" |
254 | "strings" |
255 | |
256 | "gopkg.in/check.v1" |
257 | + |
258 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
259 | ) |
260 | |
261 | var execCommand = exec.Command |
262 | @@ -55,10 +56,10 @@ |
263 | // ExecCommandErr executes a shell command and returns a string with the output |
264 | // of the command and eventually the obtained error |
265 | func ExecCommandErr(cmds ...string) (output string, err error) { |
266 | - fmt.Println(strings.Join(cmds, " ")) |
267 | + tlog.Debugf(strings.Join(cmds, " ")) |
268 | cmd := execCommand(cmds[0], cmds[1:]...) |
269 | outputByte, err := cmd.CombinedOutput() |
270 | output = string(outputByte) |
271 | - fmt.Print(output) |
272 | + tlog.Debugf(output) |
273 | return |
274 | } |
275 | |
276 | === modified file '_integration-tests/testutils/common/common.go' |
277 | --- _integration-tests/testutils/common/common.go 2015-10-01 09:37:04 +0000 |
278 | +++ _integration-tests/testutils/common/common.go 2015-10-07 15:29:59 +0000 |
279 | @@ -33,6 +33,7 @@ |
280 | "launchpad.net/snappy/_integration-tests/testutils/cli" |
281 | "launchpad.net/snappy/_integration-tests/testutils/config" |
282 | "launchpad.net/snappy/_integration-tests/testutils/partition" |
283 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
284 | ) |
285 | |
286 | const ( |
287 | @@ -102,11 +103,11 @@ |
288 | c.TestName(), contents)) |
289 | } else { |
290 | if CheckRebootMark("") { |
291 | - c.Logf("****** Running %s", c.TestName()) |
292 | + tlog.Debugf("****** Running %s", c.TestName()) |
293 | SetSavedVersion(c, GetCurrentUbuntuCoreVersion(c)) |
294 | } else { |
295 | if AfterReboot(c) { |
296 | - c.Logf("****** Resuming %s after reboot", c.TestName()) |
297 | + tlog.Debugf("****** Resuming %s after reboot", c.TestName()) |
298 | } else { |
299 | c.Skip(fmt.Sprintf("****** Skipped %s after reboot caused by %s", |
300 | c.TestName(), os.Getenv("ADT_REBOOT_MARK"))) |
301 | @@ -131,7 +132,7 @@ |
302 | partition.MakeWritable(c, target) |
303 | defer partition.MakeReadonly(c, target) |
304 | original := filepath.Join(target, channelCfgFile) |
305 | - c.Logf("Restoring %s...", original) |
306 | + tlog.Debugf("Restoring %s...", original) |
307 | cli.ExecCommand(c, "sudo", "mv", backup, original) |
308 | } |
309 | } |
310 | @@ -162,7 +163,7 @@ |
311 | } |
312 | |
313 | func replaceSystemImageValues(c *check.C, file, release, channel, version string) { |
314 | - c.Log("Switching the system image conf...") |
315 | + tlog.Debugf("Switching the system image conf...") |
316 | replaceRegex := map[string]string{ |
317 | release: `s#channel: ubuntu-core/.*/\(.*\)#channel: ubuntu-core/%s/\1#`, |
318 | channel: `s#channel: ubuntu-core/\(.*\)/.*#channel: ubuntu-core/\1/%s#`, |
319 | @@ -210,13 +211,13 @@ |
320 | |
321 | // CallFakeUpdate calls snappy update after faking the current version |
322 | func CallFakeUpdate(c *check.C) string { |
323 | - c.Log("Preparing fake and calling update.") |
324 | + tlog.Debugf("Preparing fake and calling update.") |
325 | fakeAvailableUpdate(c) |
326 | return cli.ExecCommand(c, "sudo", "snappy", "update") |
327 | } |
328 | |
329 | func fakeAvailableUpdate(c *check.C) { |
330 | - c.Log("Faking an available update...") |
331 | + tlog.Debugf("Faking an available update...") |
332 | currentVersion := GetCurrentUbuntuCoreVersion(c) |
333 | switchChannelVersionWithBackup(c, currentVersion-1) |
334 | SetSavedVersion(c, currentVersion-1) |
335 | @@ -245,7 +246,7 @@ |
336 | |
337 | // RebootWithMark requests a reboot using a specified mark. |
338 | func RebootWithMark(c *check.C, mark string) { |
339 | - c.Log("Preparing reboot with mark " + mark) |
340 | + tlog.Debugf("Preparing reboot with mark " + mark) |
341 | err := ioutil.WriteFile(needsRebootFile, []byte(mark), 0777) |
342 | c.Assert(err, check.IsNil, check.Commentf("Error writing needs-reboot file: %v", err)) |
343 | } |
344 | |
345 | === modified file '_integration-tests/testutils/config/config.go' |
346 | --- _integration-tests/testutils/config/config.go 2015-07-31 07:55:33 +0000 |
347 | +++ _integration-tests/testutils/config/config.go 2015-10-07 15:29:59 +0000 |
348 | @@ -21,9 +21,10 @@ |
349 | |
350 | import ( |
351 | "encoding/json" |
352 | - "fmt" |
353 | "io/ioutil" |
354 | "log" |
355 | + |
356 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
357 | ) |
358 | |
359 | // Config contains the values to pass to the test bed from the host. |
360 | @@ -33,24 +34,25 @@ |
361 | Channel string |
362 | TargetRelease string |
363 | TargetChannel string |
364 | + LogLevel string |
365 | RemoteTestbed bool |
366 | Update bool |
367 | Rollback bool |
368 | } |
369 | |
370 | // NewConfig is the Config constructor |
371 | -func NewConfig(fileName, release, channel, targetRelease, targetChannel string, remoteTestbed, update, rollback bool) *Config { |
372 | +func NewConfig(fileName, release, channel, targetRelease, targetChannel, logLevel string, remoteTestbed, update, rollback bool) *Config { |
373 | return &Config{ |
374 | FileName: fileName, Release: release, Channel: channel, |
375 | - TargetRelease: targetRelease, TargetChannel: targetChannel, |
376 | + TargetRelease: targetRelease, TargetChannel: targetChannel, LogLevel: logLevel, |
377 | RemoteTestbed: remoteTestbed, Update: update, Rollback: rollback, |
378 | } |
379 | } |
380 | |
381 | // Write writes the config to a file that will be copied to the test bed. |
382 | func (cfg Config) Write() { |
383 | - fmt.Println("Writing test config...") |
384 | - fmt.Println(cfg) |
385 | + tlog.Debugf("Writing test config...") |
386 | + tlog.Debugf("Config: %v", cfg) |
387 | encoded, err := json.Marshal(cfg) |
388 | if err != nil { |
389 | log.Panicf("Error encoding the test config: %v", err) |
390 | |
391 | === modified file '_integration-tests/testutils/config/config_test.go' |
392 | --- _integration-tests/testutils/config/config_test.go 2015-07-31 07:55:33 +0000 |
393 | +++ _integration-tests/testutils/config/config_test.go 2015-10-07 15:29:59 +0000 |
394 | @@ -26,7 +26,7 @@ |
395 | "path/filepath" |
396 | "testing" |
397 | |
398 | - check "gopkg.in/check.v1" |
399 | + "gopkg.in/check.v1" |
400 | ) |
401 | |
402 | // Hook up check.v1 into the "go test" runner |
403 | @@ -46,7 +46,7 @@ |
404 | func testConfigStruct(fileName string) *Config { |
405 | return NewConfig( |
406 | fileName, |
407 | - "testrelease", "testchannel", "testtargetrelease", "testtargetchannel", |
408 | + "testrelease", "testchannel", "testtargetrelease", "testtargetchannel", "info", |
409 | true, true, true) |
410 | } |
411 | func testConfigContents(fileName string) string { |
412 | @@ -56,6 +56,7 @@ |
413 | `"Channel":"testchannel",` + |
414 | `"TargetRelease":"testtargetrelease",` + |
415 | `"TargetChannel":"testtargetchannel",` + |
416 | + `"LogLevel":"info",` + |
417 | `"RemoteTestbed":true,` + |
418 | `"Update":true,` + |
419 | `"Rollback":true` + |
420 | @@ -102,6 +103,7 @@ |
421 | `"Channel":"testchannel",` + |
422 | `"TargetRelease":"testtargetrelease",` + |
423 | `"TargetChannel":"testtargetchannel",` + |
424 | + `"LogLevel":"info",` + |
425 | `"RemoteTestbed":false,` + |
426 | `"Update":true,` + |
427 | `"Rollback":true` + |
428 | @@ -113,7 +115,7 @@ |
429 | |
430 | testConfigStruct := NewConfig( |
431 | configFileName, |
432 | - "testrelease", "testchannel", "testtargetrelease", "testtargetchannel", |
433 | + "testrelease", "testchannel", "testtargetrelease", "testtargetchannel", "info", |
434 | false, true, true) |
435 | |
436 | c.Assert(err, check.IsNil, check.Commentf("Error reading config: %v", err)) |
437 | |
438 | === modified file '_integration-tests/testutils/image/image.go' |
439 | --- _integration-tests/testutils/image/image.go 2015-09-15 09:33:22 +0000 |
440 | +++ _integration-tests/testutils/image/image.go 2015-10-07 15:29:59 +0000 |
441 | @@ -20,11 +20,11 @@ |
442 | package image |
443 | |
444 | import ( |
445 | - "fmt" |
446 | "path/filepath" |
447 | "strings" |
448 | |
449 | "launchpad.net/snappy/_integration-tests/testutils" |
450 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
451 | ) |
452 | |
453 | // Image type encapsulates image actions |
454 | @@ -42,7 +42,7 @@ |
455 | |
456 | // UdfCreate forms and executes the UDF command for creating the image |
457 | func (img Image) UdfCreate() (string, error) { |
458 | - fmt.Println("Creating image...") |
459 | + tlog.Debugf("Creating image...") |
460 | |
461 | imageDir := filepath.Join(img.baseDir, "image") |
462 | |
463 | |
464 | === modified file '_integration-tests/testutils/partition/partition.go' |
465 | --- _integration-tests/testutils/partition/partition.go 2015-10-02 12:02:16 +0000 |
466 | +++ _integration-tests/testutils/partition/partition.go 2015-10-07 15:29:59 +0000 |
467 | @@ -21,7 +21,6 @@ |
468 | |
469 | import ( |
470 | "bufio" |
471 | - "fmt" |
472 | "regexp" |
473 | "strings" |
474 | |
475 | @@ -80,7 +79,6 @@ |
476 | for scanner.Scan() { |
477 | fields := strings.Fields(scanner.Text()) |
478 | if match, _ := regexp.MatchString("^[0-9]+w$", fields[3]); match { |
479 | - fmt.Printf("match! %s", fields[3]) |
480 | return fields[3], nil |
481 | } |
482 | } |
483 | |
484 | === modified file '_integration-tests/testutils/testutils.go' |
485 | --- _integration-tests/testutils/testutils.go 2015-07-28 12:45:05 +0000 |
486 | +++ _integration-tests/testutils/testutils.go 2015-10-07 15:29:59 +0000 |
487 | @@ -20,11 +20,12 @@ |
488 | package testutils |
489 | |
490 | import ( |
491 | - "fmt" |
492 | "log" |
493 | "os" |
494 | "os/exec" |
495 | "strings" |
496 | + |
497 | + "launchpad.net/snappy/_integration-tests/testutils/tlog" |
498 | ) |
499 | |
500 | // PrepareTargetDir creates the given target directory, removing it previously if it didn't exist |
501 | @@ -47,7 +48,7 @@ |
502 | |
503 | // ExecCommand executes the given command and pipes the results to os.Stdout and os.Stderr, returning the resulting error |
504 | func ExecCommand(cmds ...string) error { |
505 | - fmt.Println(strings.Join(cmds, " ")) |
506 | + tlog.Debugf(strings.Join(cmds, " ")) |
507 | |
508 | cmd := exec.Command(cmds[0], cmds[1:]...) |
509 | cmd.Stdout = os.Stdout |
510 | |
511 | === added directory '_integration-tests/testutils/tlog' |
512 | === added file '_integration-tests/testutils/tlog/tlog.go' |
513 | --- _integration-tests/testutils/tlog/tlog.go 1970-01-01 00:00:00 +0000 |
514 | +++ _integration-tests/testutils/tlog/tlog.go 2015-10-07 15:29:59 +0000 |
515 | @@ -0,0 +1,101 @@ |
516 | +// -*- Mode: Go; indent-tabs-mode: t -*- |
517 | + |
518 | +/* |
519 | + * Copyright (C) 2015 Canonical Ltd |
520 | + * |
521 | + * This program is free software: you can redistribute it and/or modify |
522 | + * it under the terms of the GNU General Public License version 3 as |
523 | + * published by the Free Software Foundation. |
524 | + * |
525 | + * This program is distributed in the hope that it will be useful, |
526 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
527 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
528 | + * GNU General Public License for more details. |
529 | + * |
530 | + * You should have received a copy of the GNU General Public License |
531 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
532 | + * |
533 | + */ |
534 | + |
535 | +package tlog |
536 | + |
537 | +import ( |
538 | + "fmt" |
539 | + "io" |
540 | + "os" |
541 | +) |
542 | + |
543 | +// Level represents the logging level |
544 | +type Level uint8 |
545 | + |
546 | +// ErrLogLevel is returned when a not recognized textual log level is passed |
547 | +// to SetTextLevel |
548 | +type ErrLogLevel struct { |
549 | + s string |
550 | +} |
551 | + |
552 | +func (e *ErrLogLevel) Error() string { |
553 | + return fmt.Sprintf("The level %s is not supported", e.s) |
554 | +} |
555 | + |
556 | +const ( |
557 | + // InfoLevel is the less verbose mode |
558 | + InfoLevel Level = iota |
559 | + // DebugLevel is the most verbose mode |
560 | + DebugLevel |
561 | +) |
562 | + |
563 | +// Logger is the type of the internal instance holding the state |
564 | +type Logger struct { |
565 | + output io.Writer // the output goes through this writer |
566 | + level Level // log level, functions with a level below this won't write to output |
567 | +} |
568 | + |
569 | +// this variable carries the underlaying state of the logger |
570 | +var l = &Logger{output: os.Stdout, level: DebugLevel} |
571 | + |
572 | +// GetOutput is the getter for the output writter |
573 | +func GetOutput() io.Writer { |
574 | + return l.output |
575 | +} |
576 | + |
577 | +// SetOutput is the setter for the output writter |
578 | +func SetOutput(w io.Writer) { |
579 | + l.output = w |
580 | +} |
581 | + |
582 | +// GetLevel is the getter for the log level |
583 | +func GetLevel() Level { |
584 | + return l.level |
585 | +} |
586 | + |
587 | +// SetLevel is the getter for the log level |
588 | +func SetLevel(lvl Level) { |
589 | + l.level = lvl |
590 | +} |
591 | + |
592 | +// SetTextLevel is the getter for the log level |
593 | +func SetTextLevel(s string) (err error) { |
594 | + switch s { |
595 | + case "info": |
596 | + SetLevel(InfoLevel) |
597 | + return |
598 | + case "debug": |
599 | + SetLevel(DebugLevel) |
600 | + return |
601 | + default: |
602 | + return &ErrLogLevel{s} |
603 | + } |
604 | +} |
605 | + |
606 | +// Debugf outputs debug messages |
607 | +func Debugf(format string, args ...interface{}) { |
608 | + if l.level >= DebugLevel { |
609 | + fmt.Fprintf(l.output, format+"\n", args...) |
610 | + } |
611 | +} |
612 | + |
613 | +// Infof outputs info messages |
614 | +func Infof(format string, args ...interface{}) { |
615 | + fmt.Fprintf(l.output, format+"\n", args...) |
616 | +} |
617 | |
618 | === added file '_integration-tests/testutils/tlog/tlog_test.go' |
619 | --- _integration-tests/testutils/tlog/tlog_test.go 1970-01-01 00:00:00 +0000 |
620 | +++ _integration-tests/testutils/tlog/tlog_test.go 2015-10-07 15:29:59 +0000 |
621 | @@ -0,0 +1,145 @@ |
622 | +// -*- Mode: Go; indent-tabs-mode: t -*- |
623 | + |
624 | +/* |
625 | + * Copyright (C) 2015 Canonical Ltd |
626 | + * |
627 | + * This program is free software: you can redistribute it and/or modify |
628 | + * it under the terms of the GNU General Public License version 3 as |
629 | + * published by the Free Software Foundation. |
630 | + * |
631 | + * This program is distributed in the hope that it will be useful, |
632 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
633 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
634 | + * GNU General Public License for more details. |
635 | + * |
636 | + * You should have received a copy of the GNU General Public License |
637 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
638 | + * |
639 | + */ |
640 | + |
641 | +package tlog |
642 | + |
643 | +import ( |
644 | + "bytes" |
645 | + "fmt" |
646 | + "os" |
647 | + "testing" |
648 | + |
649 | + "gopkg.in/check.v1" |
650 | +) |
651 | + |
652 | +// Hook up check.v1 into the "go test" runner |
653 | +func Test(t *testing.T) { check.TestingT(t) } |
654 | + |
655 | +// Different suite so that we don't initialize fields |
656 | +// of the subject and can do assertions on the default |
657 | +// values |
658 | +type logTestDefaultValuesSuite struct { |
659 | +} |
660 | + |
661 | +var _ = check.Suite(&logTestDefaultValuesSuite{}) |
662 | + |
663 | +func (s *logTestDefaultValuesSuite) TestDefaultOutput(c *check.C) { |
664 | + output := GetOutput() |
665 | + |
666 | + c.Assert(output, check.Equals, os.Stdout) |
667 | +} |
668 | + |
669 | +func (s *logTestDefaultValuesSuite) TestDefaultLevel(c *check.C) { |
670 | + level := GetLevel() |
671 | + |
672 | + c.Assert(level, check.Equals, DebugLevel) |
673 | +} |
674 | + |
675 | +type logTestSuite struct { |
676 | + output bytes.Buffer |
677 | +} |
678 | + |
679 | +var _ = check.Suite(&logTestSuite{}) |
680 | + |
681 | +func (s *logTestSuite) SetUpSuite(c *check.C) { |
682 | + SetOutput(&s.output) |
683 | +} |
684 | + |
685 | +func (s *logTestSuite) SetUpTest(c *check.C) { |
686 | + s.output.Reset() |
687 | + SetLevel(DebugLevel) |
688 | +} |
689 | + |
690 | +func (s *logTestSuite) TestLogWritesDebugOutput(c *check.C) { |
691 | + msg := "this is a debug message" |
692 | + Debugf(msg) |
693 | + |
694 | + c.Assert(s.output.String(), check.Equals, msg+"\n") |
695 | +} |
696 | + |
697 | +func (s *logTestSuite) TestLogDoesNotWritesDebugOutputWhenLevelIsInfo(c *check.C) { |
698 | + msg := "this is a debug message" |
699 | + |
700 | + SetLevel(InfoLevel) |
701 | + Debugf(msg) |
702 | + |
703 | + c.Assert(s.output.String(), check.Equals, "") |
704 | +} |
705 | + |
706 | +func (s *logTestSuite) TestLogWritesDebugOutputWithFormat(c *check.C) { |
707 | + msg := "this is a debug message with %d %s" |
708 | + par1 := 2 |
709 | + par2 := "parameters" |
710 | + expected := "this is a debug message with 2 parameters\n" |
711 | + |
712 | + Debugf(msg, par1, par2) |
713 | + |
714 | + c.Assert(s.output.String(), check.Equals, expected) |
715 | +} |
716 | + |
717 | +func (s *logTestSuite) TestLogWritesInfoOutput(c *check.C) { |
718 | + msg := "this is a info message" |
719 | + Infof(msg) |
720 | + |
721 | + c.Assert(s.output.String(), check.Equals, msg+"\n") |
722 | +} |
723 | + |
724 | +func (s *logTestSuite) TestLogWritesInfoOutputWithFormat(c *check.C) { |
725 | + msg := "this is a info message with %d %s" |
726 | + par1 := 2 |
727 | + par2 := "parameters" |
728 | + expected := "this is a info message with 2 parameters\n" |
729 | + |
730 | + Infof(msg, par1, par2) |
731 | + |
732 | + c.Assert(s.output.String(), check.Equals, expected) |
733 | +} |
734 | + |
735 | +func (s *logTestSuite) TestSetTextLevel(c *check.C) { |
736 | + currentLvl := GetLevel() |
737 | + defer SetLevel(currentLvl) |
738 | + testCases := []struct { |
739 | + textLvl string |
740 | + level Level |
741 | + }{{"info", InfoLevel}, |
742 | + {"debug", DebugLevel}, |
743 | + } |
744 | + for _, testCase := range testCases { |
745 | + err := SetTextLevel(testCase.textLvl) |
746 | + lvl := GetLevel() |
747 | + |
748 | + c.Check(err, check.IsNil) |
749 | + c.Check(lvl, check.Equals, testCase.level) |
750 | + } |
751 | +} |
752 | + |
753 | +func (s *logTestSuite) TestSetWrongTextLevel(c *check.C) { |
754 | + currentLvl := GetLevel() |
755 | + defer SetLevel(currentLvl) |
756 | + |
757 | + wrongLvl := "not-supported-level" |
758 | + |
759 | + err := SetTextLevel(wrongLvl) |
760 | + lvl := GetLevel() |
761 | + |
762 | + c.Assert(err.Error(), check.Equals, |
763 | + fmt.Sprintf("The level %s is not supported", wrongLvl)) |
764 | + |
765 | + c.Assert(lvl, check.Equals, currentLvl) |
766 | +} |
Thanks for working on this.
I'm wondering if we should use log.Print instead of fmt.Fprint. I've never done logging in go before, so I think it would be nice to get a review from mvo, sergio or chipaca. Can you please ask one of them tomorrow to take a quick look?