diff options
author | 2017-07-27 15:04:07 +0000 | |
---|---|---|
committer | 2017-07-27 15:04:07 +0000 | |
commit | 162c03ef301396072c1934e7e7e0c40a841b4fe2 (patch) | |
tree | 7a2a2781949252436450ff5832962785061a774a /app/test/fetch | |
parent | b88c78e3cf2bef22aa2f1c4d0bf305e303bc15f0 (diff) | |
parent | 7e83d0876ddb84a45e130eeba28bc40ef53c074b (diff) |
Merge "Calipso initial release for OPNFV"
Diffstat (limited to 'app/test/fetch')
66 files changed, 5998 insertions, 0 deletions
diff --git a/app/test/fetch/__init__.py b/app/test/fetch/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/api_fetch/__init__.py b/app/test/fetch/api_fetch/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/api_fetch/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/api_fetch/test_api_access.py b/app/test/fetch/api_fetch/test_api_access.py new file mode 100644 index 0000000..e4767b7 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_access.py @@ -0,0 +1,142 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from unittest.mock import patch, MagicMock +from discover.fetchers.api.api_access import ApiAccess +from test.fetch.api_fetch.test_data.api_access import * +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.regions import REGIONS + + +class TestApiAccess(TestFetch): + + def setUp(self): + self.configure_environment() + self.api_access = ApiAccess() + self.set_regions_for_fetcher(self.api_access) + + def test_parse_time_without_dot_in_time(self): + time = self.api_access.parse_time(TIME_WITHOUT_DOT) + self.assertNotEqual(time, None, "Can't parse the time without dot") + + def test_parse_time_with_dot_in_time(self): + time = self.api_access.parse_time(TIME_WITH_DOT) + self.assertNotEqual(time, None, "Can't parse the time with dot") + + def test_parse_illegal_time(self): + time = self.api_access.parse_time(ILLEGAL_TIME) + self.assertEqual(time, None, "Can't get None when the time format is wrong") + + def test_get_existing_token(self): + self.api_access.tokens = VALID_TOKENS + token = self.api_access.get_existing_token(PROJECT) + self.assertNotEqual(token, VALID_TOKENS[PROJECT], "Can't get existing token") + + def test_get_nonexistent_token(self): + self.api_access.tokens = EMPTY_TOKENS + token = self.api_access.get_existing_token(TEST_PROJECT) + self.assertEqual(token, None, "Can't get None when the token doesn't " + + "exist in tokens") + + @patch("httplib2.Http.request") + def test_v2_auth(self, mock_request): + self.api_access.get_existing_token = MagicMock(return_value=None) + # mock authentication info from OpenStack Api + mock_request.return_value = (RESPONSE, CORRECT_AUTH_CONTENT) + token_details = self.api_access.v2_auth(TEST_PROJECT, TEST_HEADER, TEST_BODY) + self.assertNotEqual(token_details, None, "Can't get the token details") + + @patch("httplib2.Http.request") + def test_v2_auth_with_error_content(self, mock_request): + self.api_access.get_existing_token = MagicMock(return_value=None) + # authentication content from OpenStack Api will be incorrect + mock_request.return_value = (RESPONSE, ERROR_AUTH_CONTENT) + token_details = self.api_access.v2_auth(TEST_PROJECT, TEST_HEADER, TEST_BODY) + self.assertIs(token_details, None, "Can't get None when the content is wrong") + + @patch("httplib2.Http.request") + def test_v2_auth_with_error_token(self, mock_request): + # authentication info from OpenStack Api will not contain token info + mock_request.return_value = (RESPONSE, ERROR_TOKEN_CONTENT) + token_details = self.api_access.v2_auth(TEST_PROJECT, TEST_HEADER, TEST_BODY) + self.assertIs(token_details, None, "Can't get None when the content " + + "doesn't contain any token info") + + @patch("httplib2.Http.request") + def test_v2_auth_with_error_expiry_time(self, mock_request): + mock_request.return_value = (RESPONSE, CORRECT_AUTH_CONTENT) + + # store original parse_time method + original_method = self.api_access.parse_time + # the time will not be parsed + self.api_access.parse_time = MagicMock(return_value=None) + + token_details = self.api_access.v2_auth(TEST_PROJECT, TEST_HEADER, TEST_BODY) + # reset original parse_time method + self.api_access.parse_time = original_method + + self.assertIs(token_details, None, "Can't get None when the time in token " + + "can't be parsed") + + @patch("httplib2.Http.request") + def test_v2_auth_pwd(self, mock_request): + # mock the authentication info from OpenStack Api + mock_request.return_value = (RESPONSE, CORRECT_AUTH_CONTENT) + token = self.api_access.v2_auth_pwd(PROJECT) + self.assertNotEqual(token, None, "Can't get token") + + @patch("httplib2.Http.request") + def test_get_url(self, mock_request): + mock_request.return_value = (RESPONSE, GET_CONTENT) + result = self.api_access.get_url(TEST_URL, TEST_HEADER) + # check whether it returns content message when the response is correct + self.assertNotIn("status", result, "Can't get content when the " + + "response is correct") + + @patch("httplib2.Http.request") + def test_get_url_with_error_response(self, mock_request): + # the response will be wrong + mock_request.return_value = (ERROR_RESPONSE, None) + result = self.api_access.get_url(TEST_URL, TEST_HEADER) + self.assertNotEqual(result, None, "Can't get response message " + + "when the response status is not 200") + + def test_get_region_url(self): + region_url = self.api_access.get_region_url(REGION_NAME, SERVICE_NAME) + + self.assertNotEqual(region_url, None, "Can't get region url") + + def test_get_region_url_with_wrong_region_name(self): + # error region name doesn't exist in the regions info + region_url = self.api_access.get_region_url(ERROR_REGION_NAME, "") + self.assertIs(region_url, None, "Can't get None with the region " + + "name is wrong") + + def test_get_region_url_without_service_endpoint(self): + # error service doesn't exist in region service endpoints + region_url = self.api_access.get_region_url(REGION_NAME, ERROR_SERVICE_NAME) + self.assertIs(region_url, None, "Can't get None with wrong service name") + + def test_region_url_nover(self): + # mock return value of get_region_url, which has something starting from v2 + self.api_access.get_region_url = MagicMock(return_value=REGION_URL) + region_url = self.api_access.get_region_url_nover(REGION_NAME, SERVICE_NAME) + # get_region_nover will remove everything from v2 + self.assertNotIn("v2", region_url, "Can't get region url without v2 info") + + def test_get_service_region_endpoints(self): + region = REGIONS[REGION_NAME] + result = self.api_access.get_service_region_endpoints(region, SERVICE_NAME) + self.assertNotEqual(result, None, "Can't get service endpoint") + + def test_get_service_region_endpoints_with_nonexistent_service(self): + region = REGIONS[REGION_NAME] + result = self.api_access.get_service_region_endpoints(region, ERROR_SERVICE_NAME) + self.assertIs(result, None, "Can't get None when the service name " + + "doesn't exist in region's services") diff --git a/app/test/fetch/api_fetch/test_api_fetch_availability_zone.py b/app/test/fetch/api_fetch/test_api_fetch_availability_zone.py new file mode 100644 index 0000000..f32be36 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_availability_zone.py @@ -0,0 +1,72 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.api.api_fetch_availability_zones import ApiFetchAvailabilityZones +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_availability_zones import * +from unittest.mock import MagicMock +from test.fetch.api_fetch.test_data.token import TOKEN + + +class TestApiFetchAvailabilityZones(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchAvailabilityZones.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchAvailabilityZones() + self.set_regions_for_fetcher(self.fetcher) + + def test_get_for_region(self): + # mock the endpoint url + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + # mock the response from OpenStack Api + self.fetcher.get_url = MagicMock(return_value=AVAILABILITY_ZONE_RESPONSE) + + result = self.fetcher.get_for_region(PROJECT, REGION_NAME, TOKEN) + self.assertNotEqual(result, [], "Can't get availability zone info") + + def test_get_for_region_with_wrong_response(self): + # mock the endpoint url + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + # mock the wrong response from OpenStack Api + self.fetcher.get_url = MagicMock(return_value=WRONG_RESPONSE) + + result = self.fetcher.get_for_region(PROJECT, REGION_NAME, TOKEN) + self.assertEqual(result, [], "Can't get [] when the response is wrong") + + def test_get_for_region_without_avz_response(self): + # mock the endpoint url + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + # mock the response from OpenStack Api + # the response doesn't contain availability zone info + self.fetcher.get_url = MagicMock(return_value=RESPONSE_WITHOUT_AVAILABILITY_ZONE) + + result = self.fetcher.get_for_region(PROJECT, REGION_NAME, TOKEN) + self.assertEqual(result, [], "Can't get [] when the response doesn't " + + "contain availability zone") + + def test_get(self): + # store original get_for_region method + original_method = self.fetcher.get_for_region + # mock the result from get_for_region method + self.fetcher.get_for_region = MagicMock(return_value=GET_REGION_RESULT) + + result = self.fetcher.get(PROJECT) + + # reset get_for_region method + self.fetcher.get_for_region = original_method + + self.assertNotEqual(result, [], "Can't get availability zone info") + + def test_get_without_token(self): + # mock the empty token + self.fetcher.v2_auth_pwd = MagicMock(return_value=None) + result = self.fetcher.get(PROJECT) + self.fetcher.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.assertEqual(result, [], "Can't get [] when the token is invalid") diff --git a/app/test/fetch/api_fetch/test_api_fetch_host_instances.py b/app/test/fetch/api_fetch/test_api_fetch_host_instances.py new file mode 100644 index 0000000..c1c7b6e --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_host_instances.py @@ -0,0 +1,83 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.api.api_fetch_host_instances import ApiFetchHostInstances +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_host_instances import * +from test.fetch.api_fetch.test_data.token import TOKEN +from unittest.mock import MagicMock + + +class TestApiFetchHostInstances(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchHostInstances.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchHostInstances() + self.set_regions_for_fetcher(self.fetcher) + + def test_get_projects(self): + # mock the projects got from the database + self.fetcher.inv.get = MagicMock(return_value=PROJECT_LIST) + + self.fetcher.get_projects() + self.assertNotEqual(self.fetcher.projects, None, "Can't get projects info") + + def test_get_instances_from_api(self): + self.fetcher.inv.get = MagicMock(return_value=PROJECT_LIST) + # mock the response from the OpenStack Api + self.fetcher.get_url = MagicMock(return_value=GET_SERVERS_RESPONSE) + + result = self.fetcher.get_instances_from_api(HOST_NAME) + self.assertEqual(result, GET_INSTANCES_FROM_API, "Can't get correct " + + "instances info") + + def test_get_instances_from_api_with_wrong_auth(self): + self.fetcher.v2_auth_pwd = MagicMock(return_value=None) + + result = self.fetcher.get_instances_from_api(HOST_NAME) + self.assertEqual(result, [], "Can't get [] when the token is invalid") + + def test_get_instances_from_api_without_hypervisors_in_res(self): + # mock the response without hypervisors info from OpenStack Api + self.fetcher.get_url = MagicMock(return_value=RESPONSE_WITHOUT_HYPERVISORS) + + result = self.fetcher.get_instances_from_api(HOST_NAME) + self.assertEqual(result, [], "Can't get [] when the response doesn't " + + "contain hypervisors info") + + def test_get_instances_from_api_without_servers_in_res(self): + # mock the response without servers info from OpenStack Api + self.fetcher.get_url = MagicMock(return_value=RESPONSE_WITHOUT_SERVERS) + + result = self.fetcher.get_instances_from_api(HOST_NAME) + self.assertEqual(result, [], "Can't get [] when the response doesn't " + + "contain servers info") + + def test_get(self): + self.fetcher.inv.get = MagicMock(return_value=PROJECT_LIST) + self.fetcher.inv.get_by_id = MagicMock(return_value=HOST) + + original_method = self.fetcher.get_instances_from_api + self.fetcher.get_instances_from_api = MagicMock(return_value= + GET_INSTANCES_FROM_API) + + self.fetcher.db_fetcher.get_instance_data = MagicMock() + result = self.fetcher.get(INSTANCE_FOLDER_ID) + self.assertNotEqual(result, [], "Can't get instances info") + + self.fetcher.get_instances_from_api = original_method + + def test_get_with_non_compute_node(self): + self.fetcher.inv.get = MagicMock(return_value=PROJECT_LIST) + self.fetcher.inv.get_by_id = MagicMock(return_value=NON_COMPUTE_HOST) + + result = self.fetcher.get(INSTANCE_FOLDER_ID) + self.assertEqual(result, [], "Can't get [] when the host is " + + "not compute node") diff --git a/app/test/fetch/api_fetch/test_api_fetch_networks.py b/app/test/fetch/api_fetch/test_api_fetch_networks.py new file mode 100644 index 0000000..1dc74ce --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_networks.py @@ -0,0 +1,65 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from unittest.mock import MagicMock +from discover.fetchers.api.api_fetch_networks import ApiFetchNetworks +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_networks import * +from test.fetch.api_fetch.test_data.token import TOKEN + + +class TestApiFetchNetworks(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchNetworks.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchNetworks() + self.set_regions_for_fetcher(self.fetcher) + + def test_get_networks(self): + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + self.fetcher.get_url = MagicMock(side_effect=[NETWORKS_RESPONSE, + SUBNETS_RESPONSE]) + self.fetcher.inv.get_by_id = MagicMock(return_value=PROJECT) + result = self.fetcher.get_networks(REGION_NAME, TOKEN) + self.assertEqual(result, NETWORKS_RESULT, "Can't get networks info") + + def test_get_networks_with_wrong_networks_response(self): + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + self.fetcher.get_url = MagicMock(return_value=WRONG_NETWORK_RESPONSE) + + result = self.fetcher.get_networks(REGION_NAME, TOKEN) + self.assertEqual(result, [], "Can't get [] when the networks " + + "response is wrong") + + def test_get_networks_with_wrong_subnet_response(self): + self.fetcher.get_region_url_nover = MagicMock(return_value=ENDPOINT) + self.fetcher.get_url = MagicMock(side_effect=[NETWORKS_RESPONSE, + WRONG_SUBNETS_RESPONSE]) + self.fetcher.inv.get_by_id = MagicMock(return_value=PROJECT) + + result = self.fetcher.get_networks(REGION_NAME, TOKEN) + + self.assertNotEqual(result, [], "Can't get networks info when the " + + "subnet response is wrong") + + def test_get(self): + original_method = self.fetcher.get_networks + self.fetcher.get_networks = MagicMock(return_value=NETWORKS_RESULT) + result = self.fetcher.get(REGION_NAME) + + self.fetcher.get_networks = original_method + self.assertEqual(result, NETWORKS_RESULT, "Can't get region networks info") + + def test_get_with_wrong_token(self): + self.fetcher.v2_auth_pwd = MagicMock(return_value=None) + result = self.fetcher.get(REGION_NAME) + self.fetcher.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.assertEqual(result, [], "Can't get [] when the " + + "token is invalid") diff --git a/app/test/fetch/api_fetch/test_api_fetch_ports.py b/app/test/fetch/api_fetch/test_api_fetch_ports.py new file mode 100644 index 0000000..ad79757 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_ports.py @@ -0,0 +1,89 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.api.api_fetch_ports import ApiFetchPorts +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_ports import * +from test.fetch.api_fetch.test_data.token import TOKEN +from unittest.mock import MagicMock + + +class TestApiFetchPorts(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchPorts.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchPorts() + self.set_regions_for_fetcher(self.fetcher) + + def check_get_ports_for_region_result_is_correct(self, network, + tenant, + port_response, + expected_result, + error_msg): + self.fetcher.get_region_url = MagicMock(return_value=ENDPOINT) + self.fetcher.get_url = MagicMock(return_value=port_response) + self.fetcher.inv.get_by_id = MagicMock(side_effect=[network, tenant]) + + result = self.fetcher.get_ports_for_region(REGION_NAME, TOKEN) + self.assertEqual(result, expected_result, error_msg) + + def test_get_ports_for_region(self): + test_cases = [ + { + "network": NETWORK, + "tenant": None, + "port_response": PORTS_RESPONSE, + "expected_result": PORTS_RESULT_WITH_NET, + "error_msg": "Can't get correct ports info " + "when network of the port exists" + }, + { + "network": None, + "tenant": None, + "port_response": PORTS_RESPONSE, + "expected_result": PORTS_RESULT_WITHOUT_NET, + "error_msg": "Can't get correct ports info " + "when network of the port doesn't exists" + }, + { + "network": NETWORK, + "tenant": TENANT, + "port_response": PORTS_RESPONSE, + "expected_result": PORTS_RESULT_WITH_PROJECT, + "error_msg": "Can't get correct ports info " + "when project of the port exists" + }, + { + "network": None, + "tenant": None, + "port_response": ERROR_PORTS_RESPONSE, + "expected_result": [], + "error_msg": "Can't get [] when ports response is wrong" + }, + ] + for test_case in test_cases: + self.check_get_ports_for_region_result_is_correct(test_case["network"], + test_case["tenant"], + test_case["port_response"], + test_case["expected_result"], + test_case["error_msg"]) + + def test_get(self): + original_method = self.fetcher.get_ports_for_region + self.fetcher.get_ports_for_region = MagicMock(return_value=PORTS_RESULT_WITH_NET) + result = self.fetcher.get(REGION_NAME) + self.fetcher.get_ports_for_region = original_method + self.assertEqual(result, PORTS_RESULT_WITH_NET, "Can't get correct ports info") + + def test_get_with_wrong_token(self): + self.fetcher.v2_auth_pwd = MagicMock(return_value=None) + result = self.fetcher.get(REGION_NAME) + self.fetcher.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.assertEqual(result, [], "Can't get [] when the token is invalid") diff --git a/app/test/fetch/api_fetch/test_api_fetch_project_hosts.py b/app/test/fetch/api_fetch/test_api_fetch_project_hosts.py new file mode 100644 index 0000000..7cedf67 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_project_hosts.py @@ -0,0 +1,137 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from unittest.mock import MagicMock +from discover.fetchers.api.api_fetch_project_hosts import ApiFetchProjectHosts +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_host_project_hosts import * +from test.fetch.api_fetch.test_data.token import TOKEN +from test.fetch.api_fetch.test_data.regions import REGIONS + + +class TestApiFetchProjectHosts(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchProjectHosts.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchProjectHosts() + self.set_regions_for_fetcher(self.fetcher) + self.region = REGIONS[REGION_NAME] + + def test_add_host_type_with_nonexistent_type(self): + # clear host type + HOST_DOC["host_type"] = [] + self.fetcher.add_host_type(HOST_DOC, NONEXISTENT_TYPE, HOST_ZONE) + self.assertIn(NONEXISTENT_TYPE, HOST_DOC["host_type"], "Can't put nonexistent " + + "type in host_type") + + def test_add_host_type_with_existent_host_type(self): + # add nonexistent host type to host type + HOST_DOC["host_type"] = [NONEXISTENT_TYPE] + # try to add existing host type + self.fetcher.add_host_type(HOST_DOC, NONEXISTENT_TYPE, HOST_ZONE) + self.assertEqual(len(HOST_DOC['host_type']), 1, "Add duplicate host type") + + def test_add_compute_host_type(self): + HOST_DOC['host_type'] = [] + # clear zone + HOST_DOC['zone'] = None + # add compute host type + self.fetcher.add_host_type(HOST_DOC, COMPUTE_TYPE, HOST_ZONE) + # for compute host type, zone information will be added + self.assertEqual(HOST_DOC['zone'], HOST_ZONE, "Can't update zone " + + "name for compute node") + self.assertEqual(HOST_DOC['parent_id'], HOST_ZONE, "Can't update parent_id " + + "for compute node") + + def test_fetch_compute_node_ip_address(self): + # mock ip address information fetched from DB + self.fetcher.get_objects_list_for_id = MagicMock(return_value=IP_ADDRESS_RESPONSE) + + self.fetcher.fetch_compute_node_ip_address(HOST_TO_BE_FETCHED_IP, + HOST_TO_BE_FETCHED_IP["host"]) + self.assertIn("ip_address", HOST_TO_BE_FETCHED_IP, "Can't update ip address " + + "for the compute host") + + def test_fetch_network_node_details(self): + # mock NETWORKS_DETAILS_RESPONSE fetched from DB + self.fetcher.get_objects_list = MagicMock(return_value=NETWORKS_DETAILS_RESPONSE) + + self.fetcher.fetch_network_node_details(HOSTS_TO_BE_FETCHED_NETWORK_DETAILS) + # get the network node document from HOSTS + NETWORK_NODE_DOC = [doc for doc in HOSTS_TO_BE_FETCHED_NETWORK_DETAILS + if doc['host'] == HOST_NAME][0] + # check if the network node document has been updated + self.assertIn("Network", NETWORK_NODE_DOC['host_type'], "Can't put Network in " + + "the network node host_type") + self.assertIn("config", NETWORK_NODE_DOC, "Can't put config in the network node") + + def test_get_host_details(self): + # test node have nova-conductor attribute, controller type will be added + result = self.fetcher.get_host_details(AVAILABILITY_ZONE, HOST_NAME) + self.assertIn("Controller", result['host_type'], "Can't put controller type " + + "in the compute node host_type") + + def test_get_hosts_from_az(self): + result = self.fetcher.get_hosts_from_az(AVAILABILITY_ZONE) + self.assertNotEqual(result, [], "Can't get hosts information from " + "availability zone") + + def test_get_for_region(self): + # mock region url for nova node + self.fetcher.get_region_url = MagicMock(return_value=REGION_URL) + # mock the response from OpenStack Api + side_effect = [AVAILABILITY_ZONE_RESPONSE, HYPERVISORS_RESPONSE] + self.fetcher.get_url = MagicMock(side_effect=side_effect) + + result = self.fetcher.get_for_region(self.region, TOKEN) + self.assertNotEqual(result, [], "Can't get hosts information for region") + + def test_get_for_region_without_token(self): + self.fetcher.get_region_url = MagicMock(return_value=REGION_URL) + result = self.fetcher.get_for_region(self.region, None) + self.assertEqual(result, [], "Can't get [] when the token is invalid") + + def test_get_for_region_with_error_availability_response(self): + self.fetcher.get_region_url = MagicMock(return_value=REGION_URL) + # mock error availability zone response from OpenStack Api + side_effect = [AVAILABILITY_ERROR_RESPONSE, None] + self.fetcher.get_url = MagicMock(side_effect=side_effect) + + result = self.fetcher.get_for_region(self.region, TOKEN) + self.assertEqual(result, [], "Can't get [] when the response is wrong") + + def test_get_for_region_with_error_hypervisors_response(self): + self.fetcher.get_region_url = MagicMock(return_value=REGION_URL) + # mock error hypervisors response from OpenStack Api + side_effect = [AVAILABILITY_ZONE_RESPONSE, HYPERVISORS_ERROR_RESPONSE] + self.fetcher.get_url = MagicMock(side_effect=side_effect) + + result = self.fetcher.get_for_region(self.region, TOKEN) + self.assertNotEqual(result, [], "Can't get hosts information when " + + "the hypervisors response is wrong") + + def test_get(self): + original_method = self.fetcher.get_for_region + self.fetcher.get_for_region = MagicMock(return_value=GET_FOR_REGION_INFO) + + result = self.fetcher.get(PROJECT_NAME) + + self.fetcher.get_for_region = original_method + + self.assertNotEqual(result, [], "Can't get hosts info for the project") + + def test_get_with_wrong_project_name(self): + result = self.fetcher.get(TEST_PROJECT_NAME) + self.assertEqual(result, [], "Can't get [] when the project name is not admin") + + def test_get_with_wrong_token(self): + self.fetcher.v2_auth_pwd = MagicMock(return_value=[]) + result = self.fetcher.get(PROJECT_NAME) + self.assertEqual(result, [], "Can't get [] when the token is invalid") diff --git a/app/test/fetch/api_fetch/test_api_fetch_projects.py b/app/test/fetch/api_fetch/test_api_fetch_projects.py new file mode 100644 index 0000000..1db4237 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_projects.py @@ -0,0 +1,120 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from unittest.mock import MagicMock +from discover.fetchers.api.api_fetch_projects import ApiFetchProjects +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_projects import * +from test.fetch.api_fetch.test_data.regions import REGIONS +from test.fetch.api_fetch.test_data.token import TOKEN + + +class TestApiFetchProjects(TestFetch): + + def setUp(self): + self.configure_environment() + ApiFetchProjects.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.fetcher = ApiFetchProjects() + self.set_regions_for_fetcher(self.fetcher) + self.region = REGIONS[REGION_NAME] + self.fetcher.get_region_url_nover = MagicMock(return_value=REGION_URL_NOVER) + + def test_get_for_region(self): + # mock request endpoint + self.fetcher.get_region_url_nover = MagicMock(return_value=REGION_URL_NOVER) + self.fetcher.get_url = MagicMock(return_value=REGION_RESPONSE) + + result = self.fetcher.get_for_region(self.region, TOKEN) + self.assertEqual(result, REGION_RESULT, "Can't get correct projects info") + + # TODO does this test case make sense? + def test_get_for_region_with_error_region_response(self): + self.fetcher.get_region_url_nover = MagicMock(return_value=REGION_URL_NOVER) + self.fetcher.get_url = MagicMock(return_value=REGION_ERROR_RESPONSE) + + result = self.fetcher.get_for_region(self.region, TOKEN) + self.assertEqual(result, [], "Can't get [] when the " + + "region response is wrong") + + def test_get_projects_for_api_user(self): + # mock the responses from OpenStack Api + self.fetcher.get_url = MagicMock(return_value=PROJECTS_CORRECT_RESPONSE) + + result = self.fetcher.get_projects_for_api_user(self.region, TOKEN) + self.assertEqual(result, PROJECT_RESULT, "Can't get correct " + + "projects info for api user") + + def test_get_projects_for_api_user_without_projects_response(self): + # the projects info from OpenStack Api will be None + self.fetcher.get_url = MagicMock(return_value= + PROJECTS_RESPONSE_WITHOUT_PROJECTS) + + result = self.fetcher.get_projects_for_api_user(self.region, TOKEN) + self.assertIs(result, None, "Can't get None when the project " + + "response doesn't contain projects info") + + def check_get_result(self, projects_for_api_user, + region_result, + token, + expected_result, error_msg): + self.fetcher.get_projects_for_api_user = MagicMock(return_value= + projects_for_api_user) + original_method = self.fetcher.get_for_region + # mock + self.fetcher.get_for_region = MagicMock(return_value=region_result) + self.fetcher.v2_auth_pwd = MagicMock(return_value=token) + + result = self.fetcher.get(PROJECT_ID) + + self.fetcher.get_for_region = original_method + self.assertEqual(result, expected_result, error_msg) + + def test_get(self): + # test get method with different test cases + test_cases = [ + { + "projects": PROJECT_RESULT, + "regions": REGION_RESULT, + "token": TOKEN, + "expected_result": REGION_RESULT, + "err_msg": "Can't get correct project result" + }, + { + "projects": PROJECT_RESULT, + "regions": REGION_RESULT_WITH_NON_USER_PROJECT, + "token": TOKEN, + "expected_result": REGION_RESULT, + "err_msg": "Can't get correct project result" + + "when the region result contains project " + + "that doesn't belong to the user" + }, + { + "projects": PROJECT_RESULT, + "regions": REGION_RESULT, + "token": None, + "expected_result": [], + "err_msg": "Can't get [] when the token is invalid" + }, + { + "projects": None, + "regions": REGION_RESULT, + "token": TOKEN, + "expected_result": REGION_RESULT, + "err_msg": "Can't get the region " + + "result if the projects " + + "for the user doesn't exist" + } + ] + + for test_case in test_cases: + self.check_get_result(test_case["projects"], + test_case["regions"], + test_case["token"], + test_case["expected_result"], + test_case["err_msg"]) diff --git a/app/test/fetch/api_fetch/test_api_fetch_regions.py b/app/test/fetch/api_fetch/test_api_fetch_regions.py new file mode 100644 index 0000000..1ff7999 --- /dev/null +++ b/app/test/fetch/api_fetch/test_api_fetch_regions.py @@ -0,0 +1,41 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.api.api_access import ApiAccess +from discover.fetchers.api.api_fetch_regions import ApiFetchRegions +from test.fetch.test_fetch import TestFetch +from test.fetch.api_fetch.test_data.api_fetch_regions import * +from test.fetch.api_fetch.test_data.token import TOKEN +from unittest.mock import MagicMock + + +class TestApiFetchRegions(TestFetch): + + def setUp(self): + ApiFetchRegions.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.configure_environment() + + def test_get(self): + fetcher = ApiFetchRegions() + fetcher.set_env(ENV) + + ApiAccess.auth_response = AUTH_RESPONSE + ret = fetcher.get("test_id") + self.assertEqual(ret, REGIONS_RESULT, + "Can't get correct regions information") + + def test_get_without_token(self): + fetcher = ApiFetchRegions() + fetcher.v2_auth_pwd = MagicMock(return_value=[]) + fetcher.set_env(ENV) + + ret = fetcher.get("test_id") + + ApiFetchRegions.v2_auth_pwd = MagicMock(return_value=TOKEN) + self.assertEqual(ret, [], "Can't get [] when the token is invalid") diff --git a/app/test/fetch/api_fetch/test_data/__init__.py b/app/test/fetch/api_fetch/test_data/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/api_fetch/test_data/api_access.py b/app/test/fetch/api_fetch/test_data/api_access.py new file mode 100644 index 0000000..2181c48 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_access.py @@ -0,0 +1,55 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from datetime import datetime, timedelta + + +TIME_WITH_DOT = "2016-10-19T23:21:09.418406Z" +TIME_WITHOUT_DOT = "2016-10-19T23:21:09Z" +ILLEGAL_TIME = "23243423" +TEST_PROJECT = "test" +PROJECT = "admin" +TEST_URL = "test_url" +TEST_HEADER = "test_headers" +TEST_BODY = "test_body" + +RESPONSE = { + 'server': 'Apache', + 'vary': 'X-Auth-Token', + 'content-type': 'application/json', + 'date': 'Wed, 19 Oct 2016 23:15:36 GMT', + 'content-length': '4876', + 'x-openstack-request-id': 'req-01cda259-7f60-4440-99a0-508fed90f815', + 'connection': 'close', + 'status': '200' +} +ERROR_RESPONSE = { + 'connection': 'close', + 'status': '400' +} +GET_CONTENT = b'{"text":"test"}' +CORRECT_AUTH_CONTENT = b'{"access": {"token": {"issued_at": "2016-10-21T23:49:50.000000Z", "expires": "2016-10-22T00:49:50.445603Z", "id": "gAAAAABYCqme1l0qCm6mi3jON4ElweTkhZjGXZ_bYuxLHZGGXgO3T_JLnxKJ7KbK4xA8KjQ-DQe2trDncKQA0M-yeX167wT0xO_rjqqcCA19JV-EeXFfx7QOukkt8eC4pfK1r8Dc_kvBc-bwAemjZ1IvPGu5Nd2f0ktGWre0Qqzbg9QGtCEJUe8", "tenant": {"is_domain": false, "description": "admin tenant", "enabled": true, "id": "8c1751e0ce714736a63fee3c776164da", "parent_id": null, "name": "admin"}, "audit_ids": ["8BvzDPpyRBmeJho-FzKuGA"]}, "serviceCatalog": [{"endpoints": [{"adminURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", "region": "RegionOne", "internalURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", "id": "274cbbd9fd6d4311b78e78dd3a1df51f", "publicURL": "http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da"}], "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": "http://192.168.0.2:9696", "region": "RegionOne", "internalURL": "http://192.168.0.2:9696", "id": "8dc28584da224c4b9671171ead3c982a", "publicURL": "http://172.16.0.3:9696"}], "endpoints_links": [], "type": "network", "name": "neutron"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da", "region": "RegionOne", "internalURL": "http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da", "id": "2c30937688e944889db4a64fab6816e6", "publicURL": "http://172.16.0.3:8776/v2/8c1751e0ce714736a63fee3c776164da"}], "endpoints_links": [], "type": "volumev2", "name": "cinderv2"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8774/v3", "region": "RegionOne", "internalURL": "http://192.168.0.2:8774/v3", "id": "1df917160dfb4ce5b469764fde22b3ab", "publicURL": "http://172.16.0.3:8774/v3"}], "endpoints_links": [], "type": "computev3", "name": "novav3"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8080", "region": "RegionOne", "internalURL": "http://192.168.0.2:8080", "id": "4f655c8f2bef46a0a7ba4a20bba53666", "publicURL": "http://172.16.0.3:8080"}], "endpoints_links": [], "type": "s3", "name": "swift_s3"}, {"endpoints": [{"adminURL": "http://192.168.0.2:9292", "region": "RegionOne", "internalURL": "http://192.168.0.2:9292", "id": "475c6c77a94e4e63a5a0f0e767f697a8", "publicURL": "http://172.16.0.3:9292"}], "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8777", "region": "RegionOne", "internalURL": "http://192.168.0.2:8777", "id": "617177a3dcb64560a5a79ab0a91a7225", "publicURL": "http://172.16.0.3:8777"}], "endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8000/v1", "region": "RegionOne", "internalURL": "http://192.168.0.2:8000/v1", "id": "0f04ec6ed49f4940822161bf677bdfb2", "publicURL": "http://172.16.0.3:8000/v1"}], "endpoints_links": [], "type": "cloudformation", "name": "heat-cfn"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da", "region": "RegionOne", "internalURL": "http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da", "id": "05643f2cf9094265b432376571851841", "publicURL": "http://172.16.0.3:8776/v1/8c1751e0ce714736a63fee3c776164da"}], "endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8773/services/Admin", "region": "RegionOne", "internalURL": "http://192.168.0.2:8773/services/Cloud", "id": "390dddc753cc4d378b489129d06c4b7d", "publicURL": "http://172.16.0.3:8773/services/Cloud"}], "endpoints_links": [], "type": "ec2", "name": "nova_ec2"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da", "region": "RegionOne", "internalURL": "http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da", "id": "9e60268a5aaf422d9e42f0caab0a19b4", "publicURL": "http://172.16.0.3:8004/v1/8c1751e0ce714736a63fee3c776164da"}], "endpoints_links": [], "type": "orchestration", "name": "heat"}, {"endpoints": [{"adminURL": "http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da", "region": "RegionOne", "internalURL": "http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da", "id": "12e78e06595f48339baebdb5d4309c70", "publicURL": "http://172.16.0.3:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da"}], "endpoints_links": [], "type": "object-store", "name": "swift"}, {"endpoints": [{"adminURL": "http://192.168.0.2:35357/v2.0", "region": "RegionOne", "internalURL": "http://192.168.0.2:5000/v2.0", "id": "404cceb349614eb39857742970408301", "publicURL": "http://172.16.0.3:5000/v2.0"}], "endpoints_links": [], "type": "identity", "name": "keystone"}], "user": {"username": "admin", "roles_links": [], "name": "admin", "roles": [{"id": "888bdf92213a477ba9f10554bc382e57", "name": "admin"}], "enabled": true, "email": "admin@localhost", "id": "13baa553aae44adca6615e711fd2f6d9"}, "metadata": {"is_admin": 0, "roles": []}}}' +ERROR_AUTH_CONTENT = b'{"access": {}}' +ERROR_TOKEN_CONTENT = b'{"error":{"code":"code","title":"title","message":"message",", URL":"URL"},"access": {}}' + +VALID_TOKENS = { + PROJECT: { + # make sure the expired time of the token is later than now + "expires": (datetime.now() + timedelta(1)).strftime("%Y-%m-%dT%H:%M:%SZ") + } +} + +EMPTY_TOKENS = {} + +REGION_NAME = "RegionOne" +ERROR_REGION_NAME = "ERROR" +SERVICE_NAME = "nova" +ERROR_SERVICE_NAME = "ERROR" + +REGION_URL = "http://10.56.20.239:8774/v2/329e0576da594c62a911d0dccb1238a7" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_availability_zones.py b/app/test/fetch/api_fetch/test_data/api_fetch_availability_zones.py new file mode 100644 index 0000000..f6e717c --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_availability_zones.py @@ -0,0 +1,71 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +AVAILABILITY_ZONE_RESPONSE = { + "availabilityZoneInfo": [ + { + "hosts": { + "node-6.cisco.com": { + } + }, + "zoneName": "internal", + "zoneState": { + "available": True + } + }, + { + "hosts": { + "node-5.cisco.com": { + } + }, + "zoneName": "osdna-zone", + "zoneState": { + "available": True + } + } + ] +} +GET_REGION_RESULT = [ + { + "available": True, + "hosts": { + "node-6.cisco.com": { + } + }, + "id": "internal", + "master_parent_id": "RegionOne", + "master_parent_type": "region", + "name": "internal", + "parent_id": "RegionOne-availability_zones", + "parent_text": "Availability Zones", + "parent_type": "availability_zones_folder" + }, + { + "available": True, + "hosts": { + "node-5.cisco.com": { + } + }, + "id": "osdna-zone", + "master_parent_id": "RegionOne", + "master_parent_type": "region", + "name": "osdna-zone", + "parent_id": "RegionOne-availability_zones", + "parent_text": "Availability Zones", + "parent_type": "availability_zones_folder" + } +] +RESPONSE_WITHOUT_AVAILABILITY_ZONE = {"text": "test"} +WRONG_RESPONSE = {"status": 400} +EMPTY_AVAILABILITY_ZONE_RESPONSE = { + "availabilityZoneInfo": [] +} +ENDPOINT = "http://10.56.20.239:8774" +PROJECT = "admin" +REGION_NAME = "RegionOne" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_host_instances.py b/app/test/fetch/api_fetch/test_data/api_fetch_host_instances.py new file mode 100644 index 0000000..d6f8ea6 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_host_instances.py @@ -0,0 +1,85 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +PROJECT_LIST = [ + { + 'name': 'OSDNA-project', + }, + { + 'name': 'admin', + } +] + +HOST = { + 'host_type': ['Compute'], +} + +NON_COMPUTE_HOST = { + 'host_type': [], +} + +HOST_NAME = "node-5.cisco.com" + +GET_INSTANCES_FROM_API = [ + { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "local_name": "instance-00000002", + "uuid": "6f29c867-9150-4533-8e19-70d749b172fa" + }, + { + "host": "node-5.cisco.com", + "id": "79e20dbf-a46d-46ee-870b-e0c9f7b357d9", + "local_name": "instance-0000001c", + "uuid": "79e20dbf-a46d-46ee-870b-e0c9f7b357d9" + }, + { + "host": "node-5.cisco.com", + "id": "bf0cb914-b316-486c-a4ce-f22deb453c52", + "local_name": "instance-00000026", + "uuid": "bf0cb914-b316-486c-a4ce-f22deb453c52" + } +] + +GET_SERVERS_RESPONSE = { + "hypervisors": [ + { + "hypervisor_hostname": "node-5.cisco.com", + "id": 1, + "servers": [ + { + "name": "instance-00000002", + "uuid": "6f29c867-9150-4533-8e19-70d749b172fa" + }, + { + "name": "instance-0000001c", + "uuid": "79e20dbf-a46d-46ee-870b-e0c9f7b357d9" + }, + { + "name": "instance-00000026", + "uuid": "bf0cb914-b316-486c-a4ce-f22deb453c52" + } + ] + } + ] +} + +RESPONSE_WITHOUT_HYPERVISORS = { + "text": "test" +} + +RESPONSE_WITHOUT_SERVERS = { + "hypervisors": [ + { + + } + ] +} + +INSTANCE_FOLDER_ID = "node-5.cisco.com-instances" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_host_project_hosts.py b/app/test/fetch/api_fetch/test_data/api_fetch_host_project_hosts.py new file mode 100644 index 0000000..3ef1ac7 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_host_project_hosts.py @@ -0,0 +1,225 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +HOST_DOC = { + "host": "node-6.cisco.com", + "host_type": [], + "id": "node-6.cisco.com", + "name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-cert": { + "active": True, + "available": True, + }, + "nova-conductor": { + "active": True, + "available": True, + }, + "nova-consoleauth": { + "active": True, + "available": True, + }, + "nova-scheduler": { + "active": True, + "available": True, + } + }, + "zone": "internal" +} + +NONEXISTENT_TYPE = "nova" +COMPUTE_TYPE = "Compute" +ZONE = "internal" +HOST_ZONE = "Test" + +REGION_NAME = "RegionOne" +TEST_PROJECT_NAME = "Test" +PROJECT_NAME = "admin" + +AVAILABILITY_ZONE_RESPONSE = { + "availabilityZoneInfo": [ + { + "hosts": { + "node-6.cisco.com": { + "nova-cert": { + "active": True, + "available": True, + }, + "nova-conductor": { + "active": True, + "available": True, + }, + "nova-consoleauth": { + "active": True, + "available": True, + }, + "nova-scheduler": { + "active": True, + "available": True, + } + } + }, + "zoneName": "internal", + "zoneState": { + "available": True + } + }, + { + "hosts": { + "node-5.cisco.com": { + "nova-compute": { + "active": True, + "available": True, + } + } + }, + "zoneName": "osdna-zone", + "zoneState": { + "available": True + } + } + ] +} + +AVAILABILITY_ERROR_RESPONSE = {'status': 400} + +HYPERVISORS_RESPONSE = { + "hypervisors": [] +} + +HYPERVISORS_ERROR_RESPONSE = {'status': 400} + +HOST_TO_BE_FETCHED_IP = { + "host": "node-5.cisco.com", + "id": "node-5.cisco.com" +} + +IP_ADDRESS_RESPONSE = [ + { + "ip_address": "192.168.0.4" + } +] + +HOSTS_TO_BE_FETCHED_NETWORK_DETAILS = [ + { + "host": "node-6.cisco.com", + "host_type": [ + "Controller" + ], + "id": "node-6.cisco.com", + "name": "node-6.cisco.com", + }, + { + "host": "node-5.cisco.com", + "host_type": [ + "Compute" + ], + "id": "node-5.cisco.com", + "name": "node-5.cisco.com", + } +] + +NETWORKS_DETAILS_RESPONSE = [ + { + "configurations": "{}", + "host": "node-6.cisco.com" + }, + { + "configurations": "{}", + "host": "node-6.cisco.com", + }, + { + "configurations": "{}", + "host": "node-6.cisco.com", + } +] + +REGION_URL = "http://192.168.0.2:8776/v2/329e0576da594c62a911d0dccb1238a7" +AVAILABILITY_ZONE = { + "hosts": { + "node-6.cisco.com": { + "nova-cert": { + "active": True, + "available": True, + }, + "nova-conductor": { + "active": True, + "available": True, + }, + "nova-consoleauth": { + "active": True, + "available": True, + }, + "nova-scheduler": { + "active": True, + "available": True, + } + } + }, + "zoneName": "internal" +} + +HOST_NAME = "node-6.cisco.com" + +GET_FOR_REGION_INFO = [ + { + "config": { + }, + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-cert": { + "active": True, + "available": True, + }, + "nova-conductor": { + "active": True, + "available": True, + }, + "nova-consoleauth": { + "active": True, + "available": True, + }, + "nova-scheduler": { + "active": True, + "available": True, + } + }, + "zone": "internal" + }, + { + "host": "node-5.cisco.com", + "host_type": [ + "Compute" + ], + "id": "node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com", + "os_id": "1", + "parent_id": "osdna-zone", + "parent_type": "availability_zone", + "services": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:22:42.000000" + } + }, + "zone": "osdna-zone" + } +] diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_networks.py b/app/test/fetch/api_fetch/test_data/api_fetch_networks.py new file mode 100644 index 0000000..5079a92 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_networks.py @@ -0,0 +1,72 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +NETWORKS_RESPONSE = { + "networks": [ + { + "id": "8673c48a-f137-4497-b25d-08b7b218fd17", + "subnets": [ + "cae3c81d-9a27-48c4-b8f6-32867ca03134" + ], + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + ] +} + +NETWORKS_RESULT = [ + { + "id": "8673c48a-f137-4497-b25d-08b7b218fd17", + "subnets": { + "test23": { + "cidr": "172.16.12.0/24", + "id": "cae3c81d-9a27-48c4-b8f6-32867ca03134", + "name": "test23", + "network_id": "0abe6331-0d74-4bbd-ad89-a5719c3793e4", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + }, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "master_parent_type": "project", + "master_parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "parent_type": "networks_folder", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "project": "Calipso-project", + "cidrs": ["172.16.12.0/24"], + "subnet_ids": ["cae3c81d-9a27-48c4-b8f6-32867ca03134"], + "network": "8673c48a-f137-4497-b25d-08b7b218fd17" + } +] + +WRONG_NETWORK_RESPONSE = { +} + +SUBNETS_RESPONSE = { + "subnets": [ + { + "cidr": "172.16.12.0/24", + "id": "cae3c81d-9a27-48c4-b8f6-32867ca03134", + "name": "test23", + "network_id": "0abe6331-0d74-4bbd-ad89-a5719c3793e4", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + ] +} + +ENDPOINT = "http://10.56.20.239:9696" +WRONG_SUBNETS_RESPONSE = {} + +PROJECT = { + "description": "", + "enabled": True, + "id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "name": "Calipso-project" + } + +REGION_NAME = "RegionOne" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_ports.py b/app/test/fetch/api_fetch/test_data/api_fetch_ports.py new file mode 100644 index 0000000..fc0552c --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_ports.py @@ -0,0 +1,72 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +PORTS_RESPONSE = { + "ports": [ + { + "id": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "mac_address": "fa:16:3e:d7:c5:16", + "name": "", + "network_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + ] +} + +PORTS_RESULT_WITH_NET = [ + { + "id": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "mac_address": "fa:16:3e:d7:c5:16", + "name": "fa:16:3e:d7:c5:16", + "network_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "master_parent_type": "network", + "master_parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "parent_type": "ports_folder", + "parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe-ports", + "parent_text": "Ports", + } +] + +PORTS_RESULT_WITHOUT_NET = [ + { + "id": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "mac_address": "fa:16:3e:d7:c5:16", + "name": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "network_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "master_parent_type": "network", + "master_parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "parent_type": "ports_folder", + "parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe-ports", + "parent_text": "Ports", + } +] + +PORTS_RESULT_WITH_PROJECT = [ + { + "id": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "mac_address": "fa:16:3e:d7:c5:16", + "name": "fa:16:3e:d7:c5:16", + "network_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "master_parent_type": "network", + "master_parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "parent_type": "ports_folder", + "parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe-ports", + "parent_text": "Ports", + "project": "Calipso-project" + } +] + +ERROR_PORTS_RESPONSE = {} +NETWORK = {"id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe"} +TENANT = {"id": "75c0eb79ff4a42b0ae4973c8375ddf40", "name": "Calipso-project"} +ENDPOINT = "http://10.56.20.239:9696" +REGION_NAME = "RegionOne" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_projects.py b/app/test/fetch/api_fetch/test_data/api_fetch_projects.py new file mode 100644 index 0000000..4b2c678 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_projects.py @@ -0,0 +1,88 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +PROJECTS_CORRECT_RESPONSE = { + "projects": [ + { + "name": "Calipso-project" + }, + { + "name": "admin", + } + ] +} + +PROJECT_RESULT = [ + "Calipso-project", + "admin" +] + +PROJECTS_RESPONSE_WITHOUT_PROJECTS = "" + +REGION_PROJECTS = [ + { + "description": "", + "enabled": True, + "id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "name": "OSDNA-project" + }, + { + "description": "admin tenant", + "enabled": True, + "id": "8c1751e0ce714736a63fee3c776164da", + "name": "admin" + } +] + +USERS_PROJECTS = [ + "OSDNA-project", + "admin" +] + +REGION_URL_NOVER = "http://10.56.20.239:35357" + +REGION_RESPONSE = { + "tenants": [ + { + "name": "Calipso-project" + }, + { + "name": "admin" + }, + { + "name": "services" + } + ] +} + +REGION_RESULT = [ + { + "name": "Calipso-project" + }, + { + "name": "admin" + } +] + +REGION_RESULT_WITH_NON_USER_PROJECT = [ + { + "name": "Calipso-project" + }, + { + "name": "admin" + }, + { + "name": "non-user project" + } +] + +REGION_ERROR_RESPONSE = [] + +REGION_NAME = "RegionOne" +PROJECT_ID = "admin" diff --git a/app/test/fetch/api_fetch/test_data/api_fetch_regions.py b/app/test/fetch/api_fetch/test_data/api_fetch_regions.py new file mode 100644 index 0000000..bd7be78 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/api_fetch_regions.py @@ -0,0 +1,50 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +REGION = "RegionOne" +ENV = "Mirantis-Liberty" + +AUTH_RESPONSE = { + "access": { + "serviceCatalog": [ + { + "endpoints": [ + { + "adminURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "id": "274cbbd9fd6d4311b78e78dd3a1df51f", + "internalURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "nova", + "type": "compute" + } + ] + } +} + +REGIONS_RESULT = [ + { + "id": "RegionOne", + "endpoints": { + "nova": { + "adminURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "id": "274cbbd9fd6d4311b78e78dd3a1df51f", + "internalURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da", + "service_type": "compute" + } + }, + "name": "RegionOne", + "parent_type": "regions_folder", + "parent_id": ENV + "-regions", + } +] diff --git a/app/test/fetch/api_fetch/test_data/configurations.py b/app/test/fetch/api_fetch/test_data/configurations.py new file mode 100644 index 0000000..ba15346 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/configurations.py @@ -0,0 +1,52 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +CONFIGURATIONS = { + "configuration": [ + { + "mock": "True", + "host": "10.56.20.239", + "name": "mysql", + "password": "102QreDdiD5sKcvNf9qbHrmr", + "port": 3307.0, + "user": "root", + "schema": "nova" + }, + { + "name": "OpenStack", + "host": "10.56.20.239", + "admin_token": "38MUh19YWcgQQUlk2VEFQ7Ec", + "port": "5000", + "user": "admin", + "pwd": "admin" + }, + { + "host": "10.56.20.239", + "key": "/Users/xiaocdon/.ssh/id_rsa", + "name": "CLI", + "pwd": "", + "user": "root" + }, + { + "name": "AMQP", + "host": "10.56.20.239", + "port": "5673", + "user": "nova", + "password": "NF2nSv3SisooxPkCTr8fbfOa" + } + ], + "distribution": "Mirantis-8.0", + "last_scanned:": "5/8/16", + "name": "Mirantis-Liberty-Xiaocong", + "network_plugins": [ + "OVS" + ], + "operational": "yes", + "type": "environment" +}
\ No newline at end of file diff --git a/app/test/fetch/api_fetch/test_data/regions.py b/app/test/fetch/api_fetch/test_data/regions.py new file mode 100644 index 0000000..9945386 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/regions.py @@ -0,0 +1,110 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +REGIONS = { + "RegionOne": { + "endpoints": { + "ceilometer": { + "adminURL": "http://192.168.0.2:8777", + "id": "617177a3dcb64560a5a79ab0a91a7225", + "internalURL": "http://192.168.0.2:8777", + "publicURL": "http://172.16.0.3:8777", + "service_type": "metering" + }, + "cinder": { + "adminURL": "http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da", + "id": "05643f2cf9094265b432376571851841", + "internalURL": "http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8776/v1/8c1751e0ce714736a63fee3c776164da", + "service_type": "volume" + }, + "cinderv2": { + "adminURL": "http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da", + "id": "2c30937688e944889db4a64fab6816e6", + "internalURL": "http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8776/v2/8c1751e0ce714736a63fee3c776164da", + "service_type": "volumev2" + }, + "glance": { + "adminURL": "http://192.168.0.2:9292", + "id": "475c6c77a94e4e63a5a0f0e767f697a8", + "internalURL": "http://192.168.0.2:9292", + "publicURL": "http://172.16.0.3:9292", + "service_type": "image" + }, + "heat": { + "adminURL": "http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da", + "id": "9e60268a5aaf422d9e42f0caab0a19b4", + "internalURL": "http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8004/v1/8c1751e0ce714736a63fee3c776164da", + "service_type": "orchestration" + }, + "heat-cfn": { + "adminURL": "http://192.168.0.2:8000/v1", + "id": "0f04ec6ed49f4940822161bf677bdfb2", + "internalURL": "http://192.168.0.2:8000/v1", + "publicURL": "http://172.16.0.3:8000/v1", + "service_type": "cloudformation" + }, + "keystone": { + "adminURL": "http://192.168.0.2:35357/v2.0", + "id": "404cceb349614eb39857742970408301", + "internalURL": "http://192.168.0.2:5000/v2.0", + "publicURL": "http://172.16.0.3:5000/v2.0", + "service_type": "identity" + }, + "neutron": { + "adminURL": "http://192.168.0.2:9696", + "id": "8dc28584da224c4b9671171ead3c982a", + "internalURL": "http://192.168.0.2:9696", + "publicURL": "http://172.16.0.3:9696", + "service_type": "network" + }, + "nova": { + "adminURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "id": "274cbbd9fd6d4311b78e78dd3a1df51f", + "internalURL": "http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da", + "service_type": "compute" + }, + "nova_ec2": { + "adminURL": "http://192.168.0.2:8773/services/Admin", + "id": "390dddc753cc4d378b489129d06c4b7d", + "internalURL": "http://192.168.0.2:8773/services/Cloud", + "publicURL": "http://172.16.0.3:8773/services/Cloud", + "service_type": "ec2" + }, + "novav3": { + "adminURL": "http://192.168.0.2:8774/v3", + "id": "1df917160dfb4ce5b469764fde22b3ab", + "internalURL": "http://192.168.0.2:8774/v3", + "publicURL": "http://172.16.0.3:8774/v3", + "service_type": "computev3" + }, + "swift": { + "adminURL": "http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da", + "id": "12e78e06595f48339baebdb5d4309c70", + "internalURL": "http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da", + "publicURL": "http://172.16.0.3:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da", + "service_type": "object-store" + }, + "swift_s3": { + "adminURL": "http://192.168.0.2:8080", + "id": "4f655c8f2bef46a0a7ba4a20bba53666", + "internalURL": "http://192.168.0.2:8080", + "publicURL": "http://172.16.0.3:8080", + "service_type": "s3" + } + }, + "id": "RegionOne", + "name": "RegionOne", + "parent_id": "Mirantis-Liberty-Xiaocong-regions", + "parent_type": "regions_folder" + } +}
\ No newline at end of file diff --git a/app/test/fetch/api_fetch/test_data/token.py b/app/test/fetch/api_fetch/test_data/token.py new file mode 100644 index 0000000..2abbdd8 --- /dev/null +++ b/app/test/fetch/api_fetch/test_data/token.py @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +TOKEN = {'tenant': { + 'description': 'admin tenant', + 'name': 'admin', + 'is_domain': False, + 'id': '8c1751e0ce714736a63fee3c776164da', + 'enabled': True, + 'parent_id': None + }, + 'issued_at': '2016-10-19T23:06:29.000000Z', + 'expires': '2016-10-20T00:06:28.615780Z', + 'id': 'gAAAAABYB_x10x_6AlA2Y5RJZ6HCcCDSXe0f8vfisKnOM_XCDZvwl2qiwzCQIOYX9mCmRyGojZ2JEjIb0vHL0f0hxqSq84g5jbZpN0h0Un_RkTZXSKf0K1uigbr3q__ilhctLvwWNem6XQSGrav1fQrec_DjdvUxSwuoBSSo82kKQ7SvPSdVwrA', + 'token_expiry_time': 1476921988, + 'audit_ids': ['2Ps0lRlHRIG80FWamMkwWg'] +}
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/__init__.py b/app/test/fetch/cli_fetch/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/cli_fetch/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/cli_fetch/test_cli_access.py b/app/test/fetch/cli_fetch/test_cli_access.py new file mode 100644 index 0000000..f393538 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_access.py @@ -0,0 +1,159 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +import time + +from discover.fetchers.cli.cli_access import CliAccess +from test.fetch.cli_fetch.test_data.cli_access import * +from test.fetch.test_fetch import TestFetch +from unittest.mock import MagicMock, patch +from utils.ssh_conn import SshConn + + +class TestCliAccess(TestFetch): + + def setUp(self): + self.configure_environment() + self.cli_access = CliAccess() + + @patch("utils.ssh_conn.SshConn.exec") + def check_run_result(self, is_gateway_host, + enable_cache, + cached_command_result, exec_result, + expected_result, err_msg, + ssh_con_exec): + # mock cached commands + if not is_gateway_host: + self.cli_access.cached_commands = { + NON_GATEWAY_CACHED_COMMAND: cached_command_result + } + else: + self.cli_access.cached_commands = { + GATEWAY_CACHED_COMMAND: cached_command_result + } + original_is_gateway_host = SshConn.is_gateway_host + SshConn.is_gateway_host = MagicMock(return_value=is_gateway_host) + ssh_con_exec.return_value = exec_result + result = self.cli_access.run(COMMAND, COMPUTE_HOST_ID, + on_gateway=False, enable_cache=enable_cache) + self.assertEqual(result, expected_result, err_msg) + + # reset the cached commands after testing + self.cli_access.cached_commands = {} + # reset method + SshConn.is_gateway_host = original_is_gateway_host + + def test_run(self): + curr_time = time.time() + test_cases = [ + { + "is_gateway_host": True, + "enable_cache": False, + "cached_command_result": None, + "exec_result": RUN_RESULT, + "expected_result": RUN_RESULT, + "err_msg": "Can't get the " + + "result of the command" + }, + { + "is_gateway_host": True, + "enable_cache": True, + "cached_command_result": { + "timestamp": curr_time, + "result": CACHED_COMMAND_RESULT + }, + "exec_result": None, + "expected_result": CACHED_COMMAND_RESULT, + "err_msg": "Can't get the cached " + + "result of the command " + + "when the host is a gateway host" + }, + { + "is_gateway_host": False, + "enable_cache": True, + "cached_command_result": { + "timestamp": curr_time, + "result": CACHED_COMMAND_RESULT + }, + "exec_result": None, + "expected_result": CACHED_COMMAND_RESULT, + "err_msg": "Can't get the cached " + + "result of the command " + + "when the host is not a gateway host" + }, + { + "is_gateway_host": True, + "enable_cache": True, + "cached_command_result": { + "timestamp": curr_time - self.cli_access.cache_lifetime, + "result": CACHED_COMMAND_RESULT + }, + "exec_result": RUN_RESULT, + "expected_result": RUN_RESULT, + "err_msg": "Can't get the result " + + "of the command when the cached result expired " + + "and the host is a gateway host" + }, + { + "is_gateway_host": False, + "enable_cache": True, + "cached_command_result": { + "timestamp": curr_time - self.cli_access.cache_lifetime, + "result": CACHED_COMMAND_RESULT + }, + "exec_result": RUN_RESULT, + "expected_result": RUN_RESULT, + "err_msg": "Can't get the result " + + "of the command when the cached result expired " + + "and the host is a not gateway host" + } + ] + + for test_case in test_cases: + self.check_run_result(test_case["is_gateway_host"], + test_case["enable_cache"], + test_case["cached_command_result"], + test_case["exec_result"], + test_case["expected_result"], + test_case["err_msg"]) + + def test_run_fetch_lines(self): + original_run = self.cli_access.run + self.cli_access.run = MagicMock(return_value=RUN_RESULT) + + result = self.cli_access.run_fetch_lines(COMMAND, COMPUTE_HOST_ID) + + self.assertEqual(result, FETCH_LINES_RESULT, + "Can't get correct result of the command line") + self.cli_access.run = original_run + + def test_run_fetch_lines_with_empty_command_result(self): + original_run = self.cli_access.run + self.cli_access.run = MagicMock(return_value="") + + result = self.cli_access.run_fetch_lines(COMMAND, COMPUTE_HOST_ID) + self.assertEqual(result, [], "Can't get [] when the command " + + "result is empty") + self.cli_access.run = original_run + + def test_merge_ws_spillover_lines(self): + fixed_lines = self.cli_access.merge_ws_spillover_lines(LINES_FOR_FIX) + self.assertEqual(fixed_lines, FIXED_LINES, "Can't merge the " + + "ws-separated spillover lines") + + def test_parse_line_with_ws(self): + parse_line = self.cli_access.parse_line_with_ws(LINE_FOR_PARSE, HEADERS) + self.assertEqual(parse_line, PARSED_LINE, "Can't parse the line with ws") + + def test_parse_cmd_result_with_whitespace(self): + result = self.cli_access.parse_cmd_result_with_whitespace(FIXED_LINES, + HEADERS, + remove_first=False) + self.assertEqual(result, PARSED_CMD_RESULT, + "Can't parse the cmd result with whitespace") diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics.py b/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics.py new file mode 100644 index 0000000..f5f327e --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics.py @@ -0,0 +1,135 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_host_pnics import CliFetchHostPnics +from test.fetch.cli_fetch.test_data.cli_fetch_host_pnics import * +from test.fetch.test_fetch import TestFetch +from unittest.mock import MagicMock +from unittest.mock import call + + +class TestCliFetchHostPnics(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchHostPnics() + self.fetcher.set_env(self.env) + + def check_get_result(self, host, + interface_lines, interface_names, + interface_details, expected_result, + err_msg): + original_get_by_id = self.fetcher.inv.get_by_id + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_find_interface_details = self.fetcher.find_interface_details + + self.fetcher.inv.get_by_id = MagicMock(return_value=host) + self.fetcher.run_fetch_lines = MagicMock(return_value=interface_lines) + self.fetcher.find_interface_details = MagicMock(side_effect= + interface_details) + result = self.fetcher.get(PNICS_FOLDER_ID) + self.assertEqual(result, expected_result, err_msg) + + if interface_names: + interface_calls = [call(HOST_ID, interface_name) for + interface_name in interface_names] + self.fetcher.find_interface_details.assert_has_calls(interface_calls, + any_order=True) + # reset the methods + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.find_interface_details = original_find_interface_details + + def test_get(self): + test_cases = [ + { + "host": NETWORK_NODE, + "interface_lines": INTERFACE_LINES, + "interface_names": INTERFACE_NAMES, + "interface_details": [INTERFACE, None], + "expected_results": INTERFACES_GET_RESULTS, + "err_msg": "Can't get interfaces" + }, + { + "host": [], + "interface_lines": None, + "interface_names": None, + "interface_details": None, + "expected_results": [], + "err_msg": "Can't get [] when the host " + + "doesn't exist in the database" + }, + { + "host": WRONG_NODE, + "interface_lines": None, + "interface_names": None, + "interface_details": None, + "expected_results": [], + "err_msg": "Can't get [] when the host doesn't " + + "have required host type" + }, + { + "host": NETWORK_NODE, + "interface_lines": [], + "interface_names": None, + "interface_details":None, + "expected_results": [], + "err_msg": "Can't get [] when " + + "the interface lines is []" + } + ] + for test_case in test_cases: + self.check_get_result(test_case["host"], + test_case["interface_lines"], + test_case["interface_names"], + test_case["interface_details"], + test_case["expected_results"], + test_case["err_msg"]) + + def test_find_interface_details(self): + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_handle_line = self.fetcher.handle_line + original_set_interface_data = self.fetcher.set_interface_data + + self.fetcher.run_fetch_lines = MagicMock(return_value=IFCONFIG_CM_RESULT) + self.fetcher.handle_line = MagicMock() + self.fetcher.set_interface_data = MagicMock() + + result = self.fetcher.find_interface_details(HOST_ID, INTERFACE_NAME) + + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.handle_line = original_handle_line + self.fetcher.set_interface_data = original_set_interface_data + + self.assertEqual(result, INTERFACE_DETAILS, "Can't get interface details") + + def test_handle_mac_address_line(self): + self.fetcher.handle_line(RAW_INTERFACE, MAC_ADDRESS_LINE) + self.assertEqual(RAW_INTERFACE["mac_address"], MAC_ADDRESS, + "Can't get the correct mac address") + + # Test failed, defect, result: addr: expected result: fe80::f816:3eff:fea1:eb73/64 + def test_handle_ipv6_address_line(self): + self.fetcher.handle_line(RAW_INTERFACE, IPV6_ADDRESS_LINE) + self.assertEqual(RAW_INTERFACE['IPv6 Address'], IPV6_ADDRESS, + "Can' get the correct ipv6 address") + + def test_handle_ipv4_address_line(self): + self.fetcher.handle_line(RAW_INTERFACE, IPV4_ADDRESS_LINE) + self.assertEqual(RAW_INTERFACE['IP Address'], IPV4_ADDRESS, + "Can't get the correct ipv4 address") + + def test_set_interface_data(self): + original_run_fetch_lines = self.fetcher.run_fetch_lines + self.fetcher.run_fetch_lines = MagicMock(return_value=ETHTOOL_RESULT) + self.fetcher.set_interface_data(INTERFACE_FOR_SET) + self.assertEqual(INTERFACE_FOR_SET, INTERFACE_AFTER_SET, "Can't get the attributes of the " + "interface from the CMD result") + + self.fetcher.run_fetch_lines = original_run_fetch_lines diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics_vpp.py b/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics_vpp.py new file mode 100644 index 0000000..805e36d --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_host_pnics_vpp.py @@ -0,0 +1,34 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_host_pnics_vpp import CliFetchHostPnicsVpp +from test.fetch.test_fetch import TestFetch +from unittest.mock import MagicMock +from test.fetch.cli_fetch.test_data.cli_fetch_host_pnics_vpp import * + + +class TestCliFetchHostPnicsVpp(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchHostPnicsVpp() + self.fetcher.set_env(self.env) + + def test_get(self): + # store original method + original_find_items = self.fetcher.inv.find_items + + # mock the method + self.fetcher.inv.find_items = MagicMock(return_value=VEDGES) + + result = self.fetcher.get(ID) + # reset the method + self.fetcher.inv.find_items = original_find_items + + self.assertNotEqual(result, [], "Can't get the pnics info")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_host_vservices.py b/app/test/fetch/cli_fetch/test_cli_fetch_host_vservices.py new file mode 100644 index 0000000..c33faca --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_host_vservices.py @@ -0,0 +1,132 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_host_vservices import CliFetchHostVservices +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_host_verservices import * +from unittest.mock import MagicMock + + +class TestCliFetchHostVservices(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchHostVservices() + self.fetcher.set_env(self.env) + + def test_get(self): + # store original get_single method + original_get_single = self.fetcher.inv.get_single + # mock the host data + self.fetcher.inv.get_single = MagicMock(return_value=NETWORK_HOST) + # store original run_fetch_lines method + original_run_fetch_lines = self.fetcher.run_fetch_lines + # mock command line results + self.fetcher.run_fetch_lines = MagicMock(return_value=NAMESPACES) + + # only test the logic on get method, mock the set_details method + original_set_details = self.fetcher.set_details + self.fetcher.set_details = MagicMock() + + result = self.fetcher.get(NETWORK_HOST['id']) + # reset methods + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.set_details = original_set_details + self.fetcher.inv.get_single = original_get_single + + self.assertNotEqual(result, [], "Can't get verservices") + + def test_get_with_wrong_host_type(self): + # store original get_single method + original_get_single = self.fetcher.inv.get_single + # mock the host data + self.fetcher.inv.get_single = MagicMock(return_value=COMPUTE_HOST) + result = self.fetcher.get(COMPUTE_HOST['id']) + + self.fetcher.inv.get_single = original_get_single + + self.assertEqual(result, [], "Can't get empty array when the host_type doesn't contain Network") + + def test_set_details(self): + # store orginal methods + original_get_router_name = self.fetcher.get_router_name + original_get_network_name = self.fetcher.get_network_name + original_get_type = self.fetcher.agents_list.get_type + + # mock methods + self.fetcher.get_network_name = MagicMock(return_value=ROUTER[0]['name']) + self.fetcher.get_router_name = MagicMock(return_value=ROUTER[0]['name']) + self.fetcher.agents_list.get_type = MagicMock(return_value=AGENT) + + self.fetcher.set_details(NETWORK_HOST['id'], LOCAL_SERVICES_IDS[0]) + + # reset methods + self.fetcher.get_network_name = original_get_network_name + self.fetcher.get_router_name = original_get_router_name + self.fetcher.agents_list.get_type = original_get_type + + self.assertIn("name", LOCAL_SERVICES_IDS[0], "Can't add name") + self.assertIn("parent_id", LOCAL_SERVICES_IDS[0], "Can't add parent id") + + def test_get_network_name(self): + # store original method + original_get_objects_list_for_id = self.fetcher.get_objects_list_for_id + # mock the result + self.fetcher.get_objects_list_for_id = MagicMock(return_value=ROUTER) + + name = self.fetcher.get_network_name(ID_CLEAN) + + self.fetcher.get_objects_list_for_id = original_get_objects_list_for_id + self.assertEqual(name, ROUTER[0]['name'], "Can't get network name") + + def test_get_network_without_router(self): + # store original method + original_get_objects_list_for_id = self.fetcher.get_objects_list_for_id + # mock the result + self.fetcher.get_objects_list_for_id = MagicMock(return_value=[]) + + name = self.fetcher.get_network_name(ID_CLEAN) + + self.fetcher.get_objects_list_for_id = original_get_objects_list_for_id + self.assertEqual(name, ID_CLEAN, "Can't use the id as the name when network info from database is empty") + + def test_get_router_name(self): + # store original method + original_get_objects_list_for_id = self.fetcher.get_objects_list_for_id + # mock the result + self.fetcher.get_objects_list_for_id = MagicMock(return_value=ROUTER) + + name = self.fetcher.get_router_name(LOCAL_SERVICES_IDS[0], ID_CLEAN) + + self.fetcher.get_objects_list_for_id = original_get_objects_list_for_id + + self.assertIn("name", LOCAL_SERVICES_IDS[0], "Can't get network name") + self.assertEqual(name, ROUTER[0]['name'], "Can't get router name") + + def test_set_agent_type(self): + # store original get_type method + original_get_type = self.fetcher.agents_list.get_type + self.fetcher.agents_list.get_type = MagicMock(return_value=AGENT) + + self.fetcher.set_agent_type(VSERVICE) + # reset method + self.fetcher.set_agent_type = original_get_type + self.assertIn("parent_id", VSERVICE, "Can't add parent id to vservice document") + + def test_set_agent_type_without_agent(self): + # store original get_type method + original_get_type = self.fetcher.agents_list.get_type + self.fetcher.agents_list.get_type = MagicMock(return_value={}) + + self.fetcher.set_agent_type(VSERVICE) + # reset method + self.fetcher.set_agent_type = original_get_type + self.assertIn("parent_id", VSERVICE, "Can't add parent id to vservice document") + self.assertEqual(VSERVICE['parent_type'], "vservice_miscellenaous_folder", + "Can't add document to miscellenaous folder when it doesn't have agent")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics.py b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics.py new file mode 100644 index 0000000..5a57b9c --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics.py @@ -0,0 +1,111 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_instance_vnics import CliFetchInstanceVnics +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_instance_vnics import * +from unittest.mock import MagicMock + + +class TestCliFetchInstanceVnics(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchInstanceVnics() + self.fetcher.set_env(self.env) + + def test_get(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_get_vnics_from_dumpxml = self.fetcher.get_vnics_from_dumpxml + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(side_effect=[INSATNCE, COMPUTE_HOST]) + self.fetcher.run_fetch_lines = MagicMock(return_value=INSTANCES_LIST) + self.fetcher.get_vnics_from_dumpxml = MagicMock(return_value=VNICS_FROM_DUMP_XML) + + result = self.fetcher.get(VNICS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.get_vnics_from_dumpxml = original_get_vnics_from_dumpxml + + self.assertNotEqual(result, [], "Can't get vnics with VNICS folder id") + + def test_get_without_instance(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=[]) + + result = self.fetcher.get(VNICS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the instance can't be found") + + def test_get_without_host(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(side_effect=[[], NETWORK_HOST]) + + result = self.fetcher.get(VNICS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the host doesn't contain network host type") + + def test_get_vnics_from_dumpxml(self): + # store original functions + original_run = self.fetcher.run + original_set_vnic_properties = self.fetcher.set_vnic_properties + + # mock the functions + self.fetcher.run = MagicMock(return_value=DUMPXML) + self.fetcher.set_vnic_properties = MagicMock() + + vnics = self.fetcher.get_vnics_from_dumpxml(ID, INSATNCE) + # reset functions + self.fetcher.run = original_run + self.fetcher.set_vnic_properties = original_set_vnic_properties + + self.assertNotEqual(vnics, [], "Can't get vnics") + + def test_get_vnics_from_dumpxml_with_empty_command_result(self): + # store original functions + original_run = self.fetcher.run + + # mock the functions + self.fetcher.run = MagicMock(return_value=" ") + + vnics = self.fetcher.get_vnics_from_dumpxml(ID, INSATNCE) + # reset functions + self.fetcher.run = original_run + + self.assertEqual(vnics, [], "Can't get empty array when the dumpxml is empty") + + def test_get_vnics_from_dumpxml_with_wrong_instance(self): + # store original functions + original_run = self.fetcher.run + + # mock the functions + self.fetcher.run = MagicMock(return_value=WRONG_DUMPXML) + + vnics = self.fetcher.get_vnics_from_dumpxml(ID, INSATNCE) + # reset functions + self.fetcher.run = original_run + + self.assertEqual(vnics, [], "Can't get empty array when the instance is wrong")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_ovs.py b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_ovs.py new file mode 100644 index 0000000..24a1b5d --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_ovs.py @@ -0,0 +1,36 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.cli_fetch_instance_vnics_ovs import CliFetchInstanceVnicsOvs +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_instance_vnics import * +from unittest.mock import MagicMock + + +class TestCliFetchInstanceVnicsOvs(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchInstanceVnicsOvs() + self.fetcher.set_env(self.env) + + def test_set_vnic_properties(self): + # store original method + original_set = self.fetcher.inv.set + self.fetcher.inv.set = MagicMock() + + self.fetcher.set_vnic_properties(VNIC, INSATNCE) + # reset method + self.fetcher.inv.set = original_set + + self.assertIn("source_bridge", VNIC, "Can't set source_bridge for ovs vnic") + + def test_get_vnic_name(self): + name = self.fetcher.get_vnic_name(VNIC, INSATNCE) + self.assertNotEqual(name, None, "Can't get vnic name")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_vpp.py b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_vpp.py new file mode 100644 index 0000000..46c25fb --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_instance_vnics_vpp.py @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.cli_fetch_instance_vnics_vpp import CliFetchInstanceVnicsVpp +from test.fetch.cli_fetch.test_data.cli_fetch_instance_vnics import * +from test.fetch.test_fetch import TestFetch + + +class TestCliFetchInstanceVnicsVpp(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchInstanceVnicsVpp() + + def test_get_name(self): + name = self.fetcher.get_vnic_name(VNIC, INSATNCE) + self.assertNotEqual(name, None, "Can't get vnic name")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors.py b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors.py new file mode 100644 index 0000000..23e0a99 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors.py @@ -0,0 +1,66 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_vconnectors import CliFetchVconnectors +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_vconnectors import * +from unittest.mock import MagicMock + + +class TestCliFetchVconnectors(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchVconnectors() + self.fetcher.set_env(self.env) + + def test_get(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + original_get_vconnectors = self.fetcher.get_vconnectors + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=HOST) + self.fetcher.get_vconnectors = MagicMock(return_value=VCONNECTORS) + + result = self.fetcher.get(VCONNECTORS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.get_vconnectors = original_get_vconnectors + + self.assertEqual(result, VCONNECTORS, "Can't get the vconnectors") + + def test_get_without_host(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=[]) + + result = self.fetcher.get(VCONNECTORS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the host doesn't exist") + + def test_get_with_wrong_host(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=WRONG_HOST) + + result = self.fetcher.get(VCONNECTORS_FOLDER['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the host doesn't contain host type")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_ovs.py b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_ovs.py new file mode 100644 index 0000000..cc882a1 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_ovs.py @@ -0,0 +1,38 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_vconnectors_ovs import CliFetchVconnectorsOvs +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_vconnectors_ovs import * +from unittest.mock import MagicMock + + +class TestCliFetchVconnectorsOvs(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchVconnectorsOvs() + self.fetcher.set_env(self.env) + + def test_get_vconnectors(self): + # store the original methods + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_find_items = self.fetcher.inv.find_items + + # mock the methods + self.fetcher.run_fetch_lines = MagicMock(return_value=BRIDGE_RESULT) + self.fetcher.inv.find_items = MagicMock(return_value=[]) + + result = self.fetcher.get_vconnectors(NETWORK_NODE) + + # reset methods + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.inv.find_items = original_find_items + + self.assertNotEqual(result, [], "Can't get vconnectors with the host id") diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_vpp.py b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_vpp.py new file mode 100644 index 0000000..f729c2c --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_vconnectors_vpp.py @@ -0,0 +1,50 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_vconnectors_vpp import CliFetchVconnectorsVpp +from test.fetch.test_fetch import TestFetch +from unittest.mock import MagicMock +from test.fetch.cli_fetch.test_data.cli_fetch_vconnectors_vpp import * + + +class TestCliFetchVconnectorsVpp(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchVconnectorsVpp() + self.fetcher.set_env(self.env) + + def test_get_vconnectors(self): + # store original method + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_get_interface_details = self.fetcher.get_interface_details + + # mock methods + self.fetcher.run_fetch_lines = MagicMock(return_value=MODE_RESULT) + self.fetcher.get_interface_details = MagicMock(return_value=None) + + result = self.fetcher.get_vconnectors(HOST) + + # reset methods + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.get_interface_details = original_get_interface_details + + self.assertNotEqual(result, {}, "Can't get vconnectors info") + + def test_set_interface_details(self): + # store original methods + original_run_fetch_lines = self.fetcher.run_fetch_lines + + # mock method + self.fetcher.run_fetch_lines = MagicMock(return_value=INTERFACE_LINES) + + result = self.fetcher.get_interface_details(HOST, INTERFACE_NAME) + # restore method + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.assertNotEqual(result, None, "Can't get the interface details")
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_cli_fetch_vservice_vnics.py b/app/test/fetch/cli_fetch/test_cli_fetch_vservice_vnics.py new file mode 100644 index 0000000..b77f41e --- /dev/null +++ b/app/test/fetch/cli_fetch/test_cli_fetch_vservice_vnics.py @@ -0,0 +1,124 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.cli.cli_fetch_vservice_vnics import CliFetchVserviceVnics +from test.fetch.test_fetch import TestFetch +from test.fetch.cli_fetch.test_data.cli_fetch_vservice_vnics import * +from unittest.mock import MagicMock + + +class TestCliFetchVserviceVnics(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = CliFetchVserviceVnics() + self.fetcher.set_env(self.env) + + def test_get(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_handle_service = self.fetcher.handle_service + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=NETWORK_NODE) + self.fetcher.run_fetch_lines = MagicMock(return_value=NAME_SPACES) + self.fetcher.handle_service = MagicMock(return_value=SERVICES) + + result = self.fetcher.get(NETWORK_NODE['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.handle_service = original_handle_service + + self.assertNotEqual(result, [], "Can't get vnics") + + def test_get_with_error_host(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=ERROR_NODE) + + result = self.fetcher.get(NETWORK_NODE['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the host doesn't contain host_type") + + def test_get_with_compute_host(self): + # store original methods + original_get_by_id = self.fetcher.inv.get_by_id + + # mock methods + self.fetcher.inv.get_by_id = MagicMock(return_value=COMPUTE_NODE) + + result = self.fetcher.get(NETWORK_NODE['id']) + + # reset methods + self.fetcher.inv.get_by_id = original_get_by_id + + self.assertEqual(result, [], "Can't get empty array when the host type doesn't contain network") + + def test_handle_service(self): + # store original method + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_set_interface_data = self.fetcher.set_interface_data + # mock the method + self.fetcher.run_fetch_lines = MagicMock(return_value=IFCONFIG_RESULT) + self.fetcher.set_interface_data = MagicMock() + result = self.fetcher.handle_service(NETWORK_NODE['id'], SERVICE_ID) + # reset method + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.set_interface_data = original_set_interface_data + + self.assertNotEqual(result, [], "Can't get interfaces data") + + def test_set_interface_data(self): + # store original methods + original_get_by_field = self.fetcher.inv.get_by_field + original_get_by_id = self.fetcher.inv.get_by_id + original_set = self.fetcher.inv.set + + # mock the methods + self.fetcher.inv.get_by_field = MagicMock(return_value=NETWORK) + self.fetcher.inv.get_by_id = MagicMock(return_value=VSERVICE) + self.fetcher.inv.set = MagicMock() + + self.fetcher.set_interface_data(VNIC) + + # reset methods + self.fetcher.inv.get_by_field = original_get_by_field + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.inv.set = original_set + + self.assertIn("data", VNIC, "Can't set data") + self.assertIn("cidr", VNIC, "Can't set cidr") + self.assertIn("network", VNIC, "Can't set network") + + def test_handle_mac_address_line(self): + self.fetcher.handle_line(RAW_VNIC, MAC_ADDRESS_LINE) + self.assertEqual(RAW_VNIC['mac_address'], MAC_ADDRESS, "Can't get the correct mac address from the line") + + def test_handle_ipv4_address_line(self): + self.fetcher.handle_line(RAW_VNIC, IPV4_ADDRESS_LINE) + self.assertEqual(RAW_VNIC['IP Address'], IPV4_ADDRESS, "Can't get the correct ipv4 address from the line") + + def test_handle_ipv6_address_line(self): + self.fetcher.handle_line(RAW_VNIC, IPV6_ADDRESS_LINE) + self.assertEqual(RAW_VNIC['IPv6 Address'], IPV6_ADDRESS, "Can't get the correct ipv6 address from the line") + + def test_get_net_size(self): + size = self.fetcher.get_net_size(NET_MASK_ARRAY) + self.assertEqual(size, SIZE, "Can't get the size of network by netmask") + + def test_get_cidr_for_vnic(self): + cidr = self.fetcher.get_cidr_for_vnic(VNIC) + self.assertEqual(cidr, CIDR, "the cidr info is wrong") diff --git a/app/test/fetch/cli_fetch/test_data/__init__.py b/app/test/fetch/cli_fetch/test_data/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/cli_fetch/test_data/cli_access.py b/app/test/fetch/cli_fetch/test_data/cli_access.py new file mode 100644 index 0000000..b151dc6 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_access.py @@ -0,0 +1,58 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +COMPUTE_HOST_ID = "node-5.cisco.com" +COMMAND = "virsh list" +NON_GATEWAY_CACHED_COMMAND = COMPUTE_HOST_ID + "," + "ssh -o StrictHostKeyChecking=no " + \ + COMPUTE_HOST_ID + " sudo " + COMMAND +GATEWAY_CACHED_COMMAND = COMPUTE_HOST_ID + "," + "sudo " + COMMAND +CACHED_COMMAND_RESULT = " Id Name State\n---\n 2 instance-00000003 running" +RUN_RESULT = " Id Name State\n---\n 2 instance-00000002 running" +FETCH_LINES_RESULT = [ + " Id Name State", + "---", + " 2 instance-00000002 running" +] + +LINES_FOR_FIX = [ + "br-ex\t\t8000.005056acc9a2\tno\t\teno33554952", + "\t\t\t\t\t\t\tp_ff798dba-0", + "\t\t\t\t\t\t\tv_public", + "\t\t\t\t\t\t\tv_vrouter_pub", + "br-fw-admin\t\t8000.005056ace897\tno\t\teno16777728" +] + +FIXED_LINES = [ + "br-ex\t\t8000.005056acc9a2\tno\t\teno33554952,p_ff798dba-0,v_public,v_vrouter_pub", + "br-fw-admin\t\t8000.005056ace897\tno\t\teno16777728" +] + +PARSED_CMD_RESULT = [ + { + "bridge_id": "8000.005056acc9a2", + "bridge_name": "br-ex", + "interfaces": "eno33554952,p_ff798dba-0,v_public,v_vrouter_pub", + "stp_enabled": "no" + }, + { + "bridge_id": "8000.005056ace897", + "bridge_name": "br-fw-admin", + "interfaces": "eno16777728", + "stp_enabled": "no" + } +] + +LINE_FOR_PARSE = "br-ex\t\t8000.005056acc9a2\tno\t\teno33554952,p_ff798dba-0,v_public,v_vrouter_pub" +PARSED_LINE = { + "bridge_id": "8000.005056acc9a2", + "bridge_name": "br-ex", + "interfaces": "eno33554952,p_ff798dba-0,v_public,v_vrouter_pub", + "stp_enabled": "no" +} +HEADERS = ["bridge_name", "bridge_id", "stp_enabled", "interfaces"] diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics.py new file mode 100644 index 0000000..316c68a --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics.py @@ -0,0 +1,147 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +PNICS_FOLDER_ID = "node-6.cisco.com-pnics" +HOST_ID = "node-6.cisco.com" + +NETWORK_NODE = { + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com" +} + +WRONG_NODE = { + "host_type": [ + "Controller" + ] +} + +INTERFACE_LINES = [ + "lrwxrwxrwx 1 root 0 Jul 5 17:17 eno16777728 -> ../../devices/0000:02:00.0/net/eno16777728", + "lrwxrwxrwx 1 root 0 Jul 5 17:17 eno33554952 -> ../../devices/0000:02:01.0/net/eno33554952" +] + +INTERFACE_NAMES = ["eno16777728", "eno33554952"] + +INTERFACE_NAME = INTERFACE_NAMES[0] +IFCONFIG_CM_RESULT = [ + "eno16777728 Link encap:Ethernet HWaddr 00:50:56:ac:e8:97 ", + " UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1", + " RX packets:409056348 errors:0 dropped:0 overruns:0 frame:0", + " TX packets:293898173 errors:0 dropped:0 overruns:0 carrier:0", + " collisions:0 txqueuelen:1000 ", + " RX bytes:103719003730 (103.7 GB) TX bytes:165090993470 (165.0 GB)", + "" +] + +INTERFACE_DETAILS = { + "host": "node-6.cisco.com", + "id": "eno16777728-unknown_mac", + "lines": [], + "local_name": "eno16777728", + "name": "eno16777728", + "state": "UP" +} + +MAC_ADDRESS_LINE = "eno16777728 Link encap:Ethernet HWaddr 00:50:56:ac:e8:97 " +MAC_ADDRESS = "00:50:56:ac:e8:97" +RAW_INTERFACE = { + "host": "node-6.cisco.com", + "lines": [], + "local_name": "eno16777728", + "name": "eno16777728" +} + +INTERFACE_AFTER_LINE_HANDLE = { + "host": "node-6.cisco.com", + "lines": [MAC_ADDRESS_LINE.strip()], + "local_name": "eno16777728", + "name": "eno16777728", + "id": "eno16777728-" + MAC_ADDRESS, + "mac_address": MAC_ADDRESS +} + +INTERFACE_FOR_SET = { + "host": "node-6.cisco.com", + "lines": [ + "Link encap:Ethernet HWaddr 00:50:56:ac:e8:97", + "UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1" + ], + "local_name": "eno16777728", + "mac_address": "00:50:56:ac:e8:97" +} + +INTERFACE_AFTER_SET = { + "host": "node-6.cisco.com", + "data": "Link encap:Ethernet HWaddr 00:50:56:ac:e8:97" + + "\nUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1", + "local_name": "eno16777728", + "mac_address": "00:50:56:ac:e8:97", + "Supported ports": "[ TP ]", + "Supported link modes": ["10baseT/Half 10baseT/Full", + "100baseT/Half 100baseT/Full", + "1000baseT/Full"], + "Supported pause frame use": "No" +} + +INTERFACE = { + "Advertised auto-negotiation": "Yes", + "Advertised link modes": [ + "10baseT/Half 10baseT/Full", + "100baseT/Half 100baseT/Full", + "1000baseT/Full" + ], + "Advertised pause frame use": "No", + "Auto-negotiation": "on", + "Current message level": [ + "0x00000007 (7)", + "drv probe link" + ], + "Duplex": "Full", + "Link detected": "yes", + "MDI-X": "off (auto)", + "PHYAD": "0", + "Port": "Twisted Pair", + "Speed": "1000Mb/s", + "Supported link modes": [ + "10baseT/Half 10baseT/Full", + "100baseT/Half 100baseT/Full", + "1000baseT/Full" + ], + "Supported pause frame use": "No", + "Supported ports": "[ TP ]", + "Supports Wake-on": "d", + "Supports auto-negotiation": "Yes", + "Transceiver": "internal", + "Wake-on": "d", + "data": "Link encap:Ethernet HWaddr 00:50:56:ac:e8:97\nUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1\nRX packets:408989052 errors:0 dropped:0 overruns:0 frame:0\nTX packets:293849880 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:1000\nRX bytes:103702814216 (103.7 GB) TX bytes:165063440009 (165.0 GB)\n", + "host": "node-6.cisco.com", + "id": "eno16777728-00:50:56:ac:e8:97", + "local_name": "eno16777728", + "mac_address": "00:50:56:ac:e8:97", + "name": "eno16777728" +} + +INTERFACES_GET_RESULTS = [INTERFACE] + +IPV6_ADDRESS_LINE = " inet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link" +IPV6_ADDRESS = "fe80::f816:3eff:fea1:eb73/64" +IPV4_ADDRESS_LINE = " inet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0" +IPV4_ADDRESS = "172.16.13.2" + +ETHTOOL_RESULT = [ + "Settings for eno16777728:", + "\tSupported ports: [ TP ]", + "\tSupported link modes: 10baseT/Half 10baseT/Full ", + "\t 100baseT/Half 100baseT/Full ", + "\t 1000baseT/Full ", + "\tSupported pause frame use: No", +] diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics_vpp.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics_vpp.py new file mode 100644 index 0000000..99bd4cd --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_pnics_vpp.py @@ -0,0 +1,204 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +ID = "node-4.cisco.com-VPP-folders" +VEDGES = [ + { + "agent_type": "Open vSwitch agent", + "binary": "neutron-openvswitch-agent", + "configurations" : { + "tunneling_ip": "192.168.2.3", + "arp_responder_enabled" : True, + "extensions" : [ + + ], + "l2_population" : True, + "enable_distributed_routing" : False, + "bridge_mappings" : { + "physnet1": "br-floating" + }, + "log_agent_heartbeats" : False, + "tunnel_types" : [ + "vxlan" + ], + "in_distributed_mode" : False + }, + "description" : None, + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "id": "1764430c-c09e-4717-86fa-c04350b1fcbb", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com/node-6.cisco.com-vedges/1764430c-c09e-4717-86fa-c04350b1fcbb", + "name": "node-6.cisco.com-OVS", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com/vEdges/node-6.cisco.com-OVS", + "object_name": "node-6.cisco.com-OVS", + "parent_id": "node-6.cisco.com-vedges", + "parent_type": "vedges_folder", + "ports" : { + "TenGigabitEthernet-g-63489f34-af" : { + "id": "8", + "name": "qg-63489f34-af", + "internal" : True, + "tag": "2", + "host": "node-4.cisco.com", + "state": "up" + }, + "qr-3ff411a2-54" : { + "id": "7", + "name": "qr-3ff411a2-54", + "internal" : True, + "tag": "5" + }, + "tap31c19fbe-5d" : { + "id": "19", + "name": "tap31c19fbe-5d", + "internal" : True, + "tag": "117" + }, + "br-int" : { + "id": "3", + "name": "br-int", + "internal" : True + }, + "qr-18f029db-77" : { + "id": "17", + "name": "qr-18f029db-77", + "internal" : True, + "tag": "105" + }, + "br-tun" : { + "id": "13", + "name": "br-tun", + "internal" : True + }, + "tap82d4992f-4d" : { + "id": "9", + "name": "tap82d4992f-4d", + "internal" : True, + "tag": "5" + }, + "tap16620a58-c4" : { + "id": "16", + "name": "tap16620a58-c4", + "internal" : True, + "tag": "6" + }, + "p_ff798dba-0" : { + "id": "15", + "name": "p_ff798dba-0", + "internal" : True + }, + "tapee8e5dbb-03" : { + "id": "6", + "name": "tapee8e5dbb-03", + "internal" : True, + "tag": "1" + }, + "tap702e9683-0c" : { + "id": "20", + "name": "tap702e9683-0c", + "internal" : True, + "tag": "118" + }, + "tapaf69959f-ef" : { + "id": "18", + "name": "tapaf69959f-ef", + "internal" : True, + "tag": "105" + }, + "tap5f22f397-d8" : { + "id": "11", + "name": "tap5f22f397-d8", + "internal" : True, + "tag": "3" + }, + "qr-bb9b8340-72" : { + "id": "1", + "name": "qr-bb9b8340-72", + "internal" : True, + "tag": "3" + }, + "qr-8733cc5d-b3" : { + "id": "2", + "name": "qr-8733cc5d-b3", + "internal" : True, + "tag": "4" + }, + "ovs-system" : { + "id": "0", + "name": "ovs-system", + "internal" : True + }, + "br-floating" : { + "id": "14", + "name": "br-floating", + "internal" : True + }, + "qg-57e65d34-3d" : { + "id": "10", + "name": "qg-57e65d34-3d", + "internal" : True, + "tag": "2" + }, + "qr-f7b44150-99" : { + "id": "4", + "name": "qr-f7b44150-99", + "internal" : True, + "tag": "1" + }, + "tapbf16c3ab-56" : { + "id": "5", + "name": "tapbf16c3ab-56", + "internal" : True, + "tag": "4" + } + }, + "show_in_tree" : True, + "topic": "N/A", + "tunnel_ports" : { + "br-tun" : { + "name": "br-tun", + "interface": "br-tun", + "type": "internal" + }, + "vxlan-c0a80201" : { + "name": "vxlan-c0a80201", + "options" : { + "local_ip": "192.168.2.3", + "out_key": "flow", + "in_key": "flow", + "df_default": "True", + "remote_ip": "192.168.2.1" + }, + "interface": "vxlan-c0a80201", + "type": "vxlan" + }, + "vxlan-c0a80202" : { + "name": "vxlan-c0a80202", + "options" : { + "local_ip": "192.168.2.3", + "out_key": "flow", + "in_key": "flow", + "df_default": "True", + "remote_ip": "192.168.2.2" + }, + "interface": "vxlan-c0a80202", + "type": "vxlan" + }, + "patch-int" : { + "name": "patch-int", + "options" : { + "peer": "patch-tun" + }, + "interface": "patch-int", + "type": "patch" + } + }, + "type": "vedge" +} + ]
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_host_verservices.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_verservices.py new file mode 100644 index 0000000..94ee38c --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_host_verservices.py @@ -0,0 +1,276 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +NETWORK_HOST = { + "config": { + "interfaces": 4, + "log_agent_heartbeats": False, + "gateway_external_network_id": "", + "router_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "ex_gw_ports": 2, + "routers": 2, + "handle_internal_only_routers": True, + "floating_ips": 1, + "external_network_bridge": "", + "use_namespaces": True, + "agent_mode": "legacy" + }, + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com", + "name": "node-6.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com", + "object_name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:10.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:54.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:45.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:56.000000" + } + }, + "show_in_tree": True, + "type" : "host", + "zone" : "internal" +} + +COMPUTE_HOST = { + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-5.cisco.com", + "host_type": [ + "Compute" + ], + "id": "node-5.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com", + "object_name": "node-5.cisco.com", + "os_id": "1", + "parent_id": "osdna-zone", + "parent_type": "availability_zone", + "services": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:42.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "osdna-zone" +} + +NAMESPACES = [ + 'qdhcp-413de095-01ed-49dc-aa50-4479f43d390e', + 'qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc', + 'qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', + 'qdhcp-eb276a62-15a9-4616-a192-11466fdd147f', + 'qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627', + 'qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f', + 'qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc', + 'qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9', + 'qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6', + 'haproxy', + 'vrouter' +] + +LOCAL_SERVICES_IDS = [ + { + "local_service_id": "qdhcp-413de095-01ed-49dc-aa50-4479f43d390e" + }, + { + "local_service_id": "qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc" + }, + { + "local_service_id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe" + }, + { + "local_service_id": "qdhcp-eb276a62-15a9-4616-a192-11466fdd147f" + }, + { + "local_service_id": "qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627" + }, + { + "local_service_id": "qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f" + }, + { + "local_service_id": "qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc" + }, + { + "local_service_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9" + }, + { + "local_service_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6" + } +] + +VSERVICE = { + "host": "node-6.cisco.com", + "id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "local_service_id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "name": "dhcp-osdna-met4", + "service_type": "dhcp" + } + +AGENT = { + "description": "DHCP agent", + "folder_text": "DHCP servers", + "type": "dhcp" +} + +ROUTER = [ + {"name": "123456"} +] + +ID_CLEAN = "413de095-01ed-49dc-aa50-4479f43d390e" +# functional test +INPUT = "node-6.cisco.com" +OUTPUT = [ + { + "host": "node-6.cisco.com", + "id": "qdhcp-413de095-01ed-49dc-aa50-4479f43d390e", + "local_service_id": "qdhcp-413de095-01ed-49dc-aa50-4479f43d390e", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-aiya", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc", + "local_service_id": "qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-123456", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "local_service_id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-osdna-met4", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-eb276a62-15a9-4616-a192-11466fdd147f", + "local_service_id": "qdhcp-eb276a62-15a9-4616-a192-11466fdd147f", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-osdna-net3", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627", + "local_service_id": "qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-osdna-net1", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "local_service_id": "qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-osdna-net2", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "host": "node-6.cisco.com", + "id": "qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc", + "local_service_id": "qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "dhcp-admin_internal_net", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp" + }, + { + "admin_state_up": 1, + "enable_snat": 1, + "gw_port_id": "63489f34-af99-44f4-81de-9a2eb1c1941f", + "host": "node-6.cisco.com", + "id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "local_service_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "router-osdna-router", + "parent_id": "node-6.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + }, + { + "admin_state_up": 1, + "enable_snat": 1, + "gw_port_id": "57e65d34-3d87-4751-8e95-fc78847a3070", + "host": "node-6.cisco.com", + "id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6", + "local_service_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "router-router04", + "parent_id": "node-6.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "status": "ACTIVE", + "tenant_id": "8c1751e0ce714736a63fee3c776164da" + } +]
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_instance_vnics.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_instance_vnics.py new file mode 100644 index 0000000..a43b5c2 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_instance_vnics.py @@ -0,0 +1,288 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +VNICS_FOLDER = { + "create_object": True, + "environment": "Mirantis-Liberty-Xiaocong", + "id": "bf0cb914-b316-486c-a4ce-f22deb453c52-vnics", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com/node-5.cisco.com-instances/bf0cb914-b316-486c-a4ce-f22deb453c52/bf0cb914-b316-486c-a4ce-f22deb453c52-vnics", + "name": "vNICs", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com/Instances/test/vNICs", + "object_name": "vNICs", + "parent_id": "bf0cb914-b316-486c-a4ce-f22deb453c52", + "parent_type": "instance", + "show_in_tree": True, + "text": "vNICs", + "type": "vnics_folder" +} + +INSATNCE = { + "_id": "5806817e4a0a8a3fbe3bee8b", + "children_url": "/osdna_dev/discover.py?type=tree&id=bf0cb914-b316-486c-a4ce-f22deb453c52", + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-5.cisco.com", + "id": "bf0cb914-b316-486c-a4ce-f22deb453c52", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com/node-5.cisco.com-instances/bf0cb914-b316-486c-a4ce-f22deb453c52", + "ip_address": "192.168.0.4", + "local_name": "instance-00000026", + "mac_address": "fa:16:3e:e8:7f:04", + "name": "test", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com/Instances/test", + "network": [ + "2e3b85f4-756c-49d9-b34c-f3db13212dbc" + ], + "network_info": [ + { + "devname": "tap1f72bd15-8a", + "id": "1f72bd15-8ab2-43cb-94d7-e823dd845255", + "profile": { + + }, + "vnic_type": "normal", + "type": "ovs", + "address": "fa:16:3e:e8:7f:04", + "qbg_params": None, + "network": { + "bridge": "br-int", + "label": "123456", + "subnets": [ + { + "cidr": "172.16.13.0/24", + "version": 4, + "gateway": { + "version": 4, + "meta": { + + }, + "address": "172.16.13.1", + "type": "gateway" + }, + "routes": [ + + ], + "dns": [ + + ], + "ips": [ + { + "meta": { + + }, + "version": 4, + "type": "fixed", + "address": "172.16.13.4", + "floating_ips": [ + + ] + } + ], + "meta": { + "dhcp_server": "172.16.13.2" + } + } + ], + "meta": { + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "injected": False + }, + "id": "2e3b85f4-756c-49d9-b34c-f3db13212dbc" + }, + "active": True, + "meta": { + + }, + "details": { + "port_filter": True, + "ovs_hybrid_plug": True + }, + "preserve_on_delete": False, + "qbh_params": None, + "ovs_interfaceid": "1f72bd15-8ab2-43cb-94d7-e823dd845255" + } + ], + "object_name": "test", + "parent_id": "node-5.cisco.com-instances", + "parent_type": "instances_folder", + "project_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "projects": [ + "OSDNA-project" + ], + "show_in_tree": True, + "type": "instance", + "uuid": "bf0cb914-b316-486c-a4ce-f22deb453c52" +} + + +COMPUTE_HOST = { + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-5.cisco.com", + "host_type": [ + "Compute" + ], + "id": "node-5.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com", + "object_name": "node-5.cisco.com", + "os_id": "1", + "parent_id": "osdna-zone", + "parent_type": "availability_zone", + "services": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:42.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "osdna-zone" +} + +NETWORK_HOST = { + "config": { + "interfaces": 4, + "log_agent_heartbeats": False, + "gateway_external_network_id": "", + "router_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "ex_gw_ports": 2, + "routers": 2, + "handle_internal_only_routers": True, + "floating_ips": 1, + "external_network_bridge": "", + "use_namespaces": True, + "agent_mode": "legacy" + }, + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com", + "name": "node-6.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com", + "object_name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:10.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:54.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:45.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:56.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +DUMPXML = "<domain type='qemu' id='38'>\n <name>instance-00000026</name>\n <uuid>bf0cb914-b316-486c-a4ce-f22deb453c52</uuid>\n <metadata>\n <nova:instance xmlns:nova=\"http://openstack.org/xmlns/libvirt/nova/1.0\">\n <nova:package version=\"12.0.0\"/>\n <nova:name>test</nova:name>\n <nova:creationTime>2016-10-17 22:37:43</nova:creationTime>\n <nova:flavor name=\"m1.micro\">\n <nova:memory>64</nova:memory>\n <nova:disk>0</nova:disk>\n <nova:swap>0</nova:swap>\n <nova:ephemeral>0</nova:ephemeral>\n <nova:vcpus>1</nova:vcpus>\n </nova:flavor>\n <nova:owner>\n <nova:user uuid=\"13baa553aae44adca6615e711fd2f6d9\">admin</nova:user>\n <nova:project uuid=\"75c0eb79ff4a42b0ae4973c8375ddf40\">OSDNA-project</nova:project>\n </nova:owner>\n <nova:root type=\"image\" uuid=\"c6f490c4-3656-43c6-8d03-b4e66bd249f9\"/>\n </nova:instance>\n </metadata>\n <memory unit='KiB'>65536</memory>\n <currentMemory unit='KiB'>65536</currentMemory>\n <vcpu placement='static'>1</vcpu>\n <cputune>\n <shares>1024</shares>\n </cputune>\n <sysinfo type='smbios'>\n <system>\n <entry name='manufacturer'>OpenStack Foundation</entry>\n <entry name='product'>OpenStack Nova</entry>\n <entry name='version'>12.0.0</entry>\n <entry name='serial'>9cf57bfd-7477-4671-b2d3-3dfeebfefb1d</entry>\n <entry name='uuid'>bf0cb914-b316-486c-a4ce-f22deb453c52</entry>\n <entry name='family'>Virtual Machine</entry>\n </system>\n </sysinfo>\n <os>\n <type arch='x86_64' machine='pc-i440fx-trusty'>hvm</type>\n <boot dev='hd'/>\n <smbios mode='sysinfo'/>\n </os>\n <features>\n <acpi/>\n <apic/>\n </features>\n <cpu>\n <topology sockets='1' cores='1' threads='1'/>\n </cpu>\n <clock offset='utc'/>\n <on_poweroff>destroy</on_poweroff>\n <on_reboot>restart</on_reboot>\n <on_crash>destroy</on_crash>\n <devices>\n <emulator>/usr/bin/qemu-system-x86_64</emulator>\n <disk type='file' device='disk'>\n <driver name='qemu' type='qcow2' cache='directsync'/>\n <source file='/var/lib/nova/instances/bf0cb914-b316-486c-a4ce-f22deb453c52/disk'/>\n <backingStore type='file' index='1'>\n <format type='raw'/>\n <source file='/var/lib/nova/instances/_base/44881e4441fbd821d0d6240f90742fc97e52f83e'/>\n <backingStore/>\n </backingStore>\n <target dev='vda' bus='virtio'/>\n <alias name='virtio-disk0'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n </disk>\n <controller type='usb' index='0'>\n <alias name='usb0'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n </controller>\n <controller type='pci' index='0' model='pci-root'>\n <alias name='pci.0'/>\n </controller>\n <interface type='bridge'>\n <mac address='fa:16:3e:e8:7f:04'/>\n <source bridge='qbr1f72bd15-8a'/>\n <target dev='tap1f72bd15-8a'/>\n <model type='virtio'/>\n <driver name='qemu'/>\n <alias name='net0'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n </interface>\n <serial type='file'>\n <source path='/var/lib/nova/instances/bf0cb914-b316-486c-a4ce-f22deb453c52/console.log'/>\n <target port='0'/>\n <alias name='serial0'/>\n </serial>\n <serial type='pty'>\n <source path='/dev/pts/8'/>\n <target port='1'/>\n <alias name='serial1'/>\n </serial>\n <console type='file'>\n <source path='/var/lib/nova/instances/bf0cb914-b316-486c-a4ce-f22deb453c52/console.log'/>\n <target type='serial' port='0'/>\n <alias name='serial0'/>\n </console>\n <input type='tablet' bus='usb'>\n <alias name='input0'/>\n </input>\n <input type='mouse' bus='ps2'/>\n <input type='keyboard' bus='ps2'/>\n <graphics type='vnc' port='5902' autoport='yes' listen='0.0.0.0' keymap='en-us'>\n <listen type='address' address='0.0.0.0'/>\n </graphics>\n <video>\n <model type='cirrus' vram='9216' heads='1'/>\n <alias name='video0'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n </video>\n <memballoon model='virtio'>\n <alias name='balloon0'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>\n <stats period='10'/>\n </memballoon>\n </devices>\n <seclabel type='dynamic' model='apparmor' relabel='yes'>\n <label>libvirt-bf0cb914-b316-486c-a4ce-f22deb453c52</label>\n <imagelabel>libvirt-bf0cb914-b316-486c-a4ce-f22deb453c52</imagelabel>\n </seclabel>\n</domain>\n\n" +WRONG_DUMPXML = "<domain type='qemu' id='38'><uuid>wrong_instance</uuid></domain>" +INSTANCES_LIST = [ + ' Id Name State', + '----------------------------------------------------', + ' 2 instance-00000002 running', + ' 27 instance-0000001c running', + ' 38 instance-00000026 running', + ' 39 instance-00000028 running', + '' +] + +VNIC = { + "@type": "bridge", + "address": { + "@bus": "0x00", + "@domain": "0x0000", + "@function": "0x0", + "@slot": "0x03", + "@type": "pci" + }, + "alias": { + "@name": "net0" + }, + "driver": { + "@name": "qemu" + }, + "mac": { + "@address": "fa:16:3e:e8:7f:04" + }, + "model": { + "@type": "virtio" + }, + "source": { + "@bridge": "qbr1f72bd15-8a" + }, + "target": { + "@dev": "tap1f72bd15-8a" + } +} + +ID = "38" + +VNICS_FROM_DUMP_XML = [ + { + "@type": "bridge", + "address": { + "@bus": "0x00", + "@domain": "0x0000", + "@function": "0x0", + "@slot": "0x03", + "@type": "pci" + }, + "alias": { + "@name": "net0" + }, + "driver": { + "@name": "qemu" + }, + "host": "node-5.cisco.com", + "id": "tap1f72bd15-8a", + "instance_db_id": "5806817e4a0a8a3fbe3bee8b", + "instance_id": "bf0cb914-b316-486c-a4ce-f22deb453c52", + "mac": { + "@address": "fa:16:3e:e8:7f:04" + }, + "mac_address": "fa:16:3e:e8:7f:04", + "model": { + "@type": "virtio" + }, + "name": "tap1f72bd15-8a", + "source": { + "@bridge": "qbr1f72bd15-8a" + }, + "source_bridge": "qbr1f72bd15-8a", + "target": { + "@dev": "tap1f72bd15-8a" + }, + "vnic_type": "instance_vnic" + } +] + + +# functional test +INPUT = "bf0cb914-b316-486c-a4ce-f22deb453c52-vnics"
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors.py new file mode 100644 index 0000000..f51e510 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors.py @@ -0,0 +1,103 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +HOST = { + "config" : { + "metadata_proxy_socket" : "/opt/stack/data/neutron/metadata_proxy", + "nova_metadata_ip" : "192.168.20.14", + "log_agent_heartbeats" : False + }, + "environment" : "Devstack-VPP-2", + "host" : "ubuntu0", + "host_type" : [ + "Controller", + "Compute", + "Network" + ], + "id" : "ubuntu0", + "id_path" : "/Devstack-VPP-2/Devstack-VPP-2-regions/RegionOne/RegionOne-availability_zones/nova/ubuntu0", + "ip_address" : "192.168.20.14", + "name" : "ubuntu0", + "name_path" : "/Devstack-VPP-2/Regions/RegionOne/Availability Zones/nova/ubuntu0", + "object_name" : "ubuntu0", + "os_id" : "1", + "parent_id" : "nova", + "parent_type" : "availability_zone", + "services" : { + "nova-conductor" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:58.000000" + }, + "nova-scheduler" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:54.000000" + }, + "nova-consoleauth" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:54.000000" + } + }, + "show_in_tree" : True, + "type" : "host", + "zone" : "nova" +} + +WRONG_HOST = { + "show_in_tree" : True, + "type" : "host", + "zone" : "nova" +} + +VCONNECTORS_FOLDER = { + "create_object" : True, + "environment" : "Mirantis-Liberty-Xiaocong", + "id" : "node-6.cisco.com-vconnectors", + "id_path" : "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com/node-6.cisco.com-vconnectors", + "name" : "vConnectors", + "name_path" : "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com/vConnectors", + "object_name" : "vConnectors", + "parent_id" : "node-6.cisco.com", + "parent_type" : "host", + "show_in_tree" : True, + "text" : "vConnectors", + "type" : "vconnectors_folder" +} + +VCONNECTORS = [ + { + "bd_id": "5678", + "host": "ubuntu0", + "id": "ubuntu0-vconnector-5678", + "interfaces": { + "name": { + "hardware": "VirtualEthernet0/0/8", + "id": "15", + "mac_address": "fa:16:3e:d1:98:73", + "name": "VirtualEthernet0/0/8", + "state": "up" + } + }, + "interfaces_names": [ + "TenGigabitEthernetc/0/0", + "VirtualEthernet0/0/0", + "VirtualEthernet0/0/1", + "VirtualEthernet0/0/2", + "VirtualEthernet0/0/3", + "VirtualEthernet0/0/4", + "VirtualEthernet0/0/5", + "VirtualEthernet0/0/6", + "VirtualEthernet0/0/7", + "VirtualEthernet0/0/8" + ], + "name": "bridge-domain-5678" + } +]
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_ovs.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_ovs.py new file mode 100644 index 0000000..9161457 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_ovs.py @@ -0,0 +1,234 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +NETWORK_NODE = { + "config": { + "interfaces": 4, + "log_agent_heartbeats": False, + "gateway_external_network_id": "", + "router_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "ex_gw_ports": 2, + "routers": 2, + "handle_internal_only_routers": True, + "floating_ips": 1, + "external_network_bridge": "", + "use_namespaces": True, + "agent_mode": "legacy" + }, + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com", + "name": "node-6.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com", + "object_name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:10.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:54.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:45.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:56.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +BRIDGE_RESULT = [ + "bridge name\tbridge id\t\tSTP enabled\tinterfaces", + "br-ex\t\t8000.005056acc9a2\tno\t\teno33554952", + "\t\t\t\t\t\t\tp_ff798dba-0", + "\t\t\t\t\t\t\tv_public", + "\t\t\t\t\t\t\tv_vrouter_pub", + "br-fw-admin\t\t8000.005056ace897\tno\t\teno16777728", + "br-mesh\t\t8000.005056acc9a2\tno\t\teno33554952.103", + "br-mgmt\t\t8000.005056ace897\tno\t\teno16777728.101", + "\t\t\t\t\t\t\tmgmt-conntrd", + "\t\t\t\t\t\t\tv_management", + "\t\t\t\t\t\t\tv_vrouter", + "br-storage\t\t8000.005056ace897\tno\t\teno16777728.102" +] + +FIXED_LINES = [ + "br-ex\t\t8000.005056acc9a2\tno\t\teno33554952,p_ff798dba-0,v_public,v_vrouter_pub", + "br-fw-admin\t\t8000.005056ace897\tno\t\teno16777728", + "br-mesh\t\t8000.005056acc9a2\tno\t\teno33554952.103", + "br-mgmt\t\t8000.005056ace897\tno\t\teno16777728.101,mgmt-conntrd,v_management,v_vrouter", + "br-storage\t\t8000.005056ace897\tno\t\teno16777728.102" +] + +PARSE_CM_RESULTS = [ + { + "bridge_id": "8000.005056acc9a2", + "bridge_name": "br-ex", + "interfaces": "eno33554952,p_ff798dba-0,v_public,v_vrouter_pub", + "stp_enabled": "no" + }, + { + "bridge_id": "8000.005056ace897", + "bridge_name": "br-fw-admin", + "interfaces": "eno16777728", + "stp_enabled": "no" + }, + { + "bridge_id": "8000.005056acc9a2", + "bridge_name": "br-mesh", + "interfaces": "eno33554952.103", + "stp_enabled": "no" + }, + { + "bridge_id": "8000.005056ace897", + "bridge_name": "br-mgmt", + "interfaces": "eno16777728.101,mgmt-conntrd,v_management,v_vrouter", + "stp_enabled": "no" + }, + { + "bridge_id": "8000.005056ace897", + "bridge_name": "br-storage", + "interfaces": "eno16777728.102", + "stp_enabled": "no" + } +] + +# functional test +INPUT = "node-6.cisco.com" +OUPUT = [ + { + "connector_type": "bridge", + "host": "node-6.cisco.com", + "id": "8000.005056acc9a2", + "interfaces": { + "eno33554952": { + "mac_address": "", + "name": "eno33554952" + }, + "p_ff798dba-0": { + "mac_address": "", + "name": "p_ff798dba-0" + }, + "v_public": { + "mac_address": "", + "name": "v_public" + }, + "v_vrouter_pub": { + "mac_address": "", + "name": "v_vrouter_pub" + } + }, + "interfaces_names": [ + "p_ff798dba-0", + "v_public", + "v_vrouter_pub", + "eno33554952" + ], + "name": "br-ex", + "stp_enabled": "no" + }, + { + "connector_type": "bridge", + "host": "node-6.cisco.com", + "id": "8000.005056ace897", + "interfaces": { + "eno16777728": { + "mac_address": "", + "name": "eno16777728" + } + }, + "interfaces_names": [ + "eno16777728" + ], + "name": "br-fw-admin", + "stp_enabled": "no" + }, + { + "connector_type": "bridge", + "host": "node-6.cisco.com", + "id": "8000.005056acc9a2", + "interfaces": { + "eno33554952.103": { + "mac_address": "", + "name": "eno33554952.103" + } + }, + "interfaces_names": [ + "eno33554952.103" + ], + "name": "br-mesh", + "stp_enabled": "no" + }, + { + "connector_type": "bridge", + "host": "node-6.cisco.com", + "id": "8000.005056ace897", + "interfaces": { + "eno16777728.101": { + "mac_address": "", + "name": "eno16777728.101" + }, + "mgmt-conntrd": { + "mac_address": "", + "name": "mgmt-conntrd" + }, + "v_management": { + "mac_address": "", + "name": "v_management" + }, + "v_vrouter": { + "mac_address": "", + "name": "v_vrouter" + } + }, + "interfaces_names": [ + "v_management", + "mgmt-conntrd", + "v_vrouter", + "eno16777728.101" + ], + "name": "br-mgmt", + "stp_enabled": "no" + }, + { + "connector_type": "bridge", + "host": "node-6.cisco.com", + "id": "8000.005056ace897", + "interfaces": { + "eno16777728.102": { + "mac_address": "", + "name": "eno16777728.102" + } + }, + "interfaces_names": [ + "eno16777728.102" + ], + "name": "br-storage", + "stp_enabled": "no" + } +]
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_vpp.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_vpp.py new file mode 100644 index 0000000..2c78b6a --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_vconnectors_vpp.py @@ -0,0 +1,137 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +HOST = { + "config" : { + "metadata_proxy_socket" : "/opt/stack/data/neutron/metadata_proxy", + "nova_metadata_ip" : "192.168.20.14", + "log_agent_heartbeats" : False + }, + "environment" : "Devstack-VPP-2", + "host" : "ubuntu0", + "host_type" : [ + "Controller", + "Compute", + "Network" + ], + "id" : "ubuntu0", + "id_path" : "/Devstack-VPP-2/Devstack-VPP-2-regions/RegionOne/RegionOne-availability_zones/nova/ubuntu0", + "ip_address" : "192.168.20.14", + "name" : "ubuntu0", + "name_path" : "/Devstack-VPP-2/Regions/RegionOne/Availability Zones/nova/ubuntu0", + "object_name" : "ubuntu0", + "os_id" : "1", + "parent_id" : "nova", + "parent_type" : "availability_zone", + "services" : { + "nova-conductor" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:58.000000" + }, + "nova-scheduler" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:54.000000" + }, + "nova-consoleauth" : { + "available" : True, + "active" : True, + "updated_at" : "2016-08-30T09:18:54.000000" + } + }, + "show_in_tree" : True, + "type" : "host", + "zone" : "nova" +} + +MODE_RESULT = [ + "l3 local0 ", + "l3 pg/stream-0 ", + "l3 pg/stream-1 ", + "l3 pg/stream-2 ", + "l3 pg/stream-3 ", + "l2 bridge TenGigabitEthernetc/0/0 bd_id 5678 shg 0", + "l3 TenGigabitEthernetd/0/0 ", + "l2 bridge VirtualEthernet0/0/0 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/1 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/2 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/3 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/4 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/5 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/6 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/7 bd_id 5678 shg 0", + "l2 bridge VirtualEthernet0/0/8 bd_id 5678 shg 0" +] + +INTERFACE_LINES = [ + " Name Idx Link Hardware", + "TenGigabitEthernetc/0/0 5 up TenGigabitEthernetc/0/0", + " Ethernet address 00:25:b5:99:00:5c", + " Cisco VIC", + " carrier up full duplex speed 40000 mtu 1500 promisc", + " rx queues 1, rx desc 5120, tx queues 1, tx desc 2048", + " cpu socket 0", + "", + " tx frames ok 81404", + " tx bytes ok 6711404", + " rx frames ok 502521", + " rx bytes ok 668002732", + " rx missed 64495", + " extended stats:", + " rx good packets 502521", + " tx good packets 81404", + " rx good bytes 668002732", + " tx good bytes 6711404" +] + +INTERFACE_NAME = "TenGigabitEthernetc/0/0" + +GET_INTERFACE_DETAIL = { + "hardware": "TenGigabitEthernetc/0/0", + "id": "5", + "mac_address": "00:25:b5:99:00:5c", + "name": "TenGigabitEthernetc/0/0", + "state": "up" +} + +# functional test +# environment: Devstack-VPP-2 +# inventory name: vpp + +INPUT = "ubuntu0" +OUPUT = [ + { + "bd_id": "5678", + "host": "ubuntu0", + "id": "ubuntu0-vconnector-5678", + "interfaces": { + "name": { + "hardware": "VirtualEthernet0/0/8", + "id": "15", + "mac_address": "fa:16:3e:d1:98:73", + "name": "VirtualEthernet0/0/8", + "state": "up" + } + }, + "interfaces_names": [ + "TenGigabitEthernetc/0/0", + "VirtualEthernet0/0/0", + "VirtualEthernet0/0/1", + "VirtualEthernet0/0/2", + "VirtualEthernet0/0/3", + "VirtualEthernet0/0/4", + "VirtualEthernet0/0/5", + "VirtualEthernet0/0/6", + "VirtualEthernet0/0/7", + "VirtualEthernet0/0/8" + ], + "name": "bridge-domain-5678" + } +]
\ No newline at end of file diff --git a/app/test/fetch/cli_fetch/test_data/cli_fetch_vservice_vnics.py b/app/test/fetch/cli_fetch/test_data/cli_fetch_vservice_vnics.py new file mode 100644 index 0000000..0b60af5 --- /dev/null +++ b/app/test/fetch/cli_fetch/test_data/cli_fetch_vservice_vnics.py @@ -0,0 +1,616 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +NETWORK_NODE = { + "config": { + "interfaces": 4, + "log_agent_heartbeats": False, + "gateway_external_network_id": "", + "router_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "ex_gw_ports": 2, + "routers": 2, + "handle_internal_only_routers": True, + "floating_ips": 1, + "external_network_bridge": "", + "use_namespaces": True, + "agent_mode": "legacy" + }, + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com", + "name": "node-6.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com", + "object_name": "node-6.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:10.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:54.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:45.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:56.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +COMPUTE_NODE = { + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-5.cisco.com", + "host_type": [ + "Compute" + ], + "id": "node-5.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com", + "object_name": "node-5.cisco.com", + "os_id": "1", + "parent_id": "osdna-zone", + "parent_type": "availability_zone", + "services": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:42.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "osdna-zone" +} + +ERROR_NODE = { + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-5.cisco.com", + "id": "node-5.cisco.com", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/osdna-zone/node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/osdna-zone/node-5.cisco.com", + "object_name": "node-5.cisco.com", + "os_id": "1", + "parent_id": "osdna-zone", + "parent_type": "availability_zone", + "services": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": "2016-10-21T18:01:42.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "osdna-zone" +} + +NAME_SPACES = [ + 'qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17', + 'qdhcp-0abe6331-0d74-4bbd-ad89-a5719c3793e4', + 'qdhcp-413de095-01ed-49dc-aa50-4479f43d390e', + 'qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc', + 'qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', + 'qdhcp-eb276a62-15a9-4616-a192-11466fdd147f', + 'qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627', + 'qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f', + 'qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc', + 'qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9', + 'qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6', + 'haproxy', + 'vrouter' +] + +SERVICE_ID = 'qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17' + +SERVICES = [ + { + "IP Address": "172.16.13.2", + "IPv6 Address": "fe80::f816:3eff:fea1:eb73/64", + "cidr": "172.16.13.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:a1:eb:73\ninet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:28 errors:0 dropped:35 overruns:0 frame:0\nTX packets:8 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:4485 (4.4 KB) TX bytes:648 (648.0 B)\n", + "host": "node-6.cisco.com", + "id": "tapa68b2627-a1", + "mac_address": "fa:16:3e:a1:eb:73", + "master_parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "master_parent_type": "vservice", + "name": "tapa68b2627-a1", + "netmask": "255.255.255.0", + "network": "8673c48a-f137-4497-b25d-08b7b218fd17", + "parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + } +] + +NET_MASK_ARRAY = ["255", "255", "255", "0"] +SIZE = '24' + +VNIC = { + "IP Address": "172.16.13.2", + "IPv6 Address": "fe80::f816:3eff:fea1:eb73/64", + "host": "node-6.cisco.com", + "id": "tapa68b2627-a1", + "lines": [ + "Link encap:Ethernet HWaddr fa:16:3e:a1:eb:73", + "inet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0", + "inet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link", + "UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1", + "RX packets:28 errors:0 dropped:35 overruns:0 frame:0", + "TX packets:8 errors:0 dropped:0 overruns:0 carrier:0", + "collisions:0 txqueuelen:0", + "RX bytes:4485 (4.4 KB) TX bytes:648 (648.0 B)", + "" + ], + "mac_address": "fa:16:3e:a1:eb:73", + "master_parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "master_parent_type": "vservice", + "name": "tapa68b2627-a1", + "netmask": "255.255.255.0", + "parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" +} + +RAW_VNIC = { + "host": "node-6.cisco.com", + "id": "tapa68b2627-a1", + "lines": [], + "master_parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "master_parent_type": "vservice", + "name": "tapa68b2627-a1", + "parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" +} + +NETWORK = [{ + "admin_state_up": True, + "cidrs": [ + "172.16.13.0/24" + ], + "environment": "Mirantis-Liberty-Xiaocong", + "id": "8673c48a-f137-4497-b25d-08b7b218fd17", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0ae4973c8375ddf40-networks/8673c48a-f137-4497-b25d-08b7b218fd17", + "mtu": 1400, + "name": "25", + "name_path": "/Mirantis-Liberty-Xiaocong/Projects/OSDNA-project/Networks/25", + "network": "8673c48a-f137-4497-b25d-08b7b218fd17", + "object_name": "25", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "OSDNA-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 52, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnets": { + "123e": { + "ip_version": 4, + "enable_dhcp": True, + "gateway_ip": "172.16.13.1", + "id": "fcfa62ec-5ae7-46ce-9259-5f30de7af858", + "ipv6_ra_mode": None, + "name": "123e", + "dns_nameservers": [ + + ], + "cidr" : "172.16.13.0/24", + "subnetpool_id": None, + "ipv6_address_mode": None, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "network_id": "8673c48a-f137-4497-b25d-08b7b218fd17", + "host_routes": [ + + ], + "allocation_pools": [ + { + "start": "172.16.13.2", + "end": "172.16.13.254" + } + ] + } + }, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +}] + +VSERVICE = { + "children_url": "/osdna_dev/discover.py?type=tree&id=qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "environment": "Mirantis-Liberty-Xiaocong", + "host": "node-6.cisco.com", + "id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "id_path": "/Mirantis-Liberty-Xiaocong/Mirantis-Liberty-Xiaocong-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com/node-6.cisco.com-vservices/node-6.cisco.com-vservices-dhcps/qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "local_service_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "name": "dhcp-25", + "name_path": "/Mirantis-Liberty-Xiaocong/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com/Vservices/DHCP servers/dhcp-25", + "network": [ + "8673c48a-f137-4497-b25d-08b7b218fd17" + ], + "object_name": "dhcp-25", + "parent_id": "node-6.cisco.com-vservices-dhcps", + "parent_text": "DHCP servers", + "parent_type": "vservice_dhcps_folder", + "service_type": "dhcp", + "show_in_tree": True, + "type": "vservice" +} + + +CIDR = "172.16.13.0/24" + +IFCONFIG_RESULT = [ + "lo Link encap:Local Loopback ", + " inet addr:127.0.0.1 Mask:255.0.0.0", + " inet6 addr: ::1/128 Scope:Host", + " UP LOOPBACK RUNNING MTU:65536 Metric:1", + " RX packets:0 errors:0 dropped:0 overruns:0 frame:0", + " TX packets:0 errors:0 dropped:0 overruns:0 carrier:0", + " collisions:0 txqueuelen:0 ", + " RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)", + "", + "tapa68b2627-a1 Link encap:Ethernet HWaddr fa:16:3e:a1:eb:73 ", + " inet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0", + " inet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link", + " UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1", + " RX packets:28 errors:0 dropped:35 overruns:0 frame:0", + " TX packets:8 errors:0 dropped:0 overruns:0 carrier:0", + " collisions:0 txqueuelen:0 ", + " RX bytes:4485 (4.4 KB) TX bytes:648 (648.0 B)", + "" +] + +MAC_ADDRESS_LINE = "tapa68b2627-a1 Link encap:Ethernet HWaddr 00:50:56:ac:e8:97 " +MAC_ADDRESS = "00:50:56:ac:e8:97" +IPV6_ADDRESS_LINE = " inet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link" +IPV6_ADDRESS = "fe80::f816:3eff:fea1:eb73/64" +IPV4_ADDRESS_LINE = " inet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0" +IPV4_ADDRESS = "172.16.13.2" + +# functional test +INPUT = "node-6.cisco.com" +OUTPUT = [ + { + "IP Address": "172.16.13.2", + "IPv6 Address": "fe80::f816:3eff:fea1:eb73/64", + "cidr": "172.16.13.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:a1:eb:73\ninet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fea1:eb73/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:28 errors:0 dropped:35 overruns:0 frame:0\nTX packets:8 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:4485 (4.4 KB) TX bytes:648 (648.0 B)\n", + "host": "node-6.cisco.com", + "id": "tapa68b2627-a1", + "mac_address": "fa:16:3e:a1:eb:73", + "master_parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17", + "master_parent_type": "vservice", + "name": "tapa68b2627-a1", + "netmask": "255.255.255.0", + "network": "8673c48a-f137-4497-b25d-08b7b218fd17", + "parent_id": "qdhcp-8673c48a-f137-4497-b25d-08b7b218fd17-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.12.2", + "IPv6 Address": "fe80::f816:3eff:fec1:7f19/64", + "cidr": "172.16.12.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:c1:7f:19\ninet addr:172.16.12.2 Bcast:172.16.12.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fec1:7f19/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:6 errors:0 dropped:8 overruns:0 frame:0\nTX packets:8 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:360 (360.0 B) TX bytes:648 (648.0 B)\n", + "host": "node-6.cisco.com", + "id": "tape67d81de-48", + "mac_address": "fa:16:3e:c1:7f:19", + "master_parent_id": "qdhcp-0abe6331-0d74-4bbd-ad89-a5719c3793e4", + "master_parent_type": "vservice", + "name": "tape67d81de-48", + "netmask": "255.255.255.0", + "network": "0abe6331-0d74-4bbd-ad89-a5719c3793e4", + "parent_id": "qdhcp-0abe6331-0d74-4bbd-ad89-a5719c3793e4-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.10.2", + "IPv6 Address": "fe80::f816:3eff:fe23:1b94/64", + "cidr": "172.16.10.0/25", + "data": "Link encap:Ethernet HWaddr fa:16:3e:23:1b:94\ninet addr:172.16.10.2 Bcast:172.16.10.127 Mask:255.255.255.128\ninet6 addr: fe80::f816:3eff:fe23:1b94/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:51 errors:0 dropped:12 overruns:0 frame:0\nTX packets:8 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:9161 (9.1 KB) TX bytes:648 (648.0 B)\n", + "host": "node-6.cisco.com", + "id": "tapa1bf631f-de", + "mac_address": "fa:16:3e:23:1b:94", + "master_parent_id": "qdhcp-413de095-01ed-49dc-aa50-4479f43d390e", + "master_parent_type": "vservice", + "name": "tapa1bf631f-de", + "netmask": "255.255.255.128", + "network": "413de095-01ed-49dc-aa50-4479f43d390e", + "parent_id": "qdhcp-413de095-01ed-49dc-aa50-4479f43d390e-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.13.2", + "IPv6 Address": "fe80::f816:3eff:fec3:c871/64", + "cidr": "172.16.13.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:c3:c8:71\ninet addr:172.16.13.2 Bcast:172.16.13.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fec3:c871/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:4614 errors:0 dropped:4 overruns:0 frame:0\nTX packets:4459 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:823296 (823.2 KB) TX bytes:929712 (929.7 KB)\n", + "host": "node-6.cisco.com", + "id": "tapaf69959f-ef", + "mac_address": "fa:16:3e:c3:c8:71", + "master_parent_id": "qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc", + "master_parent_type": "vservice", + "name": "tapaf69959f-ef", + "netmask": "255.255.255.0", + "network": "8673c48a-f137-4497-b25d-08b7b218fd17", + "parent_id": "qdhcp-2e3b85f4-756c-49d9-b34c-f3db13212dbc-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.4.2", + "IPv6 Address": "fe80::f816:3eff:fed7:c516/64", + "cidr": "172.16.4.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:d7:c5:16\ninet addr:172.16.4.2 Bcast:172.16.4.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fed7:c516/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:56928 errors:0 dropped:15 overruns:0 frame:0\nTX packets:56675 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:10526014 (10.5 MB) TX bytes:12041070 (12.0 MB)\n", + "host": "node-6.cisco.com", + "id": "tap16620a58-c4", + "mac_address": "fa:16:3e:d7:c5:16", + "master_parent_id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "master_parent_type": "vservice", + "name": "tap16620a58-c4", + "netmask": "255.255.255.0", + "network": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "parent_id": "qdhcp-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.2.2", + "IPv6 Address": "fe80::f816:3eff:feeb:39c2/64", + "cidr": "172.16.2.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:eb:39:c2\ninet addr:172.16.2.2 Bcast:172.16.2.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:feeb:39c2/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:93317 errors:0 dropped:57 overruns:0 frame:0\nTX packets:93264 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:17406098 (17.4 MB) TX bytes:19958079 (19.9 MB)\n", + "host": "node-6.cisco.com", + "id": "tap82d4992f-4d", + "mac_address": "fa:16:3e:eb:39:c2", + "master_parent_id": "qdhcp-eb276a62-15a9-4616-a192-11466fdd147f", + "master_parent_type": "vservice", + "name": "tap82d4992f-4d", + "netmask": "255.255.255.0", + "network": "eb276a62-15a9-4616-a192-11466fdd147f", + "parent_id": "qdhcp-eb276a62-15a9-4616-a192-11466fdd147f-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.3.2", + "IPv6 Address": "fe80::f816:3eff:fe1c:9936/64", + "cidr": "172.16.3.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:1c:99:36\ninet addr:172.16.3.2 Bcast:172.16.3.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe1c:9936/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:170894 errors:0 dropped:41 overruns:0 frame:0\nTX packets:170588 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:31784458 (31.7 MB) TX bytes:36444046 (36.4 MB)\n", + "host": "node-6.cisco.com", + "id": "tap5f22f397-d8", + "mac_address": "fa:16:3e:1c:99:36", + "master_parent_id": "qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627", + "master_parent_type": "vservice", + "name": "tap5f22f397-d8", + "netmask": "255.255.255.0", + "network": "7e59b726-d6f4-451a-a574-c67a920ff627", + "parent_id": "qdhcp-7e59b726-d6f4-451a-a574-c67a920ff627-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.1.2", + "IPv6 Address": "fe80::f816:3eff:fe59:5fff/64", + "cidr": "172.16.1.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:59:5f:ff\ninet addr:172.16.1.2 Bcast:172.16.1.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe59:5fff/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:93468 errors:0 dropped:38 overruns:0 frame:0\nTX packets:93452 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:17416578 (17.4 MB) TX bytes:19972565 (19.9 MB)\n", + "host": "node-6.cisco.com", + "id": "tapbf16c3ab-56", + "mac_address": "fa:16:3e:59:5f:ff", + "master_parent_id": "qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "master_parent_type": "vservice", + "name": "tapbf16c3ab-56", + "netmask": "255.255.255.0", + "network": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "parent_id": "qdhcp-a55ff1e8-3821-4e5f-bcfd-07df93720a4f-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "192.168.111.2", + "IPv6 Address": "fe80::f816:3eff:fe74:5/64", + "cidr": "192.168.111.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:74:00:05\ninet addr:192.168.111.2 Bcast:192.168.111.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe74:5/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:45 errors:0 dropped:28 overruns:0 frame:0\nTX packets:8 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:3734 (3.7 KB) TX bytes:648 (648.0 B)\n", + "host": "node-6.cisco.com", + "id": "tapee8e5dbb-03", + "mac_address": "fa:16:3e:74:00:05", + "master_parent_id": "qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc", + "master_parent_type": "vservice", + "name": "tapee8e5dbb-03", + "netmask": "255.255.255.0", + "network": "6504fcf7-41d7-40bb-aeb1-6a7658c105fc", + "parent_id": "qdhcp-6504fcf7-41d7-40bb-aeb1-6a7658c105fc-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.0.131", + "IPv6 Address": "2001:420:4482:24c1:f816:3eff:fe23:3ad7/64", + "cidr": "172.16.0.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:23:3a:d7\ninet addr:172.16.0.131 Bcast:172.16.0.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe23:3ad7/64 Scope:Link\ninet6 addr: 2001:420:4482:24c1:f816:3eff:fe23:3ad7/64 Scope:Global\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:48172796 errors:0 dropped:1144801 overruns:0 frame:0\nTX packets:63 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:4220491940 (4.2 GB) TX bytes:3162 (3.1 KB)\n", + "host": "node-6.cisco.com", + "id": "qg-63489f34-af", + "mac_address": "fa:16:3e:23:3a:d7", + "master_parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_type": "vservice", + "name": "qg-63489f34-af", + "netmask": "255.255.255.0", + "network": "c64adb76-ad9d-4605-9f5e-bd6dbe325cfb", + "parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.13.5", + "IPv6 Address": "fe80::f816:3eff:fe1f:e174/64", + "cidr": "172.16.13.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:1f:e1:74\ninet addr:172.16.13.5 Bcast:172.16.13.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe1f:e174/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:25 errors:0 dropped:1 overruns:0 frame:0\nTX packets:10 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:2460 (2.4 KB) TX bytes:864 (864.0 B)\n", + "host": "node-6.cisco.com", + "id": "qr-18f029db-77", + "mac_address": "fa:16:3e:1f:e1:74", + "master_parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_type": "vservice", + "name": "qr-18f029db-77", + "netmask": "255.255.255.0", + "network": "8673c48a-f137-4497-b25d-08b7b218fd17", + "parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.2.1", + "IPv6 Address": "fe80::f816:3eff:fe2c:fb9b/64", + "cidr": "172.16.2.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:2c:fb:9b\ninet addr:172.16.2.1 Bcast:172.16.2.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe2c:fb9b/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:49 errors:0 dropped:3 overruns:0 frame:0\nTX packets:10 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:5825 (5.8 KB) TX bytes:864 (864.0 B)\n", + "host": "node-6.cisco.com", + "id": "qr-3ff411a2-54", + "mac_address": "fa:16:3e:2c:fb:9b", + "master_parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_type": "vservice", + "name": "qr-3ff411a2-54", + "netmask": "255.255.255.0", + "network": "eb276a62-15a9-4616-a192-11466fdd147f", + "parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.1.1", + "IPv6 Address": "fe80::f816:3eff:feee:9a46/64", + "cidr": "172.16.1.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:ee:9a:46\ninet addr:172.16.1.1 Bcast:172.16.1.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:feee:9a46/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:85 errors:0 dropped:14 overruns:0 frame:0\nTX packets:10 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:7402 (7.4 KB) TX bytes:864 (864.0 B)\n", + "host": "node-6.cisco.com", + "id": "qr-8733cc5d-b3", + "mac_address": "fa:16:3e:ee:9a:46", + "master_parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_type": "vservice", + "name": "qr-8733cc5d-b3", + "netmask": "255.255.255.0", + "network": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.3.1", + "IPv6 Address": "fe80::f816:3eff:feba:5a3c/64", + "cidr": "172.16.3.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:ba:5a:3c\ninet addr:172.16.3.1 Bcast:172.16.3.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:feba:5a3c/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:3018 errors:0 dropped:15 overruns:0 frame:0\nTX packets:1766 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:295458 (295.4 KB) TX bytes:182470 (182.4 KB)\n", + "host": "node-6.cisco.com", + "id": "qr-bb9b8340-72", + "mac_address": "fa:16:3e:ba:5a:3c", + "master_parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9", + "master_parent_type": "vservice", + "name": "qr-bb9b8340-72", + "netmask": "255.255.255.0", + "network": "7e59b726-d6f4-451a-a574-c67a920ff627", + "parent_id": "qrouter-9ec3d703-0725-47e3-8f48-02b16236caf9-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "172.16.0.130", + "IPv6 Address": "fe80::f816:3eff:fecb:8d7b/64", + "cidr": "172.16.0.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:cb:8d:7b\ninet addr:172.16.0.130 Bcast:172.16.0.255 Mask:255.255.255.0\ninet6 addr: 2001:420:4482:24c1:f816:3eff:fecb:8d7b/64 Scope:Global\ninet6 addr: fe80::f816:3eff:fecb:8d7b/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:48172955 errors:0 dropped:1144729 overruns:0 frame:0\nTX packets:59 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:4220505032 (4.2 GB) TX bytes:2958 (2.9 KB)\n", + "host": "node-6.cisco.com", + "id": "qg-57e65d34-3d", + "mac_address": "fa:16:3e:cb:8d:7b", + "master_parent_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6", + "master_parent_type": "vservice", + "name": "qg-57e65d34-3d", + "netmask": "255.255.255.0", + "network": "c64adb76-ad9d-4605-9f5e-bd6dbe325cfb", + "parent_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + }, + { + "IP Address": "192.168.111.1", + "IPv6 Address": "fe80::f816:3eff:fe0a:3cc/64", + "cidr": "192.168.111.0/24", + "data": "Link encap:Ethernet HWaddr fa:16:3e:0a:03:cc\ninet addr:192.168.111.1 Bcast:192.168.111.255 Mask:255.255.255.0\ninet6 addr: fe80::f816:3eff:fe0a:3cc/64 Scope:Link\nUP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\nRX packets:79 errors:0 dropped:0 overruns:0 frame:0\nTX packets:10 errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:6475 (6.4 KB) TX bytes:864 (864.0 B)\n", + "host": "node-6.cisco.com", + "id": "qr-f7b44150-99", + "mac_address": "fa:16:3e:0a:03:cc", + "master_parent_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6", + "master_parent_type": "vservice", + "name": "qr-f7b44150-99", + "netmask": "255.255.255.0", + "network": "6504fcf7-41d7-40bb-aeb1-6a7658c105fc", + "parent_id": "qrouter-49ac7716-06da-49ed-b388-f8ba60e8a0e6-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "type": "vnic", + "vnic_type": "vservice_vnic" + } +]
\ No newline at end of file diff --git a/app/test/fetch/config/__init__.py b/app/test/fetch/config/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/config/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/config/test_config.py b/app/test/fetch/config/test_config.py new file mode 100644 index 0000000..176fd48 --- /dev/null +++ b/app/test/fetch/config/test_config.py @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +# local config info for test. + + +MONGODB_CONFIG = 'your-mongo-config-path-here' + +ENV_CONFIG = 'your-env-name-here' + +COLLECTION_CONFIG = 'your-inventory-collection-name-here' diff --git a/app/test/fetch/db_fetch/__init__.py b/app/test/fetch/db_fetch/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/db_fetch/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/db_fetch/mock_cursor.py b/app/test/fetch/db_fetch/mock_cursor.py new file mode 100644 index 0000000..71efd3b --- /dev/null +++ b/app/test/fetch/db_fetch/mock_cursor.py @@ -0,0 +1,25 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +class MockCursor: + + def __init__(self, result): + self.result = result + self.current = 0 + + def __next__(self): + if self.current < len(self.result): + next = self.result[self.current] + self.current += 1 + return next + else: + raise StopIteration + + def __iter__(self): + return self diff --git a/app/test/fetch/db_fetch/test_data/__init__.py b/app/test/fetch/db_fetch/test_data/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/__init__.py @@ -0,0 +1,9 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### diff --git a/app/test/fetch/db_fetch/test_data/db_access.py b/app/test/fetch/db_fetch/test_data/db_access.py new file mode 100644 index 0000000..a4ad548 --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_access.py @@ -0,0 +1,40 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +DB_CONFIG = { + "host": "10.56.20.239", + "name": "mysql", + "password": "102QreDdiD5sKcvNf9qbHrmr", + "port": 3307.0, + "user": "root", + "schema": "nova" + } + +QUERY_WITHOUT_ID = """ + SELECT id, name + FROM nova.aggregates + WHERE deleted = 0 + """ + +QUERY_WITH_ID = """ + SELECT CONCAT('aggregate-', a.name, '-', host) AS id, host AS name + FROM nova.aggregate_hosts ah + JOIN nova.aggregates a ON a.id = ah.aggregate_id + WHERE ah.deleted = 0 AND aggregate_id = %s + """ + +ID = "2" +OBJECT_TYPE = "host aggregate" + +OBJECTS_LIST = [ + { + "id": 1, + "name": "osdna-agg" + } +] diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_aggregate_hosts.py b/app/test/fetch/db_fetch/test_data/db_fetch_aggregate_hosts.py new file mode 100644 index 0000000..2f1313a --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_aggregate_hosts.py @@ -0,0 +1,34 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from bson.objectid import ObjectId + + +AGGREGATE = { + "id": "1", +} + +HOSTS = [ + { + "id": "aggregate-osdna-agg-node-5.cisco.com", + "name": "node-5.cisco.com" + } +] + +HOST_IN_INVENTORY = { + "_id": "595ac4b6d7c037efdb8918a7" +} + +HOSTS_RESULT = [ + { + "id": "aggregate-osdna-agg-node-5.cisco.com", + "name": "node-5.cisco.com", + "ref_id": ObjectId(HOST_IN_INVENTORY["_id"]) + } +] diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_aggregates.py b/app/test/fetch/db_fetch/test_data/db_fetch_aggregates.py new file mode 100644 index 0000000..65182fa --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_aggregates.py @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +REGION_ID = "RegionOne" + +OBJECTS_LIST = [ + { + "id": 1, + "name": "calipso-agg" + } +] diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_host_network_agents.py b/app/test/fetch/db_fetch/test_data/db_fetch_host_network_agents.py new file mode 100644 index 0000000..6188ddf --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_host_network_agents.py @@ -0,0 +1,65 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +CONFIG_WITH_MECHANISM_DRIVERS = { + 'mechanism_drivers': [ + "OVS" + ] +} + +CONFIG_WITHOUT_MECHANISM_DRIVERS = { + 'mechanism_drivers': [ + + ] +} + +NETWORK_AGENT_FOLDER_ID = 'node-6.cisco.com-network_agents' + +NETWORK_AGENT = [ + { + 'configurations': '{}', + 'id': '1764430c-c09e-4717-86fa-c04350b1fcbb', + 'binary': 'neutron-openvswitch-agent', + }, + { + 'configurations': '{}', + 'id': '2c2ddfee-91f9-47da-bd65-aceecd998b7c', + 'binary': 'neutron-dhcp-agent', + } +] + +NETWORK_AGENT_WITH_MECHANISM_DRIVERS_IN_CONFIG_RESULTS = [ + { + 'configurations': {}, + 'id': 'OVS-1764430c-c09e-4717-86fa-c04350b1fcbb', + 'binary': 'neutron-openvswitch-agent', + 'name': 'neutron-openvswitch-agent' + }, + { + 'configurations': {}, + 'id': 'OVS-2c2ddfee-91f9-47da-bd65-aceecd998b7c', + 'binary': 'neutron-dhcp-agent', + 'name': 'neutron-dhcp-agent' + } +] + +NETWORK_AGENT_WITHOUT_MECHANISM_DRIVERS_IN_CONFIG_RESULTS = [ + { + 'configurations': {}, + 'id': 'network_agent-1764430c-c09e-4717-86fa-c04350b1fcbb', + 'binary': 'neutron-openvswitch-agent', + 'name': 'neutron-openvswitch-agent' + }, + { + 'configurations': {}, + 'id': 'network_agent-2c2ddfee-91f9-47da-bd65-aceecd998b7c', + 'binary': 'neutron-dhcp-agent', + 'name': 'neutron-dhcp-agent' + } +] diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_instances.py b/app/test/fetch/db_fetch/test_data/db_fetch_instances.py new file mode 100644 index 0000000..5ba6a74 --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_instances.py @@ -0,0 +1,91 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +INSTANCES_FROM_API = [ + { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + } +] + +INSTANCES_FROM_DB = [ + { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network_info": "[{\"network\": {\"id\": \"7e59b726-d6f4-451a-a574-c67a920ff627\"}}]", + "project": "Calipso-project", + }, + { + "host": "node-5.cisco.com", + "id": "bf0cb914-b316-486c-a4ce-f22deb453c52", + "network_info": "[{\"network\": {\"id\": \"7e59b726-d6f4-451a-a574-c67a920ff627\"}}]", + "project": "Calipso-project", + } +] + +UPDATED_INSTANCES_DATA = [ + { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network": ["7e59b726-d6f4-451a-a574-c67a920ff627"], + "type": "instance", + "parent_type": "instances_folder", + "parent_id": "node-5.cisco.com-instances", + "in_project-Calipso-project": "1", + "network_info": [ + { + "network": { + "id": "7e59b726-d6f4-451a-a574-c67a920ff627" + } + } + ] + } +] + +INSTANCE_WITH_NETWORK = { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network_info": "[{\"network\": {\"id\": \"7e59b726-d6f4-451a-a574-c67a920ff627\"}}]", + "project": "Calipso-project", +} + +INSTANCE_WITH_NETWORK_RESULT = { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network": ["7e59b726-d6f4-451a-a574-c67a920ff627"], + "type": "instance", + "parent_type": "instances_folder", + "parent_id": "node-5.cisco.com-instances", + "in_project-Calipso-project": "1", + "network_info": [ + { + "network": { + "id": "7e59b726-d6f4-451a-a574-c67a920ff627" + } + } + ] +} + +INSTANCE_WITHOUT_NETWORK = { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network_info": "[]", + "project": "Calipso-project", +} + +INSTANCE_WITHOUT_NETWORK_RESULT = { + "host": "node-5.cisco.com", + "id": "6f29c867-9150-4533-8e19-70d749b172fa", + "network": [], + "type": "instance", + "parent_type": "instances_folder", + "parent_id": "node-5.cisco.com-instances", + "in_project-Calipso-project": "1", + "network_info": [] +} diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_oteps.py b/app/test/fetch/db_fetch/test_data/db_fetch_oteps.py new file mode 100644 index 0000000..a5bc63d --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_oteps.py @@ -0,0 +1,131 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +VEDGE_ID = "3858e121-d861-4348-9d64-a55fcd5bf60a" +VEDGE = { + "configurations": { + "tunnel_types": [ + "vxlan" + ], + "tunneling_ip": "192.168.2.1" + }, + "host": "node-5.cisco.com", + "id": "3858e121-d861-4348-9d64-a55fcd5bf60a", + "tunnel_ports": { + "vxlan-c0a80203": { + }, + "br-tun": { + } + }, + "type": "vedge" +} +VEDGE_WITHOUT_CONFIGS ={ + +} +VEDGE_WITHOUT_TUNNEL_TYPES = { + "configuration": { + "tunnel_types": "" + } +} +NON_ICEHOUSE_CONFIGS = { + "distribution": "Mirantis-8.0" +} +ICEHOUSE_CONFIGS = { + "distribution": "Canonical-icehouse" +} +HOST = { + "host": "node-5.cisco.com", + "id": "node-5.cisco.com", + "ip_address": "192.168.0.4", + "name": "node-5.cisco.com" +} +OTEPS_WITHOUT_CONFIGURATIONS_IN_VEDGE_RESULTS = [] +OTEPS_WITHOUT_TUNNEL_TYPES_IN_VEDGE_RESULTS = [] +OTEPS_FOR_NON_ICEHOUSE_DISTRIBUTION_RESULTS = [ + { + "host": "node-5.cisco.com", + "ip_address": "192.168.2.1", + "udp_port": 4789, + "id": "node-5.cisco.com-otep", + "name": "node-5.cisco.com-otep", + "overlay_type": "vxlan", + "ports": { + "vxlan-c0a80203": { + }, + "br-tun": { + } + } + } +] +OTEPS_FOR_ICEHOUSE_DISTRIBUTION_RESULTS = [ + { + "host": "node-5.cisco.com", + "ip_address": "192.168.0.4", + "id": "node-5.cisco.com-otep", + "name": "node-5.cisco.com-otep", + "overlay_type": "vxlan", + "ports": { + "vxlan-c0a80203": { + }, + "br-tun": { + } + }, + "udp_port": "67" + } +] + +OTEPS = [ + { + "host": "node-5.cisco.com", + "ip_address": "192.168.2.1", + "udp_port": 4789 + } +] + +OTEP_FOR_GETTING_VECONNECTOR = { + "host": "node-5.cisco.com", + "ip_address": "192.168.2.1", + "udp_port": 4789, + "id": "node-5.cisco.com-otep", + "name": "node-5.cisco.com-otep", + "overlay_type": "vxlan", + "ports": { + "vxlan-c0a80203": { + }, + "br-tun": { + } + } +} +HOST_ID = "node-5.cisco.com" +IFCONFIG_LINES = [ + "br-mesh Link encap:Ethernet HWaddr 00:50:56:ac:28:9d ", + " inet addr:192.168.2.1 Bcast:192.168.2.255 Mask:255.255.255.0", + " inet6 addr: fe80::d4e1:8fff:fe33:ed6a/64 Scope:Link", + " UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1", + " RX packets:2273307 errors:0 dropped:0 overruns:0 frame:0", + " TX packets:2255930 errors:0 dropped:0 overruns:0 carrier:0", + " collisions:0 txqueuelen:0 ", + " RX bytes:578536155 (578.5 MB) TX bytes:598541522 (598.5 MB)", + "" +] +OTEP_WITH_CONNECTOR = { + "host": "node-5.cisco.com", + "ip_address": "192.168.2.1", + "udp_port": 4789, + "id": "node-5.cisco.com-otep", + "name": "node-5.cisco.com-otep", + "overlay_type": "vxlan", + "ports": { + "vxlan-c0a80203": { + }, + "br-tun": { + } + }, + "vconnector": "br-mesh" +} diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_vedges_ovs.py b/app/test/fetch/db_fetch/test_data/db_fetch_vedges_ovs.py new file mode 100644 index 0000000..818704c --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_vedges_ovs.py @@ -0,0 +1,168 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +VEDGES_FOLDER_ID = "node-6.cisco.com-vedges" + +OBJECTS_FROM_DB = [ + { + "host": "node-6.cisco.com", + "agent_type": "Open vSwitch agent", + "configurations": '{"tunneling_ip": "192.168.2.3"}', + } +] + +HOST = { + "host": "node-6.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-6.cisco.com", + "name": "node-6.cisco.com" +} + +HOST_WITHOUT_REQUIRED_HOST_TYPES = { + "id": "node-6.cisco.com", + "host_type": [] +} + +PORTS = { + "ovs-system": { + "name": "ovs-system", + "id": "0", + "internal": True + }, + "qr-bb9b8340-72": { + "name": "qr-bb9b8340-72", + "id": "1", + "internal": True, + "tag": "3" + }, + "qr-8733cc5d-b3": { + "name": "qr-8733cc5d-b3", + "id": "2", + "internal": True, + "tag": "4" + } +} + +TUNNEL_PORTS = { + "patch-int": { + "interface": "patch-int", + "name": "patch-int", + "options": { + "peer": "patch-tun" + }, + "type": "patch" + } +} + +GET_RESULTS = [ + { + 'name': 'node-6.cisco.com-OVS', + 'host': 'node-6.cisco.com', + 'agent_type': 'Open vSwitch agent', + 'configurations': {"tunneling_ip": "192.168.2.3"}, + 'ports': PORTS, + 'tunnel_ports': TUNNEL_PORTS + } +] + + +VSCTL_LINES = [ + "3b12f08e-4e13-4976-8da5-23314b268805", + " Bridge br-int", + " fail_mode: secure", + " Port \"qr-bb9b8340-72\"", + " tag: 3", + " Interface \"qr-bb9b8340-72\"", + " type: internal", + " Port \"qr-8733cc5d-b3\"", + " tag: 4", + " Interface \"qr-8733cc5d-b3\"", + " type: internal", + " Bridge br-tun", + " fail_mode: secure", + " Port patch-int", + " Interface patch-int", + " type: patch", + " options: {peer=patch-tun}", +] + +DPCTL_LINES = [ + "system@ovs-system:", + "\tlookups: hit:14039304 missed:35687906 lost:0", + "\tflows: 4", + "\tmasks: hit:95173613 total:2 hit/pkt:1.91", + "\tport 0: ovs-system (internal)", + "\tport 1: qr-bb9b8340-72 (internal)", + "\tport 2: qr-8733cc5d-b3 (internal)" +] + +DPCTL_RESULTS = { + "ovs-system": { + "name": "ovs-system", + "id": "0", + "internal": True + }, + "qr-bb9b8340-72": { + "name": "qr-bb9b8340-72", + "id": "1", + "internal": True + }, + "qr-8733cc5d-b3": { + "name": "qr-8733cc5d-b3", + "id": "2", + "internal": True + } +} + +FETCH__PORT_TAGS_INPUT = { + "ovs-system": { + "name": "ovs-system", + "id": "0", + "internal": True + }, + "qr-bb9b8340-72": { + "name": "qr-bb9b8340-72", + "id": "1", + "internal": True + }, + "qr-8733cc5d-b3": { + "name": "qr-8733cc5d-b3", + "id": "2", + "internal": True + } +} + +FETCH_PORT_TAGS_RESULT = { + "ovs-system": { + "name": "ovs-system", + "id": "0", + "internal": True + }, + "qr-bb9b8340-72": { + "name": "qr-bb9b8340-72", + "id": "1", + "internal": True, + "tag": "3" + }, + "qr-8733cc5d-b3": { + "name": "qr-8733cc5d-b3", + "id": "2", + "internal": True, + "tag": "4" + } +} + +DOC_TO_GET_OVERLAY = { + "host": "node-6.cisco.com", + "agent_type": "Open vSwitch agent", + "configurations": {"tunneling_ip": "192.168.2.3"}, +} diff --git a/app/test/fetch/db_fetch/test_data/db_fetch_vedges_vpp.py b/app/test/fetch/db_fetch/test_data/db_fetch_vedges_vpp.py new file mode 100644 index 0000000..24265ae --- /dev/null +++ b/app/test/fetch/db_fetch/test_data/db_fetch_vedges_vpp.py @@ -0,0 +1,89 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +VEDGE_FOLDER_ID = "ubuntu0-vedges" + +HOST = { + "host_type": [ + "Controller", + "Compute", + "Network" + ], + "id": "ubuntu0", +} + +HOST_WITHOUT_REQUIRED_HOST_TYPE = { + "host_type": [ + + ] +} + +VERSION = [ + "vpp v16.09-rc0~157-g203c632 built by localadmin on ubuntu0 at Sun Jun 26 16:35:15 PDT 2016\n" +] + +INTERFACES = [ + " Name Idx State Counter Count ", + "TenGigabitEthernetc/0/0 5 up rx packets 502022", + " rx bytes 663436206", + " tx packets 81404", + " tx bytes 6366378", + " drops 1414", + " punts 1", + " rx-miss 64525", + "VirtualEthernet0/0/0 7 up tx packets 31496", + " tx bytes 2743185", + "local0 0 down ", + "pg/stream-0 1 down ", +] + +PORTS = { + "TenGigabitEthernetc/0/0": { + "id": "5", + "name": "TenGigabitEthernetc/0/0", + "state": "up" + }, + "VirtualEthernet0/0/0": { + "id": "7", + "name": "VirtualEthernet0/0/0", + "state": "up" + }, + "local0": { + "id": "0", + "name": "local0", + "state": "down" + }, + "pg/stream-0": { + "id": "1", + "name": "pg/stream-0", + "state": "down" + } +} + + +VEDGE_RESULTS = [ + { + "host": "ubuntu0", + "id": "ubuntu0-VPP", + "name": "VPP-ubuntu0", + "agent_type": "VPP", + "binary": "vpp v16.09-rc0~157-g203c632", + "ports": PORTS + } +] + +VEDGE_RESULTS_WITHOUT_BINARY = [ + { + "host": "ubuntu0", + "id": "ubuntu0-VPP", + "name": "VPP-ubuntu0", + "agent_type": "VPP", + "ports": PORTS + } +] diff --git a/app/test/fetch/db_fetch/test_db_access.py b/app/test/fetch/db_fetch/test_db_access.py new file mode 100644 index 0000000..4ef3e74 --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_access.py @@ -0,0 +1,108 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_access import DbAccess +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_access import * +from unittest.mock import MagicMock, patch +from test.fetch.db_fetch.mock_cursor import MockCursor + + +class TestDbAccess(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbAccess() + + @patch("mysql.connector.connect") + def test_db_connect(self, db_connect): + DbAccess.conn = None + db_conn = MagicMock() + db_conn.ping = MagicMock() + db_connect.return_value = db_conn + + self.fetcher.db_connect(DB_CONFIG['host'], DB_CONFIG['port'], + DB_CONFIG['user'], DB_CONFIG['password'], + DB_CONFIG['schema']) + + self.assertEqual(True, db_connect.called, "connect method has't been called") + db_conn.ping.assert_called_once_with(True) + + def test_connect_to_db(self): + DbAccess.conn = None + self.fetcher.db_connect = MagicMock() + self.fetcher.connect_to_db() + + self.assertEqual(True, self.fetcher.db_connect.called) + + def test_connect_to_db_with_force(self): + DbAccess.conn = MagicMock() + self.fetcher.db_connect = MagicMock() + self.fetcher.connect_to_db(force=True) + + self.assertEqual(True, self.fetcher.db_connect.called) + + def test_connect_to_db_without_force(self): + DbAccess.conn = MagicMock() + self.fetcher.db_connect = MagicMock() + self.fetcher.connect_to_db() + + self.assertEqual(False, self.fetcher.db_connect.called) + + def test_get_objects_list_for_id_with_id(self): + # mock the db cursor + mock_cursor = MockCursor(OBJECTS_LIST) + mock_cursor.execute = MagicMock() + + self.fetcher.connect_to_db = MagicMock() + DbAccess.conn.cursor = MagicMock(return_value=mock_cursor) + + result = self.fetcher.get_objects_list_for_id(QUERY_WITH_ID, OBJECT_TYPE, ID) + + mock_cursor.execute.assert_called_once_with(QUERY_WITH_ID, [ID]) + self.assertEqual(result, OBJECTS_LIST, "Can't get objects list") + + def test_get_objects_list_for_id_without_id(self): + mock_cursor = MockCursor(OBJECTS_LIST) + + self.fetcher.connect_to_db = MagicMock() + DbAccess.conn.cursor = MagicMock(return_value=mock_cursor) + mock_cursor.execute = MagicMock() + + result = self.fetcher.get_objects_list_for_id(QUERY_WITHOUT_ID, OBJECT_TYPE, None) + + mock_cursor.execute.assert_called_once_with(QUERY_WITHOUT_ID) + self.assertEqual(result, OBJECTS_LIST, "Can't get objects list") + + def test_get_objects_list_for_id_with_id_with_exception(self): + mock_cursor = MockCursor(OBJECTS_LIST) + self.fetcher.connect_to_db = MagicMock() + # mock exception + DbAccess.conn.cursor = MagicMock(return_value=mock_cursor) + mock_cursor.execute = MagicMock(side_effect=[AttributeError, ""]) + + result = self.fetcher.get_objects_list_for_id(QUERY_WITH_ID, OBJECT_TYPE, ID) + + self.assertEqual(mock_cursor.execute.call_count, 2, "Can't invoke execute method " + + "twice when error occurs") + self.assertEqual(result, OBJECTS_LIST, "Can't get objects list") + + def test_get_objects_list_for_id_without_id_with_exception(self): + mock_cursor = MockCursor(OBJECTS_LIST) + self.fetcher.connect_to_db = MagicMock() + DbAccess.conn.cursor = MagicMock(return_value=mock_cursor) + mock_cursor.execute = MagicMock(side_effect=[AttributeError, ""]) + + result = self.fetcher.get_objects_list_for_id(QUERY_WITHOUT_ID, + OBJECT_TYPE, + None) + + self.assertEqual(mock_cursor.execute.call_count, 2, "Can't invoke execute method " + + "twice when error occurs") + self.assertEqual(result, OBJECTS_LIST, "Can't get objects list") diff --git a/app/test/fetch/db_fetch/test_db_fetch_aggregate_hosts.py b/app/test/fetch/db_fetch/test_db_fetch_aggregate_hosts.py new file mode 100644 index 0000000..2066577 --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_aggregate_hosts.py @@ -0,0 +1,60 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_fetch_aggregate_hosts import DbFetchAggregateHosts +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_aggregate_hosts import * +from unittest.mock import MagicMock + + +class TestDbFetchAggregateHosts(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchAggregateHosts() + + def check_get_results_is_correct(self, + objects_list, + host_in_inventory, + expected_result, + err_msg): + self.fetcher.get_objects_list_for_id = MagicMock(return_value=objects_list) + self.inv.get_by_id = MagicMock(return_value=host_in_inventory) + result = self.fetcher.get(AGGREGATE["id"]) + + self.assertEqual(result, expected_result, err_msg) + + def test_get(self): + test_cases = [ + { + "objects_list": HOSTS, + "host_in_inventory": HOST_IN_INVENTORY, + "expected_result": HOSTS_RESULT, + "err_msg": "Can't get correct hosts info" + }, + { + "objects_list": [], + "host_in_inventory": None, + "expected_result": [], + "err_msg": "Can't get [] when the " + "returned objects list is empty" + }, + { + "objects_list": HOSTS, + "host_in_inventory": [], + "expected_result": HOSTS, + "err_msg": "Can't get correct hosts info " + "when the host doesn't exist in the inventory" + } + ] + for test_case in test_cases: + self.check_get_results_is_correct(test_case["objects_list"], + test_case["host_in_inventory"], + test_case["expected_result"], + test_case["err_msg"]) diff --git a/app/test/fetch/db_fetch/test_db_fetch_aggregates.py b/app/test/fetch/db_fetch/test_db_fetch_aggregates.py new file mode 100644 index 0000000..12693b7 --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_aggregates.py @@ -0,0 +1,26 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_fetch_aggregates import DbFetchAggregates +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_aggregates import * +from unittest.mock import MagicMock + + +class TestDbFetchAggregates(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchAggregates() + + def test_get(self): + self.fetcher.get_objects_list = MagicMock(return_value=OBJECTS_LIST) + result = self.fetcher.get(REGION_ID) + self.assertEqual(result, OBJECTS_LIST, "Can't get correct " + + "aggregates info") diff --git a/app/test/fetch/db_fetch/test_db_fetch_instances.py b/app/test/fetch/db_fetch/test_db_fetch_instances.py new file mode 100644 index 0000000..a1207a1 --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_instances.py @@ -0,0 +1,37 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_fetch_instances import DbFetchInstances +from test.fetch.test_fetch import TestFetch +from unittest.mock import MagicMock +from test.fetch.db_fetch.test_data.db_fetch_instances import * + + +class TestDbFetchInstances(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchInstances() + + def test_get(self): + self.fetcher.get_objects_list = MagicMock(return_value= + INSTANCES_FROM_DB) + self.fetcher.get_instance_data(INSTANCES_FROM_API) + + self.assertEqual(INSTANCES_FROM_API, UPDATED_INSTANCES_DATA) + + def test_build_instance_details_with_network(self): + self.fetcher.build_instance_details(INSTANCE_WITH_NETWORK) + self.assertEqual(INSTANCE_WITH_NETWORK, + INSTANCE_WITH_NETWORK_RESULT) + + def test_build_instance_details_without_network(self): + self.fetcher.build_instance_details(INSTANCE_WITHOUT_NETWORK) + self.assertEqual(INSTANCE_WITHOUT_NETWORK, + INSTANCE_WITHOUT_NETWORK_RESULT) diff --git a/app/test/fetch/db_fetch/test_db_fetch_oteps.py b/app/test/fetch/db_fetch/test_db_fetch_oteps.py new file mode 100644 index 0000000..905f55a --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_oteps.py @@ -0,0 +1,92 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +import copy + +from discover.fetchers.db.db_fetch_oteps import DbFetchOteps +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_oteps import * +from unittest.mock import MagicMock + + +class TestDbFetchOteps(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchOteps() + self.fetcher.set_env(self.env) + + def check_get_oteps_results(self, vedge, + config, + host, + oteps_from_db, + expected_results, + err_msg): + original_get_vconnector = self.fetcher.get_vconnector + self.fetcher.get_vconnector = MagicMock() + self.fetcher.inv.get_by_id = MagicMock(side_effect=[vedge, host]) + self.fetcher.config.get_env_config = MagicMock(return_value=config) + self.fetcher.get_objects_list_for_id = MagicMock(return_value=oteps_from_db) + results = self.fetcher.get(VEDGE_ID) + self.assertEqual(results, expected_results, err_msg) + self.fetcher.get_vconnector = original_get_vconnector + + def test_get(self): + test_cases = [ + { + "vedge": VEDGE_WITHOUT_CONFIGS, + "config": NON_ICEHOUSE_CONFIGS, + "host": None, + "oteps_from_db": None, + "expected_results": [], + "err_msg": "Can't get [] when the vedge " + + "doesn't contains configurations" + }, + { + "vedge": VEDGE_WITHOUT_TUNNEL_TYPES, + "config": NON_ICEHOUSE_CONFIGS, + "host": None, + "oteps_from_db": None, + "expected_results": [], + "err_msg": "Can't get [] when the vedge configurations " + + "doesn't contain tunnel_types" + }, + { + "vedge": VEDGE, + "config": ICEHOUSE_CONFIGS, + "host": HOST, + "oteps_from_db": None, + "expected_results": OTEPS_FOR_ICEHOUSE_DISTRIBUTION_RESULTS, + "err_msg": "Can't get correct oteps result " + + "when the distribution is icehouse" + }, + { + "vedge": VEDGE, + "config": NON_ICEHOUSE_CONFIGS, + "host": None, + "oteps_from_db": OTEPS, + "expected_results": OTEPS_FOR_NON_ICEHOUSE_DISTRIBUTION_RESULTS, + "err_msg": "Can't get correct oteps result " + + "when the distribution is not icehouse" + } + ] + for test_case in test_cases: + self.check_get_oteps_results(test_case["vedge"], + test_case["config"], + test_case["host"], + test_case["oteps_from_db"], + test_case["expected_results"], + test_case["err_msg"]) + + def test_get_vconnectors(self): + self.fetcher.run_fetch_lines = MagicMock(return_value=IFCONFIG_LINES) + self.fetcher.get_vconnector(OTEP_FOR_GETTING_VECONNECTOR, + HOST_ID, VEDGE) + self.assertEqual(OTEP_FOR_GETTING_VECONNECTOR, OTEP_WITH_CONNECTOR, + "Can't get vconnector from the config lines for otep") diff --git a/app/test/fetch/db_fetch/test_db_fetch_vedges_ovs.py b/app/test/fetch/db_fetch/test_db_fetch_vedges_ovs.py new file mode 100644 index 0000000..b08aebd --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_vedges_ovs.py @@ -0,0 +1,109 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_fetch_vedges_ovs import DbFetchVedgesOvs +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_vedges_ovs import * +from unittest.mock import MagicMock + + +class TestDbFetchVedgesOvs(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchVedgesOvs() + self.fetcher.set_env(self.env) + + def check_get_result(self, + objects_from_db, host, + vsctl_lines, ports, tunnel_ports, + expected_result, err_msg): + # store original methods + original_get_objects_list_by_id = self.fetcher.get_objects_list_for_id + original_get_by_id = self.fetcher.inv.get_by_id + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_fetch_ports = self.fetcher.fetch_ports + original_get_overlay_tunnels = self.fetcher.get_overlay_tunnels + + self.fetcher.get_objects_list_for_id = MagicMock(return_value=objects_from_db) + self.fetcher.inv.get_by_id = MagicMock(return_value=host) + self.fetcher.run_fetch_lines = MagicMock(return_value=vsctl_lines) + self.fetcher.fetch_ports = MagicMock(return_value=ports) + self.fetcher.get_overlay_tunnels = MagicMock(return_value=tunnel_ports) + + results = self.fetcher.get(VEDGES_FOLDER_ID) + self.assertEqual(results, expected_result, err_msg) + + # restore methods + self.fetcher.get_objects_list_for_id = original_get_objects_list_by_id + self.fetcher.inv.get_by_id = original_get_by_id + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.fetch_ports = original_fetch_ports + self.fetcher.get_overlay_tunnels = original_get_overlay_tunnels + + def test_get(self): + test_cases = [ + { + "objects_from_db": OBJECTS_FROM_DB, + "host": HOST, + "vsctl_lines": "", + "ports": PORTS, + "tunnel_ports": TUNNEL_PORTS, + "expected_result": GET_RESULTS, + "err_msg": "Can't get correct vedges" + }, + { + "objects_from_db": OBJECTS_FROM_DB, + "host": [], + "vsctl_lines": "", + "ports": {}, + "tunnel_ports": [], + "expected_result": [], + "err_msg": "Can't get [] when the host " + + "doesn't exist" + }, + { + "objects_from_db": OBJECTS_FROM_DB, + "host": HOST_WITHOUT_REQUIRED_HOST_TYPES, + "vsctl_lines": "", + "ports": {}, + "tunnel_ports": [], + "expected_result": [], + "err_msg": "Can't get [] when the host " + + "doesn't have required host types" + } + ] + for test_case in test_cases: + self.check_get_result(test_case["objects_from_db"], + test_case["host"], + test_case["vsctl_lines"], + test_case["ports"], + test_case["tunnel_ports"], + test_case["expected_result"], + test_case["err_msg"]) + + def test_fetch_ports_from_dpctl(self): + original_run_fetch_lines = self.fetcher.run_fetch_lines + self.fetcher.run_fetch_lines = MagicMock(return_value=DPCTL_LINES) + + results = self.fetcher.fetch_ports_from_dpctl(HOST['id']) + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.assertEqual(results, DPCTL_RESULTS, + "Can' t get correct ports info from dpctl lines") + + def test_fetch_port_tags_from_vsctl(self): + ports = self.fetcher.fetch_port_tags_from_vsctl(VSCTL_LINES, + FETCH__PORT_TAGS_INPUT) + self.assertEqual(ports, FETCH_PORT_TAGS_RESULT, + "Can't fetch tag from vsctl") + + def test_get_overlay_tunnels(self): + results = self.fetcher.get_overlay_tunnels(DOC_TO_GET_OVERLAY, + VSCTL_LINES) + self.assertEqual(results, TUNNEL_PORTS) diff --git a/app/test/fetch/db_fetch/test_db_fetch_vedges_vpp.py b/app/test/fetch/db_fetch/test_db_fetch_vedges_vpp.py new file mode 100644 index 0000000..9e6f497 --- /dev/null +++ b/app/test/fetch/db_fetch/test_db_fetch_vedges_vpp.py @@ -0,0 +1,82 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from discover.fetchers.db.db_fetch_vedges_vpp import DbFetchVedgesVpp +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_vedges_vpp import * +from unittest.mock import MagicMock + + +class TestDbFetchVedgesVpp(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchVedgesVpp() + self.fetcher.set_env(self.env) + + def check_get_results(self, version, + interfaces, host, + expected_results, err_msg): + original_run_fetch_lines = self.fetcher.run_fetch_lines + original_get_by_id = self.fetcher.inv.get_by_id + + self.fetcher.run_fetch_lines = MagicMock(side_effect=[version, interfaces]) + self.fetcher.inv.get_by_id = MagicMock(return_value=host) + + vedges = self.fetcher.get(VEDGE_FOLDER_ID) + self.assertEqual(vedges, expected_results, err_msg) + + self.fetcher.run_fetch_lines = original_run_fetch_lines + self.fetcher.inv.get_by_id = original_get_by_id + + def test_get(self): + test_cases = [ + { + "version": VERSION, + "interfaces": INTERFACES, + "host": HOST, + "expected_results": VEDGE_RESULTS, + "err_msg": "Can' get correct vedges" + }, + { + "version": [], + "interfaces": INTERFACES, + "host": HOST, + "expected_results": VEDGE_RESULTS_WITHOUT_BINARY, + "err_msg": "Can' get correct vedges when " + + "it can't get version info host" + }, + { + "version": VERSION, + "interfaces": INTERFACES, + "host": [], + "expected_results": [], + "err_msg": "Can't get [] when the host of the " + + "vedge doesn't exist in db" + }, + { + "version": VERSION, + "interfaces": INTERFACES, + "host": HOST_WITHOUT_REQUIRED_HOST_TYPE, + "expected_results": [], + "err_msg": "Can't get [] when the host of the " + + "vedge doesn't contains required host types" + } + ] + + for test_case in test_cases: + self.check_get_results(test_case["version"], + test_case["interfaces"], + test_case["host"], + test_case["expected_results"], + test_case["err_msg"]) + + def test_fetch_ports(self): + ports = self.fetcher.fetch_ports(INTERFACES) + self.assertEqual(ports, PORTS, "Can't get the correct ports info")
\ No newline at end of file diff --git a/app/test/fetch/db_fetch/test_fetch_host_network_agents.py b/app/test/fetch/db_fetch/test_fetch_host_network_agents.py new file mode 100644 index 0000000..fd68a56 --- /dev/null +++ b/app/test/fetch/db_fetch/test_fetch_host_network_agents.py @@ -0,0 +1,66 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +import copy + +from discover.fetchers.db.db_fetch_host_network_agents import DbFetchHostNetworkAgents +from test.fetch.test_fetch import TestFetch +from test.fetch.db_fetch.test_data.db_fetch_host_network_agents import * +from unittest.mock import MagicMock + + +class TestFetchHostNetworkAgents(TestFetch): + + def setUp(self): + self.configure_environment() + self.fetcher = DbFetchHostNetworkAgents() + + def check_get_result(self, + config, + network_agent_res, + expected_result, + err_msg): + self.fetcher.env_config = config + self.fetcher.get_objects_list_for_id =\ + MagicMock(return_value=network_agent_res) + result = self.fetcher.get(NETWORK_AGENT_FOLDER_ID) + self.assertEqual(result, expected_result, err_msg) + + def test_get(self): + test_cases = [ + { + 'config': CONFIG_WITH_MECHANISM_DRIVERS, + 'network_agent_res': copy.deepcopy(NETWORK_AGENT), + 'expected_result': + NETWORK_AGENT_WITH_MECHANISM_DRIVERS_IN_CONFIG_RESULTS, + 'err_msg': "Can't get correct result when the " + + "mechanism drivers exists in the config" + }, + { + 'config': CONFIG_WITHOUT_MECHANISM_DRIVERS, + 'network_agent_res': copy.deepcopy(NETWORK_AGENT), + 'expected_result': + NETWORK_AGENT_WITHOUT_MECHANISM_DRIVERS_IN_CONFIG_RESULTS, + 'err_msg': "Can't get correct result when the " + + "mechanism drivers doesn't exist in the config" + }, + { + 'config': CONFIG_WITH_MECHANISM_DRIVERS, + 'network_agent_res': [], + 'expected_result': [], + 'err_msg': "Can't get [] when the network agent result " + + "is empty" + } + ] + + for test_case in test_cases: + self.check_get_result(test_case['config'], + test_case['network_agent_res'], + test_case['expected_result'], + test_case['err_msg']) diff --git a/app/test/fetch/test_fetch.py b/app/test/fetch/test_fetch.py new file mode 100644 index 0000000..b9fd3f1 --- /dev/null +++ b/app/test/fetch/test_fetch.py @@ -0,0 +1,46 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +import unittest + +from discover.configuration import Configuration +from discover.fetchers.db.db_access import DbAccess +from test.fetch.config.test_config import MONGODB_CONFIG, ENV_CONFIG, COLLECTION_CONFIG +from test.fetch.api_fetch.test_data.regions import REGIONS +from test.fetch.api_fetch.test_data.configurations import CONFIGURATIONS +from unittest.mock import MagicMock +from utils.inventory_mgr import InventoryMgr +from utils.mongo_access import MongoAccess +from utils.ssh_connection import SshConnection +from utils.ssh_conn import SshConn + + +class TestFetch(unittest.TestCase): + + def configure_environment(self): + self.env = ENV_CONFIG + self.inventory_collection = COLLECTION_CONFIG + # mock the Mongo Access + MongoAccess.mongo_connect = MagicMock() + MongoAccess.db = MagicMock() + + self.conf = Configuration() + self.conf.use_env = MagicMock() + self.conf.environment = CONFIGURATIONS + self.conf.configuration = CONFIGURATIONS["configuration"] + + self.inv = InventoryMgr() + self.inv.set_collections(self.inventory_collection) + DbAccess.conn = MagicMock() + SshConnection.connect = MagicMock() + SshConnection.check_definitions = MagicMock() + SshConn.check_definitions = MagicMock() + + def set_regions_for_fetcher(self, fetcher): + fetcher.regions = REGIONS |