Merge ~mertkirpici/charm-hw-health:lp/1928403 into charm-hw-health:master
- Git
- lp:~mertkirpici/charm-hw-health
- lp/1928403
- Merge into master
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Eric Chen | ||||
Approved revision: | 612a1bd1ee05ce9139aafdd7d86fcf6318eed80e | ||||
Merged at revision: | cdc5bce8035b5cfceafda258e676bb0119ef29f8 | ||||
Proposed branch: | ~mertkirpici/charm-hw-health:lp/1928403 | ||||
Merge into: | charm-hw-health:master | ||||
Diff against target: |
483 lines (+153/-136) 6 files modified
src/actions/actions.py (+31/-13) src/lib/hwhealth/tools.py (+16/-10) src/tests/functional/test_hwhealth.py (+0/-98) src/tests/unit/test_actions.py (+92/-0) src/tests/unit/test_ipmi_sensor.py (+14/-14) src/tox.ini (+0/-1) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eric Chen | Approve | ||
Facundo Ciccioli | Approve | ||
🤖 prod-jenkaas-bootstack (community) | continuous-integration | Approve | |
JamesLin | Approve | ||
BootStack Reviewers | Pending | ||
Review via email: mp+431836@code.launchpad.net |
Commit message
Close LP #1928403
Description of the change
Since the ipmi-sel option "--date-range" has a resolution of 1 day, the ack-sel action used to fail acknowledging the entries on the same day. With this change we are trying to figure out the last entry id and use that to exclude the entries up to that point.
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
PASSED: Continuous integration, rev:62a7337ebc7
https:/
Executed test runs:
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
JamesLin (jneo8) wrote : | # |
Appropriate update to fix the issue. But I would like have more information inside the source code's comment.
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
PASSED: Continuous integration, rev:ab5a1f83995
https:/
Executed test runs:
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Mert Kirpici (mertkirpici) wrote : | # |
Hey James, thanks for the review. I pushed an update that adds typing info and docstrings like you suggested.
Eric Chen (eric-chen) wrote : | # |
Please see my inline question. thanks
Eric Chen (eric-chen) wrote (last edit ): | # |
One of my comment disappear.. weird.. I will leave it again. Please wait a moment.
Eric Chen (eric-chen) wrote : | # |
Please see my inline question. thanks
Mert Kirpici (mertkirpici) wrote : | # |
Hi Eric, thanks for the review. I tried to answer your questions/comments to the best of my understanding. Please see below.
Eric Chen (eric-chen) wrote : | # |
LGTM, but wait for 1 more COE to review it.
Facundo Ciccioli (fandanbango) wrote : | # |
This looks amazing to me. The only caveat I can think of is that a config change may implicitly ack SELs since the last ack-sel. I'd say this is very unlikely, but could happen:
If this is done within the same UTC day:
1. New SEL entries
2. Operator runs the ack-sel action
3. New SEL entires
4. A config change is made
then the new SEL entries on 3. are implicitly acked.
Then again, this would seldom happen, as whenever we receive an IPMI alert we check it and it'd be a huge coincidence if a config change is made while we are investigating (can only think of a colleague doing some unrelated work concurrently).
Still, it is unexpected and we've spotted it, hence if there's a simple way to fix it then maybe we might?
I believe if we can easily check if the code's running as part of an action then that check could be added to line 805 on tools.py:
def install_
date_filter = unitdata.
805 -> if date_filter:
)
Thoughts?
Mert Kirpici (mertkirpici) wrote : | # |
Hi Facundo thanks for the review and thoughts.
> Thoughts?
This is a very good catch! Thanks for bringing this up.
As rare as this scenario might be I think if we could avoid it, we should. I am thinking around two solutions:
1 - Introducing a `force=False` parameter in the Ipmi::install_
2 - Delegating the max record id getting code to the action code and storing _that_ in the unit data rather than the date. This will render everything static(nothing getting figured out during charm runtime after the action call completes). This is somewhat a bigger change(unit data key, purpose changing, etc.) however I think it is the proper way to implement this change.
I am inclined to push an update towards option 2. Is there anything I am missing here?
Facundo Ciccioli (fandanbango) wrote : | # |
> Hi Facundo thanks for the review and thoughts.
>
> > Thoughts?
> This is a very good catch! Thanks for bringing this up.
> As rare as this scenario might be I think if we could avoid it, we should. I
> am thinking around two solutions:
>
> 1 - Introducing a `force=False` parameter in the Ipmi::install_
> signature . That will be checked alongside the date_filter variable that
> you're pointing out. Only the action code will set it to True when calling,
> i.e. Ipmi().
> to fix this however it smells like bad design to me.
>
> 2 - Delegating the max record id getting code to the action code and storing
> _that_ in the unit data rather than the date. This will render everything
> static(nothing getting figured out during charm runtime after the action call
> completes). This is somewhat a bigger change(unit data key, purpose changing,
> etc.) however I think it is the proper way to implement this change.
>
> I am inclined to push an update towards option 2. Is there anything I am
> missing here?
I'd really prefer telling you to go for option 1. as it's simpler, and I wouldn't invest time in implementing the "right" option for a charm like this one which has a death sentence in the wake of the COS.
*But*, I believe option 1 doesn't cut, as it breaks in other ways. If a config-changed is triggered, then add_exclude_
Option 2. is, like you say, the way to go. We only care about the record ID up to which we're ignoring, and the action code is the only one which should mess around with it.
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
FAILED: Continuous integration, rev:9e8b0d0adc1
https:/
Executed test runs:
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
PASSED: Continuous integration, rev:2dff736e15b
https:/
Executed test runs:
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
FAILED: Continuous integration, rev:188386ec4c3
https:/
Executed test runs:
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote : | # |
PASSED: Continuous integration, rev:612a1bd1ee0
https:/
Executed test runs:
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Facundo Ciccioli (fandanbango) wrote : | # |
Looks good! Too bad about the tests going away, the alternatives I can think of are probably worse than not having tests...
Eric Chen (eric-chen) : | # |
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision cdc5bce8035b5cf
Preview Diff
1 | diff --git a/src/actions/actions.py b/src/actions/actions.py |
2 | index 62b2b50..6f1e342 100755 |
3 | --- a/src/actions/actions.py |
4 | +++ b/src/actions/actions.py |
5 | @@ -59,9 +59,9 @@ def show_sel(): |
6 | show_all = action_get("show-all") |
7 | command = [IPMI_SEL, "--output-event-state"] |
8 | |
9 | - date_start = unitdata.kv().get(tools.Ipmi.SEL_DATE_FILTER_START_KEY) |
10 | - if date_start: |
11 | - command.extend(["--date-range", "{}-now".format(date_start)]) |
12 | + max_record_id = unitdata.kv().get(tools.Ipmi.SEL_EXCLUDE_RANGE_MAX_KEY) |
13 | + if max_record_id: |
14 | + command.extend(["--exclude-display-range", "1-{}".format(max_record_id)]) |
15 | |
16 | try: |
17 | header, body = None, None |
18 | @@ -74,8 +74,8 @@ def show_sel(): |
19 | body = [line for line in body if "Nominal" not in line] |
20 | if body: |
21 | final_output = "\n".join([header] + body) |
22 | - if date_start: |
23 | - final_output += "Has been date filtered: {}".format(date_start) |
24 | + if max_record_id: |
25 | + final_output += "Has been id filtered: {}".format(max_record_id) |
26 | else: |
27 | final_output = "No matching entries found" |
28 | log("Action show-sel completed:\n{}".format(final_output)) |
29 | @@ -84,12 +84,31 @@ def show_sel(): |
30 | action_fail("Action failed with {}".format(e)) |
31 | |
32 | |
33 | +def _get_sel_max_event_id_for_date(date): |
34 | + try: |
35 | + output = subprocess.check_output( |
36 | + args=[ |
37 | + IPMI_SEL, |
38 | + "--no-header-output", |
39 | + "--comma-separated-output", |
40 | + "--date-range", |
41 | + "01/01/1970-{}".format(date.strftime("%m/%d/%Y")), |
42 | + ], |
43 | + universal_newlines=True, |
44 | + ).splitlines() |
45 | + max_record_id = output[-1].split(",")[0].strip() |
46 | + except IndexError: |
47 | + max_record_id = None |
48 | + |
49 | + return max_record_id |
50 | + |
51 | + |
52 | def ack_sel(): |
53 | """Set the acknowledgement date filter.""" |
54 | message = "" |
55 | - if "--date-range" in config("ipmi_check_options"): |
56 | + if "--exclude-display-range" in config("ipmi_check_options"): |
57 | message = ( |
58 | - "WARNING: Will override user specified --date-range " |
59 | + "WARNING: Will override user specified --exclude-display-range " |
60 | "option on ipmi_check_options config\n" |
61 | ) |
62 | |
63 | @@ -107,12 +126,11 @@ def ack_sel(): |
64 | date = datetime.utcnow() |
65 | |
66 | try: |
67 | - unitdata.kv().set( |
68 | - tools.Ipmi.SEL_DATE_FILTER_START_KEY, date.strftime("%m/%d/%Y") |
69 | - ) |
70 | + max_record_id = _get_sel_max_event_id_for_date(date) |
71 | + unitdata.kv().set(tools.Ipmi.SEL_EXCLUDE_RANGE_MAX_KEY, max_record_id) |
72 | unitdata.kv().flush() |
73 | - message += "Only SEL entries newer than {} will be considered".format( |
74 | - date.strftime("%Y-%m-%d") |
75 | + message += "Only SEL entries with id greater than {} will be considered".format( |
76 | + max_record_id |
77 | ) |
78 | action_set({"message": message}) |
79 | tools.Ipmi().install_cronjob() |
80 | @@ -123,7 +141,7 @@ def ack_sel(): |
81 | def unack_sel(): |
82 | """Unset the acknowledgement date filter.""" |
83 | try: |
84 | - unitdata.kv().unset(tools.Ipmi.SEL_DATE_FILTER_START_KEY) |
85 | + unitdata.kv().unset(tools.Ipmi.SEL_EXCLUDE_RANGE_MAX_KEY) |
86 | unitdata.kv().flush() |
87 | message = "SEL entries from all times will be considered" |
88 | action_set({"message": message}) |
89 | diff --git a/src/lib/hwhealth/tools.py b/src/lib/hwhealth/tools.py |
90 | index 71273d6..3a3e8b4 100644 |
91 | --- a/src/lib/hwhealth/tools.py |
92 | +++ b/src/lib/hwhealth/tools.py |
93 | @@ -686,7 +686,7 @@ class Ipmi(Tool): |
94 | OUTPUT_FILE = "/var/lib/nagios/ipmi_sensors.out" |
95 | EXCLUDE_FILE = "/var/lib/nagios/ipmi_exclude" |
96 | SEL_EXCLUDE_FILE = "/var/lib/nagios/sel_exclude" |
97 | - SEL_DATE_FILTER_START_KEY = "ipmi_sel_date_filter_start" |
98 | + SEL_EXCLUDE_RANGE_MAX_KEY = "ipmi_exclude_range_max" |
99 | |
100 | def __init__(self, nrpe_opts=""): |
101 | self.set_exclusions( |
102 | @@ -737,7 +737,13 @@ class Ipmi(Tool): |
103 | perms=0o444, |
104 | ) |
105 | |
106 | - def add_date_range_to_cron_args(self, date): |
107 | + def add_exclude_display_range_to_cron_args(self, max_record_id): |
108 | + """Add exclude display range option to the check script. |
109 | + |
110 | + This function is used during the "ack-sel" action workflow. |
111 | + The idea is to add --exclude-display-range=1-{last_record_id} |
112 | + to silence(or "ack") the SEL entries up to a certain point. |
113 | + """ |
114 | seloptions_argument = "" |
115 | split_cron_args = self._cron_script_args.split() |
116 | if "--seloptions" in split_cron_args: |
117 | @@ -745,15 +751,15 @@ class Ipmi(Tool): |
118 | # init code is adding the --sexclude option. |
119 | seloptions_argument_index = split_cron_args.index("--seloptions") + 1 |
120 | seloptions_argument = split_cron_args[seloptions_argument_index] |
121 | - # This could happen if the user specified the date range option |
122 | + # This could happen if the user specified the exclude display range option |
123 | # through the ipmi_check_options config. We override it (the action |
124 | # already warned the user about this). |
125 | - if "--date-range" in seloptions_argument: |
126 | + if "--exclude-display-range" in seloptions_argument: |
127 | seloptions_argument = ",".join( |
128 | [ |
129 | x |
130 | for x in seloptions_argument.split(",") |
131 | - if "--date-range" not in x |
132 | + if "--exclude-display-range" not in x |
133 | ] |
134 | ) |
135 | if seloptions_argument: |
136 | @@ -761,15 +767,15 @@ class Ipmi(Tool): |
137 | else: |
138 | split_cron_args.extend(["--seloptions", ""]) |
139 | seloptions_argument_index = len(split_cron_args) - 1 |
140 | - seloptions_argument += "--date-range=" + date + "-now" |
141 | + seloptions_argument += "--exclude-display-range=1-" + max_record_id |
142 | split_cron_args[seloptions_argument_index] = seloptions_argument |
143 | self._cron_script_args = " ".join(split_cron_args) |
144 | |
145 | def install_cronjob(self, cron_user="nagios"): |
146 | - date_filter = unitdata.kv().get(self.SEL_DATE_FILTER_START_KEY) |
147 | - if date_filter: |
148 | - self.add_date_range_to_cron_args(date_filter) |
149 | - hookenv.log("Added date filter to ipmi sensors cmdline", hookenv.DEBUG) |
150 | + max_record_id = unitdata.kv().get(self.SEL_EXCLUDE_RANGE_MAX_KEY) |
151 | + if max_record_id: |
152 | + self.add_exclude_display_range_to_cron_args(max_record_id=max_record_id) |
153 | + hookenv.log("Added record id filter to ipmi sensors cmdline", hookenv.DEBUG) |
154 | super().install_cronjob(cron_user) |
155 | |
156 | def configure_nrpe_check(self, nrpe_setup): |
157 | diff --git a/src/tests/functional/test_hwhealth.py b/src/tests/functional/test_hwhealth.py |
158 | index 98e497a..2951b7a 100644 |
159 | --- a/src/tests/functional/test_hwhealth.py |
160 | +++ b/src/tests/functional/test_hwhealth.py |
161 | @@ -2,7 +2,6 @@ import asyncio |
162 | import os |
163 | import subprocess |
164 | import sys |
165 | -from datetime import datetime |
166 | from os.path import abspath, dirname |
167 | |
168 | sys.path.append("lib") |
169 | @@ -444,103 +443,6 @@ async def test_imports( |
170 | ) |
171 | |
172 | |
173 | -IPMI_CROND_FILE = os.path.join(tools.Ipmi.CROND_DIR, "hwhealth_ipmi") |
174 | - |
175 | - |
176 | -async def test_action_ack_sel(deployed_unit, run_command): |
177 | - action = await deployed_unit.run_action("ack-sel") |
178 | - action = await action.wait() |
179 | - |
180 | - assert action.status == "completed", "Action did not complete successfully" |
181 | - |
182 | - # NOTE: This test might fail if run very very close to UTC midnight... I'm |
183 | - # purposedly not contemplating that case in favor of test simplicity. |
184 | - today = datetime.utcnow().strftime("%m/%d/%Y") |
185 | - cmd = "grep -E '[ ,]--date-range={}-now([ ,]|$)' {}".format(today, IPMI_CROND_FILE) |
186 | - result = await run_command(cmd, deployed_unit) |
187 | - assert ( |
188 | - result["Code"] == "0" |
189 | - ), "--date-range parameter not found on cron file (or it has the wrong date)" |
190 | - |
191 | - |
192 | -async def test_action_ack_sel_date_param(deployed_unit, run_command): |
193 | - action = await deployed_unit.run_action("ack-sel", date="2021-3-9") |
194 | - action = await action.wait() |
195 | - |
196 | - assert action.status == "completed", "Action did not complete successfully" |
197 | - |
198 | - cmd = "grep -E '[ ,]--date-range=03/09/2021-now([ ,]|$)' {}".format(IPMI_CROND_FILE) |
199 | - result = await run_command(cmd, deployed_unit) |
200 | - assert ( |
201 | - result["Code"] == "0" |
202 | - ), "--date-range parameter not found on cron file (or it has the wrong date)" |
203 | - |
204 | - |
205 | -async def test_action_ack_sel_invalid_date_param(deployed_unit, run_command): |
206 | - result = await run_command( |
207 | - "TMP=`mktemp` && cp {} $TMP && echo $TMP".format(IPMI_CROND_FILE), deployed_unit |
208 | - ) |
209 | - assert result["Code"] == "0", "Error copying original cron file: {}".format( |
210 | - result["Stderr"] |
211 | - ) |
212 | - original_crond = result["Stdout"].strip() |
213 | - |
214 | - action = await deployed_unit.run_action("ack-sel", date="03/09/2021") |
215 | - action = await action.wait() |
216 | - assert action.status == "failed", "Action didn't fail" |
217 | - assert ( |
218 | - "Invalid date format" in action.message |
219 | - ), "Expected 'Invalid date format' phrase not in action message: {}".format( |
220 | - action.message |
221 | - ) |
222 | - |
223 | - result = await run_command( |
224 | - "cmp {} {}".format(original_crond, IPMI_CROND_FILE), deployed_unit |
225 | - ) |
226 | - assert result["Code"] == "0", "Cron file changed when it shouldn't have" |
227 | - |
228 | - |
229 | -async def test_action_ack_sel_warning(model, deploy_app, deployed_unit, run_command): |
230 | - await deploy_app.set_config( |
231 | - {"ipmi_check_options": "--seloptions --date-range=2/27/2021-now"} |
232 | - ) |
233 | - await model.block_until( |
234 | - lambda: deployed_unit.agent_status == "idle", timeout=DEF_TIMEOUT |
235 | - ) |
236 | - |
237 | - action = await deployed_unit.run_action("ack-sel", date="2021-3-9") |
238 | - action = await action.wait() |
239 | - |
240 | - assert action.status == "completed", "Action did not complete successfully" |
241 | - |
242 | - message = action.results["message"] |
243 | - # NOTE: We don't check the actual date range value, that's covered on the |
244 | - # unit tests and tests above. We just wanna see if the warning's there. |
245 | - assert ( |
246 | - "WARNING: Will override" in message |
247 | - ), "Warning about overriding user config is not there: {}".format(message) |
248 | - |
249 | - |
250 | -async def test_action_unack_sel(model, deploy_app, deployed_unit, run_command): |
251 | - await deploy_app.set_config({"ipmi_check_options": ""}) |
252 | - await model.block_until( |
253 | - lambda: deployed_unit.agent_status == "idle", timeout=DEF_TIMEOUT |
254 | - ) |
255 | - |
256 | - cmd = "grep -Fe '--date-range' {}".format(IPMI_CROND_FILE) |
257 | - result = await run_command(cmd, deployed_unit) |
258 | - assert result["Code"] == "0", "Test expected --date-range to be there but it isn't" |
259 | - |
260 | - action = await deployed_unit.run_action("unack-sel") |
261 | - action = await action.wait() |
262 | - |
263 | - assert action.status == "completed", "Action did not complete successfully" |
264 | - |
265 | - cmd = "grep -Fe '--date-range' {}".format(IPMI_CROND_FILE) |
266 | - result = await run_command(cmd, deployed_unit) |
267 | - assert result["Code"] == "1", "--date-range parameter is still there" |
268 | - |
269 | - |
270 | async def test_removal(monkeypatch, toolset, model, deploy_app, file_stat): |
271 | """Remove the unit, test that all files have been cleaned up.""" |
272 | hw_health_app_name = deploy_app.name |
273 | diff --git a/src/tests/unit/test_actions.py b/src/tests/unit/test_actions.py |
274 | index 15ee573..7c919ec 100644 |
275 | --- a/src/tests/unit/test_actions.py |
276 | +++ b/src/tests/unit/test_actions.py |
277 | @@ -26,6 +26,8 @@ from actions.actions import ( # noqa:E402 |
278 | _run_job_file, |
279 | run_cron_action, |
280 | show_sel, |
281 | + ack_sel, |
282 | + _get_sel_max_event_id_for_date, |
283 | ) |
284 | |
285 | |
286 | @@ -295,3 +297,93 @@ class ListCronTestCase(unittest.TestCase): |
287 | mock_run_job_file.assert_called_once_with( |
288 | pathlib.Path("/etc/cron.d/hwhealth_test") |
289 | ) |
290 | + |
291 | + |
292 | +class AckSelTestCase(unittest.TestCase): |
293 | + @mock.patch("subprocess.check_output") |
294 | + def test_get_sel_max_event_id_for_date(self, mock_check_output): |
295 | + mock_date = mock.MagicMock() |
296 | + mock_date.strftime.return_value = "01/01/2022" |
297 | + mock_check_output.return_value = ( |
298 | + "1,May-06-2011,20:48:43,Sensor #10,Power Supply,Critical,Power Supply Failure detected\n" # noqa |
299 | + "2,Sep-21-2013,14:05:03,Sensor #7,Power Supply,Critical,Power Supply Failure detected\n" # noqa |
300 | + "3,Sep-21-2013,14:05:03,Sensor #10,Power Supply,Critical,Power Supply Failure detected\n" # noqa |
301 | + ) |
302 | + |
303 | + ret = _get_sel_max_event_id_for_date(mock_date) |
304 | + |
305 | + self.assertEqual(ret, "3") |
306 | + mock_check_output.assert_called_once_with( |
307 | + args=[ |
308 | + "/usr/sbin/ipmi-sel", |
309 | + "--no-header-output", |
310 | + "--comma-separated-output", |
311 | + "--date-range", |
312 | + "01/01/1970-01/01/2022", |
313 | + ], |
314 | + universal_newlines=True, |
315 | + ) |
316 | + |
317 | + @mock.patch("subprocess.check_output") |
318 | + def test_get_sel_max_event_id_for_date_returns_none(self, mock_check_output): |
319 | + mock_date = mock.MagicMock() |
320 | + mock_date.strftime.return_value = "01/01/2022" |
321 | + mock_check_output.return_value = "" |
322 | + |
323 | + ret = _get_sel_max_event_id_for_date(mock_date) |
324 | + |
325 | + self.assertEqual(ret, None) |
326 | + mock_check_output.assert_called_once_with( |
327 | + args=[ |
328 | + "/usr/sbin/ipmi-sel", |
329 | + "--no-header-output", |
330 | + "--comma-separated-output", |
331 | + "--date-range", |
332 | + "01/01/1970-01/01/2022", |
333 | + ], |
334 | + universal_newlines=True, |
335 | + ) |
336 | + |
337 | + @mock.patch("actions.actions._get_sel_max_event_id_for_date") |
338 | + @mock.patch("hwhealth.tools.Ipmi") |
339 | + @mock.patch("actions.actions.unitdata.kv") |
340 | + @mock.patch("actions.actions.config") |
341 | + @mock.patch("actions.actions.action_set") |
342 | + @mock.patch("actions.actions.action_get") |
343 | + def test_ack_sel( |
344 | + self, |
345 | + mock_action_get, |
346 | + mock_action_set, |
347 | + mock_config, |
348 | + mock_kv, |
349 | + mock_ipmi, |
350 | + mock_get_sel_max_event_id_for_date, |
351 | + ): |
352 | + mock_action_get.return_value = "2022-01-01" |
353 | + mock_config.return_value = "" |
354 | + mock_get_sel_max_event_id_for_date.return_value = "42" |
355 | + |
356 | + ack_sel() |
357 | + |
358 | + mock_action_get.assert_called_once_with("date") |
359 | + mock_kv.return_value.set.assert_called_once_with( |
360 | + mock_ipmi.SEL_EXCLUDE_RANGE_MAX_KEY, "42" |
361 | + ) |
362 | + mock_kv.return_value.flush.assert_called_once() |
363 | + mock_ipmi.return_value.install_cronjob.assert_called_once() |
364 | + mock_action_set.assert_called_once() |
365 | + |
366 | + @mock.patch("actions.actions.config") |
367 | + @mock.patch("actions.actions.action_fail") |
368 | + @mock.patch("actions.actions.action_get") |
369 | + def test_ack_sel_fails_on_bad_date( |
370 | + self, mock_action_get, mock_action_fail, mock_config |
371 | + ): |
372 | + mock_action_get.return_value = "foo" |
373 | + mock_config.return_value = "" |
374 | + |
375 | + ret = ack_sel() |
376 | + |
377 | + mock_action_get.assert_called_once_with("date") |
378 | + mock_action_fail.assert_called_once() |
379 | + self.assertEqual(ret, None) |
380 | diff --git a/src/tests/unit/test_ipmi_sensor.py b/src/tests/unit/test_ipmi_sensor.py |
381 | index 3048261..5611cdf 100644 |
382 | --- a/src/tests/unit/test_ipmi_sensor.py |
383 | +++ b/src/tests/unit/test_ipmi_sensor.py |
384 | @@ -48,19 +48,19 @@ class TestIpmiSensor(unittest.TestCase): |
385 | ) |
386 | @mock.patch("hwhealth.tools.write_file") |
387 | @mock.patch("hwhealth.tools.hookenv.config") |
388 | - def test_add_date_range_to_cron_args(self, config, *rest_of_mocks): |
389 | + def test_add_exclude_display_range_to_cron_args(self, config, *rest_of_mocks): |
390 | subtests = [ # (ipmi_check_options, expected _cron_script_args) |
391 | ( |
392 | "--option1 --option2 arg1", |
393 | "--option1 --option2 arg1 --sexclude {} --selexclude {} " |
394 | - "--seloptions --date-range=03/08/2021-now".format( |
395 | + "--seloptions --exclude-display-range=1-42".format( |
396 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
397 | ), |
398 | ), |
399 | ( |
400 | "--option1 --option2 arg1 --seloptions --some-option", |
401 | "--option1 --option2 arg1 --seloptions " |
402 | - "--some-option,--date-range=03/08/2021-now --sexclude {} " |
403 | + "--some-option,--exclude-display-range=1-42 --sexclude {} " |
404 | "--selexclude {}".format( |
405 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
406 | ), |
407 | @@ -68,47 +68,47 @@ class TestIpmiSensor(unittest.TestCase): |
408 | ( |
409 | "--option1 --option2 arg1 --seloptions --some-option --option3", |
410 | "--option1 --option2 arg1 --seloptions " |
411 | - "--some-option,--date-range=03/08/2021-now --option3 " |
412 | + "--some-option,--exclude-display-range=1-42 --option3 " |
413 | "--sexclude {} --selexclude {}".format( |
414 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
415 | ), |
416 | ), |
417 | ( |
418 | "--seloptions --some-option --option1 --option2 arg1", |
419 | - "--seloptions --some-option,--date-range=03/08/2021-now " |
420 | + "--seloptions --some-option,--exclude-display-range=1-42 " |
421 | "--option1 --option2 arg1 --sexclude {} --selexclude {}".format( |
422 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
423 | ), |
424 | ), |
425 | # Pre-existing date range options are overriden |
426 | ( |
427 | - "--seloptions --some-option,--date-range=09/01/2021 " |
428 | + "--seloptions --some-option,--exclude-display-range=1-2 " |
429 | "--option1 --option2 arg1", |
430 | - "--seloptions --some-option,--date-range=03/08/2021-now " |
431 | + "--seloptions --some-option,--exclude-display-range=1-42 " |
432 | "--option1 --option2 arg1 --sexclude {} --selexclude {}".format( |
433 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
434 | ), |
435 | ), |
436 | ( |
437 | - "--seloptions --date-range=09/01/2021,--some-option " |
438 | + "--seloptions --exclude-display-range=1-2,--some-option " |
439 | "--option1 --option2 arg1", |
440 | - "--seloptions --some-option,--date-range=03/08/2021-now " |
441 | + "--seloptions --some-option,--exclude-display-range=1-42 " |
442 | "--option1 --option2 arg1 --sexclude {} --selexclude {}".format( |
443 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
444 | ), |
445 | ), |
446 | ( |
447 | - "--seloptions --some-option,--date-range=09/01/2021," |
448 | + "--seloptions --some-option,--exclude-display-range=1-2," |
449 | "--some-option2 --option1 --option2 arg1", |
450 | "--seloptions " |
451 | - "--some-option,--some-option2,--date-range=03/08/2021-now " |
452 | + "--some-option,--some-option2,--exclude-display-range=1-42 " |
453 | "--option1 --option2 arg1 --sexclude {} --selexclude {}".format( |
454 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
455 | ), |
456 | ), |
457 | ( |
458 | - "--seloptions --date-range=09/01/2021 --option1 --option2 arg1", |
459 | - "--seloptions --date-range=03/08/2021-now --option1 " |
460 | + "--seloptions --exclude-display-range=1-2 --option1 --option2 arg1", |
461 | + "--seloptions --exclude-display-range=1-42 --option1 " |
462 | "--option2 arg1 --sexclude {} --selexclude {}".format( |
463 | tools.Ipmi.EXCLUDE_FILE, tools.Ipmi.SEL_EXCLUDE_FILE |
464 | ), |
465 | @@ -123,5 +123,5 @@ class TestIpmiSensor(unittest.TestCase): |
466 | config.side_effect = lambda x: config_dict[x] |
467 | |
468 | ipmi = tools.Ipmi() |
469 | - ipmi.add_date_range_to_cron_args("03/08/2021") |
470 | + ipmi.add_exclude_display_range_to_cron_args("42") |
471 | self.assertEqual(ipmi._cron_script_args, i[1]) |
472 | diff --git a/src/tox.ini b/src/tox.ini |
473 | index afa9c71..566c5dd 100644 |
474 | --- a/src/tox.ini |
475 | +++ b/src/tox.ini |
476 | @@ -69,7 +69,6 @@ commands = |
477 | --cov=reactive \ |
478 | --cov=actions \ |
479 | --cov=hooks \ |
480 | - --cov=src \ |
481 | --cov=files \ |
482 | --cov-report=term \ |
483 | --cov-report=annotate:report/annotated \ |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.