Merge lp:~gmb/maas-test/dont-report-successes into lp:maas-test

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: 115
Merged at revision: 115
Proposed branch: lp:~gmb/maas-test/dont-report-successes
Merge into: lp:maas-test
Diff against target: 207 lines (+56/-65)
3 files modified
maastest/main.py (+5/-2)
maastest/report.py (+25/-23)
maastest/tests/test_report.py (+26/-40)
To merge this branch: bzr merge lp:~gmb/maas-test/dont-report-successes
Reviewer Review Type Date Requested Status
Julian Edwards (community) Disapprove
Raphaël Badin (community) Approve
Review via email: mp+201019@code.launchpad.net

Commit message

Only report to Launchpad on failure; always log on success (unless told otherwise).

Description of the change

This branch changes the way that reporting works so that we only report to Launchpad on failure, but always store the test results unless told not to.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Looks good.

On the one hand, I think that the code is better structured this way (having the control of whether or not things are logged in the main execution flow and all the actual work done in helper methods) but on the other hand, it means part of the code escaped in non-tested territory. Oh well, this is still probably for the best.

[0]

96 + "Visit https://bugs.launchpad.net/maas/+filebug/%s "
97 + "to file a bug and complete the maas-test reporting process."

Btw, this is unrelated to this change but I was wondering if we could pre-fill the title of the bug somehow. Do you know if it's possible? If it is, it would be nice because —unless the user changes it of course— it would enable us to quickly spot if a bug has been submitted because of a failed maas-test run; it would be even better if we could attach a tag to it.

review: Approve
Revision history for this message
Graham Binns (gmb) wrote :

On 9 January 2014 15:27, Raphaël Badin <email address hidden> wrote:
> Btw, this is unrelated to this change but I was wondering if we could pre-fill the title of the bug somehow. Do you know if it's possible? If it is, it would be nice because —unless the user changes it of course— it would enable us to quickly spot if a bug has been submitted because of a failed maas-test run; it would be even better if we could attach a tag to it.

We can — and we did, in my initial branch, but we dropped it IIRC. We
already tag it with "maas-test-results". Do you think just pre-filling
it with "maas-test failure" would be sufficient? We can always update
the title to be more specific later.

Revision history for this message
Raphaël Badin (rvb) wrote :

> We can — and we did, in my initial branch, but we dropped it IIRC. We
> already tag it with "maas-test-results". Do you think just pre-filling
> it with "maas-test failure" would be sufficient? We can always update
> the title to be more specific later.

Yeah, "maas-test failure" sounds like a good start.

115. By Graham Binns

Added subject header.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

While I appreciate we don't necessarily want to file bugs for successes, the point of maas-test is that we DO report successes *somewhere*. Since we don't have somewhere else, I am afraid this branch should be reverted.

review: Disapprove
Revision history for this message
Graham Binns (gmb) wrote :

Warning: early-morning shambolic rambling ahead:

On 10 January 2014 00:57, Julian Edwards <email address hidden> wrote:
> Review: Disapprove
>
> While I appreciate we don't necessarily want to file bugs for
> successes, the point of maas-test is that we DO report successes
> *somewhere*. Since we don't have somewhere else, I am afraid this
> branch should be reverted.

Okay, I can see that recording successes has some value — maybe more
value than I realise beyond the "look at everything that works with
MAAS" marketing standpoint. But do we _really_ want to have every
success captured?

I suppose we could file them as "Fix Released" :). (Assuming LP lets you
do that).

My argument's a little fuzzy here — hey, it's 07:24 and I haven't
finished my first cup of tea yet — but here goes:

 1. We want to record all test runs, be they pass or failure.
 2. However, passes all look the same
 3. That means that we'd end up with a lot of duplicate bugs
 4. Worse, de-duping them will be really hard because there's nothing
    unique about the reports. (In fact this applies to failures as well
    as successes — imagine if 10 companies try maas-test on similar but
    subtly different hardware).
 5. Actually, then, my argument isn't "we shouldn't report successes" at
    all; in fact, my argument is "maas-test reports should carry some
    identifying information as standard so that de-duping is easier".
 6. If that were true, I'd be fine with reverting this; at the moment
    I'm -0 at the most.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

We do need to report success, so some way of IDing the test run on a
hardware basis would be the best way forwards here (and then dupe on that).

Revision history for this message
Graham Binns (gmb) wrote :

On 10 January 2014 09:27, Julian Edwards <email address hidden> wrote:
> We do need to report success, so some way of IDing the test run on a
> hardware basis would be the best way forwards here (and then dupe on that).

+1. I'll revert this branch for starters.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On 10/01/14 19:42, Graham Binns wrote:
> On 10 January 2014 09:27, Julian Edwards <email address hidden> wrote:
>> We do need to report success, so some way of IDing the test run on a
>> hardware basis would be the best way forwards here (and then dupe on that).
>
> +1. I'll revert this branch for starters.
>

Thanks. Sorry I wasn't around to put you off in the first place, I keep
assuming everyone knows everything... and you know what they say about
assumptions.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'maastest/main.py'
2--- maastest/main.py 2014-01-09 11:35:01 +0000
3+++ maastest/main.py 2014-01-09 16:05:20 +0000
4@@ -96,14 +96,17 @@
5 ConfiguredTestMAAS.tearDownClass()
6 raise
7 from maastest import report
8+
9 encoded_results = (
10 output_stream.cache.getvalue().encode('utf-8'))
11 if not args.no_reporting:
12- report.report_test_results(
13- encoded_results, log_only=args.log_results_only)
14+ report.write_test_results(encoded_results)
15+
16 if result.wasSuccessful():
17 return RETURN_CODES.SUCCESS
18 else:
19+ if not args.no_reporting and not args.log_results_only:
20+ report.report_test_results(encoded_results)
21 return RETURN_CODES.TEST_FAILED
22
23
24
25=== modified file 'maastest/report.py'
26--- maastest/report.py 2014-01-09 12:12:32 +0000
27+++ maastest/report.py 2014-01-09 16:05:20 +0000
28@@ -60,6 +60,7 @@
29 launchpad_form_data['tags'] = 'maas-test-results'
30 launchpad_form_data['private'] = 'yes'
31 launchpad_form_data['subscribers'] = "private-canonical-maas"
32+ launchpad_form_data['subject'] = "maas-test failure"
33
34 results_payload = make_file_payload(
35 'maas-test.log', test_results.encode('utf-8', 'replace'))
36@@ -130,48 +131,49 @@
37 return token
38
39
40-def write_test_results(log_file_name, results, log_dir=None):
41+def write_test_results(results, log_file_name=None, log_dir=None, now=None):
42 """Write maas-test results to a file.
43
44- :param log_file_name: The filename to which to write the results.
45 :param results: The results from maas-test.
46+ :param log_file_name: The filename to which to write the results
47+ (used for testing only).
48 :param log_dir: The directory under which to create `log_file_name`.
49+ :param now: The current date/time (used for testing only).
50+ :type now: datetime.datetime.
51 """
52+ if now is None:
53+ now = datetime.utcnow()
54+
55 if log_dir is None:
56 log_dir = DEFAULT_LOG_DIR
57 if not os.path.exists(log_dir):
58 os.makedirs(log_dir)
59
60+ if log_file_name is None:
61+ log_file_name = (
62+ "maas-test.%s.log" % now.strftime("%Y-%m-%d_%H:%M:%S"))
63+
64 log_file_path = os.path.join(log_dir, log_file_name)
65 with open(log_file_path, 'w') as log_file:
66 log_file.write(results)
67+
68 logging.info("Test log saved to %s." % log_file_path)
69
70
71-def report_test_results(results, log_only=False, now=None):
72+def report_test_results(results):
73 """Handle the reporting of maas-test results.
74
75 :param results: The results to report.
76 :param log_only: If True, write the results to a file but don't submit
77 them to Launchpad.
78- :param now: The current date/time (used for testing only).
79- :type now: datetime.datetime.
80 """
81- if now is None:
82- now = datetime.utcnow()
83-
84- log_file_name = (
85- "maas-test.%s.log" % now.strftime("%Y-%m-%d_%H:%M:%S"))
86- write_test_results(log_file_name, results)
87-
88- if not log_only:
89- blob = create_launchpad_blob(results)
90- blob_token = upload_blob(blob)
91- if blob_token is not None:
92- logging.info("Test results uploaded to Launchpad.")
93- logging.info(
94- "Visit https://bugs.launchpad.net/maas/+filebug/%s "
95- "to file a bug and complete the maas-test reporting process."
96- % blob_token)
97- else:
98- logging.info("Unable to store test results on Launchpad.")
99+ blob = create_launchpad_blob(results)
100+ blob_token = upload_blob(blob)
101+ if blob_token is not None:
102+ logging.info("Test results uploaded to Launchpad.")
103+ logging.info(
104+ "Visit https://bugs.launchpad.net/maas/+filebug/%s "
105+ "to file a bug and complete the maas-test reporting process."
106+ % blob_token)
107+ else:
108+ logging.info("Unable to store test results on Launchpad.")
109
110=== modified file 'maastest/tests/test_report.py'
111--- maastest/tests/test_report.py 2014-01-09 12:12:32 +0000
112+++ maastest/tests/test_report.py 2014-01-09 16:05:20 +0000
113@@ -65,6 +65,10 @@
114 blob = report.create_launchpad_blob(self.getUniqueString())
115 self.assertEqual("maas-test-results", blob['tags'])
116
117+ def test_sets_subject_header(self):
118+ blob = report.create_launchpad_blob(self.getUniqueString())
119+ self.assertEqual("maas-test failure", blob['subject'])
120+
121 def test_sets_private_header(self):
122 blob = report.create_launchpad_blob(self.getUniqueString())
123 self.assertEqual("yes", blob['private'])
124@@ -227,43 +231,6 @@
125 % token)
126 ])
127
128- def test_saves_log(self):
129- blob = email.mime.multipart.MIMEMultipart()
130- mock_logger = mock.MagicMock()
131- mock_create_launchpad_blob = mock.MagicMock(return_value=blob)
132- mock_upload_blob = mock.MagicMock()
133- mock_write_test_results = mock.MagicMock()
134-
135- self.patch(logging, 'info', mock_logger)
136- self.patch(report, 'create_launchpad_blob', mock_create_launchpad_blob)
137- self.patch(report, 'upload_blob', mock_upload_blob)
138- self.patch(report, 'write_test_results', mock_write_test_results)
139-
140- results = self.getUniqueString()
141- now = datetime(2013, 12, 17, 7, 18, 0)
142- now_string = now.strftime("%Y-%m-%d_%H:%M:%S")
143- expected_filename = 'maas-test.%s.log' % now_string
144- report.report_test_results(results, now=now)
145- mock_write_test_results.assert_has_calls([
146- mock.call(expected_filename, results)])
147-
148- def test_does_not_upload_blob_if_log_only_set(self):
149- mock_write_test_results = mock.MagicMock()
150- mock_upload_blob = mock.MagicMock()
151-
152- self.patch(report, 'upload_blob', mock_upload_blob)
153- self.patch(report, 'write_test_results', mock_write_test_results)
154-
155- results = self.getUniqueString()
156- now = datetime(2013, 12, 17, 7, 18, 0)
157- now_string = now.strftime("%Y-%m-%d_%H:%M:%S")
158- expected_filename = 'maas-test.%s.log' % now_string
159- report.report_test_results(results, log_only=True, now=now)
160- self.assertIn(
161- mock.call(expected_filename, results),
162- mock_write_test_results.mock_calls)
163- mock_upload_blob.assert_has_calls([])
164-
165
166 class TestWriteTestResults(testtools.TestCase):
167
168@@ -272,7 +239,7 @@
169 results = self.getUniqueString()
170 log_file_name = self.getUniqueString()
171
172- report.write_test_results(log_file_name, results, temp_dir)
173+ report.write_test_results(results, log_file_name, temp_dir)
174
175 with open(os.path.join(temp_dir, log_file_name), 'rb') as log_file:
176 self.assertEqual(results, log_file.read().strip())
177@@ -280,9 +247,28 @@
178 def test_creates_log_dir(self):
179 temp_dir = self.useFixture(TempDir()).path
180 results = self.getUniqueString()
181- log_dir = os.path.join(temp_dir, 'logs')
182+ log_dir = os.path.join(temp_dir, self.getUniqueString())
183 log_file_name = self.getUniqueString()
184
185 self.assertFalse(os.path.exists(log_dir))
186- report.write_test_results(log_file_name, results, log_dir)
187+ report.write_test_results(results, log_file_name, log_dir)
188 self.assertTrue(os.path.exists(log_dir))
189+
190+ def test_saves_log_with_timestamp(self):
191+ temp_dir = self.useFixture(TempDir()).path
192+ results = self.getUniqueString()
193+ mock_logger = mock.MagicMock()
194+
195+ self.patch(logging, 'info', mock_logger)
196+
197+ results = self.getUniqueString()
198+ now = datetime(2013, 12, 17, 7, 18, 0)
199+ now_string = now.strftime("%Y-%m-%d_%H:%M:%S")
200+ expected_filename = 'maas-test.%s.log' % now_string
201+ expected_file_path = os.path.join(temp_dir, expected_filename)
202+ report.write_test_results(results, log_dir=temp_dir, now=now)
203+ self.assertIn(
204+ mock.call("Test log saved to %s." % expected_file_path),
205+ mock_logger.mock_calls
206+ )
207+ self.assertTrue(os.path.exists(expected_file_path))

Subscribers

People subscribed via source and target branches