-
Notifications
You must be signed in to change notification settings - Fork 1k
Convert 'read_mac' ansible test to pytest #2322
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
22 changes: 0 additions & 22 deletions
22
ansible/roles/test/tasks/read_mac/check_interfaces_and_mtu.yml
This file was deleted.
Oops, something went wrong.
20 changes: 0 additions & 20 deletions
20
ansible/roles/test/tasks/read_mac/loganalyzer_analyze_mac.yml
This file was deleted.
Oops, something went wrong.
1 change: 0 additions & 1 deletion
1
ansible/roles/test/tasks/read_mac/read_mac_meta_match_messages.txt
This file was deleted.
Oops, something went wrong.
84 changes: 0 additions & 84 deletions
84
ansible/roles/test/tasks/read_mac/read_mac_metadata_loop.yml
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,52 +1,11 @@ | ||
| # Input Parameters: | ||
| # -e image1=http://IP_ADDR/SERVER_URL/IMAGE_NAME.bin | ||
| # -e image2=http://IP_ADDR/SERVER_URL/IMAGE_NAME.bin | ||
| # -e iterations=INT_NUMBER | ||
| # Optional: | ||
| # -e minigraph1=/path/to/the/minigraph.xml | ||
| # -e minigraph2=/path/to/the/minigraph.xml | ||
| # Note | ||
| # This test has at least 2 parameters that cannot be defined as default (image1 and image2) | ||
| # Because of this backward compatibility currently does not work (I mean ability to run test using ansible-playbook) | ||
|
|
||
| - block: | ||
| - fail: msg="Please specify URL to the image1" | ||
| when: image1 is not defined | ||
| # ansible-playbook test_sonic.yml -i inventory --limit {DUT_NAME} -e testbed_name={TESTBED_NAME} -e testbed_type={TESTBED_TYPE} -e testcase_name=read_mac -e iterations={ITERATIONS} -e image1={IMAGE1} -e image2={IMAGE2} | ||
| # Current implementation of ansible to pytest wrapper does not allow to pass python input params. And this may be motivation to improve it fuctionality in future | ||
|
|
||
| - fail: msg="Please specify URL to the image2" | ||
| when: image2 is not defined | ||
|
|
||
| - fail: msg="Please specify 'iterations' variable" | ||
| when: iterations is not defined | ||
|
|
||
| # Prepare variables for loganalyzer | ||
| - set_fact: | ||
| testname: read_mac | ||
| - set_fact: | ||
| testname_unique: "{{ testname }}.{{ lookup('pipe','date +%Y-%m-%d-%H:%M:%S') }}" | ||
| - set_fact: | ||
| # Set custom match instead of default match | ||
| test_match_file: read_mac_meta_match_messages.txt | ||
| summary_file: summary.loganalysis.{{ testname_unique }}.log | ||
| result_file: result.loganalysis.{{ testname_unique }}.log | ||
| errors_expected: false | ||
| skip_common_match: true | ||
| out_dir: /tmp | ||
| run_dir: /tmp | ||
| tests_location: roles/test/tasks | ||
| current_image: "" | ||
| temp_minigraph: "" | ||
|
|
||
| - name: Check minigraph exists | ||
| stat: | ||
| path: /etc/sonic/minigraph.xml | ||
| register: output | ||
|
|
||
| - set_fact: store_original_minigraph=true | ||
| when: output.stat.exists | ||
|
|
||
| # Store current minigraph for debug purpose | ||
| - shell: cp /etc/sonic/minigraph.xml /home/ | ||
| become: true | ||
| when: (minigraph1 is defined) or (minigraph2 is defined) and (store_original_minigraph is defined) | ||
|
|
||
| - name: Verify MAC in image reinstall loop | ||
| include_tasks: roles/test/tasks/read_mac/read_mac_metadata_loop.yml | ||
| with_sequence: count={{ iterations }} | ||
| - name: run test | ||
| include_tasks: roles/test/tasks/pytest_runner.yml | ||
| vars: | ||
| test_node: read_mac/test_read_mac_metadata.py |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| """ | ||
| Pytest configuration used by the read MAC tests. | ||
| """ | ||
|
|
||
| def pytest_addoption(parser): | ||
| """ | ||
| Adding arguments required for read MAC metadata testcase | ||
| """ | ||
| parser.addoption( | ||
| "--iteration", | ||
| action="store", | ||
| type=int, | ||
| help="Number of image installing iterations", | ||
| ) | ||
|
|
||
| parser.addoption( | ||
| '--image1', | ||
| action='store', | ||
| type=str, | ||
| help='1st image to download and install', | ||
| ) | ||
|
|
||
| parser.addoption( | ||
| '--image2', | ||
| action='store', | ||
| type=str, | ||
| help='2nd image to download and install', | ||
| ) | ||
|
|
||
| parser.addoption( | ||
| '--minigraph1', | ||
| action='store', | ||
| type=str, | ||
| help='path to the minigraph1', | ||
| ) | ||
| parser.addoption( | ||
| '--minigraph2', | ||
| action='store', | ||
| type=str, | ||
| help='path to the minigraph2', | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| import pytest | ||
| import logging | ||
|
|
||
| from tests.common.utilities import wait | ||
| from tests.common.utilities import wait_until | ||
| from tests.common.plugins.sanity_check import checks | ||
| from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer | ||
| from tests.common.helpers.assertions import pytest_assert | ||
| from datetime import datetime | ||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
| BINARY_FILE_ON_LOCALHOST = "/tmp/update_image.bin" | ||
| BINARY_FILE_ON_DUTHOST = "/tmp/mellanox.bin" | ||
ayurkiv-nvda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| pytestmark = [ | ||
| pytest.mark.topology('any') | ||
| ] | ||
|
|
||
| @pytest.fixture(scope='function') | ||
| def cleanup_read_mac(duthost, localhost): | ||
| yield | ||
| logger.info('Remove temporary images') | ||
| duthost.shell("rm -rf {}".format(BINARY_FILE_ON_DUTHOST)) | ||
| localhost.shell("rm -rf {}".format(BINARY_FILE_ON_LOCALHOST)) | ||
|
|
||
| backup_minigraph_exist = duthost.stat(path = "/etc/sonic/minigraph.xml.backup")["stat"]["exists"] | ||
| if backup_minigraph_exist: | ||
| logger.info("Apply minigraph from backup") | ||
| duthost.shell("mv /etc/sonic/minigraph.xml.backup /etc/sonic/minigraph.xml") | ||
| duthost.shell("config load_minigraph -y") | ||
| duthost.shell("config save -y") | ||
|
|
||
| class ReadMACMetadata(): | ||
| def __init__(self, request): | ||
| self.iteration = request.config.getoption("--iteration") | ||
| self.image1 = request.config.getoption("--image1") | ||
| self.image2 = request.config.getoption("--image2") | ||
| self.minigraph1 = request.config.getoption("--minigraph1") | ||
| self.minigraph2 = request.config.getoption("--minigraph2") | ||
|
|
||
| if not self.image1: | ||
| pytest.fail("Please specify --image1") | ||
| if not self.image2: | ||
| pytest.fail("Please specify --image2") | ||
ayurkiv-nvda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if not self.iteration or self.iteration < 1: | ||
| pytest.fail("Please specify --iteration in correct range") | ||
|
|
||
| self.request = request | ||
| duthost = request.getfixturevalue('duthost') | ||
|
|
||
| minigraph_exist = duthost.stat(path = "/etc/sonic/minigraph.xml")["stat"]["exists"] | ||
| if (self.minigraph1 is not None or self.minigraph2 is not None) and minigraph_exist: | ||
| logger.info("Store current minigraph for debug purpose") | ||
| duthost.shell("cp /etc/sonic/minigraph.xml /etc/sonic/minigraph.xml.backup") | ||
|
|
||
| def run_test_in_reinstall_loop(self): | ||
| logger.info("Verify MAC in image reinstall loop") | ||
| duthost = self.request.getfixturevalue('duthost') | ||
| localhost = self.request.getfixturevalue('localhost') | ||
|
|
||
| for counter in range(1, self.iteration + 1): | ||
| current_minigraph = None | ||
|
|
||
| if counter % 2 == 1: | ||
| current_image = self.image1 | ||
| current_minigraph = self.minigraph1 | ||
| else: | ||
| current_image = self.image2 | ||
| current_minigraph = self.minigraph2 | ||
|
|
||
| logger.info("Iteration #{}".format(counter)) | ||
| logger.info("Current image: {}, temporary minigraph: {}".format(current_image, current_minigraph)) | ||
| if current_minigraph: | ||
| logger.info("Copy specified minigraph {} to the /etc/sonic folder".format(current_minigraph)) | ||
| duthost.copy(src=current_minigraph, dest="/etc/sonic/minigraph.xml") | ||
|
|
||
| loganalyzer = LogAnalyzer(ansible_host=duthost, marker_prefix="read_mac_metadata") | ||
| loganalyzer.match_regex = [ ".*can't parse mac address 'None'*" ] | ||
|
|
||
| with loganalyzer: | ||
| self.deploy_image_to_duthost(duthost, localhost , current_image) | ||
| self.reboot_dut(localhost, duthost) | ||
|
|
||
ayurkiv-nvda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if current_minigraph: | ||
| logger.info("Execute cli 'config load_minigraph -y' to apply new minigraph") | ||
| duthost.shell("config load_minigraph -y") | ||
| duthost.shell("config save -y") | ||
|
|
||
| logger.info("Remove old (not current) sonic image") | ||
| duthost.reduce_and_add_sonic_images(disk_used_pcent = 1) | ||
|
|
||
| self.check_mtu_and_interfaces(duthost) | ||
|
|
||
| def deploy_image_to_duthost(self, duthost, localhost, current_image): | ||
| logger.info("Download SONiC image {}".format(current_image)) | ||
| localhost.get_url(url=current_image, dest=BINARY_FILE_ON_LOCALHOST) | ||
ayurkiv-nvda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| logger.info("Upload SONiC image to device") | ||
| duthost.copy(src=BINARY_FILE_ON_LOCALHOST, dest=BINARY_FILE_ON_DUTHOST) | ||
|
|
||
| logger.info("Installing new SONiC image") | ||
| duthost.shell("sonic_installer install -y {}".format(BINARY_FILE_ON_DUTHOST)) | ||
|
|
||
| def reboot_dut(self, localhost, duthost): | ||
ayurkiv-nvda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| hostname = duthost.hostname | ||
| logger.info("Execute task: reboot {}".format(hostname)) | ||
| duthost.command("sudo reboot", module_ignore_errors=True, module_async=True) | ||
| logger.info("Wait for {} to go down".format(hostname)) | ||
| result = localhost.wait_for(host=hostname, port=22, state='stopped', timeout=180, module_ignore_errors=True) | ||
| if 'msg' in result.keys() and 'Timeout' in result['msg']: | ||
| pytest.fail(result['msg']) | ||
|
|
||
| logger.info("Wait for {} to come back".format(hostname)) | ||
| localhost.wait_for(host=hostname, port=22, state='started', delay=10, timeout=300) | ||
| logger.info("Wait until system is stable") | ||
| pytest_assert(wait_until(300, 20, duthost.critical_services_fully_started), "Not all critical services are fully started") | ||
|
|
||
| def check_mtu_and_interfaces(self, duthost): | ||
| logger.info("Verify that MAC address fits template XX:XX:XX:XX:XX:XX") | ||
| mac = duthost.shell("redis-cli -n 4 hget 'DEVICE_METADATA|localhost' mac| grep -io '[0-9a-fA-F:]\{17\}'", module_ignore_errors=True)['stdout'] | ||
| logger.info("DUT MAC is {}".format(mac)) | ||
|
|
||
| if not mac: | ||
| pytest.fail("MAC entry does not exist") | ||
|
|
||
| logger.info("Verify interfaces are UP and MTU == 9100") | ||
| checks.check_interfaces(duthost) | ||
|
|
||
| cfg_facts = duthost.config_facts(host=duthost.hostname, source="persistent")['ansible_facts'] | ||
| non_default_ports = [k for k,v in cfg_facts["PORT"].items() if "mtu" in v and v["mtu"] != "9100" and "admin_status" in v and v["admin_status"] == "up" ] | ||
| non_default_portchannel = [k for k,v in cfg_facts["PORTCHANNEL"].items() if "mtu" in v and v["mtu"] != "9100" and "admin_status" in v and v["admin_status"] == "up" ] | ||
|
|
||
| if len(non_default_ports) != 0 or len(non_default_portchannel) != 0: | ||
| pytest.fail("There are ports/portchannel with non default MTU:\nPorts: {}\nPortchannel: {}".format(non_default_ports,non_default_portchannel)) | ||
|
|
||
|
|
||
| @pytest.mark.disable_loganalyzer | ||
| def test_read_mac_metadata(request,cleanup_read_mac): | ||
| """ | ||
| Verify that after installing new image on duthost MAC remains valid on interfaces | ||
| """ | ||
| read_mac_metadata = ReadMACMetadata(request) | ||
| read_mac_metadata.run_test_in_reinstall_loop() | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.