aboutsummaryrefslogtreecommitdiffstats
path: root/app/test/fetch/api_fetch
diff options
context:
space:
mode:
Diffstat (limited to 'app/test/fetch/api_fetch')
-rw-r--r--app/test/fetch/api_fetch/__init__.py9
-rw-r--r--app/test/fetch/api_fetch/test_api_access.py142
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_availability_zone.py72
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_host_instances.py83
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_networks.py65
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_ports.py89
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_project_hosts.py137
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_projects.py120
-rw-r--r--app/test/fetch/api_fetch/test_api_fetch_regions.py41
-rw-r--r--app/test/fetch/api_fetch/test_data/__init__.py9
-rw-r--r--app/test/fetch/api_fetch/test_data/api_access.py55
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_availability_zones.py71
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_host_instances.py85
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_host_project_hosts.py225
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_networks.py72
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_ports.py72
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_projects.py88
-rw-r--r--app/test/fetch/api_fetch/test_data/api_fetch_regions.py50
-rw-r--r--app/test/fetch/api_fetch/test_data/configurations.py52
-rw-r--r--app/test/fetch/api_fetch/test_data/regions.py110
-rw-r--r--app/test/fetch/api_fetch/test_data/token.py23
21 files changed, 1670 insertions, 0 deletions
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