Merge lp:~javier.collado/utah/bug1082074 into lp:utah

Proposed by Javier Collado
Status: Merged
Approved by: Javier Collado
Approved revision: 761
Merged at revision: 759
Proposed branch: lp:~javier.collado/utah/bug1082074
Merge into: lp:utah
Diff against target: 95 lines (+23/-18)
1 file modified
utah/run.py (+23/-18)
To merge this branch: bzr merge lp:~javier.collado/utah/bug1082074
Reviewer Review Type Date Requested Status
Max Brustkern (community) Approve
Javier Collado (community) Needs Resubmitting
Review via email: mp+135732@code.launchpad.net

Description of the change

This branch uses that return code from the utah client as the return code for
the server. This way, failures in the client can be detected easily in jenkins.

Aside from this, a few pep8 warnings and a refactoring on the client log
filename has been committed (look into the changes for further detail).

To post a comment you must log in.
Revision history for this message
Max Brustkern (nuclearbob) wrote :

The way the scripts are currently setup, we can execute more than one runlist. If the first runlist fails and the second runlist passes, I think exitstatus will be 0 with this merge proposal.

Revision history for this message
Javier Collado (javier.collado) wrote :

Yes, you're right, exitstatus will be overwritten with the result of machine.run
for every runlist.

What I can do is keep the return code for all runs and do something like this:
retuncode = int(any(returncodes))

this way if the client returns a failure in any runlist, then the server will
return 1. Otherwise, it will return 0.

Would that be fine?

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Yep, that should work, as long as you also capture the bit under the except: that sets the exit status to 1 when we can't run a runlist (line 28 of the merge.)

lp:~javier.collado/utah/bug1082074 updated
761. By Javier Collado

Collect exitstatus for each runlist and return 0 only if all runs were successful

Moved code inside runlist loop to a function so that the returned value from
the function can be used as the returned value from the client.

Revision history for this message
Javier Collado (javier.collado) wrote :

Code updated to get the exitstatus for each runlist and return 0 only if the
execution of all runlists was successful.

review: Needs Resubmitting
Revision history for this message
Max Brustkern (nuclearbob) wrote :

Line 57 of the merge skips over this:

        machine.logger.info('Test log copied to ' + locallog)
        locallogs.append(locallog)
        if args.dumplogs:

I don't think locallogs is in scope for your new _run function, so I don't think any client logs will be returned at the end of the run_tests function (line 72 of the merge.)

review: Needs Fixing
Revision history for this message
Javier Collado (javier.collado) wrote :

_run is defined inside run_test, not as a separate function, so all the
variables in the latter are available are available when looking in the outer
scope.

I've executed a simple runlist and didn't get any error, but if there's some
other way to better exercise the code, let me know and I'll run the test.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Okay, I guess I need to brush up on my variable scoping. If you can execute two runlists and it returns logs for both of them, then we should be in good shape.

review: Approve
Revision history for this message
Javier Collado (javier.collado) wrote :

Yes, I've executed the pass runlist twice and it has worked fine (maybe utah
should have detected the duplicated runlist, but for the purpose of the test,
it was fine).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'utah/run.py'
2--- utah/run.py 2012-11-16 21:17:32 +0000
3+++ utah/run.py 2012-11-27 11:58:36 +0000
4@@ -21,38 +21,39 @@
5
6 if args.json:
7 extraopts = ' -f json'
8- suffix = '.json'
9+ suffix = 'json'
10 else:
11 extraopts = ''
12- suffix = '.yaml'
13+ suffix = 'yaml'
14
15 locallogs = []
16- exitstatus = 0
17
18 machine.installclient()
19
20 extraopts += " --install-type " + machine.installtype
21
22- for runlist in args.runlists:
23+ def _run(runlist):
24+ """Run a single runlist."""
25 locallist = urllib.urlretrieve(runlist)[0]
26 machine.uploadfiles([locallist], os.path.normpath('/tmp'))
27
28 options = ' -r /tmp/' + os.path.basename(locallist)
29 utah_command = 'utah' + extraopts + options
30 try:
31- _returncode, stdout, _stderr = machine.run(utah_command, root=True)
32- # TODO: Decide which returncode means utah client failure
33- # and which one means test case failure
34+ # Server will return same code as client
35+ exitstatus, stdout, _stderr = machine.run(utah_command, root=True)
36 except UTAHException as error:
37 machine.logger.error('Failed to run test: ' + str(error))
38- exitstatus = 1
39- break
40+ return 1
41
42 listname = os.path.basename(runlist)
43- locallog = os.path.join(config.logpath,
44- machine.name + '_' + listname
45- + time.strftime('_%Y-%m-%d_%H-%m-%S', time.gmtime())
46- + suffix)
47+ timestamp = time.strftime('%Y-%m-%d_%H-%m-%S', time.gmtime())
48+ log_filename = ('{machine}_{runlist}_{timestamp}.{suffix}'
49+ .format(machine=machine.name,
50+ runlist=listname,
51+ timestamp=timestamp,
52+ suffix=suffix))
53+ locallog = os.path.join(config.logpath, log_filename)
54 locallog = os.path.normpath(locallog)
55 with open(locallog, 'w') as f:
56 f.write(stdout)
57@@ -62,6 +63,11 @@
58 with open(locallog, 'r') as f:
59 print(f.read())
60
61+ return exitstatus
62+
63+ exitstatuses = [_run(runlist) for runlist in args.runlists]
64+ exitstatus = int(any(exitstatuses))
65+
66 if args.files is not None:
67 try:
68 locallogs += getfiles(args, machine)
69@@ -69,8 +75,8 @@
70 machine.logger.warning('Failed to download files: ' + str(err))
71
72 return exitstatus, locallogs
73-
74-
75+
76+
77 def getfiles(args, machine):
78 if args.outdir is None:
79 outdir = os.path.join(config.logpath, machine.name)
80@@ -80,13 +86,12 @@
81 os.makedirs(outdir)
82
83 machine.downloadfilesrecursive(args.files, outdir)
84-
85+
86 localfiles = []
87-
88+
89 for mydir, dirs, files in os.walk(outdir):
90 myfiles = [os.path.join(mydir, x) for x in files]
91 for myfile in myfiles:
92 localfiles.append(myfile)
93
94 return localfiles
95-

Subscribers

People subscribed via source and target branches