-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add integration test for power_state_change module #717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
20fcc5a
f25f7c6
3a2e147
2c7f39d
1275ccb
1ee6622
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| def ordered_items_in_text(to_verify: list, text: str) -> bool: | ||
| """Return if all items in list appear in order in text. | ||
|
|
||
| Examples: | ||
| ordered_items_in_text(['a', '1'], 'ab1') # Returns True | ||
| ordered_items_in_text(['1', 'a'], 'ab1') # Returns False | ||
| """ | ||
| index = 0 | ||
| for item in to_verify: | ||
| index = text[index:].find(item) | ||
| if index < 0: | ||
| return False | ||
| return True |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| """Integration test of the cc_power_state_change module. | ||
|
|
||
| Test that the power state config options work as expected. | ||
| """ | ||
|
|
||
| import time | ||
|
|
||
| import pytest | ||
|
|
||
| from tests.integration_tests.clouds import IntegrationCloud | ||
| from tests.integration_tests.instances import IntegrationInstance | ||
| from tests.integration_tests.log_utils import ordered_items_in_text | ||
|
|
||
| USER_DATA = """\ | ||
| #cloud-config | ||
| power_state: | ||
| delay: {delay} | ||
| mode: {mode} | ||
| message: msg | ||
| timeout: {timeout} | ||
| condition: {condition} | ||
| """ | ||
|
|
||
|
|
||
| def _detect_reboot(instance: IntegrationInstance): | ||
| # We'll wait for instance up here, but we don't know if we're | ||
| # detecting the first boot or second boot, so we also check | ||
| # the logs to ensure we've booted twice. If the logs show we've | ||
| # only booted once, wait until we've booted twice | ||
| instance.instance.wait(raise_on_cloudinit_failure=False) | ||
| for _ in range(600): | ||
| try: | ||
| log = instance.read_from_file('/var/log/cloud-init.log') | ||
| boot_count = log.count("running 'init-local'") | ||
| if boot_count == 1: | ||
| instance.instance.wait(raise_on_cloudinit_failure=False) | ||
| elif boot_count > 1: | ||
| break | ||
| except Exception: | ||
| pass | ||
| time.sleep(1) | ||
| else: | ||
| raise Exception('Could not detect reboot') | ||
|
|
||
|
|
||
| def _can_connect(instance): | ||
| return instance.execute('true').ok | ||
|
|
||
|
|
||
| # This test is marked unstable because even though it should be able to | ||
| # run anywhere, I can only get it to run in an lxd container, and even then | ||
| # occasionally some timing issues will crop up. | ||
| @pytest.mark.unstable | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be nice to have a timed element like we have in the curtin tests: |
||
| @pytest.mark.sru_2020_11 | ||
| @pytest.mark.ubuntu | ||
| @pytest.mark.lxd_container | ||
| class TestPowerChange: | ||
| @pytest.mark.parametrize('mode,delay,timeout,expected', [ | ||
| ('poweroff', 'now', '10', 'will execute: shutdown -P now msg'), | ||
| ('reboot', 'now', '0', 'will execute: shutdown -r now msg'), | ||
| ('halt', '+1', '0', 'will execute: shutdown -H +1 msg'), | ||
|
OddBloke marked this conversation as resolved.
|
||
| ]) | ||
| def test_poweroff(self, session_cloud: IntegrationCloud, | ||
| mode, delay, timeout, expected): | ||
| with session_cloud.launch( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a nice example of the flexibility of the framework we have; good job! |
||
| user_data=USER_DATA.format( | ||
| delay=delay, mode=mode, timeout=timeout, condition='true'), | ||
| wait=False | ||
| ) as instance: | ||
| if mode == 'reboot': | ||
| _detect_reboot(instance) | ||
| else: | ||
| instance.instance.wait_for_stop() | ||
| instance.instance.start(wait=True) | ||
| log = instance.read_from_file('/var/log/cloud-init.log') | ||
| assert _can_connect(instance) | ||
| lines_to_check = [ | ||
| 'Running module power-state-change', | ||
| expected, | ||
| "running 'init-local'", | ||
| 'config-power-state-change already ran', | ||
| ] | ||
| assert ordered_items_in_text(lines_to_check, log), ( | ||
| 'Expected data not in logs') | ||
|
|
||
| @pytest.mark.user_data(USER_DATA.format(delay='0', mode='poweroff', | ||
| timeout='0', condition='false')) | ||
| def test_poweroff_false_condition(self, client: IntegrationInstance): | ||
| log = client.read_from_file('/var/log/cloud-init.log') | ||
| assert _can_connect(client) | ||
| assert 'Condition was false. Will not perform state change' in log | ||
Uh oh!
There was an error while loading. Please reload this page.