Merge ~pwlars/testflinger-agent:fix-empty-sections-exception into testflinger-agent:master

Proposed by Paul Larson
Status: Merged
Approved by: Paul Larson
Approved revision: eaf55c25242a8e5c49008576f676adc3b212d609
Merged at revision: 7eb7331bbc6b4b16c38ecb38c1a9cdf406f1c934
Proposed branch: ~pwlars/testflinger-agent:fix-empty-sections-exception
Merge into: testflinger-agent:master
Diff against target: 99 lines (+24/-10)
3 files modified
testflinger_agent/job.py (+3/-3)
testflinger_agent/tests/test_agent.py (+7/-7)
testflinger_agent/tests/test_job.py (+14/-0)
Reviewer Review Type Date Requested Status
Sheila Miguez (community) Approve
Review via email: mp+414824@code.launchpad.net

Description of the change

We already support the idea of skipping a section if it's missing (ex. if you want to skip provision, simply leave out the provisioning section). however I also noticed today that if you leave out the data in the provisioning section, it gives you a pretty confusing error.

Now, if it's present but doesn't have anything in it, it should result in the same sort of non-fatal message that happens when the section is missing completely. However it will still try to do the other parts of the job that it can.

To post a comment you must log in.
Revision history for this message
Sheila Miguez (codersquid) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/testflinger_agent/job.py b/testflinger_agent/job.py
2index b76dfdc..b717d32 100644
3--- a/testflinger_agent/job.py
4+++ b/testflinger_agent/job.py
5@@ -55,13 +55,13 @@ class TestflingerJob:
6 if not cmd:
7 logger.info('No %s_command configured, skipping...', phase)
8 return 0
9- if phase == 'provision' and 'provision_data' not in self.job_data:
10+ if phase == 'provision' and not self.job_data.get('provision_data'):
11 logger.info('No provision_data defined in job data, skipping...')
12 return 0
13- if phase == 'test' and 'test_data' not in self.job_data:
14+ if phase == 'test' and not self.job_data.get('test_data'):
15 logger.info('No test_data defined in job data, skipping...')
16 return 0
17- if phase == 'reserve' and 'reserve_data' not in self.job_data:
18+ if phase == 'reserve' and not self.job_data.get('reserve_data'):
19 return 0
20 output_log = os.path.join(rundir, phase+'.log')
21 serial_log = os.path.join(rundir, phase+'-serial.log')
22diff --git a/testflinger_agent/tests/test_agent.py b/testflinger_agent/tests/test_agent.py
23index 496dbe3..e9ce10c 100644
24--- a/testflinger_agent/tests/test_agent.py
25+++ b/testflinger_agent/tests/test_agent.py
26@@ -52,7 +52,7 @@ class TestClient:
27 self.config['provision_command'] = 'echo provision1'
28 fake_job_data = {'job_id': str(uuid.uuid1()),
29 'job_queue': 'test',
30- 'provision_data': ''}
31+ 'provision_data': {'url': 'foo'}}
32 requests_mock.get(rmock.ANY, [{'text': json.dumps(fake_job_data)},
33 {'text': '{}'}])
34 requests_mock.post(rmock.ANY, status_code=200)
35@@ -67,7 +67,7 @@ class TestClient:
36 self.config['test_command'] = 'echo test1'
37 fake_job_data = {'job_id': str(uuid.uuid1()),
38 'job_queue': 'test',
39- 'test_data': ''}
40+ 'test_data': {'test_cmds': 'foo'}}
41 requests_mock.get(rmock.ANY, [{'text': json.dumps(fake_job_data)},
42 {'text': '{}'}])
43 requests_mock.post(rmock.ANY, status_code=200)
44@@ -82,7 +82,7 @@ class TestClient:
45 self.config['test_command'] = 'echo test_string is $test_string'
46 fake_job_data = {'job_id': str(uuid.uuid1()),
47 'job_queue': 'test',
48- 'test_data': ''}
49+ 'test_data': {'test_cmds': 'foo'}}
50 requests_mock.get(rmock.ANY, [{'text': json.dumps(fake_job_data)},
51 {'text': '{}'}])
52 requests_mock.post(rmock.ANY, status_code=200)
53@@ -99,8 +99,8 @@ class TestClient:
54 self.config['test_command'] = 'echo test1'
55 fake_job_data = {'job_id': str(uuid.uuid1()),
56 'job_queue': 'test',
57- 'provision_data': '',
58- 'test_data': ''}
59+ 'provision_data': {'url': 'foo'},
60+ 'test_data': {'test_cmds': 'foo'}}
61 requests_mock.get(rmock.ANY, [{'text': json.dumps(fake_job_data)},
62 {'text': '{}'}])
63 requests_mock.post(rmock.ANY, status_code=200)
64@@ -153,8 +153,8 @@ class TestClient:
65 job_id = str(uuid.uuid1())
66 fake_job_data = {'job_id': job_id,
67 'job_queue': 'test',
68- 'provision_data': '',
69- 'test_data': ''}
70+ 'provision_data': {'url': 'foo'},
71+ 'test_data': {'test_cmds': 'foo'}}
72 # In this case we are making sure that the repost job request
73 # gets good status
74 with rmock.Mocker() as m:
75diff --git a/testflinger_agent/tests/test_job.py b/testflinger_agent/tests/test_job.py
76index 481e7b4..bb70c22 100644
77--- a/testflinger_agent/tests/test_job.py
78+++ b/testflinger_agent/tests/test_job.py
79@@ -38,6 +38,20 @@ class TestJob():
80 log_output = log.read()
81 assert("No provision_data defined in job data" in log_output)
82
83+ def test_skip_empty_provision_data(self, client):
84+ """
85+ Test that provision phase is skipped when provision_data is
86+ present but empty
87+ """
88+ self.config['provision_command'] = '/bin/true'
89+ fake_job_data = {'global_timeout': 1, 'provision_data': ''}
90+ job = _TestflingerJob(fake_job_data, client)
91+ job.run_test_phase('provision', None)
92+ logfile = os.path.join(self.tmpdir, 'testflinger-agent.log')
93+ with open(logfile) as log:
94+ log_output = log.read()
95+ assert("No provision_data defined in job data" in log_output)
96+
97 def test_job_global_timeout(self, client, requests_mock):
98 """Test that timeout from job_data is respected"""
99 timeout_str = '\nERROR: Global timeout reached! (1s)\n'

Subscribers

People subscribed via source and target branches