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 | |
parent | b88c78e3cf2bef22aa2f1c4d0bf305e303bc15f0 (diff) | |
parent | 7e83d0876ddb84a45e130eeba28bc40ef53c074b (diff) |
Merge "Calipso initial release for OPNFV"
Diffstat (limited to 'app/test')
155 files changed, 16150 insertions, 0 deletions
diff --git a/app/test/__init__.py b/app/test/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/__init__.py b/app/test/api/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/api/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/responders_test/__init__.py b/app/test/api/responders_test/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/api/responders_test/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/responders_test/auth/__init__.py b/app/test/api/responders_test/auth/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/api/responders_test/auth/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/responders_test/auth/test_tokens.py b/app/test/api/responders_test/auth/test_tokens.py new file mode 100644 index 0000000..d7b9675 --- /dev/null +++ b/app/test/api/responders_test/auth/test_tokens.py @@ -0,0 +1,105 @@ +############################################################################### +# 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 json +from unittest.mock import patch + +from test.api.responders_test.test_data import base + +from test.api.responders_test.test_data import tokens +from test.api.test_base import TestBase + + +class TestTokens(TestBase): + + def test_create_token_without_auth_obj(self): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITHOUT_AUTH), + expected_code=base.BAD_REQUEST_CODE) + + def test_create_token_without_methods(self): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITHOUT_METHODS), + expected_code=base.BAD_REQUEST_CODE) + + def test_create_token_without_credentials_in_credentials_method(self): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITHOUT_CREDENTIALS), + expected_code=base.UNAUTHORIZED_CODE) + + def test_create_token_without_token_in_token_method(self): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITHOUT_TOKEN), + expected_code=base.UNAUTHORIZED_CODE) + + @patch(tokens.AUTH_VALIDATE_CREDENTIALS) + def test_create_token_with_wrong_credentials(self, validate_credentials): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITH_WRONG_CREDENTIALS), + mocks={ + validate_credentials: False + }, + expected_code=base.UNAUTHORIZED_CODE) + + @patch(tokens.AUTH_VALIDATE_TOKEN) + def test_create_token_with_wrong_token(self, validate_token): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITH_WRONG_TOKEN), + mocks={ + validate_token: 'token error' + }, + expected_code=base.UNAUTHORIZED_CODE) + + @patch(tokens.AUTH_WRITE_TOKEN) + @patch(tokens.AUTH_VALIDATE_CREDENTIALS) + def test_create_token_with_correct_credentials(self, validate_credentials, write_token): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITH_CORRECT_CREDENTIALS), + mocks={ + validate_credentials: True, + write_token: None + }, + expected_code=base.CREATED_CODE) + + @patch(tokens.AUTH_WRITE_TOKEN) + @patch(tokens.AUTH_VALIDATE_TOKEN) + def test_create_token_with_correct_token(self, validate_token, write_token): + self.validate_post_request(tokens.URL, + body=json.dumps(tokens.AUTH_OBJ_WITH_CORRECT_TOKEN), + mocks={ + validate_token: None, + write_token: None + }, + expected_code=base.CREATED_CODE) + + def test_delete_token_without_token(self): + self.validate_delete_request(tokens.URL, + headers=tokens.HEADER_WITHOUT_TOKEN, + expected_code=base.UNAUTHORIZED_CODE + ) + + @patch(tokens.AUTH_VALIDATE_TOKEN) + def test_delete_token_with_wrong_token(self, validate_token): + self.validate_delete_request(tokens.URL, + headers=tokens.HEADER_WITH_WRONG_TOKEN, + mocks={ + validate_token: 'token error' + }, + expected_code=base.UNAUTHORIZED_CODE) + + @patch(tokens.AUTH_VALIDATE_TOKEN) + @patch(tokens.AUTH_DELETE_TOKEN) + def test_delete_token_with_correct_token(self, delete_token, validate_token): + self.validate_delete_request(tokens.URL, + headers=tokens.HEADER_WITH_CORRECT_TOKEN, + mocks={ + validate_token: None, + delete_token: None + }, + expected_code=base.SUCCESSFUL_CODE) diff --git a/app/test/api/responders_test/resource/__init__.py b/app/test/api/responders_test/resource/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/api/responders_test/resource/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/responders_test/resource/test_aggregates.py b/app/test/api/responders_test/resource/test_aggregates.py new file mode 100644 index 0000000..1b642e0 --- /dev/null +++ b/app/test/api/responders_test/resource/test_aggregates.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 # +############################################################################### +from test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import aggregates +from unittest.mock import patch + + +class TestAggregates(TestBase): + + def test_get_aggregate_without_type(self): + self.validate_get_request(aggregates.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_aggregate_with_wrong_filter(self): + self.validate_get_request(aggregates.URL, + params={ + "unknown": "unknown" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_environment_aggregates_without_env_name(self): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.ENV_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_get_environment_aggregates_with_unknown_env_name(self, + check_env_name): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.ENV_TYPE, + "env_name": base.UNKNOWN_ENV + }, + mocks={ + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_AGGREGATE) + def test_get_environment_aggregates_with_env_name(self, aggregates_method, + check_env_name): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.ENV_TYPE, + "env_name": base.ENV_NAME + }, + mocks={ + check_env_name: True, + aggregates_method: + aggregates.ENVIRONMENT_AGGREGATES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response= + aggregates.ENVIRONMENT_AGGREGATES_RESPONSE + ) + + @patch(base.RESPONDER_BASE_AGGREGATE) + def test_get_message_aggregates(self, aggregate): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.MESSAGE_TYPE + }, + side_effects={aggregate: [ + aggregates.MESSAGE_ENV_AGGREGATES, + aggregates.MESSAGE_LEVEL_AGGREGATES] + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response= + aggregates.MESSAGE_AGGREGATES_RESPONSE + ) + + @patch(base.RESPONDER_BASE_AGGREGATE) + def test_get_constant_aggregates(self, aggregate): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.CONSTANT_TYPE + }, + mocks={ + aggregate: aggregates.CONSTANT_AGGREGATES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response= + aggregates.CONSTANT_AGGREGATES_RESPONSE + ) + + def test_get_unknown_aggregates(self): + self.validate_get_request(aggregates.URL, + params={ + "type": aggregates.UNKNOWN_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) diff --git a/app/test/api/responders_test/resource/test_clique_constraints.py b/app/test/api/responders_test/resource/test_clique_constraints.py new file mode 100644 index 0000000..f990b5c --- /dev/null +++ b/app/test/api/responders_test/resource/test_clique_constraints.py @@ -0,0 +1,138 @@ +############################################################################### +# 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 test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import clique_constraints +from unittest.mock import patch + + +class TestCliqueConstraints(TestBase): + + def test_get_clique_constraints_list_with_invalid_filter(self): + self.validate_get_request(clique_constraints.URL, + params={ + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_clique_constraints_list_with_non_int_page(self): + self.validate_get_request(clique_constraints.URL, + params={ + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_list_with_int_page(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "page": base.INT_PAGE + }, + mocks={ + read: clique_constraints.CLIQUE_CONSTRAINTS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_constraints. + CLIQUE_CONSTRAINTS_RESPONSE + ) + + def test_get_clique_constraints_list_with_non_int_pagesize(self): + self.validate_get_request(clique_constraints.URL, + params={ + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_list_with_int_pagesize(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: clique_constraints.CLIQUE_CONSTRAINTS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_constraints. + CLIQUE_CONSTRAINTS_RESPONSE + ) + + def test_get_clique_constraints_with_wrong_id(self): + self.validate_get_request(clique_constraints.URL, + params={ + 'id': clique_constraints.WRONG_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_with_nonexistent_id(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "id": clique_constraints.NONEXISTENT_ID + }, + mocks={ + read: [] + }, + expected_code=base.NOT_FOUND_CODE + ) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_with_id(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "id": clique_constraints.CORRECT_ID + }, + mocks={ + read: clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_ID[0] + ) + + def test_get_clique_constraints_list_with_wrong_focal_point_type(self): + self.validate_get_request(clique_constraints.URL, + params={ + "focal_point_type": + clique_constraints.WRONG_FOCAL_POINT_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_list_with_focal_point_type(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "focal_point_type": + clique_constraints.CORRECT_FOCAL_POINT_TYPE + }, + mocks={ + read: clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_FOCAL_POINT_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE + ) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_constraints_list_with_constraints(self, read): + self.validate_get_request(clique_constraints.URL, + params={ + "constraint": clique_constraints.CONSTRAINT + }, + mocks={ + read: clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_CONSTRAINT + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_constraints. + CLIQUE_CONSTRAINTS_WITH_SPECIFIC_CONSTRAINT_RESPONSE + ) diff --git a/app/test/api/responders_test/resource/test_clique_types.py b/app/test/api/responders_test/resource/test_clique_types.py new file mode 100644 index 0000000..f5e331e --- /dev/null +++ b/app/test/api/responders_test/resource/test_clique_types.py @@ -0,0 +1,267 @@ +############################################################################### +# 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 json + +from test.api.responders_test.test_data import base +from test.api.test_base import TestBase +from test.api.responders_test.test_data import clique_types +from unittest.mock import patch + + +class TestCliqueTypes(TestBase): + + def test_get_clique_types_list_without_env_name(self): + self.validate_get_request(clique_types.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_clique_types_with_invalid_filter(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_clique_type_with_wrong_id(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "id": clique_types.WRONG_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_type_with_id(self, read): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "id": clique_types.CORRECT_ID + }, + mocks={ + read: clique_types.CLIQUE_TYPES_WITH_SPECIFIC_ID + }, + expected_response=clique_types. + CLIQUE_TYPES_WITH_SPECIFIC_ID[0], + expected_code=base.SUCCESSFUL_CODE + ) + + def test_get_clique_types_list_with_wrong_focal_point_type(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point_type": clique_types.WRONG_FOCAL_POINT_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_correct_focal_point_type(self, read): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point_type": + clique_types.CORRECT_FOCAL_POINT_POINT_TYPE + }, + mocks={ + read: clique_types. + CLIQUE_TYPES_WITH_SPECIFIC_FOCAL_POINT_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_types. + CLIQUE_TYPES_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE + ) + + def test_get_clique_types_list_with_wrong_link_type(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "link_type": clique_types.WRONG_LINK_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_correct_link_type(self, read): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "link_type": base.CORRECT_LINK_TYPE + }, + mocks={ + read: clique_types. + CLIQUE_TYPES_WITH_SPECIFIC_LINK_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_types. + CLIQUE_TYPES_WITH_SPECIFIC_LINK_TYPE_RESPONSE + ) + + def test_get_clique_types_list_with_non_int_page(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_int_page(self, read): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.INT_PAGE + }, + mocks={ + read: clique_types.CLIQUE_TYPES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_types.CLIQUE_TYPES_RESPONSE) + + def test_get_clique_types_list_with_non_int_page_size(self): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_int_page_size(self, read): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: clique_types.CLIQUE_TYPES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=clique_types.CLIQUE_TYPES_RESPONSE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_unknown_env_name(self, read, check_env_name): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_types_list_with_env_name_and_nonexistent_link_type(self, read, check_env_name): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "link_type": clique_types.NONEXISTENT_LINK_TYPE + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_type_with_unknown_env_name_and_id(self, read, check_env_name): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.UNKNOWN_ENV, + "id": clique_types.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_type_with_env_name_and_nonexistent_id(self, read, check_env_name): + self.validate_get_request(clique_types.URL, + params={ + "env_name": base.ENV_NAME, + "id": clique_types.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + def test_post_clique_type_with_non_dict_clique_type(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types.NON_DICT_CLIQUE_TYPE), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_without_env_name(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types.CLIQUE_TYPE_WITHOUT_ENVIRONMENT), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_post_clique_type_with_unknown_env_name(self, check_environment_name): + self.validate_post_request(clique_types.URL, + mocks={ + check_environment_name: False + }, + body=json.dumps(clique_types. + CLIQUE_TYPE_WITH_UNKNOWN_ENVIRONMENT), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_without_focal_point_type(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types. + CLIQUE_TYPE_WITHOUT_FOCAL_POINT_TYPE), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_with_wrong_focal_point_type(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types. + CLIQUE_TYPE_WITH_WRONG_FOCAL_POINT_TYPE), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_without_link_types(self): + self.validate_post_request(clique_types.URL, + body=json.dumps( + clique_types.CLIQUE_TYPE_WITHOUT_LINK_TYPES + ), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_with_non_list_link_types(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types. + CLIQUE_TYPE_WITH_NON_LIST_LINK_TYPES), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_with_wrong_link_type(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types. + CLIQUE_TYPE_WITH_WRONG_LINK_TYPE), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_clique_type_without_name(self): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types.CLIQUE_TYPE_WITHOUT_NAME), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_WRITE) + def test_post_clique_type(self, write, check_environment_name): + self.validate_post_request(clique_types.URL, + body=json.dumps(clique_types.CLIQUE_TYPE), + mocks={ + write: None, + check_environment_name: True + }, + expected_code=base.CREATED_CODE) diff --git a/app/test/api/responders_test/resource/test_cliques.py b/app/test/api/responders_test/resource/test_cliques.py new file mode 100644 index 0000000..de3576b --- /dev/null +++ b/app/test/api/responders_test/resource/test_cliques.py @@ -0,0 +1,240 @@ +############################################################################### +# 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 test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import cliques +from unittest.mock import patch + + +class TestCliques(TestBase): + + def test_get_cliques_list_without_env_name(self): + self.validate_get_request(cliques.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_cliques_list_with_invalid_filter(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_cliques_list_with_non_int_page(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_int_page(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.INT_PAGE + }, + mocks={ + read: cliques.CLIQUES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques.CLIQUES_RESPONSE) + + def test_get_cliques_list_with_non_int_pagesize(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_int_pagesize(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: cliques.CLIQUES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques.CLIQUES_RESPONSE) + + def test_get_clique_with_wrong_clique_id(self): + self.validate_get_request(cliques.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': cliques.WRONG_CLIQUE_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_with_clique_id(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "id": cliques.CORRECT_CLIQUE_ID + }, + mocks={ + read: cliques.CLIQUES_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques.CLIQUES_WITH_SPECIFIC_ID[0] + ) + + def test_get_cliques_list_with_wrong_focal_point(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point": cliques.WRONG_FOCAL_POINT + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_focal_point(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point": cliques.CORRECT_FOCAL_POINT + }, + mocks={ + read: cliques.CLIQUES_WITH_SPECIFIC_FOCAL_POINT + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques. + CLIQUES_WITH_SPECIFIC_FOCAL_POINT_RESPONSE + ) + + def test_get_cliques_list_with_wrong_focal_point_type(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point_type": cliques.WRONG_FOCAL_POINT_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_focal_point_type(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "focal_point_type": cliques.CORRECT_FOCAL_POINT_TYPE + }, + mocks={ + read: cliques.CLIQUES_WITH_SPECIFIC_FOCAL_POINT_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques. + CLIQUES_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE + ) + + def test_get_cliques_list_with_wrong_link_type(self): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "link_type": base.WRONG_LINK_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_link_type(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "link_type": cliques.CORRECT_LINK_TYPE + }, + mocks={ + read: cliques.CLIQUES_WITH_SPECIFIC_LINK_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques. + CLIQUES_WITH_SPECIFIC_LINK_TYPE_RESPONSE + ) + + def test_get_cliques_list_with_wrong_link_id(self): + self.validate_get_request(cliques.URL, + { + "env_name": base.ENV_NAME, + "link_id": cliques.WRONG_LINK_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_ids_with_correct_link_id(self, read): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "link_id": cliques.CORRECT_LINK_ID + }, + mocks={ + read: cliques.CLIQUES_WITH_SPECIFIC_LINK_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=cliques. + CLIQUES_WITH_SPECIFIC_LINK_ID_RESPONSE + ) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_env_name_and_nonexistent_link_id(self, read, check_env_name): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "link_id": cliques.NONEXISTENT_LINK_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_cliques_list_with_unknown_env_name(self, read, check_env_name): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_with_env_name_and_nonexistent_clique_id(self, read, check_env_name): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.ENV_NAME, + "id": cliques.NONEXISTENT_CLIQUE_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_clique_with_unknown_env_name_and_clique_id(self, read, check_env_name): + self.validate_get_request(cliques.URL, + params={ + "env_name": base.UNKNOWN_ENV, + "id": cliques.NONEXISTENT_CLIQUE_ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) diff --git a/app/test/api/responders_test/resource/test_constants.py b/app/test/api/responders_test/resource/test_constants.py new file mode 100644 index 0000000..0d92ebe --- /dev/null +++ b/app/test/api/responders_test/resource/test_constants.py @@ -0,0 +1,53 @@ +############################################################################### +# 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 test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import constants +from unittest.mock import patch + + +class TestConstants(TestBase): + + def test_get_constant_without_name(self): + self.validate_get_request(constants.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_constant_with_unknown_filter(self): + self.validate_get_request(constants.URL, + params={ + "unknown": "unknown" + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_constant_with_unknown_name(self, read): + self.validate_get_request(constants.URL, + params={ + "name": constants.UNKNOWN_NAME + }, + mocks={ + read: [] + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_constant(self, read): + self.validate_get_request(constants.URL, + params={ + "name": constants.NAME + }, + mocks={ + read: constants.CONSTANTS_WITH_SPECIFIC_NAME + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=constants. + CONSTANTS_WITH_SPECIFIC_NAME[0] + ) diff --git a/app/test/api/responders_test/resource/test_environment_configs.py b/app/test/api/responders_test/resource/test_environment_configs.py new file mode 100644 index 0000000..7002ed7 --- /dev/null +++ b/app/test/api/responders_test/resource/test_environment_configs.py @@ -0,0 +1,420 @@ +############################################################################### +# 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 json + +from test.api.responders_test.test_data import base +from test.api.test_base import TestBase +from test.api.responders_test.test_data import environment_configs +from utils.constants import EnvironmentFeatures +from utils.inventory_mgr import InventoryMgr +from unittest.mock import patch + + +class TestEnvironmentConfigs(TestBase): + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list(self, read): + self.validate_get_request(environment_configs.URL, + params={}, + mocks={ + read: environment_configs.ENV_CONFIGS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_RESPONSE + ) + + def test_get_environment_configs_list_with_invalid_filters(self): + self.validate_get_request(environment_configs.URL, + params={ + "unknown": "unknown" + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_name(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "name": environment_configs.NAME + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_NAME + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_NAME[0] + ) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_unknown_name(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "name": environment_configs.UNKNOWN_NAME + }, + mocks={ + read: [] + }, + expected_code=base.NOT_FOUND_CODE) + + def test_get_environment_configs_list_with_wrong_distribution(self): + self.validate_get_request(environment_configs.URL, + params={ + "distribution": + environment_configs.WRONG_DISTRIBUTION + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_distribution(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "distribution": + environment_configs.CORRECT_DISTRIBUTION + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_DISTRIBUTION + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_DISTRIBUTION_RESPONSE) + + def test_get_environment_configs_list_with_wrong_mechanism_driver(self): + self.validate_get_request(environment_configs.URL, + params={ + "mechanism_drivers": + environment_configs.WRONG_MECHANISM_DRIVER + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_mechanism_driver(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "mechanism_drivers": + environment_configs.CORRECT_MECHANISM_DRIVER + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_MECHANISM_DRIVER + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_MECHANISM_DRIVER_RESPONSE + ) + + def test_get_environment_configs_list_with_wrong_type_driver(self): + self.validate_get_request(environment_configs.URL, + params={ + "type_drivers": + environment_configs.WRONG_TYPE_DRIVER + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_type_driver(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "type_drivers": + environment_configs.CORRECT_TYPE_DRIVER + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_TYPE_DRIVER + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_TYPE_DRIVER_RESPONSE + ) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_user(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "user": environment_configs.USER + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_USER + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_USER_RESPONSE + ) + + def test_get_environment_configs_list_with_non_bool_listen(self): + self.validate_get_request(environment_configs.URL, + params={ + "listen": environment_configs.NON_BOOL_LISTEN + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_bool_listen(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "listen": environment_configs.BOOL_LISTEN + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_LISTEN + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_LISTEN_RESPONSE + ) + + def test_get_environment_configs_list_with_non_bool_scanned(self): + self.validate_get_request(environment_configs.URL, + params={ + "scanned": environment_configs. + NON_BOOL_SCANNED + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_bool_scanned(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "scanned": environment_configs.BOOL_SCANNED + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_SCANNED + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_SCANNED_RESPONSE + ) + + def test_get_environment_configs_list_with_non_bool_monitoring_setup_done(self): + self.validate_get_request(environment_configs.URL, + params={ + "listen": environment_configs. + NON_BOOL_MONITORING_SETUP_DONE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_bool_monitoring_setup_done(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "scanned": environment_configs. + BOOL_MONITORING_SETUP_DONE + }, + mocks={ + read: environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_MONITORING_SETUP_DONE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_WITH_SPECIFIC_MONITORING_SETUP_DONE_RESPONSE + ) + + def test_get_environment_configs_list_with_non_int_page(self): + self.validate_get_request(environment_configs.URL, + params={ + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_int_page(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "page": base.INT_PAGE + }, + mocks={ + read: environment_configs.ENV_CONFIGS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_RESPONSE + ) + + def test_get_environment_configs_list_with_non_int_page_size(self): + self.validate_get_request(environment_configs.URL, + params={ + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_environment_configs_list_with_int_page_size(self, read): + self.validate_get_request(environment_configs.URL, + params={ + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: environment_configs.ENV_CONFIGS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=environment_configs. + ENV_CONFIGS_RESPONSE + ) + + def test_post_environment_config_without_app_path(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["app_path"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_configuration(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["configuration"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_distribution(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["distribution"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_distribution(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={"distribution": environment_configs.WRONG_DISTRIBUTION}) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_listen(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["listen"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_listen(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={"listen": environment_configs.NON_BOOL_LISTEN}) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_mechanism_driver(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["mechanism_drivers"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_mechanism_driver(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={ + "mechanism_drivers": + [environment_configs.WRONG_MECHANISM_DRIVER] + }) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_name(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["name"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_operational(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["operational"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_scanned(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={ + "scanned": environment_configs.NON_BOOL_SCANNED + }) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_last_scanned(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={ + "last_scanned": base.WRONG_FORMAT_TIME + }) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_type(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["type"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_without_type_drivers(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + deleted_keys=["type_drivers"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_environment_config_with_wrong_type_drivers(self): + test_data = self.get_updated_data(environment_configs.ENV_CONFIG, + updates={ + "type_drivers": [environment_configs.WRONG_TYPE_DRIVER] + }) + self.validate_post_request(environment_configs.URL, + body=json.dumps(test_data), + expected_code=base.BAD_REQUEST_CODE) + + def mock_validate_env_config_with_supported_envs(self, scanning, + monitoring, listening): + InventoryMgr.is_feature_supported_in_env = lambda self, matches, feature: { + EnvironmentFeatures.SCANNING: scanning, + EnvironmentFeatures.MONITORING: monitoring, + EnvironmentFeatures.LISTENING: listening + }[feature] + + @patch(base.RESPONDER_BASE_WRITE) + def test_post_environment_config(self, write): + self.mock_validate_env_config_with_supported_envs(True, True, True) + self.validate_post_request(environment_configs.URL, + mocks={ + write: None + }, + body=json.dumps(environment_configs.ENV_CONFIG), + expected_code=base.CREATED_CODE) + + def test_post_unsupported_environment_config(self): + test_cases = [ + { + "scanning": False, + "monitoring": True, + "listening": True + }, + { + "scanning": True, + "monitoring": False, + "listening": True + }, + { + "scanning": True, + "monitoring": True, + "listening": False + } + ] + for test_case in test_cases: + self.mock_validate_env_config_with_supported_envs(test_case["scanning"], + test_case["monitoring"], + test_case["listening"]) + self.validate_post_request(environment_configs.URL, + body=json.dumps(environment_configs.ENV_CONFIG), + expected_code=base.BAD_REQUEST_CODE) diff --git a/app/test/api/responders_test/resource/test_inventory.py b/app/test/api/responders_test/resource/test_inventory.py new file mode 100644 index 0000000..0ef9089 --- /dev/null +++ b/app/test/api/responders_test/resource/test_inventory.py @@ -0,0 +1,162 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base +from test.api.responders_test.test_data import inventory +from test.api.test_base import TestBase +from unittest.mock import patch + + +class TestInventory(TestBase): + + def test_get_objects_list_without_env_name(self): + self.validate_get_request(inventory.URL, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_objects_list_with_invalid_filter(self): + self.validate_get_request(inventory.URL, + params={ + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_objects_list_with_non_boolean_subtree(self): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'sub_tree': base.NON_BOOL + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_objects_list_with_boolean_subtree(self, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'sub_tree': base.BOOL + }, + mocks={ + read: inventory.OBJECTS_LIST + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=inventory.OBJECT_IDS_RESPONSE + ) + + def test_get_objects_list_with_non_int_page(self): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_objects_list_with_int_page(self, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.INT_PAGE + }, + mocks={ + read: inventory.OBJECTS_LIST + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=inventory.OBJECT_IDS_RESPONSE + ) + + def test_get_objects_list_with_non_int_pagesize(self): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_objects_list_with_int_pagesize(self, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.INT_PAGESIZE + }, + mocks={ + read: inventory.OBJECTS_LIST + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=inventory.OBJECT_IDS_RESPONSE + ) + + @patch(base.RESPONDER_BASE_READ) + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_get_nonexistent_objects_list_with_env_name(self, check_env_name, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE, + ) + + @patch(base.RESPONDER_BASE_READ) + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_get_objects_list_with_unkown_env_name(self, check_env_name, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_object_with_env_name_and_id(self, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': inventory.ID + }, + mocks={ + read: inventory.OBJECTS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=inventory.OBJECTS[0] + ) + + @patch(base.RESPONDER_BASE_READ) + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_get_nonexistent_object_with_env_name_and_id(self, check_env_name, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': inventory.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_READ) + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_get_object_with_unkown_env_name_and_id(self, check_env_name, read): + self.validate_get_request(inventory.URL, + params={ + 'env_name': base.UNKNOWN_ENV, + 'id': inventory.ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) diff --git a/app/test/api/responders_test/resource/test_links.py b/app/test/api/responders_test/resource/test_links.py new file mode 100644 index 0000000..b312aa1 --- /dev/null +++ b/app/test/api/responders_test/resource/test_links.py @@ -0,0 +1,193 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base +from test.api.responders_test.test_data import links +from test.api.test_base import TestBase +from unittest.mock import patch + + +class TestLinks(TestBase): + + def test_get_links_list_without_env_name(self): + self.validate_get_request(links.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_links_list_with_invalid_filters(self): + self.validate_get_request(links.URL, + params={ + 'invalid': 'invalid' + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_links_list_with_wrong_link_type(self): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'link_type': links.WRONG_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_correct_link_type(self, read): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'link_type': links.CORRECT_TYPE + }, + mocks={ + read: links.LINKS_WITH_SPECIFIC_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=links. + LINKS_WITH_SPECIFIC_TYPE_RESPONSE + ) + + def test_get_links_list_with_wrong_state(self): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'state': links.WRONG_STATE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_correct_state(self, read): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'state': links.CORRECT_STATE + }, + mocks={ + read: links.LINKS_WITH_SPECIFIC_STATE, + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=links. + LINKS_WITH_SPECIFIC_STATE_RESPONSE + ) + + def test_get_link_with_env_name_and_wrong_link_id(self): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': links.WRONG_LINK_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_link_with_env_name_and_link_id(self, read): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': links.LINK_ID + }, + mocks={ + read: links.LINKS_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=links. + LINKS_WITH_SPECIFIC_ID[0] + ) + + def test_get_links_list_with_non_int_page(self): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_int_page(self, read): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.INT_PAGE + }, + mocks={ + read: links.LINKS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=links.LINKS_LIST_RESPONSE) + + def test_get_link_ids_with_non_int_page_size(self): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_int_page_size(self, read): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.INT_PAGESIZE + }, + mocks={ + read: links.LINKS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=links.LINKS_LIST_RESPONSE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_env_name_and_unknown_host(self, read, check_env_name): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'host': links.UNKNOWN_HOST + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_links_list_with_unknown_env_name(self, read, check_env_name): + self.validate_get_request(links.URL, + params={ + 'env_name': base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_link_with_env_name_and_nonexistent_link_id(self, read, check_env_name): + self.validate_get_request(links.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': links.NONEXISTENT_LINK_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_link_with_unknown_env_name(self, read, check_env_name): + self.validate_get_request(links.URL, + params={ + 'env_name': base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) diff --git a/app/test/api/responders_test/resource/test_messages.py b/app/test/api/responders_test/resource/test_messages.py new file mode 100644 index 0000000..6999cee --- /dev/null +++ b/app/test/api/responders_test/resource/test_messages.py @@ -0,0 +1,236 @@ +############################################################################### +# 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 test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import messages +from unittest.mock import patch + + +class TestMessage(TestBase): + + def test_get_messages_list_without_env_name(self): + self.validate_get_request(messages.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_messages_list_with_invalid_filter(self): + self.validate_get_request(messages.URL, + params={ + 'invalid': 'invalid' + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_messages_list_with_wrong_format_start_time(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'start_time': messages.WRONG_FORMAT_TIME + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_correct_format_start_time(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'start_time': messages.CORRECT_FORMAT_TIME + }, + mocks={ + read: messages.MESSAGES_WITH_SPECIFIC_TIME + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response= + messages.MESSAGES_WITH_SPECIFIC_TIME_RESPONSE + ) + + def test_get_messages_list_with_wrong_format_end_time(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'end_time': messages.WRONG_FORMAT_TIME + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_correct_format_end_time(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'end_time': messages.CORRECT_FORMAT_TIME + }, + mocks={ + read: messages.MESSAGES_WITH_SPECIFIC_TIME + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response= + messages.MESSAGES_WITH_SPECIFIC_TIME_RESPONSE + ) + + def test_get_messages_list_with_wrong_level(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'level': messages.WRONG_SEVERITY + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_level(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'level': messages.CORRECT_SEVERITY + }, + mocks={ + read: messages.MESSAGES_WITH_SPECIFIC_SEVERITY + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=messages. + MESSAGES_WITH_SPECIFIC_SEVERITY_RESPONSE + ) + + def test_get_messages_list_with_wrong_related_object_type(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'related_object_type': + messages.WRONG_RELATED_OBJECT_TYPE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_correct_related_object_type(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'related_object_type': + messages.CORRECT_RELATED_OBJECT_TYPE + }, + mocks={ + read: messages. + MESSAGES_WITH_SPECIFIC_RELATED_OBJECT_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=messages. + MESSAGES_WITH_SPECIFIC_RELATED_OBJECT_TYPE_RESPONSE + ) + + def test_get_messages_list_with_non_int_page(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_int_page(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'page': base.INT_PAGE + }, + mocks={ + read: messages.MESSAGES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=messages.MESSAGES_RESPONSE) + + def test_get_messages_list_with_non_int_page_size(self): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_int_pagesize(self, read): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'page_size': base.INT_PAGESIZE + }, + mocks={ + read: messages.MESSAGES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=messages.MESSAGES_RESPONSE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_env_name_and_nonexistent_related_object(self, read, check_env_name): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'related_object': messages.NONEXISTENT_RELATED_OBJECT + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_messages_list_with_unknown_env_name(self, read, check_env_name): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.UNKNOWN_ENV, + 'related_object': messages.RELATED_OBJECT + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_message_with_env_name_and_nonexistent_id(self, read, check_env_name): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': messages.NONEXISTENT_MESSAGE_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_message_with_unknown_env_name_and_id(self, read, check_env_name): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.UNKNOWN_ENV, + 'id': messages.MESSAGE_ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_message_with_env_name_and_id(self, read, check_env_name): + self.validate_get_request(messages.URL, + params={ + 'env_name': base.ENV_NAME, + 'id': messages.MESSAGE_ID + }, + mocks={ + read: messages.MESSAGES_WITH_SPECIFIC_ID, + check_env_name: False + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=messages.MESSAGES_WITH_SPECIFIC_ID[0]) diff --git a/app/test/api/responders_test/resource/test_monitoring_config_templates.py b/app/test/api/responders_test/resource/test_monitoring_config_templates.py new file mode 100644 index 0000000..04f413e --- /dev/null +++ b/app/test/api/responders_test/resource/test_monitoring_config_templates.py @@ -0,0 +1,156 @@ +############################################################################### +# 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 test.api.test_base import TestBase +from test.api.responders_test.test_data import base +from test.api.responders_test.test_data import monitoring_config_templates +from unittest.mock import patch + + +class TestMonitoringConfigTemplates(TestBase): + + def test_get_templates_list_with_unknown_filter(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "unknown": "unknown" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_templates_list_with_non_int_order(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "order": monitoring_config_templates.NON_INT_ORDER + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_templates_list_with_order(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "order": monitoring_config_templates.INT_ORDER + }, + mocks={ + read: monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_ORDER + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_ORDER_RESPONSE + ) + + def test_get_templates_list_with_wrong_side(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "side": monitoring_config_templates.WRONG_SIDE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_templates_list_with_side(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "side": monitoring_config_templates.CORRECT_SIDE + }, + mocks={ + read: monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_SIDE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_SIDE_RESPONSE + ) + + @patch(base.RESPONDER_BASE_READ) + def test_get_templates_list_with_type(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "type": monitoring_config_templates.TYPE + }, + mocks={ + read: monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_TYPE + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_TYPE_RESPONSE + ) + + def test_get_templates_list_with_non_int_page(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_templates_list_with_int_page(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "page": base.INT_PAGE + }, + mocks={ + read: monitoring_config_templates.TEMPLATES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_RESPONSE + ) + + def test_get_templates_list_with_non_int_pagesize(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_templates_list_with_int_pagesize(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: monitoring_config_templates.TEMPLATES + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_RESPONSE + ) + + def test_get_template_with_wrong_id(self): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "id": monitoring_config_templates.WRONG_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_template_with_unknown_id(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "id": monitoring_config_templates.UNKNOWN_ID + }, + mocks={ + read: [] + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_template_with_id(self, read): + self.validate_get_request(monitoring_config_templates.URL, + params={ + "id": monitoring_config_templates.CORRECT_ID + }, + mocks={ + read: monitoring_config_templates.TEMPLATES_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=monitoring_config_templates. + TEMPLATES_WITH_SPECIFIC_ID[0] + ) diff --git a/app/test/api/responders_test/resource/test_scans.py b/app/test/api/responders_test/resource/test_scans.py new file mode 100644 index 0000000..708cd54 --- /dev/null +++ b/app/test/api/responders_test/resource/test_scans.py @@ -0,0 +1,239 @@ +############################################################################### +# 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 json + +from test.api.responders_test.test_data import base +from test.api.test_base import TestBase +from test.api.responders_test.test_data import scans +from unittest.mock import patch + + +class TestScans(TestBase): + + def test_get_scans_list_without_env_name(self): + self.validate_get_request(scans.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_scans_list_with_invalid_filter(self): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_scans_list_with_non_int_page(self): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scans_list_with_int_page(self, read): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "page": base.INT_PAGE + }, + mocks={ + read: scans.SCANS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scans.SCANS_RESPONSE) + + def test_get_scans_list_with_non_int_pagesize(self): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scans_list_with_int_pagesize(self, read): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: scans.SCANS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scans.SCANS_RESPONSE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scans_list_with_unknown_env(self, read, check_env_name): + self.validate_get_request(scans.URL, + params={ + "env_name": base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scans_list_with_base_object(self, read): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "base_object": scans.BASE_OBJECT + }, + mocks={ + read: scans.SCANS_WITH_SPECIFIC_BASE_OBJ + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scans. + SCANS_WITH_SPECIFIC_BASE_OBJ_RESPONSE + ) + + def test_get_scans_list_with_wrong_status(self): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "status": scans.WRONG_STATUS + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scans_list_with_status(self, read): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "status": scans.CORRECT_STATUS + }, + mocks={ + read: scans.SCANS_WITH_SPECIFIC_STATUS, + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scans. + SCANS_WITH_SPECIFIC_STATUS_RESPONSE + ) + + def test_get_scan_with_wrong_id(self): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "id": scans.WRONG_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scan_with_nonexistent_id(self, read, check_env_name): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "id": scans.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scan_with_unknown_env_and_nonexistent_id(self, read, check_env_name): + self.validate_get_request(scans.URL, + params={ + "env_name": base.UNKNOWN_ENV, + "id": scans.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scan_with_id(self, read): + self.validate_get_request(scans.URL, + params={ + "env_name": base.ENV_NAME, + "id": scans.CORRECT_ID + }, + mocks={ + read: scans.SCANS_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scans.SCANS_WITH_SPECIFIC_ID[0] + ) + + def test_post_scan_with_non_dict_scan(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.NON_DICT_SCAN), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_without_env_name(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITHOUT_ENV), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_post_scan_with_unknown_env_name(self, check_environment_name): + self.validate_post_request(scans.URL, + mocks={ + check_environment_name: False + }, + body=json.dumps(scans.SCAN_WITH_UNKNOWN_ENV), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_without_status(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITHOUT_STATUS), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_wrong_status(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_WRONG_STATUS), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_wrong_log_level(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_WRONG_LOG_LEVEL), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_non_bool_clear(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_NON_BOOL_CLEAR), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_non_bool_scan_only_inventory(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_NON_BOOL_SCAN_ONLY_INVENTORY), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_non_bool_scan_only_links(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_NON_BOOL_SCAN_ONLY_LINKS), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_scan_with_non_bool_scan_only_cliques(self): + self.validate_post_request(scans.URL, + body=json.dumps(scans.SCAN_WITH_NON_BOOL_SCAN_ONLY_CLIQUES), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_WRITE) + def test_post_scan(self, write, check_env_name): + self.validate_post_request(scans.URL, + mocks={ + check_env_name: True, + write: None + }, + body=json.dumps(scans.SCAN), + expected_code=base.CREATED_CODE) diff --git a/app/test/api/responders_test/resource/test_scheduled_scans.py b/app/test/api/responders_test/resource/test_scheduled_scans.py new file mode 100644 index 0000000..23c38de --- /dev/null +++ b/app/test/api/responders_test/resource/test_scheduled_scans.py @@ -0,0 +1,247 @@ +############################################################################### +# 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 json + +from test.api.responders_test.test_data import base +from test.api.test_base import TestBase +from test.api.responders_test.test_data import scheduled_scans +from unittest.mock import patch + + +class TestScheduledScans(TestBase): + def test_get_scheduled_scans_list_without_env_name(self): + self.validate_get_request(scheduled_scans.URL, + params={}, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_scheduled_scans_list_with_invalid_filter(self): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "invalid": "invalid" + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_scheduled_scans_list_with_non_int_page(self): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "page": base.NON_INT_PAGE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scans_list_with_int_page(self, read): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "page": base.INT_PAGE + }, + mocks={ + read: scheduled_scans.SCHEDULED_SCANS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scheduled_scans. + SCHEDULED_SCANS_RESPONSE + ) + + def test_get_scheduled_scans_list_with_non_int_pagesize(self): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "page_size": base.NON_INT_PAGESIZE + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scans_list_with_int_pagesize(self, read): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "page_size": base.INT_PAGESIZE + }, + mocks={ + read: scheduled_scans.SCHEDULED_SCANS + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scheduled_scans. + SCHEDULED_SCANS_RESPONSE + ) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scans_list_with_unknown_env(self, read, check_env_name): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.UNKNOWN_ENV + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + def test_get_scheduled_scans_list_with_wrong_freq(self): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "freq": scheduled_scans.WRONG_FREQ + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scans_list_with_freq(self, read): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "freq": scheduled_scans.CORRECT_FREQ + }, + mocks={ + read: scheduled_scans. + SCHEDULED_SCAN_WITH_SPECIFIC_FREQ, + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scheduled_scans. + SCHEDULED_SCAN_WITH_SPECIFIC_FREQ_RESPONSE + ) + + def test_get_scheduled_scan_with_wrong_id(self): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "id": scheduled_scans.WRONG_ID + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scan_with_nonexistent_id(self, read, check_env_name): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "id": scheduled_scans.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: True + }, + expected_code=base.NOT_FOUND_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scan_with_unknown_env_and_nonexistent_id(self, read, + check_env_name): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.UNKNOWN_ENV, + "id": scheduled_scans.NONEXISTENT_ID + }, + mocks={ + read: [], + check_env_name: False + }, + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_READ) + def test_get_scheduled_scan_with_id(self, read): + self.validate_get_request(scheduled_scans.URL, + params={ + "environment": base.ENV_NAME, + "id": scheduled_scans.CORRECT_ID + }, + mocks={ + read: scheduled_scans. + SCHEDULED_SCAN_WITH_SPECIFIC_ID + }, + expected_code=base.SUCCESSFUL_CODE, + expected_response=scheduled_scans. + SCHEDULED_SCAN_WITH_SPECIFIC_ID[0] + ) + + def test_post_scheduled_scan_with_non_dict_scheduled_scan(self): + self.validate_post_request(scheduled_scans.URL, + body=json.dumps(scheduled_scans. + NON_DICT_SCHEDULED_SCAN), + expected_code=base.BAD_REQUEST_CODE) + + def test_post_bad_scheduled_scans(self): + test_cases = [ + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITHOUT_ENV + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITHOUT_FREQ + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_WRONG_FREQ + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_WRONG_LOG_LEVEL + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITHOUT_SUBMIT_TIMESTAMP + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_WRONG_SUBMIT_TIMESTAMP + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_NON_BOOL_CLEAR + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_LINKS + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_CLIQUES + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_INVENTORY + }, + { + "body": scheduled_scans. + SCHEDULED_SCAN_WITH_EXTRA_SCAN_ONLY_FLAGS + } + ] + for test_case in test_cases: + self.validate_post_request(scheduled_scans.URL, + body=json.dumps(test_case["body"]), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + def test_post_scheduled_scan_with_unknown_env_name(self, + check_environment_name): + self.validate_post_request(scheduled_scans.URL, + mocks={ + check_environment_name: False + }, + body=json.dumps(scheduled_scans. + SCHEDULED_SCAN_WITH_UNKNOWN_ENV), + expected_code=base.BAD_REQUEST_CODE) + + @patch(base.RESPONDER_BASE_CHECK_ENVIRONMENT_NAME) + @patch(base.RESPONDER_BASE_WRITE) + def test_post_scheduled_scan(self, write, check_env_name): + self.validate_post_request(scheduled_scans.URL, + mocks={ + check_env_name: True, + write: None + }, + body=json.dumps(scheduled_scans. + SCHEDULED_SCAN), + expected_code=base.CREATED_CODE) diff --git a/app/test/api/responders_test/test_data/__init__.py b/app/test/api/responders_test/test_data/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/api/responders_test/test_data/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/api/responders_test/test_data/aggregates.py b/app/test/api/responders_test/test_data/aggregates.py new file mode 100644 index 0000000..52ce985 --- /dev/null +++ b/app/test/api/responders_test/test_data/aggregates.py @@ -0,0 +1,67 @@ +############################################################################### +# 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 # +############################################################################### +URL = "/aggregates" + +CONSTANT_TYPE = "constant" +ENV_TYPE = "environment" +MESSAGE_TYPE = "message" +UNKNOWN_TYPE = "unknown" + +CONSTANT_AGGREGATES = [ + {"name": "type_drivers", "total": 5}, + {"name": "environment_monitoring_types", "total": 1}, + {"name": "link_states", "total": 2} +] +ENVIRONMENT_AGGREGATES = [ + {'_id': 'otep', 'total': 3}, + {'_id': 'instance', 'total': 2}, + {'_id': 'network_agent', 'total': 6} +] +MESSAGE_ENV_AGGREGATES = [ + {'_id': 'Mirantis-Liberty-API', 'total': 15} +] +MESSAGE_LEVEL_AGGREGATES = [ + {'_id': 'info', 'total': 15} +] + +CONSTANT_AGGREGATES_RESPONSE = { + "type": "constant", + "aggregates": { + "names": { + "type_drivers": 5, + "environment_monitoring_types": 1, + "link_states": 2 + } + } + } + +ENVIRONMENT_AGGREGATES_RESPONSE = { + "aggregates": { + "object_types": { + "otep": 3, + "instance": 2, + "network_agent": 6 + } + }, + "env_name": "Mirantis-Liberty-API", + "type": "environment" +} + +MESSAGE_AGGREGATES_RESPONSE = { + "aggregates": { + "environments": { + "Mirantis-Liberty-API": 15 + }, + "levels": { + "info": 15 + } + }, + "type": "message" + } diff --git a/app/test/api/responders_test/test_data/base.py b/app/test/api/responders_test/test_data/base.py new file mode 100644 index 0000000..1e85800 --- /dev/null +++ b/app/test/api/responders_test/test_data/base.py @@ -0,0 +1,179 @@ +############################################################################### +# 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 # +############################################################################### +# HTTP status code +SUCCESSFUL_CODE = "200" +NOT_FOUND_CODE = "404" +CONFLICT_CODE = "409" +BAD_REQUEST_CODE = "400" +UNAUTHORIZED_CODE = "401" +CREATED_CODE = "201" + +ENV_NAME = "Mirantis-Liberty-API" +UNKNOWN_ENV = "Unkown-Environment" +NON_INT_PAGE = 1.4 +INT_PAGE = 1 +NON_INT_PAGESIZE = 2.4 +INT_PAGESIZE = 2 + +WRONG_LINK_TYPE = "instance-host" +CORRECT_LINK_TYPE= "instance-vnic" + +WRONG_LINK_STATE = "wrong" +CORRECT_LINK_STATE = "up" + +WRONG_SCAN_STATUS = "error" +CORRECT_SCAN_STATUS = "completed" + +WRONG_MONITORING_SIDE = "wrong-side" +CORRECT_MONITORING_SIDE = "client" + +WRONG_MESSAGE_SEVERITY = "wrong-severity" +CORRECT_MESSAGE_SEVERITY = "warn" + +WRONG_TYPE_DRIVER = "wrong_type" +CORRECT_TYPE_DRIVER = "local" + +WRONG_MECHANISM_DRIVER = "wrong-mechanism-dirver" +CORRECT_MECHANISM_DRIVER = "ovs" + +WRONG_LOG_LEVEL = "wrong-log-level" +CORRECT_LOG_LEVEL = "critical" + +WRONG_OBJECT_TYPE = "wrong-object-type" +CORRECT_OBJECT_TYPE = "vnic" + +WRONG_ENV_TYPE = "" +CORRECT_ENV_TYPE = "development" + +WRONG_DISTRIBUTION = "wrong-environment" +CORRECT_DISTRIBUTION = "Mirantis-6.0" + +WRONG_OBJECT_ID = "58a2406e6a283a8bee15d43" +CORRECT_OBJECT_ID = "58a2406e6a283a8bee15d43f" + +WRONG_FORMAT_TIME = "2017-01-25T23:34:333+TX0012" +CORRECT_FORMAT_TIME = "2017-01-25T14:28:32.400Z" + +NON_BOOL = "falses" +BOOL = False +NON_DICT_OBJ = "" + +# fake constants +CONSTANTS_BY_NAMES = { + "link_types": [ + "instance-vnic", + "otep-vconnector", + "otep-pnic", + "pnic-network", + "vedge-otep", + "vnic-vconnector", + "vconnector-pnic", + "vconnector-vedge", + "vnic-vedge", + "vedge-pnic", + "vservice-vnic" + ], + "link_states": [ + "up", + "down" + ], + "scan_statuses": [ + "draft", + "pending", + "running", + "completed", + "failed", + "aborted" + ], + "monitoring_sides": [ + "client", + "server" + ], + "messages_severity": [ + "panic", + "alert", + "crit", + "error", + "warn", + "notice", + "info", + "debug" + ], + "type_drivers": [ + "local", + "vlan", + "vxlan", + "gre", + "flat" + ], + "mechanism_drivers": [ + "ovs", + "vpp", + "LinuxBridge", + "Arista", + "Nexus" + ], + "log_levels": [ + "critical", + "error", + "warning", + "info", + "debug", + "notset" + ], + "object_types": [ + "vnic", + "vconnector", + "vedge", + "instance", + "vservice", + "pnic", + "network", + "port", + "otep", + "agent" + ], + "env_types": [ + "development", + "testing", + "staging", + "production" + ], + "distributions": [ + "Mirantis-6.0", + "Mirantis-7.0", + "Mirantis-8.0", + "Mirantis-9.0", + "RDO-Juno" + ], + "environment_operational_status": [ + "stopped", + "running", + "error" + ], + "environment_provision_types": [ + "None", + "Deploy", + "Files", + "DB" + ], + "environment_monitoring_types": [ + "Sensu" + ] +} + +# path info +RESPONDER_BASE_PATH = "api.responders.responder_base.ResponderBase" +RESPONDER_BASE_GET_OBJECTS_LIST = RESPONDER_BASE_PATH + ".get_objects_list" +RESPONDER_BASE_GET_OBJECT_BY_ID = RESPONDER_BASE_PATH + ".get_object_by_id" +RESPONDER_BASE_CHECK_ENVIRONMENT_NAME = RESPONDER_BASE_PATH + ".check_environment_name" +RESPONDER_BASE_READ = RESPONDER_BASE_PATH + ".read" +RESPONDER_BASE_WRITE = RESPONDER_BASE_PATH + ".write" +RESPONDER_BASE_AGGREGATE = RESPONDER_BASE_PATH + ".aggregate" diff --git a/app/test/api/responders_test/test_data/clique_constraints.py b/app/test/api/responders_test/test_data/clique_constraints.py new file mode 100644 index 0000000..6f867ae --- /dev/null +++ b/app/test/api/responders_test/test_data/clique_constraints.py @@ -0,0 +1,74 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + +URL = "/clique_constraints" + +WRONG_ID = base.WRONG_OBJECT_ID +NONEXISTENT_ID = "576a4176a83d5313f21971f0" +CORRECT_ID = base.CORRECT_OBJECT_ID + +WRONG_FOCAL_POINT_TYPE = base.WRONG_OBJECT_TYPE +CORRECT_FOCAL_POINT_TYPE = base.CORRECT_OBJECT_TYPE + +CONSTRAINT = "network" + +CLIQUE_CONSTRAINTS_WITH_SPECIFIC_ID = [ + { + "id": CORRECT_ID + } +] + +CLIQUE_CONSTRAINTS_WITH_SPECIFIC_FOCAL_POINT_TYPE = [ + { + "id": "576a4176a83d5313f21971f5", + "focal_point_type": CORRECT_FOCAL_POINT_TYPE + }, + { + "id": "576ac7069f6ba3074882b2eb", + "focal_point_type": CORRECT_FOCAL_POINT_TYPE + } +] + +CLIQUE_CONSTRAINTS_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE = { + "clique_constraints": CLIQUE_CONSTRAINTS_WITH_SPECIFIC_FOCAL_POINT_TYPE +} + +CLIQUE_CONSTRAINTS_WITH_SPECIFIC_CONSTRAINT = [ + { + "id": "576a4176a83d5313f21971f5", + "constraints": [ + CONSTRAINT + ] + }, + { + "id": "576ac7069f6ba3074882b2eb", + "constraints": [ + CONSTRAINT + ] + } +] + +CLIQUE_CONSTRAINTS_WITH_SPECIFIC_CONSTRAINT_RESPONSE = { + "clique_constraints": CLIQUE_CONSTRAINTS_WITH_SPECIFIC_CONSTRAINT +} + +CLIQUE_CONSTRAINTS = [ + { + "id": "576a4176a83d5313f21971f5" + }, + { + "id": "576ac7069f6ba3074882b2eb" + } +] + +CLIQUE_CONSTRAINTS_RESPONSE = { + "clique_constraints": CLIQUE_CONSTRAINTS +} diff --git a/app/test/api/responders_test/test_data/clique_types.py b/app/test/api/responders_test/test_data/clique_types.py new file mode 100644 index 0000000..0fbe839 --- /dev/null +++ b/app/test/api/responders_test/test_data/clique_types.py @@ -0,0 +1,170 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + + +URL = "/clique_types" + +WRONG_ID = base.WRONG_OBJECT_ID +NONEXISTENT_ID = "58ca73ae3a8a836d10ff3b44" +CORRECT_ID = base.CORRECT_OBJECT_ID + +WRONG_FOCAL_POINT_TYPE = base.WRONG_OBJECT_TYPE +CORRECT_FOCAL_POINT_POINT_TYPE = base.CORRECT_OBJECT_TYPE + +WRONG_LINK_TYPE = base.WRONG_LINK_TYPE +NONEXISTENT_LINK_TYPE = "otep-pnic" +CORRECT_LINK_TYPE = base.CORRECT_LINK_TYPE + +CLIQUE_TYPES_WITH_SPECIFIC_ID = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": "pnic", + "id": CORRECT_ID + } +] + +CLIQUE_TYPES_WITH_SPECIFIC_FOCAL_POINT_TYPE = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": CORRECT_FOCAL_POINT_POINT_TYPE, + "id": "58ca73ae3a8a836d10ff3b80" + }, + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": CORRECT_FOCAL_POINT_POINT_TYPE, + "id": "58ca73ae3a8a836d10ff3b81" + } +] + +CLIQUE_TYPES_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE = { + "clique_types": CLIQUE_TYPES_WITH_SPECIFIC_FOCAL_POINT_TYPE +} + +CLIQUE_TYPES_WITH_SPECIFIC_LINK_TYPE = [ + { + "environment": "Mirantis-Liberty-API", + "link_types": [ + CORRECT_LINK_TYPE + ], + "id": "58ca73ae3a8a836d10ff3b80" + }, + { + "environment": "Mirantis-Liberty-API", + "link_types": [ + CORRECT_LINK_TYPE + ], + "id": "58ca73ae3a8a836d10ff3b81" + } +] + +CLIQUE_TYPES_WITH_SPECIFIC_LINK_TYPE_RESPONSE = { + "clique_types": CLIQUE_TYPES_WITH_SPECIFIC_LINK_TYPE +} + +CLIQUE_TYPES = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": "58ca73ae3a8a836d10ff3b80" + }, + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": "58ca73ae3a8a836d10ff3b81" + } +] + +CLIQUE_TYPES_RESPONSE = { + "clique_types": CLIQUE_TYPES +} + +NON_DICT_CLIQUE_TYPE = base.NON_DICT_OBJ + +CLIQUE_TYPE_WITHOUT_ENVIRONMENT = { + "name": "instance_vconnector_clique", + "link_types": [ + "instance-vnic", + "vnic-vconnector" + ], + "focal_point_type": "instance" +} + +CLIQUE_TYPE_WITH_UNKNOWN_ENVIRONMENT = { + "environment": base.UNKNOWN_ENV, + "id": "589a3969761b0555a3ef6093", + "name": "instance_vconnector_clique", + "link_types": [ + "instance-vnic", + "vnic-vconnector" + ], + "focal_point_type": "instance" +} + +CLIQUE_TYPE_WITHOUT_FOCAL_POINT_TYPE = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "link_types": [ + "instance-vnic", + "vnic-vconnector" + ] +} + +CLIQUE_TYPE_WITH_WRONG_FOCAL_POINT_TYPE = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "link_types": [ + "instance-vnic", + "vnic-vconnector" + ], + "focal_point_type": WRONG_FOCAL_POINT_TYPE +} + +CLIQUE_TYPE_WITHOUT_LINK_TYPES = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "focal_point_type": "instance" +} + +CLIQUE_TYPE_WITH_NON_LIST_LINK_TYPES = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "link_types": "instance-vnic", + "focal_point_type": "instance" +} + +CLIQUE_TYPE_WITH_WRONG_LINK_TYPE = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "link_types": [ + WRONG_LINK_TYPE, + "vnic-vconnector" + ], + "focal_point_type": "instance" +} + +CLIQUE_TYPE_WITHOUT_NAME = { + "environment": "Mirantis-Liberty-API", + "link_types": [ + "instance-vnic", + "vnic-vconnector", + ], + "focal_point_type": "instance" +} + +CLIQUE_TYPE = { + "environment": "Mirantis-Liberty-API", + "name": "instance_vconnector_clique", + "link_types": [ + "instance-vnic", + "vnic-vconnector" + ], + "focal_point_type": "instance" +} diff --git a/app/test/api/responders_test/test_data/cliques.py b/app/test/api/responders_test/test_data/cliques.py new file mode 100644 index 0000000..e1995cd --- /dev/null +++ b/app/test/api/responders_test/test_data/cliques.py @@ -0,0 +1,171 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + +URL = "/cliques" + +WRONG_CLIQUE_ID = "58a2406e6a283a8bee15d43" +CORRECT_CLIQUE_ID = "58a2406e6a283a8bee15d43f" +NONEXISTENT_CLIQUE_ID = "58a2406e6a283a8bee15d43e" + +WRONG_FOCAL_POINT = "58a2406e6a283a8bee15d43" +CORRECT_FOCAL_POINT = "58a2406e6a283a8bee15d43f" + +WRONG_LINK_ID = "58a2406e6a283a8bee15d43" +CORRECT_LINK_ID = "58a2406e6a283a8bee15d43f" +NONEXISTENT_LINK_ID = "58a2406e6a283a8bee15d43e" + +WRONG_FOCAL_POINT_TYPE = base.WRONG_OBJECT_TYPE +CORRECT_FOCAL_POINT_TYPE = base.CORRECT_OBJECT_TYPE + +WRONG_LINK_TYPE = base.WRONG_LINK_TYPE +CORRECT_LINK_TYPE = base.CORRECT_LINK_TYPE + +CLIQUES_WITH_SPECIFIC_ID = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": CORRECT_CLIQUE_ID + } +] + +CLIQUES_WITH_SPECIFIC_FOCAL_POINT_TYPE = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": CORRECT_FOCAL_POINT_TYPE, + "id": "576c119a3f4173144c7a75c5" + }, + { + "environment": "Mirantis-Liberty-API", + "focal_point_type": CORRECT_FOCAL_POINT_TYPE, + "id": "576c119a3f4173144c7a75cc6" + } +] + +CLIQUES_WITH_SPECIFIC_FOCAL_POINT_TYPE_RESPONSE = { + "cliques": CLIQUES_WITH_SPECIFIC_FOCAL_POINT_TYPE +} + +CLIQUES_WITH_SPECIFIC_FOCAL_POINT = [ + { + "environment": "Mirantis-Liberty-API", + "focal_point": CORRECT_FOCAL_POINT, + "id": "576c119a3f4173144c7a75c5" + }, + { + "environment": "Mirantis-Liberty-API", + "focal_point": CORRECT_FOCAL_POINT, + "id": "576c119a3f4173144c7a758e" + } +] + +CLIQUES_WITH_SPECIFIC_FOCAL_POINT_RESPONSE = { + "cliques": CLIQUES_WITH_SPECIFIC_FOCAL_POINT +} + +CLIQUES_WITH_SPECIFIC_LINK_TYPE = [ + { + "links_detailed": [ + { + "link_type": CORRECT_LINK_TYPE, + "_id": "58a2405a6a283a8bee15d42f" + }, + { + "link_type": "vnic-vconnector", + "_id": "58a240056a283a8bee15d3f2" + } + ], + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": "576c119a3f4173144c7a75c5" + }, + { + "links_detailed": [ + { + "link_type": CORRECT_LINK_TYPE, + "_id": "58a2405a6a283a8bee15d42f" + } + ], + "environment": "Mirantis-Liberty-API", + "focal_point_type": "pnic", + "id": "576c119a3f4173144c7a75c7" + } +] + +CLIQUES_WITH_SPECIFIC_LINK_TYPE_RESPONSE = { + "cliques": CLIQUES_WITH_SPECIFIC_LINK_TYPE +} + +CLIQUES_WITH_SPECIFIC_LINK_ID = [ + { + "links_detailed": [ + { + "_id": CORRECT_LINK_ID + }, + { + "_id": "58a240056a283a8bee15d3f2" + } + ], + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": "576c119a3f4173144c7a75c5" + }, + { + "links_detailed": [ + { + "_id": CORRECT_LINK_ID + } + ], + "environment": "Mirantis-Liberty-API", + "focal_point_type": "pnic", + "id": "576c119a3f4173144c7a75c7" + } +] + +CLIQUES_WITH_SPECIFIC_LINK_ID_RESPONSE = { + "cliques": CLIQUES_WITH_SPECIFIC_LINK_ID +} + +# response +CLIQUES = [{ + "links_detailed": [ + { + "link_type": "instance-vnic", + "_id": "58a2405a6a283a8bee15d42f" + }, + { + "link_type": "vnic-vconnector", + "_id": "58a240056a283a8bee15d3f2" + } + ], + "environment": "Mirantis-Liberty-API", + "focal_point_type": "vnic", + "id": "576c119a3f4173144c7a75c5" + }, + { + "links_detailed": [ + { + "link_type": "instance-vnic", + "_id": "58a2405a6a283a8bee15d42f" + }, + { + "link_type": "vnic-vconnector", + "_id": "58a240056a283a8bee15d3f2" + } + ], + "environment": "Miratis-Liberty-API", + "focal_point_type": "pnic", + "id": "576c119a3f4173144c7a75c6" + } +] + +CLIQUES_RESPONSE = { + "cliques": CLIQUES +} diff --git a/app/test/api/responders_test/test_data/constants.py b/app/test/api/responders_test/test_data/constants.py new file mode 100644 index 0000000..9293209 --- /dev/null +++ b/app/test/api/responders_test/test_data/constants.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 # +############################################################################### +URL = "/constants" +UNKNOWN_NAME = "unknown constant" +NAME = "distributions" +CONSTANTS_WITH_SPECIFIC_NAME = [{ + "id": "YmPDAQAchr39KjECQ", + "name": NAME, + "data": [{ + "value": "Canonical-icehouse", + "label": "Canonical-icehouse" + }, { + "value": "Canonical-juno", + "label": "Canonical-juno" + }], +}] diff --git a/app/test/api/responders_test/test_data/environment_configs.py b/app/test/api/responders_test/test_data/environment_configs.py new file mode 100644 index 0000000..2a67fb6 --- /dev/null +++ b/app/test/api/responders_test/test_data/environment_configs.py @@ -0,0 +1,221 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + + +URL = "/environment_configs" + +NAME = "Mirantis-Liberty-API" +UNKNOWN_NAME = "UNKNOWN NAME" +WRONG_DISTRIBUTION = base.WRONG_DISTRIBUTION +CORRECT_DISTRIBUTION = base.CORRECT_DISTRIBUTION +WRONG_MECHANISM_DRIVER = base.WRONG_MECHANISM_DRIVER +CORRECT_MECHANISM_DRIVER = base.CORRECT_MECHANISM_DRIVER +WRONG_TYPE_DRIVER = base.WRONG_TYPE_DRIVER +CORRECT_TYPE_DRIVER = base.CORRECT_TYPE_DRIVER +USER = "WS7j8oTbWPf3LbNne" +NON_BOOL_LISTEN = NON_BOOL_SCANNED = \ + NON_BOOL_MONITORING_SETUP_DONE = base.NON_BOOL + +BOOL_LISTEN = BOOL_SCANNED = \ + BOOL_MONITORING_SETUP_DONE = base.BOOL + +ENV_CONFIGS = [ + { + "distribution": "Mirantis-8.0", + "name": "Mirantis-Liberty-API" + }, + { + "distribution": "Mirantis-9.0", + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_RESPONSE = { + "environment_configs": ENV_CONFIGS +} + +ENV_CONFIGS_WITH_SPECIFIC_NAME = [ + { + "distribution": "Mirantis-8.0", + "name": NAME + } +] + +ENV_CONFIGS_WITH_SPECIFIC_DISTRIBUTION = [ + { + "distribution": CORRECT_DISTRIBUTION, + "name": "Mirantis-Liberty-API", + }, + { + "distribution": CORRECT_DISTRIBUTION, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_DISTRIBUTION_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_DISTRIBUTION +} + +ENV_CONFIGS_WITH_SPECIFIC_MECHANISM_DRIVER = [ + { + "name": "Mirantis-Liberty-API", + "mechanism_drivers": [ + CORRECT_MECHANISM_DRIVER + ] + }, + { + "name": "Mirantis-Liberty", + "mechanism_drivers": [ + CORRECT_MECHANISM_DRIVER + ] + } +] + +ENV_CONFIGS_WITH_SPECIFIC_MECHANISM_DRIVER_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_MECHANISM_DRIVER +} + +ENV_CONFIGS_WITH_SPECIFIC_TYPE_DRIVER = [ + { + "type_drivers": CORRECT_TYPE_DRIVER, + "name": "Mirantis-Liberty-API", + }, + { + "type_drivers": CORRECT_TYPE_DRIVER, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_TYPE_DRIVER_RESPONSE = { + 'environment_configs': ENV_CONFIGS_WITH_SPECIFIC_TYPE_DRIVER +} + +ENV_CONFIGS_WITH_SPECIFIC_USER = [ + { + "user": USER, + "name": "Mirantis-Liberty-API", + }, + { + "user": USER, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_USER_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_USER +} + +ENV_CONFIGS_WITH_SPECIFIC_LISTEN = [ + { + "listen": BOOL_LISTEN, + "name": "Mirantis-Liberty-API", + }, + { + "listen": BOOL_LISTEN, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_LISTEN_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_LISTEN +} + +ENV_CONFIGS_WITH_SPECIFIC_SCANNED = [ + { + "scanned": BOOL_SCANNED, + "name": "Mirantis-Liberty-API", + }, + { + "scanned": BOOL_SCANNED, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_SCANNED_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_SCANNED +} + +ENV_CONFIGS_WITH_SPECIFIC_MONITORING_SETUP_DONE = [ + { + "monitoring_setup_done": BOOL_MONITORING_SETUP_DONE, + "name": "Mirantis-Liberty-API", + }, + { + "monitoring_setup_done": BOOL_MONITORING_SETUP_DONE, + "name": "Mirantis-Liberty" + } +] + +ENV_CONFIGS_WITH_SPECIFIC_MONITORING_SETUP_DONE_RESPONSE = { + "environment_configs": ENV_CONFIGS_WITH_SPECIFIC_MONITORING_SETUP_DONE +} + +ENV_CONFIG = { + "app_path": "/home/korenlev/Calipso/app/", + "configuration": [ + { + "host": "10.56.20.239", + "name": "mysql", + "password": "G1VKEbcqKZXoPthrtNma2D9Y", + "port": "3307", + "user": "root" + }, + { + "name": "OpenStack", + "host": "10.56.20.239", + "admin_token": "wLWefGuD0uYJ7tqkeEScdnNo", + "port": "5000", + "user": "admin", + "pwd": "admin" + }, + { + "host": "10.56.20.239", + "key": "/etc/calipso/keys/Mirantis-Liberty-id_rsa", + "name": "CLI", + "user": "root" + }, + { + "host": "10.56.20.239", + "name": "AMQP", + "password": "YVWMiKMshZhlJCGqFu5PdT9d", + "port": "5673", + "user": "nova" + }, + { + "config_folder": "/tmp/sensu_test", + "provision": "None", + "env_type": "development", + "name": "Monitoring", + "api_port": "4567", + "rabbitmq_port": "5671", + "rabbitmq_pass": "sensuaccess", + "rabbitmq_user": "sensu", + "ssh_port": "20022", + "ssh_user": "root", + "ssh_password": "calipso", + "server_ip": "korlev-calipso-staging1.cisco.com", + "server_name": "calipso-sensu", + "type": "Sensu" + } + ], + "distribution": "Mirantis-8.0", + "last_scanned": "2017-03-16T11:14:54Z", + "listen": True, + "mechanism_drivers": [ + "ovs" + ], + "name": "Mirantis-Liberty", + "operational": "running", + "scanned": True, + "type": "environment", + "type_drivers": "vxlan", + "user": "WS7j8oTbWPf3LbNne" +} diff --git a/app/test/api/responders_test/test_data/inventory.py b/app/test/api/responders_test/test_data/inventory.py new file mode 100644 index 0000000..47d611d --- /dev/null +++ b/app/test/api/responders_test/test_data/inventory.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 # +############################################################################### +URL = "/inventory" + +ID = "RegionOne-aggregates" +NONEXISTENT_ID = "Unkown-Id" + + +OBJECTS_LIST = [ + { + "id": "Mirantis-Liberty-regions", + "name": "Regions", + "name_path": "/Mirantis-Liberty-API/Regions" + }, + { + "id": "Mirantis-Liberty-projects", + "name": "Projects", + "name_path": "/Mirantis-Liberty-API/Projects" + } +] + +OBJECT_IDS_RESPONSE = { + "objects": OBJECTS_LIST +} + + +OBJECTS = [{ + "environment": "Mirantis-Liberty-API", + "id": "RegionOne-aggregates" +}] diff --git a/app/test/api/responders_test/test_data/links.py b/app/test/api/responders_test/test_data/links.py new file mode 100644 index 0000000..e71c02d --- /dev/null +++ b/app/test/api/responders_test/test_data/links.py @@ -0,0 +1,90 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + + +URL = "/links" + +UNKNOWN_HOST = "unknown host" + +WRONG_TYPE = base.WRONG_LINK_TYPE +CORRECT_TYPE = base.CORRECT_LINK_TYPE + +WRONG_STATE = base.WRONG_LINK_STATE +CORRECT_STATE = base.CORRECT_LINK_STATE + +LINK_ID = "58ca73ae3a8a836d10ff3b45" +WRONG_LINK_ID = "58ca73ae3a8a836d10ff3b4" +NONEXISTENT_LINK_ID = "58ca73ae3a8a836d10ff3b46" + +LINKS_WITH_SPECIFIC_TYPE = [ + { + "id": "58ca73ae3a8a836d10ff3bb5", + "host": "node-1.cisco.com", + "link_type": CORRECT_TYPE, + "link_name": "Segment-103", + "environment": "Mirantis-Liberty-API" + }, + { + "id": "58ca73ae3a8a836d10ff3b4d", + "host": "node-1.cisco.com", + "link_type": CORRECT_TYPE, + "link_name": "Segment-104", + "environment": "Mirantis-Liberty-API" + } +] + + +LINKS_WITH_SPECIFIC_STATE = [ + { + "id": "58ca73ae3a8a836d10ff3bb5", + "host": "node-1.cisco.com", + "state": CORRECT_STATE, + "environment": "Mirantis-Liberty-API" + }, + { + "id": "58ca73ae3a8a836d10ff3b4d", + "host": "node-1.cisco.com", + "state": CORRECT_STATE, + "environment": "Mirantis-Liberty-API" + } +] + +LINKS_WITH_SPECIFIC_STATE_RESPONSE = { + "links": LINKS_WITH_SPECIFIC_STATE +} + +LINKS_WITH_SPECIFIC_TYPE_RESPONSE = { + "links": LINKS_WITH_SPECIFIC_TYPE +} + +LINKS_WITH_SPECIFIC_ID = [ + { + "id": LINK_ID, + "host": "node-1.cisco.com", + "link_type": "pnic-network", + "link_name": "Segment-103", + "environment": "Mirantis-Liberty-API" + } +] + +LINKS = [ + { + "id": "58ca73ae3a8a836d10ff3b45", + "host": "node-1.cisco.com", + "link_type": "pnic-network", + "link_name": "Segment-103", + "environment": "Mirantis-Liberty-API" + } +] + +LINKS_LIST_RESPONSE = { + "links": LINKS +} diff --git a/app/test/api/responders_test/test_data/messages.py b/app/test/api/responders_test/test_data/messages.py new file mode 100644 index 0000000..b7b5abd --- /dev/null +++ b/app/test/api/responders_test/test_data/messages.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 test.api.responders_test.test_data import base + +# url +URL = "/messages" + +NONEXISTENT_MESSAGE_ID = "80b5e074-0f1a-4b67-810c-fa9c92d41a9f" +MESSAGE_ID = "80b5e074-0f1a-4b67-810c-fa9c92d41a98" + +WRONG_SEVERITY = base.WRONG_MESSAGE_SEVERITY +CORRECT_SEVERITY = base.CORRECT_MESSAGE_SEVERITY + +WRONG_RELATED_OBJECT_TYPE = base.WRONG_OBJECT_TYPE +CORRECT_RELATED_OBJECT_TYPE = base.CORRECT_OBJECT_TYPE + +RELATED_OBJECT = "instance" +NONEXISTENT_RELATED_OBJECT = "nonexistent-instance" + +WRONG_FORMAT_TIME = base.WRONG_FORMAT_TIME +CORRECT_FORMAT_TIME = base.CORRECT_FORMAT_TIME + +MESSAGES_WITH_SPECIFIC_TIME = [ + { + "level": "info", + "environment": "Mirantis-Liberty-API", + "id": "3c64fe31-ca3b-49a3-b5d3-c485d7a452e7", + "source_system": "OpenStack", + "timestamp": CORRECT_FORMAT_TIME + } +] + +MESSAGES_WITH_SPECIFIC_TIME_RESPONSE = { + "messages": MESSAGES_WITH_SPECIFIC_TIME +} + +MESSAGES_WITH_SPECIFIC_SEVERITY = [ + { + "level": CORRECT_SEVERITY, + "environment": "Mirantis-Liberty-API", + "id": "3c64fe31-ca3b-49a3-b5d3-c485d7a452e7", + "source_system": "OpenStack" + }, + { + "level": CORRECT_SEVERITY, + "environment": "Mirantis-Liberty-API", + "id": "c7071ec0-04db-4820-92ff-3ed2b916738f", + "source_system": "OpenStack" + }, +] + +MESSAGES_WITH_SPECIFIC_SEVERITY_RESPONSE = { + "messages": MESSAGES_WITH_SPECIFIC_SEVERITY +} + +MESSAGES_WITH_SPECIFIC_RELATED_OBJECT_TYPE = [ + { + "level": "info", + "environment": "Mirantis-Liberty-API", + "related_object_type": CORRECT_RELATED_OBJECT_TYPE, + "id": "3c64fe31-ca3b-49a3-b5d3-c485d7a452e7" + }, + { + "level": "error", + "environment": "Mirantis-Liberty-API", + "related_object_type": CORRECT_RELATED_OBJECT_TYPE, + "id": "c7071ec0-04db-4820-92ff-3ed2b916738f" + }, +] + +MESSAGES_WITH_SPECIFIC_RELATED_OBJECT_TYPE_RESPONSE = { + "messages": MESSAGES_WITH_SPECIFIC_RELATED_OBJECT_TYPE +} + +MESSAGES_WITH_SPECIFIC_ID = [ + { + "level": "info", + "environment": "Mirantis-Liberty", + "id": MESSAGE_ID, + "source_system": "OpenStack" + } +] + +MESSAGES = [ + { + "level": "info", + "environment": "Mirantis-Liberty", + "id": "3c64fe31-ca3b-49a3-b5d3-c485d7a452e7", + "source_system": "OpenStack" + }, + { + "level": "info", + "environment": "Mirantis-Liberty", + "id": "c7071ec0-04db-4820-92ff-3ed2b916738f", + "source_system": "OpenStack" + }, +] + +MESSAGES_RESPONSE = { + "messages": MESSAGES +} diff --git a/app/test/api/responders_test/test_data/monitoring_config_templates.py b/app/test/api/responders_test/test_data/monitoring_config_templates.py new file mode 100644 index 0000000..0f387a4 --- /dev/null +++ b/app/test/api/responders_test/test_data/monitoring_config_templates.py @@ -0,0 +1,98 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + + +URL = "/monitoring_config_templates" + +WRONG_ID = base.WRONG_OBJECT_ID +UNKNOWN_ID = "583711893e149c14785d6da5" +CORRECT_ID = base.CORRECT_OBJECT_ID + +NON_INT_ORDER = 1.3 +INT_ORDER = 1 + +WRONG_SIDE = base.WRONG_MONITORING_SIDE +CORRECT_SIDE = base.CORRECT_MONITORING_SIDE + +TYPE = "client.json" + +TEMPLATES_WITH_SPECIFIC_ORDER = [ + { + "order": INT_ORDER, + "id": "583711893e149c14785d6daa" + }, + { + "order": INT_ORDER, + "id": "583711893e149c14785d6da7" + } +] + +TEMPLATES_WITH_SPECIFIC_ORDER_RESPONSE = { + "monitoring_config_templates": + TEMPLATES_WITH_SPECIFIC_ORDER +} + +TEMPLATES_WITH_SPECIFIC_SIDE = [ + { + "side": CORRECT_SIDE, + "id": "583711893e149c14785d6daa" + }, + { + "side": CORRECT_SIDE, + "id": "583711893e149c14785d6da7" + } +] + +TEMPLATES_WITH_SPECIFIC_SIDE_RESPONSE = { + "monitoring_config_templates": + TEMPLATES_WITH_SPECIFIC_SIDE +} + +TEMPLATES_WITH_SPECIFIC_TYPE = [ + { + "type": TYPE, + "id": "583711893e149c14785d6daa" + }, + { + "type": TYPE, + "id": "583711893e149c14785d6da7" + } +] + +TEMPLATES_WITH_SPECIFIC_TYPE_RESPONSE = { + "monitoring_config_templates": + TEMPLATES_WITH_SPECIFIC_TYPE +} + +TEMPLATES_WITH_SPECIFIC_ID = [ + { + "type": "rabbitmq.json", + "side": "client", + "id": CORRECT_ID + } +] + +TEMPLATES = [ + { + "type": "rabbitmq.json", + "side": "client", + "id": "583711893e149c14785d6daa" + }, + { + "type": "rabbitmq.json", + "side": "client", + "id": "583711893e149c14785d6da7" + } +] + +TEMPLATES_RESPONSE = { + "monitoring_config_templates": TEMPLATES +} diff --git a/app/test/api/responders_test/test_data/scans.py b/app/test/api/responders_test/test_data/scans.py new file mode 100644 index 0000000..479d371 --- /dev/null +++ b/app/test/api/responders_test/test_data/scans.py @@ -0,0 +1,187 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + +URL = "/scans" + +WRONG_ID = base.WRONG_OBJECT_ID +NONEXISTENT_ID = "58c96a075eb66a121cc4e750" +CORRECT_ID = base.CORRECT_OBJECT_ID + +BASE_OBJECT = "node-2.cisco.com" + +WRONG_STATUS = base.WRONG_SCAN_STATUS +CORRECT_STATUS = base.CORRECT_SCAN_STATUS + +SCANS = [ + { + "status": "pending", + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75f", + }, + { + "status": "completed", + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75e", + "scan_completed": True + } +] + +SCANS_RESPONSE = { + "scans": SCANS +} + +SCANS_WITH_SPECIFIC_ID = [ + { + "status": "pending", + "environment": "Mirantis-Liberty-API", + "id": CORRECT_ID, + } +] + +SCANS_WITH_SPECIFIC_BASE_OBJ = [ + { + "status": "pending", + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75f", + "object_id": BASE_OBJECT + }, + { + "status": "completed", + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75e", + "object_id": BASE_OBJECT, + "scan_completed": True + } +] + +SCANS_WITH_SPECIFIC_BASE_OBJ_RESPONSE = { + "scans": SCANS_WITH_SPECIFIC_BASE_OBJ +} + +SCANS_WITH_SPECIFIC_STATUS = [ + { + "status": CORRECT_STATUS, + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75f", + "scan_completed": True + }, + { + "status": CORRECT_STATUS, + "environment": "Mirantis-Liberty-API", + "id": "58c96a075eb66a121cc4e75e", + "scan_completed": True + } +] + +SCANS_WITH_SPECIFIC_STATUS_RESPONSE = { + "scans": SCANS_WITH_SPECIFIC_STATUS +} + +NON_DICT_SCAN = base.NON_DICT_OBJ + +SCAN = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_inventory": True, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITHOUT_ENV = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_inventory": True, + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_UNKNOWN_ENV = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_inventory": True, + "environment": base.UNKNOWN_ENV, + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITHOUT_STATUS = { + "log_level": "warning", + "clear": True, + "scan_only_inventory": True, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_WRONG_STATUS = { + "status": WRONG_STATUS, + "log_level": "warning", + "clear": True, + "scan_only_inventory": True, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_WRONG_LOG_LEVEL = { + "status": "pending", + "log_level": base.WRONG_LOG_LEVEL, + "clear": True, + "scan_only_inventory": True, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_NON_BOOL_CLEAR = { + "status": "pending", + "log_level": "warning", + "clear": base.NON_BOOL, + "scan_only_inventory": True, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + + +SCAN_WITH_NON_BOOL_SCAN_ONLY_INVENTORY = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_inventory": base.NON_BOOL, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_NON_BOOL_SCAN_ONLY_LINKS = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_links": base.NON_BOOL, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} + +SCAN_WITH_NON_BOOL_SCAN_ONLY_CLIQUES = { + "status": "pending", + "log_level": "warning", + "clear": True, + "scan_only_cliques": base.NON_BOOL, + "environment": "Mirantis-Liberty-API", + "inventory": "inventory", + "object_id": "ff" +} diff --git a/app/test/api/responders_test/test_data/scheduled_scans.py b/app/test/api/responders_test/test_data/scheduled_scans.py new file mode 100644 index 0000000..1019572 --- /dev/null +++ b/app/test/api/responders_test/test_data/scheduled_scans.py @@ -0,0 +1,138 @@ +############################################################################### +# 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 test.api.responders_test.test_data import base + +URL = "/scheduled_scans" +WRONG_FREQ = "wrong_freq" +CORRECT_FREQ = "WEEKLY" +WRONG_ID = base.WRONG_OBJECT_ID +NONEXISTENT_ID = "58c96a075eb66a121cc4e750" +CORRECT_ID = "ff4d3e80e42e886bef13a084" +NON_DICT_SCHEDULED_SCAN = "" + + +SCHEDULED_SCANS = [ + { + "id": "ff4d3e80e42e886bef13a084", + "environment": base.ENV_NAME, + "scheduled_timestamp": "2017-07-24T12:45:03.784+0000", + "freq": "WEEKLY" + }, + { + "id": "58e4e1aa6df71e971324ea62", + "environment": base.ENV_NAME, + "scheduled_timestamp": "2017-07-24T12:45:03.784+0000", + "freq": "WEEKLY" + } +] + +SCHEDULED_SCANS_RESPONSE = { + "scheduled_scans": SCHEDULED_SCANS +} + +SCHEDULED_SCAN_WITH_SPECIFIC_FREQ = [{ + "id": "ff4d3e80e42e886bef13a084", + "environment": base.ENV_NAME, + "scheduled_timestamp": "2017-07-24T12:45:03.784+0000", + "freq": CORRECT_FREQ +}] + +SCHEDULED_SCAN_WITH_SPECIFIC_FREQ_RESPONSE = { + "scheduled_scans": SCHEDULED_SCAN_WITH_SPECIFIC_FREQ +} + +SCHEDULED_SCAN_WITH_SPECIFIC_ID = [{ + "id": CORRECT_ID, + "environment": base.ENV_NAME, + "scheduled_timestamp": "2017-07-24T12:45:03.784+0000", + "freq": CORRECT_FREQ +}] + +SCHEDULED_SCAN = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITHOUT_ENV = { + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITH_UNKNOWN_ENV = { + "environment": base.UNKNOWN_ENV, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITHOUT_FREQ = { + "environment": base.ENV_NAME, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITHOUT_SUBMIT_TIMESTAMP = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, +} + +SCHEDULED_SCAN_WITH_WRONG_FREQ = { + "environment": base.ENV_NAME, + "freq": WRONG_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITH_WRONG_LOG_LEVEL = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "log_level": base.WRONG_LOG_LEVEL, + "submit_timestamp": "2017-07-24T12:45:03.784+0000" +} + +SCHEDULED_SCAN_WITH_WRONG_SUBMIT_TIMESTAMP = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": base.WRONG_FORMAT_TIME +} + +SCHEDULED_SCAN_WITH_NON_BOOL_CLEAR = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000", + "clear": base.NON_BOOL +} + +SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_LINKS = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000", + "scan_only_links": base.NON_BOOL +} + +SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_CLIQUES = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000", + "scan_only_cliques": base.NON_BOOL +} + +SCHEDULED_SCAN_WITH_NON_BOOL_SCAN_ONLY_INVENTORY = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000", + "scan_only_inventory": base.NON_BOOL +} + +SCHEDULED_SCAN_WITH_EXTRA_SCAN_ONLY_FLAGS = { + "environment": base.ENV_NAME, + "freq": CORRECT_FREQ, + "submit_timestamp": "2017-07-24T12:45:03.784+0000", + "scan_only_links": True, + "scan_only_inventory": True +} diff --git a/app/test/api/responders_test/test_data/tokens.py b/app/test/api/responders_test/test_data/tokens.py new file mode 100644 index 0000000..8d9960d --- /dev/null +++ b/app/test/api/responders_test/test_data/tokens.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 # +############################################################################### +URL = '/auth/tokens' + +AUTH_OBJ_WITHOUT_AUTH = { + +} + +AUTH_OBJ_WITHOUT_METHODS = { + 'auth': {} +} + +AUTH_OBJ_WITHOUT_CREDENTIALS = { + 'auth': { + 'methods': ['credentials'] + } +} + +AUTH_OBJ_WITHOUT_TOKEN = { + 'auth': { + 'methods': ['token'] + } +} + +AUTH_OBJ_WITH_WRONG_CREDENTIALS = { + 'auth': { + 'methods': ['credentials'], + 'credentials': { + 'username': 'wrong_user', + 'password': 'password' + } + } +} + +AUTH_OBJ_WITH_WRONG_TOKEN = { + 'auth': { + 'methods': ['token'], + 'token': 'wrong_token' + } +} + +AUTH_OBJ_WITH_CORRECT_CREDENTIALS = { + 'auth': { + 'methods': ['credentials'], + 'credentials': { + 'username': 'wrong_user', + 'password': 'password' + } + } +} + +AUTH_OBJ_WITH_CORRECT_TOKEN = { + 'auth': { + 'methods': ['token'], + 'token': '17dfa88789aa47f6bb8501865d905f13' + } +} + +HEADER_WITHOUT_TOKEN = { + +} + +HEADER_WITH_WRONG_TOKEN = { + 'X-Auth-Token': 'wrong token' +} + +HEADER_WITH_CORRECT_TOKEN = { + 'X-Auth-Token': '17dfa88789aa47f6bb8501865d905f13' +} + +AUTH_BASE_PATH = 'api.auth.auth.Auth' +AUTH_GET_TOKEN = AUTH_BASE_PATH + '.get_token' +AUTH_WRITE_TOKEN = AUTH_BASE_PATH + '.write_token' +AUTH_DELETE_TOKEN = AUTH_BASE_PATH + '.delete_token' +AUTH_VALIDATE_CREDENTIALS = AUTH_BASE_PATH + '.validate_credentials' +AUTH_VALIDATE_TOKEN = AUTH_BASE_PATH + '.validate_token' diff --git a/app/test/api/test_base.py b/app/test/api/test_base.py new file mode 100644 index 0000000..c126b2b --- /dev/null +++ b/app/test/api/test_base.py @@ -0,0 +1,101 @@ +############################################################################### +# 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 api.app import App +from api.middleware.authentication import AuthenticationMiddleware +from api.responders.responder_base import ResponderBase +from api.backends.ldap_access import LDAPAccess +from falcon.testing import TestCase +from test.api.responders_test.test_data import base +from unittest.mock import MagicMock +from utils.mongo_access import MongoAccess + + +def mock_auth_method(*args): + return None + + +class TestBase(TestCase): + + def setUp(self, authenticate=False): + super().setUp() + # mock + self.authenticate = authenticate + if not authenticate: + self.original_auth_method = AuthenticationMiddleware.process_request + AuthenticationMiddleware.process_request = mock_auth_method + + ResponderBase.get_constants_by_name = MagicMock(side_effect= + lambda name: base.CONSTANTS_BY_NAMES[name]) + # mock mongo access + MongoAccess.mongo_connect = MagicMock() + MongoAccess.db = MagicMock() + MongoAccess.client = MagicMock() + # mock ldap access + LDAPAccess.get_ldap_params = MagicMock() + LDAPAccess.connect_ldap_server = MagicMock() + + log_level = 'debug' + self.app = App(log_level=log_level).get_app() + + def validate_get_request(self, url, params={}, headers=None, mocks={}, + side_effects={}, + expected_code=base.SUCCESSFUL_CODE, + expected_response=None): + self.validate_request("GET", url, params, headers, "", + mocks, side_effects, + expected_code, + expected_response) + + def validate_request(self, action, url, params, headers, body, + mocks, side_effects, expected_code, + expected_response): + for mock_method, mock_data in mocks.items(): + mock_method.return_value = mock_data + + for mock_method, side_effect in side_effects.items(): + mock_method.side_effect = side_effect + + result = self.simulate_request(action, url, params=params, headers=headers, body=body) + self.assertEqual(result.status, expected_code) + if expected_response: + self.assertEqual(result.json, expected_response) + + def validate_post_request(self, url, headers={}, body="", mocks={}, + side_effects={}, + expected_code=base.CREATED_CODE, expected_response=None): + self.validate_request("POST", url, {}, headers, body, mocks, side_effects, + expected_code, expected_response) + + def validate_delete_request(self, url, params={}, headers={}, mocks={}, + side_effects={}, + expected_code=base.SUCCESSFUL_CODE, expected_response=None): + self.validate_request("DELETE", url, params, headers, "", + mocks, side_effects, + expected_code, + expected_response) + + def get_updated_data(self, original_data, deleted_keys=[], updates={}): + copy_data = copy.deepcopy(original_data) + + for key in deleted_keys: + del copy_data[key] + + for key, value in updates.items(): + copy_data[key] = value + + return copy_data + + def tearDown(self): + # if the authentication method has been mocked, it needs to be reset after test + if not self.authenticate: + AuthenticationMiddleware.process_request = self.original_auth_method diff --git a/app/test/event_based_scan/__init__.py b/app/test/event_based_scan/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/event_based_scan/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/event_based_scan/config/__init__.py b/app/test/event_based_scan/config/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/event_based_scan/config/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/event_based_scan/config/test_config.py b/app/test/event_based_scan/config/test_config.py new file mode 100644 index 0000000..176fd48 --- /dev/null +++ b/app/test/event_based_scan/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/event_based_scan/test_data/__init__.py b/app/test/event_based_scan/test_data/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/event_based_scan/test_data/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/event_based_scan/test_data/event_payload_instance_add.py b/app/test/event_based_scan/test_data/event_payload_instance_add.py new file mode 100644 index 0000000..316444a --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_instance_add.py @@ -0,0 +1,122 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_INSTANCE_ADD = { + 'publisher_id': 'compute.node-251.cisco.com', '_context_resource_uuid': None, + '_context_instance_lock_checked': False, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_request_id': 'req-432fccc8-4d13-4e62-8639-c99acee82cb3', + '_context_show_deleted': False, + '_context_timestamp': '2016-09-08T22:01:41.724236', + '_unique_id': '537fc5b27c244479a69819a4a435723b', + '_context_roles': ['_member_', 'admin'], '_context_read_only': False, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_project_name': 'calipso-project', + '_context_project_domain': None, 'event_type': 'compute.instance.update', + '_context_service_catalog': [{'endpoints': [ + {'internalURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volumev2', + 'name': 'cinderv2'}, + {'endpoints': [{ + 'internalURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volume', + 'name': 'cinder'}], + 'payload': {'instance_type': 'm1.micro', 'progress': '', 'display_name': 'test8', + 'kernel_id': '', + 'new_task_state': None, 'old_display_name': 'name-change', + 'state_description': '', + 'old_state': 'building', 'ramdisk_id': '', + 'created_at': '2016-09-08 16:32:46+00:00', + 'os_type': None, + 'ephemeral_gb': 0, 'launched_at': '2016-09-08T16:25:08.000000', + 'instance_flavor_id': 'f068e24b-5d7e-4819-b5ca-89a33834a918', + 'image_meta': {'min_ram': '64', 'container_format': 'bare', 'min_disk': '0', + 'disk_format': 'qcow2', + 'base_image_ref': 'c6f490c4-3656-43c6-8d03-b4e66bd249f9'}, + 'audit_period_beginning': '2016-09-01T00:00:00.000000', 'memory_mb': 64, + 'cell_name': '', + 'access_ip_v6': None, 'instance_type_id': 6, 'reservation_id': 'r-bycutzve', + 'access_ip_v4': None, + 'hostname': 'chengli-test-vm1', 'metadata': {}, + 'user_id': '13baa553aae44adca6615e711fd2f6d9', + 'availability_zone': 'calipso-zone', + 'instance_id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'deleted_at': '', + 'image_ref_url': 'http://172.16.0.4:9292/images/c6f490c4-3656-43c6-8d03-b4e66bd249f9', + 'host': 'node-252.cisco.com', 'vcpus': 1, 'state': 'active', + 'old_task_state': None, + 'architecture': None, + 'terminated_at': '', 'root_gb': 0, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'node': 'node-252.cisco.com', 'bandwidth': {}, 'disk_gb': 0, + 'audit_period_ending': '2016-09-08T22:01:43.165282'}, + '_context_quota_class': None, + '_context_is_admin': True, '_context_read_deleted': 'no', + 'timestamp': '2016-09-08 22:01:43.189907', + 'message_id': '4a9068c6-dcd1-4d6c-81d7-db866e07c1ff', 'priority': 'INFO', + '_context_domain': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_remote_address': '192.168.0.2', '_context_user_domain': None, + '_context_auth_token': '''gAAAAABX0d-R0Q4zIrznmZ_L8BT0m4r_lp-7eOr4IenbKz511g2maNo8qhIb86HtA7S + VGsEJvy4KRcNIGlVRdmGyXBYm3kEuakQXTsXLxvyQeTtgZ9UgnLLXhQvMLbA2gwaimVpyRljq92R7Y7CwnNFLjibhOiYs + NlvBqitJkaRaQa4sg4xCN2tBj32Re-jRu6dR_sIA-haT''', + '_context_user_name': 'admin'} + +INSTANCES_ROOT = { + "create_object": True, + "environment": ENV_CONFIG, + "id": "node-252.cisco.com-instances", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/calipso-zone/node-252.cisco.com/node-252.cisco.com-instances", + "name": "Instances", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/calipso-zone/node-252.cisco.com/Instances", + "object_name": "Instances", + "parent_id": "node-252.cisco.com", + "parent_type": "host", + "show_in_tree": True, + "text": "Instances", + "type": "instances_folder" +} + +INSTANCE_DOCUMENT = { + 'projects': ['calipso-project'], + 'network': [], + 'host': 'node-252.cisco.com', 'parent_type': 'instances_folder', + '_id': '57e421194a0a8a3fbe3bd2d0', 'mac_address': 'fa:16:3e:5e:9e:db', 'type': 'instance', + 'name': 'name-change', + 'uuid': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'environment': ENV_CONFIG, + 'ip_address': '192.168.0.4', 'local_name': 'instance-00000020', 'object_name': 'test8', + 'parent_id': 'node-223.cisco.com-instances', 'project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'name_path': '/'+ENV_CONFIG+'/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-252.cisco.com/Instances/name-change', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/'+ENV_CONFIG+'/'+ENV_CONFIG+'-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'show_in_tree': True} + +HOST = { + 'name_path': '/'+ ENV_CONFIG +'/Regions/RegionOne/Availability Zones/calipso-zone/node-252.cisco.com', + 'id_path': '/'+ENV_CONFIG+ '/'+ENV_CONFIG+'-regions/RegionOne/' + + 'RegionOne-availability_zones/calipso-zone/node-252.cisco.com', + 'object_name': 'node-252.cisco.com', 'last_scanned': 0, + 'type': 'host', 'environment': ENV_CONFIG, 'host': 'node-252.cisco.com', 'id': 'node-252.cisco.com', + 'ip_address': '192.168.0.4', 'name': 'node-252.cisco.com', 'host_type': ['Compute'], + 'services': {'nova-compute': {'updated_at': '2016-09-26T22:47:09.000000', 'active': True, 'available': True}}, + 'show_in_tree': True, 'zone': 'calipso-zone', 'os_id': '1', + 'parent_type': 'availability_zone', 'parent_id': 'calipso-zone' +} diff --git a/app/test/event_based_scan/test_data/event_payload_instance_delete.py b/app/test/event_based_scan/test_data/event_payload_instance_delete.py new file mode 100644 index 0000000..a94de63 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_instance_delete.py @@ -0,0 +1,97 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + + +EVENT_PAYLOAD_INSTANCE_DELETE = { + 'publisher_id': 'compute.node-253.cisco.com', '_context_resource_uuid': None, + '_context_instance_lock_checked': False, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_request_id': 'req-432fccc8-4d13-4e62-8639-c99acee82cb3', + '_context_show_deleted': False, + '_context_timestamp': '2016-09-08T22:01:41.724236', + '_unique_id': '537fc5b27c244479a69819a4a435723b', + '_context_roles': ['_member_', 'admin'], '_context_read_only': False, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_project_name': 'calipso-project', + '_context_project_domain': None, 'event_type': 'compute.instance.update', + '_context_service_catalog': [{'endpoints': [ + {'internalURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volumev2', + 'name': 'cinderv2'}, + {'endpoints': [{ + 'internalURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volume', + 'name': 'cinder'}], + 'payload': {'instance_type': 'm1.micro', 'progress': '', 'display_name': 'test8', + 'kernel_id': '', + 'new_task_state': None, 'old_display_name': 'name-change', + 'state_description': '', + 'old_state': 'active', 'ramdisk_id': '', + 'created_at': '2016-09-08 16:32:46+00:00', + 'os_type': None, + 'ephemeral_gb': 0, 'launched_at': '2016-09-08T16:25:08.000000', + 'instance_flavor_id': 'f068e24b-5d7e-4819-b5ca-89a33834a918', + 'image_meta': {'min_ram': '64', 'container_format': 'bare', + 'min_disk': '0', + 'disk_format': 'qcow2', + 'base_image_ref': 'c6f490c4-3656-43c6-8d03-b4e66bd249f9'}, + 'audit_period_beginning': '2016-09-01T00:00:00.000000', 'memory_mb': 64, + 'cell_name': '', + 'access_ip_v6': None, 'instance_type_id': 6, + 'reservation_id': 'r-bycutzve', + 'access_ip_v4': None, + 'hostname': 'chengli-test-vm1', 'metadata': {}, + 'user_id': '13baa553aae44adca6615e711fd2f6d9', + 'availability_zone': 'calipso-zone', + 'instance_id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'deleted_at': '', + 'image_ref_url': 'http://172.16.0.4:9292/images/c6f490c4-3656-43c6-8d03-b4e66bd249f9', + 'host': 'node-252.cisco.com', 'vcpus': 1, 'state': 'deleted', + 'old_task_state': None, + 'architecture': None, + 'terminated_at': '', 'root_gb': 0, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'node': 'node-252.cisco.com', 'bandwidth': {}, 'disk_gb': 0, + 'audit_period_ending': '2016-09-08T22:01:43.165282'}, + '_context_quota_class': None, + '_context_is_admin': True, '_context_read_deleted': 'no', + 'timestamp': '2016-09-08 22:01:43.189907', + 'message_id': '4a9068c6-dcd1-4d6c-81d7-db866e07c1ff', 'priority': 'INFO', + '_context_domain': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_remote_address': '192.168.0.2', '_context_user_domain': None, + '_context_auth_token': '''gAAAAABX0d-R0Q4zIrznmZ_L8BT0m4r_lp-7eOr4IenbKz511g2maNo8qhIb86HtA7S + VGsEJvy4KRcNIGlVRdmGyXBYm3kEuakQXTsXLxvyQeTtgZ9UgnLLXhQvMLbA2gwaimVpyRljq92R7Y7CwnNFLjibhOiYs + NlvBqitJkaRaQa4sg4xCN2tBj32Re-jRu6dR_sIA-haT''', + '_context_user_name': 'admin'} + + +INSTANCE_DOCUMENT = { + 'projects': ['calipso-project'], + 'network': ['b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', '7e59b726-d6f4-451a-a574-c67a920ff627'], + 'host': 'node-252.cisco.com', 'parent_type': 'instances_folder', + '_id': '57e421194a0a8a3fbe3bd2d0', 'mac_address': 'fa:16:3e:5e:9e:db', 'type': 'instance', + 'name': 'test8', + 'uuid': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'environment': ENV_CONFIG, + 'ip_address': '192.168.0.4', 'local_name': 'instance-00000020', 'object_name': 'test8', + 'parent_id': 'node-252.cisco.com-instances', 'project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne/Availability Zones/calipso-zone/node-252.cisco.com/Instances/test8', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne/RegionOne-availability_zones/calipso-zone/'+ + 'node-252.cisco.com/node-252.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'show_in_tree': True} diff --git a/app/test/event_based_scan/test_data/event_payload_instance_update.py b/app/test/event_based_scan/test_data/event_payload_instance_update.py new file mode 100644 index 0000000..8b4f1af --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_instance_update.py @@ -0,0 +1,99 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + + +EVENT_PAYLOAD_INSTANCE_UPDATE = { + 'publisher_id': 'compute.node-222.cisco.com', '_context_resource_uuid': None, + '_context_instance_lock_checked': False, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_request_id': 'req-432fccc8-4d13-4e62-8639-c99acee82cb3', + '_context_show_deleted': False, + '_context_timestamp': '2016-09-08T22:01:41.724236', + '_unique_id': '537fc5b27c244479a69819a4a435723b', + '_context_roles': ['_member_', 'admin'], '_context_read_only': False, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_project_name': 'calipso-project', + '_context_project_domain': None, 'event_type': 'compute.instance.update', + '_context_service_catalog': [ + {'endpoints': [ + {'internalURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v2/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volumev2', + 'name': 'cinderv2'}, + {'endpoints': [{ + 'internalURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'publicURL': 'http://172.16.0.3:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'adminURL': 'http://192.168.0.2:8776/v1/75c0eb79ff4a42b0ae4973c8375ddf40', + 'region': 'RegionOne'}], + 'type': 'volume', + 'name': 'cinder'}], + 'payload': {'instance_type': 'm1.micro', 'progress': '', 'display_name': 'test8', + 'kernel_id': '', + 'new_task_state': None, 'old_display_name': 'name-change', + 'state_description': '', + 'old_state': 'active', 'ramdisk_id': '', + 'created_at': '2016-09-08 16:32:46+00:00', + 'os_type': None, + 'ephemeral_gb': 0, 'launched_at': '2016-09-08T16:25:08.000000', + 'instance_flavor_id': 'f068e24b-5d7e-4819-b5ca-89a33834a918', + 'image_meta': {'min_ram': '64', 'container_format': 'bare', + 'min_disk': '0', + 'disk_format': 'qcow2', + 'base_image_ref': 'c6f490c4-3656-43c6-8d03-b4e66bd249f9'}, + 'audit_period_beginning': '2016-09-01T00:00:00.000000', 'memory_mb': 64, + 'cell_name': '', + 'access_ip_v6': None, 'instance_type_id': 6, + 'reservation_id': 'r-bycutzve', + 'access_ip_v4': None, + 'hostname': 'chengli-test-vm1', 'metadata': {}, + 'user_id': '13baa553aae44adca6615e711fd2f6d9', + 'availability_zone': 'calipso-zone', + 'instance_id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'deleted_at': '', + 'image_ref_url': 'http://172.16.0.4:9292/images/c6f490c4-3656-43c6-8d03-b4e66bd249f9', + 'host': 'node-223.cisco.com', 'vcpus': 1, 'state': 'active', + 'old_task_state': None, + 'architecture': None, + 'terminated_at': '', 'root_gb': 0, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'node': 'node-223.cisco.com', 'bandwidth': {}, 'disk_gb': 0, + 'audit_period_ending': '2016-09-08T22:01:43.165282'}, + '_context_quota_class': None, + '_context_is_admin': True, '_context_read_deleted': 'no', + 'timestamp': '2016-09-08 22:01:43.189907', + 'message_id': '4a9068c6-dcd1-4d6c-81d7-db866e07c1ff', 'priority': 'INFO', + '_context_domain': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_remote_address': '192.168.0.2', '_context_user_domain': None, + '_context_auth_token': '''gAAAAABX0d-R0Q4zIrznmZ_L8BT0m4r_lp-7eOr4IenbKz511g2maNo8qhIb86HtA7S + VGsEJvy4KRcNIGlVRdmGyXBYm3kEuakQXTsXLxvyQeTtgZ9UgnLLXhQvMLbA2gwaimVpyRljq92R7Y7CwnNFLjibhOiYs + NlvBqitJkaRaQa4sg4xCN2tBj32Re-jRu6dR_sIA-haT''', + '_context_user_name': 'admin'} + + +INSTANCE_DOCUMENT = { + 'projects': ['calipso-project'], + 'network': ['b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', '7e59b726-d6f4-451a-a574-c67a920ff627'], + 'host': 'node-223.cisco.com', 'parent_type': 'instances_folder', + '_id': '57e421194a0a8a3fbe3bd2d0', 'mac_address': 'fa:16:3e:5e:9e:db', 'type': 'instance', + 'name': 'name-change', + 'uuid': '27a87908-bc1b-45cc-9238-09ad1ae686a7', 'environment': ENV_CONFIG, + 'ip_address': '192.168.0.4', 'local_name': 'instance-00000020', 'object_name': 'name-change', + 'parent_id': 'node-223.cisco.com-instances', 'project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'name_path': '/'+ENV_CONFIG+'/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-223.cisco.com/Instances/name-change', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/'+ENV_CONFIG+'/'+ENV_CONFIG+'-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'show_in_tree': True} diff --git a/app/test/event_based_scan/test_data/event_payload_interface_add.py b/app/test/event_based_scan/test_data/event_payload_interface_add.py new file mode 100644 index 0000000..263b010 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_interface_add.py @@ -0,0 +1,350 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_INTERFACE_ADD = { + '_context_timestamp': '2016-10-26 21:52:18.893134', '_context_project_name': 'calipso-project', + 'publisher_id': 'network.node-251.cisco.com', 'timestamp': '2016-10-26 21:52:22.377165', + '_context_user_name': 'admin', + '_context_roles': ['_member_', 'admin'], '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_unique_id': '44d8a3be1078455b9f73e76cdda9f67a', 'priority': 'INFO', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_user_domain': None, + '_context_show_deleted': False, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_is_admin': True, 'message_id': 'b81eb79f-f5d2-4bc8-b68e-81650cca1c92', 'payload': { + 'router_interface': {'port_id': '1233445-75b6-4c05-9480-4bc648845c6f', + 'id': 'c57216ca-c1c4-430d-a045-32851ca879e3', + 'subnet_ids': ['6f6ef3b5-76c9-4f70-81e5-f3cc196db025'], + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'subnet_id': '6f6ef3b5-76c9-4f70-81e5-f3cc196db025'}}, '_context_domain': None, + '_context_read_only': False, '_context_resource_uuid': None, 'event_type': 'router.interface.create', + '_context_request_id': 'req-260fe6fd-0e14-42de-8dbc-acd480015166', '_context_project_domain': None, + '_context_tenant_name': 'calipso-project', + '_context_auth_token': 'gAAAAABYERgkK8sR80wFsQywjt8vwG0caJW5oxfsWNURcDaYAxy0O6P0u2QQczoMuHBAZa-Ga8T1b3O-5p7p' + + 'jw-vAyI1z5whuY7i-hJSl2II6WUX2-9dy7BALQgxhCGpe60atLcyTl-rW6o_TKc3f-ppvqtiul4UTlzH9OtY' + + 'N7b-CezaywYDCIMuzGbThPARd9ilQR2B6DuE'} + +NETWORK_DOC = { + "admin_state_up": True, + "cidrs": [ + "172.16.12.0/24" + ], + "environment": ENV_CONFIG, + "id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0a" + + "e4973c8375ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2", + "last_scanned": 0, + "mtu": 0, + "name": "please_connect", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/please_connect", + "network": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "please_connect", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "calipso-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 23, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnet_ids": [ + "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + ], + "subnets": { + "1234": { + "cidr": "172.16.12.0/24", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "allocation_pools": [ + { + "start": "172.16.12.2", + "end": "172.16.12.254" + } + ], + "id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025", + "enable_dhcp": True, + "ipv6_address_mode": None, + "name": "1234", + "host_routes": [ + + ], + "ipv6_ra_mode": None, + "gateway_ip": "172.16.12.1", + "ip_version": 4, + "subnetpool_id": None, + "dns_nameservers": [ + + ], + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + }, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +} + +EVENT_PAYLOAD_REGION = { + 'RegionOne': { + 'object_name': 'RegionOne', 'id': 'RegionOne', 'name': 'RegionOne', + 'environment': ENV_CONFIG, + 'last_scanned': 0, + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne', + 'parent_id': ENV_CONFIG + '-regions', 'parent_type': 'regions_folder', + 'endpoints': {'nova': {'id': '274cbbd9fd6d4311b78e78dd3a1df51f', + 'adminURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'compute', + 'publicURL': 'http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da'}, + 'heat-cfn': {'id': '0f04ec6ed49f4940822161bf677bdfb2', + 'adminURL': 'http://192.168.0.2:8000/v1', + 'service_type': 'cloudformation', + 'publicURL': 'http://172.16.0.3:8000/v1', + 'internalURL': 'http://192.168.0.2:8000/v1'}, + 'nova_ec2': {'id': '390dddc753cc4d378b489129d06c4b7d', + 'adminURL': 'http://192.168.0.2:8773/services/Admin', + 'service_type': 'ec2', + 'publicURL': 'http://172.16.0.3:8773/services/Cloud', + 'internalURL': 'http://192.168.0.2:8773/services/Cloud'}, + 'glance': {'id': '475c6c77a94e4e63a5a0f0e767f697a8', + 'adminURL': 'http://192.168.0.2:9292', + 'service_type': 'image', + 'publicURL': 'http://172.16.0.3:9292', + 'internalURL': 'http://192.168.0.2:9292'}, + 'swift': {'id': '12e78e06595f48339baebdb5d4309c70', + 'adminURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'service_type': 'object-store', + 'publicURL': 'http://172.16.0.3:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da'}, + 'swift_s3': {'id': '4f655c8f2bef46a0a7ba4a20bba53666', + 'adminURL': 'http://192.168.0.2:8080', + 'service_type': 's3', + 'publicURL': 'http://172.16.0.3:8080', + 'internalURL': 'http://192.168.0.2:8080'}, + 'keystone': {'id': '404cceb349614eb39857742970408301', + 'adminURL': 'http://192.168.0.2:35357/v2.0', + 'service_type': 'identity', + 'publicURL': 'http://172.16.0.3:5000/v2.0', + 'internalURL': 'http://192.168.0.2:5000/v2.0'}, + 'cinderv2': {'id': '2c30937688e944889db4a64fab6816e6', + 'adminURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volumev2', + 'publicURL': 'http://172.16.0.3:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da'}, + 'novav3': {'id': '1df917160dfb4ce5b469764fde22b3ab', + 'adminURL': 'http://192.168.0.2:8774/v3', + 'service_type': 'computev3', + 'publicURL': 'http://172.16.0.3:8774/v3', + 'internalURL': 'http://192.168.0.2:8774/v3'}, + 'ceilometer': {'id': '617177a3dcb64560a5a79ab0a91a7225', + 'adminURL': 'http://192.168.0.2:8777', + 'service_type': 'metering', + 'publicURL': 'http://172.16.0.3:8777', + 'internalURL': 'http://192.168.0.2:8777'}, + 'neutron': {'id': '8dc28584da224c4b9671171ead3c982a', + 'adminURL': 'http://192.168.0.2:9696', + 'service_type': 'network', + 'publicURL': 'http://172.16.0.3:9696', + 'internalURL': 'http://192.168.0.2:9696'}, + 'cinder': {'id': '05643f2cf9094265b432376571851841', + 'adminURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volume', + 'publicURL': 'http://172.16.0.3:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da'}, + 'heat': {'id': '9e60268a5aaf422d9e42f0caab0a19b4', + 'adminURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'orchestration', + 'publicURL': 'http://172.16.0.3:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da'}}, + 'show_in_tree': True, + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne', + 'type': 'region'}} + +PORT_DOC = { + "admin_state_up": True, + "allowed_address_pairs": [ + + ], + "binding:host_id": "", + "binding:profile": { + + }, + "binding:vif_details": { + + }, + "binding:vif_type": "unbound", + "binding:vnic_type": "normal", + "device_id": "c57216ca-c1c4-430d-a045-32851ca879e3", + "device_owner": "network:router_interface", + "dns_assignment": [ + { + "hostname": "host-172-16-10-1", + "ip_address": "172.16.10.1", + "fqdn": "host-172-16-10-1.openstacklocal." + } + ], + "dns_name": "", + "environment": ENV_CONFIG, + "extra_dhcp_opts": [ + + ], + "fixed_ips": [ + { + "ip_address": "172.16.10.1", + "subnet_id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + } + ], + "id": "1233445-75b6-4c05-9480-4bc648845c6f", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0a" + + "e4973c8375ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2/55550a69-24eb-47f5-a458-3aa086cc71c2" + + "-ports/1233445-75b6-4c05-9480-4bc648845c6f", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "master_parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "master_parent_type": "network", + "name": "fa:16:3e:13:b2:aa", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/test_interface/Ports" + + "/1233445-75b6-4c05-9480-4bc648845c6f", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "1233445-75b6-4c05-9480-4bc648845c6f", + "parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2-ports", + "parent_text": "Ports", + "parent_type": "ports_folder", + "port_security_enabled": False, + "project": "calipso-project", + "security_groups": [ + + ], + "status": "DOWN", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "port" +} + +ROUTER_DOCUMENT = { + "admin_state_up": True, + "enable_snat": 1, + "environment": ENV_CONFIG, + "gw_port_id": "e2f31c24-d0f9-499e-a8b1-883941543aa4", + "host": "node-251.cisco.com", + "id": "node-251.cisco.com-qrouter-c57216ca-c1c4-430d-a045-32851ca879e3", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-routers/node-251.cisco.com-qrouter-bde87" + + "a5a-7968-4f3b-952c-e87681a96078", + "last_scanned": 0, + "local_service_id": "node-251.cisco.com-qrouter-c57216ca-c1c4-430d-a045-32851ca879e3", + "master_parent_id": "node-251.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "1234", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/Gateways/router-1234", + "network": [ + "55550a69-24eb-47f5-a458-3aa086cc71c2" + ], + "object_name": "router-1234", + "parent_id": "node-251.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "vservice" +} + +HOST = { + "config": { + "use_namespaces": True, + "handle_internal_only_routers": True, + "ex_gw_ports": 2, + "agent_mode": "legacy", + "log_agent_heartbeats": False, + "floating_ips": 1, + "external_network_bridge": "", + "router_id": "", + "gateway_external_network_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "routers": 2, + "interfaces": 4 + }, + "environment": ENV_CONFIG, + "host": "node-251.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-251.cisco.com", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/internal/node-251.cisco.com", + "last_scanned": 0, + "name": "node-251.cisco.com", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com", + "object_name": "node-251.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-conductor": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:08.000000" + }, + "nova-scheduler": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:38.000000" + }, + "nova-cert": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:29.000000" + }, + "nova-consoleauth": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:37.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +VNIC_DOCS = [{ + "IP Address": "172.16.10.2", + "IPv6 Address": "fe80::f816:3eff:fe96:5066/64", + "cidr": "172.16.10.0/25", + "data": "Link encap:Ethernet HWaddr fa:16:3e:96:50:66\ninet addr:172.16.10.2 Bcast:172.16.10.127 " + + "Mask:255.255.255.128\ninet6 addr: fe80::f816:3eff:fe96:5066/64 Scope:Link\nUP BROADCAST RUNNING " + + "MULTICAST MTU:1450 Metric:1\nRX packets:17 errors:0 dropped:2 overruns:0 frame:0\nTX packets:8 " + + "errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:1593 " + + "(1.5 KB) TX bytes:648 (648.0 B)\n", + "environment": ENV_CONFIG, + "host": "node-251.cisco.com", + "id": "tapca33c645-5b", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-dhcps/qdhcp-911fe57e" + + "-1ddd-4151-9dc7-6b578ab357b1/qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics/tapca33c645-5b", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "name": "tapca33c645-5b", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/DHCP servers/dhcp-test_interface/vNICs/tapca33c645-5b", + "netmask": "255.255.255.128", + "network": "911fe57e-1ddd-4151-9dc7-6b578ab357b1", + "object_name": "tapca33c645-5b", + "parent_id": "qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "show_in_tree": True, + "type": "vnic", + "vnic_type": "vservice_vnic" +}] diff --git a/app/test/event_based_scan/test_data/event_payload_interface_delete.py b/app/test/event_based_scan/test_data/event_payload_interface_delete.py new file mode 100644 index 0000000..5dbed2c --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_interface_delete.py @@ -0,0 +1,350 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_INTERFACE_DELETE = { + 'message_id': 'da190e5f-127d-4e85-a813-bbdbbb35a2d0', '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_user_domain': None, '_context_resource_uuid': None, '_context_timestamp': '2016-11-07 23:41:04.169781', + '_unique_id': 'a4c4ef7a07c9431299047a59d4e0730c', 'event_type': 'router.interface.delete', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_request_id': 'req-e7d61486-2c0a-40cd-b346-1ec884b0e8d0', '_context_is_admin': True, + '_context_project_name': 'calipso-project', 'timestamp': '2016-11-07 23:41:09.769453', + '_context_auth_token': 'gAAAAABYIQ_M00kY8hGiB6zsD8BWn7b5x0aKIEv1HHQ3Ty0t5MAK68Lm7E6E0pDgJVqBSQsqZsNDqQkn4M0spYlz' + + 'WPTEdl3L4d-7ihNmWGOE76J4EtP9tl6nw22ZzdUhu4V8dVB5dqC3lhf61Ot9OsU7XRjp2zfVTb_Ip2yI2_auqUWZ' + + 'f6ryWdFPUZqbpJ3-jrVpUP1iXxlT', + '_context_roles': ['_member_', 'admin'], '_context_domain': None, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_project_domain': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_user_name': 'admin', + 'publisher_id': 'network.node-251.cisco.com', '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_tenant_name': 'calipso-project', 'priority': 'INFO', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_show_deleted': False, + 'payload': {'router_interface': {'port_id': '1233445-75b6-4c05-9480-4bc648845c6f', + 'id': 'c57216ca-c1c4-430d-a045-32851ca879e3', + 'subnet_ids': ['6f6ef3b5-76c9-4f70-81e5-f3cc196db025'], + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'subnet_id': '6f6ef3b5-76c9-4f70-81e5-f3cc196db025'}}, + '_context_read_only': False} + +NETWORK_DOC = { + "admin_state_up": True, + "cidrs": [ + "172.16.12.0/24" + ], + "environment": ENV_CONFIG, + "id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0ae49" + + "73c8375ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2", + "last_scanned": 0, + "mtu": 0, + "name": "please_connect", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/please_connect", + "network": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "please_connect", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "calipso-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 23, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnet_ids": [ + "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + ], + "subnets": { + "1234": { + "cidr": "172.16.12.0/24", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "allocation_pools": [ + { + "start": "172.16.12.2", + "end": "172.16.12.254" + } + ], + "id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025", + "enable_dhcp": True, + "ipv6_address_mode": None, + "name": "1234", + "host_routes": [ + + ], + "ipv6_ra_mode": None, + "gateway_ip": "172.16.12.1", + "ip_version": 4, + "subnetpool_id": None, + "dns_nameservers": [ + + ], + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + }, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +} + +EVENT_PAYLOAD_REGION = { + 'RegionOne': { + 'object_name': 'RegionOne', 'id': 'RegionOne', 'name': 'RegionOne', + 'environment': ENV_CONFIG, + 'last_scanned': 0, + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne', + 'parent_id': ENV_CONFIG + '-regions', 'parent_type': 'regions_folder', + 'endpoints': {'nova': {'id': '274cbbd9fd6d4311b78e78dd3a1df51f', + 'adminURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'compute', + 'publicURL': 'http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da'}, + 'heat-cfn': {'id': '0f04ec6ed49f4940822161bf677bdfb2', + 'adminURL': 'http://192.168.0.2:8000/v1', + 'service_type': 'cloudformation', + 'publicURL': 'http://172.16.0.3:8000/v1', + 'internalURL': 'http://192.168.0.2:8000/v1'}, + 'nova_ec2': {'id': '390dddc753cc4d378b489129d06c4b7d', + 'adminURL': 'http://192.168.0.2:8773/services/Admin', + 'service_type': 'ec2', + 'publicURL': 'http://172.16.0.3:8773/services/Cloud', + 'internalURL': 'http://192.168.0.2:8773/services/Cloud'}, + 'glance': {'id': '475c6c77a94e4e63a5a0f0e767f697a8', + 'adminURL': 'http://192.168.0.2:9292', + 'service_type': 'image', + 'publicURL': 'http://172.16.0.3:9292', + 'internalURL': 'http://192.168.0.2:9292'}, + 'swift': {'id': '12e78e06595f48339baebdb5d4309c70', + 'adminURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'service_type': 'object-store', + 'publicURL': 'http://172.16.0.3:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da'}, + 'swift_s3': {'id': '4f655c8f2bef46a0a7ba4a20bba53666', + 'adminURL': 'http://192.168.0.2:8080', + 'service_type': 's3', + 'publicURL': 'http://172.16.0.3:8080', + 'internalURL': 'http://192.168.0.2:8080'}, + 'keystone': {'id': '404cceb349614eb39857742970408301', + 'adminURL': 'http://192.168.0.2:35357/v2.0', + 'service_type': 'identity', + 'publicURL': 'http://172.16.0.3:5000/v2.0', + 'internalURL': 'http://192.168.0.2:5000/v2.0'}, + 'cinderv2': {'id': '2c30937688e944889db4a64fab6816e6', + 'adminURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volumev2', + 'publicURL': 'http://172.16.0.3:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da'}, + 'novav3': {'id': '1df917160dfb4ce5b469764fde22b3ab', + 'adminURL': 'http://192.168.0.2:8774/v3', + 'service_type': 'computev3', + 'publicURL': 'http://172.16.0.3:8774/v3', + 'internalURL': 'http://192.168.0.2:8774/v3'}, + 'ceilometer': {'id': '617177a3dcb64560a5a79ab0a91a7225', + 'adminURL': 'http://192.168.0.2:8777', + 'service_type': 'metering', + 'publicURL': 'http://172.16.0.3:8777', + 'internalURL': 'http://192.168.0.2:8777'}, + 'neutron': {'id': '8dc28584da224c4b9671171ead3c982a', + 'adminURL': 'http://192.168.0.2:9696', + 'service_type': 'network', + 'publicURL': 'http://172.16.0.3:9696', + 'internalURL': 'http://192.168.0.2:9696'}, + 'cinder': {'id': '05643f2cf9094265b432376571851841', + 'adminURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volume', + 'publicURL': 'http://172.16.0.3:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da'}, + 'heat': {'id': '9e60268a5aaf422d9e42f0caab0a19b4', + 'adminURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'orchestration', + 'publicURL': 'http://172.16.0.3:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da'}}, + 'show_in_tree': True, + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne', + 'type': 'region'}} + +PORT_DOC = { + "admin_state_up": True, + "allowed_address_pairs": [ + + ], + "binding:host_id": "", + "binding:profile": { + + }, + "binding:vif_details": { + + }, + "binding:vif_type": "unbound", + "binding:vnic_type": "normal", + "device_id": "c57216ca-c1c4-430d-a045-32851ca879e3", + "device_owner": "network:router_interface", + "dns_assignment": [ + { + "hostname": "host-172-16-10-1", + "ip_address": "172.16.10.1", + "fqdn": "host-172-16-10-1.openstacklocal." + } + ], + "dns_name": "", + "environment": ENV_CONFIG, + "extra_dhcp_opts": [ + + ], + "fixed_ips": [ + { + "ip_address": "172.16.10.1", + "subnet_id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + } + ], + "id": "1233445-75b6-4c05-9480-4bc648845c6f", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "+/-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb" + + "79ff4a42b0ae4973c8375ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2/55550a69-24eb-" + + "47f5-a458-3aa086cc71c2-ports/1233445-75b6-4c05-9480-4bc648845c6f", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "master_parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "master_parent_type": "network", + "name": "fa:16:3e:13:b2:aa", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/test_interface/Ports/" + + "1233445-75b6-4c05-9480-4bc648845c6f", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "1233445-75b6-4c05-9480-4bc648845c6f", + "parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2-ports", + "parent_text": "Ports", + "parent_type": "ports_folder", + "port_security_enabled": False, + "project": "calipso-project", + "security_groups": [ + + ], + "status": "DOWN", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "port" +} + +ROUTER_DOCUMENT = { + "admin_state_up": True, + "enable_snat": 1, + "environment": ENV_CONFIG, + "gw_port_id": "e2f31c24-d0f9-499e-a8b1-883941543aa4", + "host": "node-251.cisco.com", + "id": "node-251.cisco.com-qrouter-c57216ca-c1c4-430d-a045-32851ca879e3", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-routers/node-251.cisco.com-qrouter-bde8" + + "7a5a-7968-4f3b-952c-e87681a96078", + "last_scanned": 0, + "local_service_id": "node-251.cisco.com-qrouter-c57216ca-c1c4-430d-a045-32851ca879e3", + "master_parent_id": "node-251.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "1234", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/Gateways/router-1234", + "network": [ + "55550a69-24eb-47f5-a458-3aa086cc71c2" + ], + "object_name": "router-1234", + "parent_id": "node-251.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "vservice" +} + +HOST = { + "config": { + "use_namespaces": True, + "handle_internal_only_routers": True, + "ex_gw_ports": 2, + "agent_mode": "legacy", + "log_agent_heartbeats": False, + "floating_ips": 1, + "external_network_bridge": "", + "router_id": "", + "gateway_external_network_id": "", + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "routers": 2, + "interfaces": 4 + }, + "environment": ENV_CONFIG, + "host": "node-251.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-251.cisco.com", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/internal/node-251.cisco.com", + "last_scanned": 0, + "name": "node-251.cisco.com", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com", + "object_name": "node-251.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-conductor": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:08.000000" + }, + "nova-scheduler": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:38.000000" + }, + "nova-cert": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:29.000000" + }, + "nova-consoleauth": { + "available": True, + "active": True, + "updated_at": "2016-11-08T19:12:37.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +VNIC_DOCS = [{ + "IP Address": "172.16.10.2", + "IPv6 Address": "fe80::f816:3eff:fe96:5066/64", + "cidr": "172.16.10.0/25", + "data": "Link encap:Ethernet HWaddr fa:16:3e:96:50:66\ninet addr:172.16.10.2 Bcast:172.16.10.127 " + + "Mask:255.255.255.128\ninet6 addr: fe80::f816:3eff:fe96:5066/64 Scope:Link\nUP BROADCAST RUNNING " + + "MULTICAST MTU:1450 Metric:1\nRX packets:17 errors:0 dropped:2 overruns:0 frame:0\nTX packets:8 " + + "errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:1593 " + + "(1.5 KB) TX bytes:648 (648.0 B)\n", + "environment": ENV_CONFIG, + "host": "node-251.cisco.com", + "id": "tapca33c645-5b", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-dhcps/qdhcp-911fe57e" + + "-1ddd-4151-9dc7-6b578ab357b1/qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics/tapca33c645-5b", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "name": "tapca33c645-5b", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/DHCP servers/dhcp-test_interface/vNICs/tapca33c645-5b", + "netmask": "255.255.255.128", + "network": "911fe57e-1ddd-4151-9dc7-6b578ab357b1", + "object_name": "tapca33c645-5b", + "parent_id": "qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "show_in_tree": True, + "type": "vnic", + "vnic_type": "vservice_vnic" +}] diff --git a/app/test/event_based_scan/test_data/event_payload_network_add.py b/app/test/event_based_scan/test_data/event_payload_network_add.py new file mode 100644 index 0000000..9630965 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_network_add.py @@ -0,0 +1,32 @@ +############################################################################### +# 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 # +############################################################################### +EVENT_PAYLOAD_NETWORK_ADD = { + '_context_request_id': 'req-d8593c49-8424-459b-9ac1-1fd8667310eb', '_context_project_domain': None, + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_project_name': 'calipso-project', + '_context_show_deleted': False, '_context_timestamp': '2016-09-30 17:45:01.738932', '_context_domain': None, + '_context_roles': ['_member_', 'admin'], '_context_is_admin': True, 'priority': 'INFO', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + 'message_id': '093e1ee0-87a7-4d40-9303-68d5eaf11f71', '_context_read_only': False, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_unique_id': '3dc7690856e14066902d861631236297', '_context_resource_uuid': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_user_domain': None, + 'event_type': 'network.create.end', '_context_user_name': 'admin', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_auth_token': 'gAAAAABX7qQJkXEm4q2dRrVg4gjxYZ4iKWOFdkA4IVWXpDOiDtu_nwtAeSpTP3W0sEJiTjQXgxqCXrhCzi5cZ1edo6' + + 'DqEhND8TTtCqknIMwXcGGonUV0TkhKDOEnOgJhQLiV6JG-CtI4x0VnAp6muwankIGNChndH-gP0lw3bdIK29' + + 'aqDS4obeXGsYA3oLoORLubgPQjUpdO', + 'publisher_id': 'network.node-6.cisco.com', 'timestamp': '2016-09-30 17:45:02.125633', + '_context_tenant_name': 'calipso-project', + 'payload': { + 'network': {'provider:physical_network': None, 'router:external': False, 'shared': False, + 'id': 'a8226605-40d0-4111-93bd-11ffa5b2d1d7', 'provider:network_type': 'vxlan', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'mtu': 1400, 'subnets': [], 'status': 'ACTIVE', + 'provider:segmentation_id': 8, 'port_security_enabled': True, 'name': 'calipso-network-add', + 'admin_state_up': True}}} diff --git a/app/test/event_based_scan/test_data/event_payload_network_delete.py b/app/test/event_based_scan/test_data/event_payload_network_delete.py new file mode 100644 index 0000000..6884dd6 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_network_delete.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 # +############################################################################### +from test.event_based_scan.config.test_config import ENV_CONFIG + + +EVENT_PAYLOAD_NETWORK_DELETE = { + 'event_type': 'network.delete.end', 'priority': 'INFO', '_context_tenant_name': 'calipso-project', + '_context_domain': None, '_context_show_deleted': False, '_unique_id': 'e6f3a44575dd45ea891ec527335a55d7', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_read_only': False, '_context_timestamp': '2016-10-13 23:48:29.632205', '_context_project_domain': None, + '_context_roles': ['_member_', 'admin'], '_context_user_domain': None, + '_context_request_id': 'req-21307ef4-f4f7-4e8e-afaf-75dd04d71463', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'payload': {'network_id': '0bb0ba6c-6863-4121-ac89-93f81a9da2b0'}, '_context_user_name': 'admin', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_is_admin': True, + '_context_resource_uuid': None, + 'timestamp': '2016-10-13 23:48:31.609788', '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'message_id': '7b78b897-7a82-4aab-82a5-b1c431535dce', '_context_project_name': 'calipso-project', + '_context_auth_token': 'gAAAAABYAB0cVTm6fzL1S2q2lskw3z7FiEslh_amLhDmDEwQsm3M7L4omSjZ5qKacvgFTXS0HtpbCQfkZn8' + + 'BQK80qfbzaQdh05tW1gnboB_FR7vfsUZ1yKUzpDdAgfStDzj_SMWK6FGyZperukjp7Xhmxh91O6cxFvG1' + + '0qZmxwtJoKyuW0pCM1593rTsj1Lh6zOIo2iaoC1a', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', 'publisher_id': 'network.node-6.cisco.com'} + + +EVENT_PAYLOAD_NETWORK = { + "admin_state_up" : True, + "cidrs" : [ + "172.16.9.0/24" + ], + "environment" : ENV_CONFIG, + "id" : '0bb0ba6c-6863-4121-ac89-93f81a9da2b0', + "id_path" : '/%s/%s-projects/' % (ENV_CONFIG, ENV_CONFIG) +'75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b' + + '0ae4973c8375ddf40-networks/0bb0ba6c-6863-4121-ac89-93f81a9da2b0' , + "last_scanned" : 0, + "mtu" : 1400, + "name" : "testnetwork", + "name_path" : "/"+ENV_CONFIG+"/Projects/calipso-project/Networks/testnetwork", + "network" : "0bb0ba6c-6863-4121-ac89-93f81a9da2b0", + "object_name" : "testnetwork", + "parent_id" : "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text" : "Networks", + "parent_type" : "networks_folder", + "port_security_enabled" : True, + "project" : "calipso-project", + "provider:network_type" : "vxlan", + "provider:physical_network" : None, + "provider:segmentation_id" : 107, + "router:external" : False, + "shared" : False, + "show_in_tree" : True, + "status" : "ACTIVE", + "subnets" : { + "testabc" : { + "dns_nameservers" : [ + + ], + "enable_dhcp" : False, + "host_routes" : [ + + ], + "cidr" : "172.16.9.0/24", + "ip_version" : 4, + "id" : "7a1be27e-4aae-43ef-b3c0-7231a41625b8", + "subnetpool_id" : None, + "ipv6_ra_mode" : None, + "ipv6_address_mode" : None, + "network_id" : "0bb0ba6c-6863-4121-ac89-93f81a9da2b0", + "tenant_id" : "75c0eb79ff4a42b0ae4973c8375ddf40", + "name" : "testabc", + "allocation_pools" : [ + { + "end" : "172.16.9.254", + "start" : "172.16.9.2" + } + ], + "gateway_ip" : "172.16.9.1" + } + }, + "tenant_id" : "75c0eb79ff4a42b0ae4973c8375ddf40", + "type" : "network" +}
\ No newline at end of file diff --git a/app/test/event_based_scan/test_data/event_payload_network_update.py b/app/test/event_based_scan/test_data/event_payload_network_update.py new file mode 100644 index 0000000..3485cd1 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_network_update.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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_NETWORK_UPDATE = { + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + 'priority': 'INFO', + '_context_auth_token': 'gAAAAABYBrNJA6Io1infkUKquvCpC1bAWOCRxKE-8YQ71qLJhli200beztKmlY5ToBHSqFyPvoadkVKjA740jF' + + 'bqeY-YtezMHhJAe-t_VyRJQ46IWAv8nPYvWRd_lmgtHrvBeId8NIPCZkhoAEmj5GwcZUZgnFYEhVlUliNO6IfV' + + 'Oxcb17Z_1MKfdrfu1AtgD5hWb61w1F6x', + '_context_user_name': 'admin', '_context_project_name': 'calipso-project', '_context_domain': None, + '_unique_id': 'd1a96723db9341dca6f0d5fb9620f548', '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'message_id': '6b99d060-9cd6-4c14-8a0a-cbfc5c50d122', 'timestamp': '2016-10-18 23:47:31.636433', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_resource_uuid': None, '_context_request_id': 'req-b33cbd49-7af9-4c64-bcfb-782fcd400a5e', + 'publisher_id': 'network.node-6.cisco.com', 'payload': { + 'network': {'provider:network_type': 'vxlan', 'port_security_enabled': True, 'status': 'ACTIVE', + 'id': '8673c48a-f137-4497-b25d-08b7b218fd17', 'shared': False, 'router:external': False, + 'subnets': ['fcfa62ec-5ae7-46ce-9259-5f30de7af858'], 'admin_state_up': True, + 'provider:segmentation_id': 52, 'provider:physical_network': None, 'name': '24', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'mtu': 1400}}, 'event_type': 'network.update.end', + '_context_roles': ['_member_', 'admin'], '_context_project_domain': None, '_context_is_admin': True, + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_show_deleted': False, '_context_user_domain': None, + '_context_read_only': False, '_context_timestamp': '2016-10-18 23:47:20.629297', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_tenant_name': 'calipso-project'} + + +NETWORK_DOCUMENT = { + "admin_state_up" : True, + "cidrs" : [ + "172.16.4.0/24" + ], + "environment" : ENV_CONFIG, + "id" : "8673c48a-f137-4497-b25d-08b7b218fd17", + "id_path" : '/%s/%s-projects/' % (ENV_CONFIG, ENV_CONFIG) +'75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b' + + '0ae4973c8375ddf40-networks/8673c48a-f137-4497-b25d-08b7b218fd17', + "last_scanned" : 0, + "mtu" : 1400, + "name" : "calipso-met4", + "name_path" : "/"+ENV_CONFIG+"/Projects/calipso-project/Networks/calipso-met4", + "network" : "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "object_name" : "calipso-met4", + "parent_id" : "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text" : "Networks", + "parent_type" : "networks_folder", + "port_security_enabled" : True, + "project" : "calipso-project", + "provider:network_type" : "vxlan", + "provider:physical_network" : None, + "provider:segmentation_id" : 0, + "router:external" : False, + "shared" : False, + "show_in_tree" : True, + "status" : "ACTIVE", + "subnets" : {}, + "tenant_id" : "75c0eb79ff4a42b0ae4973c8375ddf40", + "type" : "network" +}
\ No newline at end of file diff --git a/app/test/event_based_scan/test_data/event_payload_port_add.py b/app/test/event_based_scan/test_data/event_payload_port_add.py new file mode 100644 index 0000000..92f6d2f --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_port_add.py @@ -0,0 +1,314 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_PORT_INSTANCE_ADD = { + '_context_user_id': '73638a2687534f9794cd8057ba860637', 'payload': { + 'port': {'port_security_enabled': True, 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'binding:vif_type': 'ovs', + 'mac_address': 'fa:16:3e:04:cd:ab', + 'fixed_ips': [{'subnet_id': '9a9c1848-ea23-4c5d-8c40-ae1def4c2de3', 'ip_address': '172.16.13.6'}], + 'security_groups': ['2dd5c169-1ff7-40e5-ad96-18924b6d23f1'], 'allowed_address_pairs': [], + 'binding:host_id': 'node-223.cisco.com', 'dns_name': '', 'status': 'DOWN', + 'id': '1233445-75b6-4c05-9480-4bc648845c6f', 'binding:profile': {}, 'admin_state_up': True, + 'device_owner': 'compute:calipso-zone', 'device_id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'network_id': '55550a69-24eb-47f5-a458-3aa086cc71c2', 'name': '', + 'binding:vif_details': {'ovs_hybrid_plug': True, 'port_filter': True}, 'extra_dhcp_opts': [], + 'binding:vnic_type': 'normal'}}, '_context_project_domain': None, 'event_type': 'port.create.end', + 'message_id': '2e0da8dc-6d2d-4bde-9e52-c43ec4687864', 'publisher_id': 'network.node-6.cisco.com', + '_context_domain': None, '_context_tenant_name': 'services', '_context_tenant': 'a83c8b0d2df24170a7c54f09f824230e', + '_context_project_name': 'services', '_context_user': '73638a2687534f9794cd8057ba860637', + '_context_user_name': 'neutron', 'priority': 'INFO', '_context_timestamp': '2016-10-24 21:29:52.127098', + '_context_read_only': False, '_context_roles': ['admin'], '_context_is_admin': True, '_context_show_deleted': False, + '_context_user_domain': None, + '_context_auth_token': 'gAAAAABYDnRG3mhPMwyF17iUiIT4nYjtcSktNmmCKlMrUtmpHYsJWl44xU-boIaf4ChWcBsTjl6jOk6Msu7l17As' + + '1Y9vFc1rlmKMl86Eknqp0P22RV_Xr6SIobsl6Axl2Z_w-AB1cZ4pSsY4uscxeJdVkoxRb0aC9B7gllrvAgrfO9O' + + 'GDqw2ILA', + '_context_tenant_id': 'a83c8b0d2df24170a7c54f09f824230e', '_context_resource_uuid': None, + '_context_request_id': 'req-3d6810d9-bee9-41b5-a224-7e9641689cc8', '_unique_id': 'b4f1ffae88b342c09658d9ed2829670c', + 'timestamp': '2016-10-24 21:29:56.383789', '_context_project_id': 'a83c8b0d2df24170a7c54f09f824230e', + '_context_user_identity': '73638a2687534f9794cd8057ba860637 a83c8b0d2df24170a7c54f09f824230e - - -'} + +NETWORK_DOC = { + "admin_state_up": True, + "cidrs": [ + "172.16.12.0/24" + ], + "environment": ENV_CONFIG, + "id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0ae" + + "4973c8375ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2", + "last_scanned": 0, + "mtu": 0, + "name": "please_connect", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/please_connect", + "network": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "please_connect", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "calipso-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 23, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnet_ids": [ + "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + ], + "subnets": { + "1234": { + "cidr": "172.16.12.0/24", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "allocation_pools": [ + { + "start": "172.16.12.2", + "end": "172.16.12.254" + } + ], + "id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025", + "enable_dhcp": True, + "ipv6_address_mode": None, + "name": "1234", + "host_routes": [ + + ], + "ipv6_ra_mode": None, + "gateway_ip": "172.16.12.1", + "ip_version": 4, + "subnetpool_id": None, + "dns_nameservers": [ + + ], + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40" + } + }, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +} + +INSTANCE_DOC = { + "environment": ENV_CONFIG, + "id": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "type": "instance", + "uuid": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "network": [ + "a09455d9-399a-4193-9cb4-95e9d8e9a560" + ], + "local_name": "instance-00000002", + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-223.cisco.com/Instances/name-change', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + "name": "name-change", + "network_info": [ + { + "qbg_params": None, + "id": "1233445-75b6-4c05-9480-4bc648845c6f", + "network": { + "bridge": "br-int", + "meta": { + "injected": False, + "tenant_id": "a3efb05cd0484bf0b600e45dab09276d" + }, + "id": "a09455d9-399a-4193-9cb4-95e9d8e9a560", + "subnets": [ + { + "gateway": { + "meta": { + + }, + "type": "gateway", + "version": 4, + "address": "172.16.50.254" + }, + "version": 4, + "dns": [ + + ], + "cidr": "172.16.50.0/24", + "routes": [ + + ], + "meta": { + "dhcp_server": "172.16.50.1" + }, + "ips": [ + { + "floating_ips": [ + + ], + "meta": { + + }, + "type": "fixed", + "version": 4, + "address": "172.16.50.3" + } + ] + } + ], + "label": "calipso-network" + }, + "active": True, + "address": "fa:16:3e:04:cd:ab", + "vnic_type": "normal", + "meta": { + }, + "ovs_interfaceid": "1233445-75b6-4c05-9480-4bc648845c6f", + "type": "ovs", + "devname": "tapa9a8fa24-11", + } + ], + "host": "node-223.cisco.com", + "project_id": "a3efb05cd0484bf0b600e45dab09276d", + "object_name": "libertyDD", + "parent_id": "node-223.cisco.com-instances", + "parent_type": "instances_folder", + "projects": [ + "project-calipso" + ], + "mac_address": "fa:16:3e:04:cd:ab" +} + +INSTANCES_ROOT = { + "create_object": True, + "environment": ENV_CONFIG, + "id": "node-223.cisco.com-instances", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/calipso-zone/node-223.cisco.com/node-223.cisco.com-instances", + "name": "Instances", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/calipso-zone/node-223.cisco.com/Instances", + "object_name": "Instances", + "parent_id": "node-223.cisco.com", + "parent_type": "host", + "show_in_tree": True, + "text": "Instances", + "type": "instances_folder" +} + +INSTANCE_DOCS = [ + { + "environment": ENV_CONFIG, + "type": "instance", + "uuid": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "network": [ + "a09455d9-399a-4193-9cb4-95e9d8e9a560" + ], + "local_name": "instance-00000002", + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-223.cisco.com/Instances/name-change', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + "name": "name-change", + "network_info": [ + { + "qbg_params": None, + "id": "2233445-75b6-4c05-9480-4bc648845c6f", + "network": { + "bridge": "br-int", + "meta": { + "injected": False, + "tenant_id": "a3efb05cd0484bf0b600e45dab09276d" + }, + "id": "a09455d9-399a-4193-9cb4-95e9d8e9a560", + "subnets": [ + { + "gateway": { + "meta": { + + }, + "type": "gateway", + "version": 4, + "address": "172.16.50.254" + }, + "version": 4, + "dns": [ + + ], + "cidr": "172.16.50.0/24", + "routes": [ + + ], + "meta": { + "dhcp_server": "172.16.50.1" + }, + "ips": [ + { + "floating_ips": [ + + ], + "meta": { + + }, + "type": "fixed", + "version": 4, + "address": "172.16.50.3" + } + ] + } + ], + "label": "calipso-network" + }, + "active": True, + "address": "fa:16:3e:04:cd:ab", + "vnic_type": "normal", + "meta": { + }, + "ovs_interfaceid": "2233445-75b6-4c05-9480-4bc648845c6f", + "type": "ovs", + "devname": "tapa9a8fa24-12", + } + ], + "host": "node-223.cisco.com", + "project_id": "a3efb05cd0484bf0b600e45dab09276d", + "object_name": "libertyDD", + "parent_id": "node-223.cisco.com-instances", + "parent_type": "instances_folder", + "projects": [ + "project-calipso" + ], + "mac_address": "fa:16:3e:04:cd:ab" + } +] + +VNIC_DOCS = [{ + "IP Address": "172.16.10.2", + "IPv6 Address": "fe80::f816:3eff:fe96:5066/64", + "cidr": "172.16.10.0/25", + "data": "Link encap:Ethernet HWaddr fa:16:3e:96:50:66\ninet addr:172.16.10.2 Bcast:172.16.10.127 " + + "Mask:255.255.255.128\ninet6 addr: fe80::f816:3eff:fe96:5066/64 Scope:Link\nUP BROADCAST RUNNING " + + "MULTICAST MTU:1450 Metric:1\nRX packets:17 errors:0 dropped:2 overruns:0 frame:0\nTX packets:8 " + + "errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:1593 " + + "(1.5 KB) TX bytes:648 (648.0 B)\n", + "host": "node-251.cisco.com", + "id": "tapca33c645-5b", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-dhcps/qdhcp-911fe57e" + + "-1ddd-4151-9dc7-6b578ab357b1/qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics/tapca33c645-5b", + "last_scanned": 0, + "mac_address": "fa:16:3e:04:cd:ab", + "name": "tapca33c645-5b", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/DHCP servers/dhcp-test_interface/vNICs/tapca33c645-5b", + "netmask": "255.255.255.128", + "network": "911fe57e-1ddd-4151-9dc7-6b578ab357b1", + "object_name": "tapca33c645-5b", + "parent_id": "qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "show_in_tree": True, + "vnic_type": "instance_vnic" +}] diff --git a/app/test/event_based_scan/test_data/event_payload_port_delete.py b/app/test/event_based_scan/test_data/event_payload_port_delete.py new file mode 100644 index 0000000..afbba32 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_port_delete.py @@ -0,0 +1,290 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_PORT_DELETE = { + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_tenant_name': 'calipso-project', + '_context_project_name': 'calipso-project', '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_auth_token': 'gAAAAABYIR4eeMzyZ6IWHjWSK9kmr-p4hxRhm5LtDp--kiu5v5MzpnShwkZAbFTkIBR0fC2iaBurXlAvI0pE' + + 'myBRpAuxWFsM5rbsiFlo_qpuo_dqIGe6_R7J-MDIGnLCl4T3z3Rb4asZKksXRhP5brkJF1-LdqAXJJ55sgQ' + + 'aH-22H9g9Wxhziz5YaoshWskJYhb_geTeqPsa', + '_context_show_deleted': False, '_context_read_only': False, '_context_is_admin': True, + '_context_timestamp': '2016-11-08 00:58:07.248644', + 'payload': {'port_id': '2233445-55b6-4c05-9480-4bc648845c6f'}, + 'timestamp': '2016-11-08 00:58:07.294731', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + 'event_type': 'port.delete.start', '_unique_id': '83a98a31743c4c11aa1d1787037f6683', + '_context_request_id': 'req-51f0aeba-2648-436f-9505-0c5efb259146', 'publisher_id': 'network.node-6.cisco.com', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_domain': None, '_context_user_domain': None, 'priority': 'INFO', '_context_user_name': 'admin', + '_context_roles': ['_member_', 'admin'], 'message_id': 'ce1e3e9c-e2ef-47e2-99e1-0b6c69e5eeca', + '_context_resource_uuid': None, '_context_project_domain': None, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40'} + +PORT_DOC = { + "admin_state_up": True, + "allowed_address_pairs": [ + + ], + "binding:host_id": "", + "binding:profile": { + + }, + "binding:vif_details": { + + }, + "binding:vif_type": "unbound", + "binding:vnic_type": "normal", + "device_id": "c57216ca-c1c4-430d-a045-32851ca879e3", + "device_owner": "compute:nova", + "dns_assignment": [ + { + "hostname": "host-172-16-10-1", + "ip_address": "172.16.10.1", + "fqdn": "host-172-16-10-1.openstacklocal." + } + ], + "dns_name": "", + "environment": ENV_CONFIG, + "extra_dhcp_opts": [ + + ], + "fixed_ips": [ + { + "ip_address": "172.16.10.1", + "subnet_id": "6f6ef3b5-76c9-4f70-81e5-f3cc196db025" + } + ], + "id": "2233445-55b6-4c05-9480-4bc648845c6f", + "id_path": ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0ae4973c837" + + "5ddf40-networks/55550a69-24eb-47f5-a458-3aa086cc71c2/55550a69-24eb-47f5-a458-3aa086cc71c2-ports" + + "/2233445-55b6-4c05-9480-4bc648845c6f", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "master_parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "master_parent_type": "network", + "name": "fa:16:3e:13:b2:aa", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/test_interface/Ports/" + + "2233445-55b6-4c05-9480-4bc648845c6f", + "network_id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "object_name": "2233445-55b6-4c05-9480-4bc648845c6f", + "parent_id": "55550a69-24eb-47f5-a458-3aa086cc71c2-ports", + "parent_text": "Ports", + "parent_type": "ports_folder", + "port_security_enabled": False, + "project": "calipso-project", + "security_groups": [ + + ], + "status": "DOWN", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "port" +} + +VNIC_DOCS = [{ + "IP Address": "172.16.10.2", + "IPv6 Address": "fe80::f816:3eff:fe96:5066/64", + "cidr": "172.16.10.0/25", + "data": "Link encap:Ethernet HWaddr fa:16:3e:96:50:66\ninet addr:172.16.10.2 Bcast:172.16.10.127 " + + "Mask:255.255.255.128\ninet6 addr: fe80::f816:3eff:fe96:5066/64 Scope:Link\nUP BROADCAST RUNNING " + + "MULTICAST MTU:1450 Metric:1\nRX packets:17 errors:0 dropped:2 overruns:0 frame:0\nTX packets:8 " + + "errors:0 dropped:0 overruns:0 carrier:0\ncollisions:0 txqueuelen:0\nRX bytes:1593 " + + "(1.5 KB) TX bytes:648 (648.0 B)\n", + "environment": ENV_CONFIG, + "host": "node-251.cisco.com", + "id": "tapca33c645-5b", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-251.cisco.com/node-251.cisco.com-vservices/node-251.cisco.com-vservices-dhcps/qdhcp-911fe57e-" + + "1ddd-4151-9dc7-6b578ab357b1/qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics/tapca33c645-5b", + "last_scanned": 0, + "mac_address": "fa:16:3e:13:b2:aa", + "name": "tapca33c645-5b", + "name_path": "/"+ENV_CONFIG+"/Regions/RegionOne/Availability Zones/internal/node-251.cisco.com/" + + "Vservices/DHCP servers/dhcp-test_interface/vNICs/tapca33c645-5b", + "netmask": "255.255.255.128", + "network": "911fe57e-1ddd-4151-9dc7-6b578ab357b1", + "object_name": "tapca33c645-5b", + "parent_id": "qdhcp-911fe57e-1ddd-4151-9dc7-6b578ab357b1-vnics", + "parent_text": "vNICs", + "parent_type": "vnics_folder", + "show_in_tree": True, + "type": "vnic", + "vnic_type": "vservice_vnic" +}] + +INSTANCE_DOC = { + "environment": ENV_CONFIG, + "id": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "type": "instance", + "uuid": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "network": [ + "55550a69-24eb-47f5-a458-3aa086cc71c2" + ], + "local_name": "instance-00000002", + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-223.cisco.com/Instances/name-change', + 'id': '27a87908-bc1b-45cc-9238-09ad1ae686a7', + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/27a87908-bc1b-45cc-9238-09ad1ae686a7', + "name": "name-change", + "network_info": [ + { + "qbg_params": None, + "id": "2233445-55b6-4c05-9480-4bc648845c6f", + "network": { + "bridge": "br-int", + "meta": { + "injected": False, + "tenant_id": "a3efb05cd0484bf0b600e45dab09276d" + }, + "id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "subnets": [ + { + "gateway": { + "meta": { + + }, + "type": "gateway", + "version": 4, + "address": "172.16.50.254" + }, + "version": 4, + "dns": [ + + ], + "cidr": "172.16.50.0/24", + "routes": [ + + ], + "meta": { + "dhcp_server": "172.16.50.1" + }, + "ips": [ + { + "floating_ips": [ + + ], + "meta": { + + }, + "type": "fixed", + "version": 4, + "address": "172.16.50.3" + } + ] + } + ], + "label": "calipso-network" + }, + "active": True, + "address": "fa:16:3e:04:ab:cd", + "vnic_type": "normal", + "meta": { + }, + "ovs_interfaceid": "2233445-55b6-4c05-9480-4bc648845c6f", + "type": "ovs", + "devname": "tapa9a8fa24-11", + } + ], + "host": "node-223.cisco.com", + "project_id": "a3efb05cd0484bf0b600e45dab09276d", + "object_name": "libertyDD", + "parent_id": "node-223.cisco.com-instances", + "parent_type": "instances_folder", + "projects": [ + "project-calipso" + ], + "mac_address": "fa:16:3e:13:b2:aa" +} + +INSTANCE_DOCS = [ + { + "environment": ENV_CONFIG, + "type": "instance", + "uuid": "b2bda4bf-1259-4d60-99ab-85ab4d5014a8", + "network": [ + "55550a69-24eb-47f5-a458-3aa086cc71c2" + ], + "local_name": "instance-00000002", + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne/Availability Zones' + + '/calipso-zone/node-223.cisco.com/Instances/name-change', + 'id': 'c57216ca-c1c4-430d-a045-32851ca879e3', + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne/RegionOne-availability_zones/calipso-zone' + + '/node-223.cisco.com/node-223.cisco.com-instances/c57216ca-c1c4-430d-a045-32851ca879e3', + "name": "name-change", + "network_info": [ + { + "qbg_params": None, + "id": "2233445-55b6-4c05-9480-4bc648845c6f", + "network": { + "bridge": "br-int", + "meta": { + "injected": False, + "tenant_id": "a3efb05cd0484bf0b600e45dab09276d" + }, + "id": "55550a69-24eb-47f5-a458-3aa086cc71c2", + "subnets": [ + { + "gateway": { + "meta": { + + }, + "type": "gateway", + "version": 4, + "address": "172.16.50.254" + }, + "version": 4, + "dns": [ + + ], + "cidr": "172.16.50.0/24", + "routes": [ + + ], + "meta": { + "dhcp_server": "172.16.50.1" + }, + "ips": [ + { + "floating_ips": [ + + ], + "meta": { + + }, + "type": "fixed", + "version": 4, + "address": "172.16.50.3" + } + ] + } + ], + "label": "calipso-network" + }, + "active": True, + "address": "fa:16:3e:04:ab:cd", + "vnic_type": "normal", + "meta": { + }, + "ovs_interfaceid": "2233445-75b6-4c05-9480-4bc648845c6f", + "type": "ovs", + "devname": "tapa9a8fa24-12", + } + ], + "host": "node-223.cisco.com", + "project_id": "a3efb05cd0484bf0b600e45dab09276d", + "object_name": "libertyDD", + "parent_id": "node-223.cisco.com-instances", + "parent_type": "instances_folder", + "projects": [ + "project-calipso" + ], + } +]
\ No newline at end of file diff --git a/app/test/event_based_scan/test_data/event_payload_port_update.py b/app/test/event_based_scan/test_data/event_payload_port_update.py new file mode 100644 index 0000000..90befbf --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_port_update.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 # +############################################################################### +from test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_PORT_UPDATE = { + '_context_timestamp': '2016-10-25 21:27:05.591848', '_context_user_name': 'admin', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_name': 'calipso-project', '_context_resource_uuid': None, + 'priority': 'INFO', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_domain': None, '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', 'event_type': 'port.update.end', + '_context_project_domain': None, '_context_show_deleted': False, + '_context_request_id': 'req-5c502a18-cf79-4903-85c0-84eeab525378', + '_context_roles': ['_member_', 'admin'], + 'message_id': 'ee8e493e-1134-4077-bb0a-db9d28b625dd', 'payload': {'port': { + 'dns_assignment': [ + {'ip_address': '172.16.4.2', 'fqdn': 'host-172-16-4-2.openstacklocal.', 'hostname': 'host-172-16-4-2'}], + 'mac_address': 'fa:16:3e:d7:c5:16', 'security_groups': [], 'admin_state_up': True, 'dns_name': '', + 'allowed_address_pairs': [], 'binding:profile': {}, + 'binding:vif_details': {'port_filter': True, 'ovs_hybrid_plug': True}, 'port_security_enabled': False, + 'device_id': 'dhcp7a15cee0-2af1-5441-b1dc-94897ef4dee9-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', + 'id': '16620a58-c48c-4195-b9c1-779a8ba2e6f8', + 'fixed_ips': [{'subnet_id': 'f68b9dd3-4cb5-46aa-96b1-f9c8a7abc3aa', 'ip_address': '172.16.4.2'}], + 'name': 'test', + 'binding:vnic_type': 'normal', 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'extra_dhcp_opts': [], + 'network_id': 'b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe', 'binding:vif_type': 'ovs', + 'binding:host_id': 'node-6.cisco.com', 'status': 'ACTIVE', 'device_owner': 'network:dhcp'}}, + 'timestamp': '2016-10-25 21:27:06.281892', + '_unique_id': '964361cb7a434daf9fa6452507133fe5', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_user_domain': None, + '_context_auth_token': 'gAAAAABYD8zsy7c8LhL2SoZTzmK-YpUMFBJHare_RA7_4E94zqj328sC0cETsFAoWoBY' + + '6X8ZvjBQg--5UCqgj7iUE-zfIQwZLzXbl46MP1Fg5ZKCUtdCCPN5yqXxGA-ebYlBB_G' + + 'If0LUo1YXCKe3GacmfFNC-k0T_B1p340stgLdpW7r0g1jvTDleqK7NWNrnCniZHrgGiLw', + '_context_is_admin': True, '_context_read_only': False, + '_context_project_name': 'calipso-project', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + 'publisher_id': 'network.node-6.cisco.com'} + +PORT_DOCUMENT = { + "admin_state_up": True, + "allowed_address_pairs": [ + + ], + "binding:host_id": "node-6.cisco.com", + "binding:profile": { + + }, + "binding:vif_details": { + "port_filter": True, + "ovs_hybrid_plug": True + }, + "binding:vif_type": "ovs", + "binding:vnic_type": "normal", + "device_id": "dhcp7a15cee0-2af1-5441-b1dc-94897ef4dee9-b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "device_owner": "network:dhcp", + "dns_assignment": [ + { + "hostname": "host-172-16-4-2", + "fqdn": "host-172-16-4-2.openstacklocal.", + "ip_address": "172.16.4.2" + } + ], + "dns_name": "", + "environment": ENV_CONFIG, + "extra_dhcp_opts": [ + + ], + "fixed_ips": [ + { + "subnet_id": "f68b9dd3-4cb5-46aa-96b1-f9c8a7abc3aa", + "ip_address": "172.16.4.2" + } + ], + "id": "16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb" + + "79ff4a42b0ae4973c8375ddf40-networks/b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe/b6fd5175-4b22" + + "-4256-9b1a-9fc4b9dce1fe-ports/16620a58-c48c-4195-b9c1-779a8ba2e6f8", + "last_scanned": 0, + "mac_address": "fa:16:3e:d7:c5:16", + "name": "123", + "name_path": "/"+ENV_CONFIG+"/Projects/calipso-project/Networks/calipso-met4/Ports/fa:16:3e:d7:c5:16", + "network_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe", + "object_name": "fa:16:3e:d7:c5:16", + "parent_id": "b6fd5175-4b22-4256-9b1a-9fc4b9dce1fe-ports", + "parent_text": "Ports", + "parent_type": "ports_folder", + "port_security_enabled": False, + "project": "calipso-project", + "security_groups": [ + + ], + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "port" +} diff --git a/app/test/event_based_scan/test_data/event_payload_router_add.py b/app/test/event_based_scan/test_data/event_payload_router_add.py new file mode 100644 index 0000000..153538d --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_router_add.py @@ -0,0 +1,176 @@ +############################################################################### +# 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 datetime + +from test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_ROUTER_ADD = { + '_context_show_deleted': False, '_context_domain': None, + '_context_user': '13baa553aae44adca6615e711fd2f6d9', + 'message_id': '05682485-9283-4cef-aae5-0bc1e86ed14d', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_read_only': False, + '_context_user_domain': None, '_unique_id': '40f10fd246814669b61d906fd71be301', + '_context_auth_token': 'gAAAAABYE58-bIhpHKOyCNnav0czsBonPJbJJPxtkTFHT_gJ-sVPPO1xCldKOoJoJ58M5egmK0' + + 'tsCOiH9N6u-2h08rH84nrnE6YUoLJM_SWyJlbYDzH7rJyHYPBVE1aYkzMceiy7Jr33G4k6cGZQ' + + '7UzAaZRrGLxMMFddvNZa47dVPZsg1oJpdIVVcoaRHf4hPM8lj1qSn6WG', + 'event_type': 'router.create.end', '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'priority': 'INFO', '_context_roles': ['_member_', 'admin'], + '_context_project_name': 'calipso-project', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_request_id': 'req-a543a2e4-3160-4e98-b1b8-21a876fff205', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'timestamp': '2016-10-28 19:00:36.600958', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_name': 'calipso-project', 'payload': { + 'router': {'name': 'test-router-add', + 'external_gateway_info': { + 'enable_snat': True, + 'external_fixed_ips': [{ + 'ip_address': '172.16.0.137', + 'subnet_id': 'a5336853-cbc0-49e8-8401-a093e8bab7bb'}], + 'network_id': 'c64adb76-ad9d-4605-9f5e-123456781234'}, + 'admin_state_up': True, + 'distributed': False, + 'routes': [], 'ha': False, + 'id': 'c485d5f4-dfec-430f-8ad8-409c7034b46d', + 'status': 'ACTIVE', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40'}}, + '_context_timestamp': '2016-10-28 19:00:34.395521', '_context_project_domain': None, + 'publisher_id': 'network.node-250.cisco.com', '_context_is_admin': True, + '_context_user_name': 'admin', '_context_resource_uuid': None} + +ROUTER_DOCUMENT = {'host': 'node-250.cisco.com', 'service_type': 'router', 'name': 'router-test-router-add', + 'id': 'node-250.cisco.com-qrouter-c485d5f4-dfec-430f-8ad8-409c7034b46d', + 'local_service_id': 'node-250.cisco.com-qrouter-c485d5f4-dfec-430f-8ad8-409c7034b46d', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'status': 'ACTIVE', + 'master_parent_type': 'vservices_folder', + 'admin_state_up': 1, 'parent_type': 'vservice_routers_folder', 'enable_snat': 1, + 'parent_text': 'Gateways', + 'gw_port_id': 'e2f31c24-d0f9-499e-a8b1-883941543aa4', + 'master_parent_id': 'node-250.cisco.com-vservices', + 'parent_id': 'node-250.cisco.com-vservices-routers'} + +HOST_DOC = { + "config": { + "gateway_external_network_id": "", + "router_id": "", + "handle_internal_only_routers": True, + "agent_mode": "legacy", + "ex_gw_ports": 4, + "floating_ips": 1, + "external_network_bridge": "", + "interfaces": 1, + "log_agent_heartbeats": False, + "use_namespaces": True, + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "routers": 4 + }, + "environment": ENV_CONFIG, + "host": "node-250.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-250.cisco.com", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/internal/node-250.cisco.com", + "last_scanned": datetime.datetime.utcnow(), + "name": "node-250.cisco.com", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-250.cisco.com", + "object_name": "node-250.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:47.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:48.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:41.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:52.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +} + +NETWORK_DOC = { + "admin_state_up": True, + "cidrs": [ + "172.16.0.0/24" + ], + "environment": ENV_CONFIG, + "id": "c64adb76-ad9d-4605-9f5e-123456781234", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/8c1751e0ce714736a63fee3c776164da/8c1751e0ce71" + + "4736a63fee3c776164da-networks/c64adb76-ad9d-4605-9f5e-123456781234", + "last_scanned": datetime.datetime.utcnow(), + "mtu": 1500, + "name": "admin_floating_net", + "name_path": "/" + ENV_CONFIG + "/Projects/admin/Networks/admin_floating_net", + "network": "c64adb76-ad9d-4605-9f5e-123456781234", + "object_name": "admin_floating_net", + "parent_id": "8c1751e0ce714736a63fee3c776164da-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "admin", + "provider:network_type": "flat", + "provider:physical_network": "physnet1", + "provider:segmentation_id": None, + "router:external": True, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnets": { + "admin_floating_net__subnet": { + "allocation_pools": [ + { + "end": "172.16.0.254", + "start": "172.16.0.130" + } + ], + "id": "a5336853-cbc0-49e8-8401-a093e8bab7bb", + "network_id": "c64adb76-ad9d-4605-9f5e-123456781234", + "ipv6_ra_mode": None, + "ipv6_address_mode": None, + "ip_version": 4, + "tenant_id": "8c1751e0ce714736a63fee3c776164da", + "cidr": "172.16.0.0/24", + "dns_nameservers": [ + + ], + "name": "admin_floating_net__subnet", + "subnetpool_id": None, + "gateway_ip": "172.16.0.1", + "host_routes": [ + + ], + "enable_dhcp": False, + } + }, + "subnets_id": [ + "a5336853-cbc0-49e8-8401-a093e8bab7bb" + ], + "tenant_id": "8c1751e0ce714736a63fee3c776164da", + "type": "network" +} diff --git a/app/test/event_based_scan/test_data/event_payload_router_delete.py b/app/test/event_based_scan/test_data/event_payload_router_delete.py new file mode 100644 index 0000000..8ab8cc3 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_router_delete.py @@ -0,0 +1,59 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_ROUTER_DELETE = { + '_context_request_id': 'req-8b2dd9ba-5faa-4471-94c3-fb41781eef8d', '_unique_id': 'c7417f771ee74bb19036b06e685c93dc', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_auth_token': 'gAAAAABYE7T7789XjB_Nir9PykWTIpDNI0VhgtVQJNyGVImHnug2AVRX9e2JDcXe8F73eNmFepASsoCfqvZet9qN' + + '38vrX6GqzL89Quf6pQyLxgRorMv6RlScSCDBQzE8Hj5szSYi_a7F_O2Lr77omUiLi2R_Ludt25mcMiuaMgPknJ2b' + + 'joAyV_-eE_8CrSbdJ5Dk1MaCSq5K', + '_context_user_name': 'admin', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_timestamp': '2016-10-28 20:31:27.902723', 'message_id': '569118ad-1f5b-4a50-96ec-f160ebbb1b34', + 'payload': {'router_id': 'bde87a5a-7968-4f3b-952c-e87681a96078'}, '_context_resource_uuid': None, + 'event_type': 'router.delete.end', '_context_project_name': 'calipso-project', 'priority': 'INFO', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_roles': ['_member_', 'admin'], + '_context_project_domain': None, '_context_user_domain': None, '_context_read_only': False, + '_context_is_admin': True, '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_domain': None, + '_context_show_deleted': False, '_context_tenant_name': 'calipso-project', 'publisher_id': 'network.node-6.cisco.com', + 'timestamp': '2016-10-28 20:31:37.012032'} + +ROUTER_DOCUMENT = { + "admin_state_up": True, + "enable_snat": 1, + "environment": ENV_CONFIG, + "gw_port_id": None, + "host": "node-6.cisco.com", + "id": "node-6.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-6.cisco.com/node-6.cisco.com-vservices/node-6.cisco.com-vservices-routers/qrouter-bde87a5a" + + "-7968-4f3b-952c-e87681a96078", + "last_scanned": 0, + "local_service_id": "node-6.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078", + "master_parent_id": "node-6.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "1234", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com/" + + "Vservices/Gateways/router-1234", + "network": [ + "c64adb76-ad9d-4605-9f5e-bd6dbe325cfb" + ], + "object_name": "router-1234", + "parent_id": "node-6.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "vservice" +} diff --git a/app/test/event_based_scan/test_data/event_payload_router_update.py b/app/test/event_based_scan/test_data/event_payload_router_update.py new file mode 100644 index 0000000..b0a917e --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_router_update.py @@ -0,0 +1,271 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_ROUTER_UPDATE = { + '_context_request_id': 'req-da45908c-0765-4f8a-9fac-79246901de41', '_unique_id': '80723cc09a4748c6b13214dcb867719e', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_user': '13baa553aae44adca6615e711fd2f6d9', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_auth_token': 'gAAAAABYE7T7789XjB_Nir9PykWTIpDNI0VhgtVQJNyGVImHnug2AVRX9e2JDcXe8F73eNmFepASsoCfqvZet9q' + + 'N38vrX6GqzL89Quf6pQyLxgRorMv6RlScSCDBQzE8Hj5szSYi_a7F_O2Lr77omUiLi2R_Ludt25mcMiuaMgPkn' + + 'J2bjoAyV_-eE_8CrSbdJ5Dk1MaCSq5K', + '_context_user_name': 'admin', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_timestamp': '2016-10-28 20:29:35.548123', 'message_id': '42c0ca64-cea1-4c89-a059-72abf7990c40', + 'payload': { + 'router': {'id': 'bde87a5a-7968-4f3b-952c-e87681a96078', 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'ha': False, 'distributed': False, 'name': 'abc', 'status': 'ACTIVE', 'external_gateway_info': None, + 'admin_state_up': True, 'routes': []}}, '_context_resource_uuid': None, + 'event_type': 'router.update.end', '_context_project_name': 'calipso-project', 'priority': 'INFO', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_roles': ['_member_', 'admin'], + '_context_project_domain': None, '_context_user_domain': None, '_context_read_only': False, + '_context_is_admin': True, '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_domain': None, + '_context_show_deleted': False, '_context_tenant_name': 'calipso-project', 'publisher_id': 'network.node-250.cisco.com', + 'timestamp': '2016-10-28 20:29:39.986161'} + +ROUTER_VSERVICE = {'host': 'node-250.cisco.com', 'service_type': 'router', 'name': '1234', + 'id': 'node-250.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078', + 'local_service_id': 'node-250.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'status': 'ACTIVE', + 'master_parent_type': 'vservices_folder', + 'admin_state_up': 1, 'parent_type': 'vservice_routers_folder', 'enable_snat': 1, + 'parent_text': 'Gateways', + 'gw_port_id': 'e2f31c24-d0f9-499e-a8b1-883941543aa4', + 'master_parent_id': 'node-250.cisco.com-vservices', + 'parent_id': 'node-250.cisco.com-vservices-routers'} + +ROUTER_DOCUMENT = { + "admin_state_up": True, + "enable_snat": 1, + "environment": ENV_CONFIG, + "gw_port_id": "e2f31c24-d0f9-499e-a8b1-883941543aa4", + "host": "node-250.cisco.com", + "id": "node-250.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones/internal" + + "/node-250.cisco.com/node-250.cisco.com-vservices/node-250.cisco.com-vservices-routers/qrouter-bde87a5a" + + "-7968-4f3b-952c-e87681a96078", + "last_scanned": 0, + "local_service_id": "node-250.cisco.com-qrouter-bde87a5a-7968-4f3b-952c-e87681a96078", + "master_parent_id": "node-250.cisco.com-vservices", + "master_parent_type": "vservices_folder", + "name": "1234", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-250.cisco.com/" + + "Vservices/Gateways/router-1234", + "network": [ + "a55ff1e8-3821-4e5f-bcfd-07df93720a4f" + ], + "object_name": "router-1234", + "parent_id": "node-250.cisco.com-vservices-routers", + "parent_text": "Gateways", + "parent_type": "vservice_routers_folder", + "service_type": "router", + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "vservice" +} + +EVENT_PAYLOAD_ROUTER_SET_GATEWAY = { + 'publisher_id': 'network.node-250.cisco.com', + '_context_request_id': 'req-79d53b65-47b8-46b2-9a72-3f4031e2d605', + '_context_project_name': 'calipso-project', '_context_show_deleted': False, + '_context_user_name': 'admin', '_context_timestamp': '2016-11-02 21:44:31.156447', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', 'payload': { + 'router': {'id': 'bde87a5a-7968-4f3b-952c-e87681a96078', 'admin_state_up': True, 'routes': [], + 'status': 'ACTIVE', 'ha': False, 'name': 'test_namespace', 'distributed': False, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'external_gateway_info': {'external_fixed_ips': [ + {'ip_address': '172.16.0.144', 'subnet_id': 'a5336853-cbc0-49e8-8401-a093e8bab7bb'}], + 'network_id': 'a55ff1e8-3821-4e5f-bcfd-07df93720a4f', + 'enable_snat': True}}}, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_read_only': False, + '_context_auth_token': 'gAAAAABYGlU6mEqntx5E9Nss203DIKH352JKSZP0RsJrAJQ_PfjyZEAzYcFvMh4FYVRDRWLvu0cSDsvUk1ILu' + + 'nHkpNF28pwcvkBgVModV2Xd2_BW2QbBa2csCOXYiN0LE2uOo3BkrLDEcblvJVT0XTJdDhrBldfyCH0_xSfJ7_' + + 'wzdy8bB34HwHq2w0S3Okp8Tk_Zx_-xpIqB', + 'priority': 'INFO', 'timestamp': '2016-11-02 21:44:35.627776', + '_context_roles': ['_member_', 'admin'], '_context_resource_uuid': None, + '_context_user_domain': None, '_context_project_domain': None, + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + 'message_id': '71889925-14ce-40c3-a3dc-f26731b10b26', + 'event_type': 'router.update.end', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_unique_id': '9e6ab72c5901451f81748e0aa654ae25', + '_context_tenant_name': 'calipso-project', '_context_is_admin': True, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_domain': None} + +EVENT_PAYLOAD_ROUTER_DEL_GATEWAY = { + '_context_show_deleted': False, '_context_timestamp': '2016-11-03 18:48:40.420170', '_context_read_only': False, + 'publisher_id': 'network.node-250.cisco.com', + '_context_auth_token': 'gAAAAABYG4UUGbe9bykUJUPY0lKye578aF0RrMCc7nA21eLbhpwcsh5pWWqz6hnOi7suUCUtr1DPTbqF1M8CVJ' + + '9FT2EevbqiahcyphrV2VbmP5_tebOcIHIPJ_f_K3KYJM1C6zgcWgdf9KFu_8t_G99wd1MwWBrZyUUElXgSNv48' + + 'W4uaCKcbYclnZW78lgXVik5x6WLT_j5V', + '_context_user_name': 'admin', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_unique_id': '266f2bb0ab2c4a328ae0759d01b0035b', + 'timestamp': '2016-11-03 18:48:41.634214', '_context_roles': ['_member_', 'admin'], + 'event_type': 'router.update.end', + '_context_user_domain': None, '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_is_admin': True, + '_context_tenant_name': 'calipso-project', '_context_project_domain': None, '_context_domain': None, + 'priority': 'INFO', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'message_id': '5272cd90-7151-4d13-8c1f-e8ff2db773a1', + '_context_project_name': 'calipso-project', '_context_resource_uuid': None, 'payload': { + 'router': {'id': 'bde87a5a-7968-4f3b-952c-e87681a96078', 'external_gateway_info': None, 'distributed': False, + 'name': 'TEST_AAA', 'routes': [], 'ha': False, 'admin_state_up': True, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'status': 'ACTIVE'}}, + '_context_request_id': 'req-d7e73189-4709-4234-8b4c-fb6b4dc2017b'} + +PORTS = { + "admin_state_up": True, + "allowed_address_pairs": [ + + ], + "binding:host_id": "node-250.cisco.com", + "binding:profile": { + + }, + "binding:vif_details": { + "port_filter": True, + "ovs_hybrid_plug": True + }, + "binding:vif_type": "ovs", + "binding:vnic_type": "normal", + "device_id": "9ec3d703-0725-47e3-8f48-02b16236caf9", + "device_owner": "network:router_interface", + "dns_assignment": [ + { + "hostname": "host-172-16-1-1", + "fqdn": "host-172-16-1-1.openstacklocal.", + "ip_address": "172.16.1.1" + } + ], + "dns_name": "", + "environment": ENV_CONFIG, + "extra_dhcp_opts": [ + + ], + "fixed_ips": [ + { + "subnet_id": "c1287696-224b-4a72-9f1d-d45176671bce", + "ip_address": "172.16.1.1" + } + ], + "id": "e2f31c24-d0f9-499e-a8b1-883941543aa4", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b" + + "0ae4973c8375ddf40-networks/a55ff1e8-3821-4e5f-bcfd-07df93720a4f/a55ff1e8-3821-4e5f-bcfd-07df93720a4" + + "f-ports/e2f31c24-d0f9-499e-a8b1-883941543aa4", + "last_scanned": 0, + "mac_address": "fa:16:3e:ee:9a:46", + "name": "fa:16:3e:ee:9a:46", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/calipso-net2/Ports/fa:16:3e:ee:9a:46", + "network_id": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "object_name": "fa:16:3e:ee:9a:46", + "parent_id": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f-ports", + "parent_text": "Ports", + "parent_type": "ports_folder", + "port_security_enabled": False, + "project": "calipso-project", + "security_groups": [ + + ], + "show_in_tree": True, + "status": "ACTIVE", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "port" +} + +NETWORK_DOC = { + "admin_state_up": True, + "cidrs": [ + "172.16.4.0/24" + ], + "environment": ENV_CONFIG, + "id": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b" + + "0ae4973c8375ddf40-networks/a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "last_scanned": 0, + "mtu": 1400, + "name": "calipso-net2", + "name_path": "/" + ENV_CONFIG + "/Projects/calipso-project/Networks/calipso-net2", + "network": "a55ff1e8-3821-4e5f-bcfd-07df93720a4f", + "object_name": "calipso-net2", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "calipso-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 0, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnets": {}, + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +} + +HOST_DOC = { + "config": { + "gateway_external_network_id": "", + "router_id": "", + "handle_internal_only_routers": True, + "agent_mode": "legacy", + "ex_gw_ports": 4, + "floating_ips": 1, + "external_network_bridge": "", + "interfaces": 1, + "log_agent_heartbeats": False, + "use_namespaces": True, + "interface_driver": "neutron.agent.linux.interface.OVSInterfaceDriver", + "routers": 4 + }, + "environment": ENV_CONFIG, + "host": "node-250.cisco.com", + "host_type": [ + "Controller", + "Network" + ], + "id": "node-250.cisco.com", + "id_path": "/" + ENV_CONFIG + "/" + ENV_CONFIG + "-regions/RegionOne/RegionOne-availability_zones" + + "/internal/node-250.cisco.com", + "last_scanned": 0, + "name": "node-250.cisco.com", + "name_path": "/" + ENV_CONFIG + "/Regions/RegionOne/Availability Zones/internal/node-250.cisco.com", + "object_name": "node-250.cisco.com", + "parent_id": "internal", + "parent_type": "availability_zone", + "services": { + "nova-scheduler": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:47.000000" + }, + "nova-consoleauth": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:48.000000" + }, + "nova-cert": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:41.000000" + }, + "nova-conductor": { + "active": True, + "available": True, + "updated_at": "2016-11-02T21:19:52.000000" + } + }, + "show_in_tree": True, + "type": "host", + "zone": "internal" +}
\ No newline at end of file diff --git a/app/test/event_based_scan/test_data/event_payload_subnet_add.py b/app/test/event_based_scan/test_data/event_payload_subnet_add.py new file mode 100644 index 0000000..7167f4c --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_subnet_add.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 # +############################################################################### +import datetime + +from test.event_based_scan.config.test_config import ENV_CONFIG + +NETWORK_DOC = {'port_security_enabled': True, 'status': 'ACTIVE', 'subnet_ids': [], 'parent_type': 'networks_folder', + 'parent_id': '75c0eb79ff4a42b0ae4973c8375ddf40-networks', 'parent_text': 'Networks', 'subnets': {}, + 'admin_state_up': True, 'show_in_tree': True, 'project': 'calipso-project', + 'name_path': '/' + ENV_CONFIG + '/Projects/calipso-project/Networks/testsubnetadd', + 'router:external': False, + 'provider:physical_network': None, + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0' + + 'ae4973c8375ddf40-networks/1bb0ba6c-6863-4121-ac89-93f81a9da2b0', + 'object_name': 'testsubnetadd', 'provider:segmentation_id': 46, 'provider:network_type': 'vxlan', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'environment': ENV_CONFIG, 'name': 'testsubnetadd', + 'last_scanned': '2016-10-13 00:20:59.280329', 'id': '1bb0ba6c-6863-4121-ac89-93f81a9da2b0', 'cidrs': [], + 'type': 'network', 'network': '1bb0ba6c-6863-4121-ac89-93f81a9da2b0', 'shared': False, 'mtu': 1400} + +EVENT_PAYLOAD_SUBNET_ADD = { + 'payload': { + 'subnet': {'dns_nameservers': [], 'ipv6_address_mode': None, 'ipv6_ra_mode': None, 'gateway_ip': '172.16.10.1', + 'allocation_pools': [{'start': '172.16.10.2', 'end': '172.16.10.126'}], 'enable_dhcp': True, + 'id': 'e950055d-231c-4380-983c-a258ea958d58', 'network_id': '1bb0ba6c-6863-4121-ac89-93f81a9da2b0', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'ip_version': 4, 'cidr': '172.16.10.0/25', + 'subnetpool_id': None, 'name': 'testsubnetadd', 'host_routes': []}}, '_context_domain': None, + 'timestamp': '2016-10-13 00:20:59.776358', '_context_project_domain': None, '_context_user_domain': None, + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'publisher_id': 'network.node-6.cisco.com', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + 'event_type': 'subnet.create.end', 'message_id': '90581321-e9c9-4112-8fe6-38ebf57d5b6b', + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_tenant_name': 'calipso-project', + '_context_project_name': 'calipso-project', '_context_user_name': 'admin', '_context_resource_uuid': None, + '_unique_id': 'e8b328229a724938a6bc63f9db737f49', '_context_request_id': 'req-20cfc138-4e1a-472d-b996-7f27ac58446d', + 'priority': 'INFO', '_context_roles': ['_member_', 'admin'], + '_context_auth_token': 'gAAAAABX_tLMEzC9KhdcD20novcuvgwmpQkwV9hOk86d4AZlsQwXSRbCwBZgUPQZco4VsuCg59_gFeM_scBVmI' + + 'dDysNUrAhZctDzXneM0cb5nBtjJTfJPpI2_kKgAuGDBARrHZpNs-vPg-SjMtu87w2rgTKfda6idTMKWG3ipe' + + '-jXrgNN7p-2kkJzGhZXbMaaeBs3XU-X_ew', + '_context_read_only': False, + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_is_admin': True, '_context_show_deleted': False, + '_context_timestamp': '2016-10-13 00:20:59.307917'} + +EVENT_PAYLOAD_REGION = { + 'RegionOne': { + 'object_name': 'RegionOne', 'id': 'RegionOne', 'name': 'RegionOne', + 'environment': ENV_CONFIG, + 'last_scanned': datetime.datetime.utcnow(), + 'name_path': '/' + ENV_CONFIG + '/Regions/RegionOne', + 'parent_id': ENV_CONFIG + '-regions', 'parent_type': 'regions_folder', + 'endpoints': {'nova': {'id': '274cbbd9fd6d4311b78e78dd3a1df51f', + 'adminURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'compute', + 'publicURL': 'http://172.16.0.3:8774/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8774/v2/8c1751e0ce714736a63fee3c776164da'}, + 'heat-cfn': {'id': '0f04ec6ed49f4940822161bf677bdfb2', + 'adminURL': 'http://192.168.0.2:8000/v1', + 'service_type': 'cloudformation', + 'publicURL': 'http://172.16.0.3:8000/v1', + 'internalURL': 'http://192.168.0.2:8000/v1'}, + 'nova_ec2': {'id': '390dddc753cc4d378b489129d06c4b7d', + 'adminURL': 'http://192.168.0.2:8773/services/Admin', + 'service_type': 'ec2', + 'publicURL': 'http://172.16.0.3:8773/services/Cloud', + 'internalURL': 'http://192.168.0.2:8773/services/Cloud'}, + 'glance': {'id': '475c6c77a94e4e63a5a0f0e767f697a8', + 'adminURL': 'http://192.168.0.2:9292', + 'service_type': 'image', + 'publicURL': 'http://172.16.0.3:9292', + 'internalURL': 'http://192.168.0.2:9292'}, + 'swift': {'id': '12e78e06595f48339baebdb5d4309c70', + 'adminURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'service_type': 'object-store', + 'publicURL': 'http://172.16.0.3:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8080/v1/AUTH_8c1751e0ce714736a63fee3c776164da'}, + 'swift_s3': {'id': '4f655c8f2bef46a0a7ba4a20bba53666', + 'adminURL': 'http://192.168.0.2:8080', + 'service_type': 's3', + 'publicURL': 'http://172.16.0.3:8080', + 'internalURL': 'http://192.168.0.2:8080'}, + 'keystone': {'id': '404cceb349614eb39857742970408301', + 'adminURL': 'http://192.168.0.2:35357/v2.0', + 'service_type': 'identity', + 'publicURL': 'http://172.16.0.3:5000/v2.0', + 'internalURL': 'http://192.168.0.2:5000/v2.0'}, + 'cinderv2': {'id': '2c30937688e944889db4a64fab6816e6', + 'adminURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volumev2', + 'publicURL': 'http://172.16.0.3:8776/v2/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v2/8c1751e0ce714736a63fee3c776164da'}, + 'novav3': {'id': '1df917160dfb4ce5b469764fde22b3ab', + 'adminURL': 'http://192.168.0.2:8774/v3', + 'service_type': 'computev3', + 'publicURL': 'http://172.16.0.3:8774/v3', + 'internalURL': 'http://192.168.0.2:8774/v3'}, + 'ceilometer': {'id': '617177a3dcb64560a5a79ab0a91a7225', + 'adminURL': 'http://192.168.0.2:8777', + 'service_type': 'metering', + 'publicURL': 'http://172.16.0.3:8777', + 'internalURL': 'http://192.168.0.2:8777'}, + 'neutron': {'id': '8dc28584da224c4b9671171ead3c982a', + 'adminURL': 'http://192.168.0.2:9696', + 'service_type': 'network', + 'publicURL': 'http://172.16.0.3:9696', + 'internalURL': 'http://192.168.0.2:9696'}, + 'cinder': {'id': '05643f2cf9094265b432376571851841', + 'adminURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'volume', + 'publicURL': 'http://172.16.0.3:8776/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8776/v1/8c1751e0ce714736a63fee3c776164da'}, + 'heat': {'id': '9e60268a5aaf422d9e42f0caab0a19b4', + 'adminURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'service_type': 'orchestration', + 'publicURL': 'http://172.16.0.3:8004/v1/8c1751e0ce714736a63fee3c776164da', + 'internalURL': 'http://192.168.0.2:8004/v1/8c1751e0ce714736a63fee3c776164da'}}, + 'show_in_tree': True, + 'id_path': '/' + ENV_CONFIG + '/' + ENV_CONFIG + '-regions/RegionOne', + 'type': 'region'}} diff --git a/app/test/event_based_scan/test_data/event_payload_subnet_delete.py b/app/test/event_based_scan/test_data/event_payload_subnet_delete.py new file mode 100644 index 0000000..55a785d --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_subnet_delete.py @@ -0,0 +1,95 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +EVENT_PAYLOAD_SUBNET_DELETE = { + 'payload': {'subnet_id': '88442b4a-e62d-4d72-9d18-b8d6973eb3da'}, + '_context_auth_token': 'gAAAAABYGRxBKUKuNjrN4Z9H5HNhfpfS9h671aqjRNwPT_2snUk5OI52zTpAh-9yjIlcJOZRXHUlWZW7R'+ + '-vNAjUwdSJ4ILwMW9smDT8hLTsBIki-QtJl1nSSlfhVAqhMsnrQxREJeagESGuvsR3BxHgMVrCt1Vh5wR9'+ + 'E1_pHgn0WFpwVJEN0U8IxNfBvU8uLuIHq1j6XRiiY', + '_context_user_domain': None, '_context_user_name': 'admin', '_context_read_only': False, + 'publisher_id': 'network.node-6.cisco.com', 'event_type': 'subnet.delete.end', + 'timestamp': '2016-11-01 22:58:04.504790', 'priority': 'INFO', + '_context_roles': ['_member_', 'admin'], + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', + '_unique_id': 'f79384f4c7764bdc93ee2469d79123d1', + '_context_tenant_name': 'calipso-project', + '_context_request_id': 'req-cbb08126-3027-49f0-a896-aedf05cc3389', + '_context_domain': None, '_context_is_admin': True, + '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_project_domain': None, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', + '_context_project_name': 'calipso-project', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_resource_uuid': None, + '_context_timestamp': '2016-11-01 22:58:02.675098', '_context_show_deleted': False, + 'message_id': '7bd8402e-8f1f-4f8c-afc2-5042b3388ae7', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40'} + + +EVENT_PAYLOAD_NETWORK = { + "admin_state_up": True, + "cidrs": [ + "172.16.10.0/25" + ], + "environment": ENV_CONFIG, + "id": "121c727b-6376-4a86-a5a8-793dfe7a8ef4", + "id_path": "/"+ENV_CONFIG+"/"+ENV_CONFIG+"-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a" + + "42b0ae4973c8375ddf40-networks/121c727b-6376-4a86-a5a8-793dfe7a8ef4", + "last_scanned": 0, + "mtu": 1400, + "name": "asad", + "name_path": "/"+ENV_CONFIG+"/Projects/calipso-project/Networks/asad", + "network": "121c727b-6376-4a86-a5a8-793dfe7a8ef4", + "object_name": "asad", + "parent_id": "75c0eb79ff4a42b0ae4973c8375ddf40-networks", + "parent_text": "Networks", + "parent_type": "networks_folder", + "port_security_enabled": True, + "project": "calipso-project", + "provider:network_type": "vxlan", + "provider:physical_network": None, + "provider:segmentation_id": 18, + "router:external": False, + "shared": False, + "show_in_tree": True, + "status": "ACTIVE", + "subnets": { + "testsubnet": { + "subnetpool_id": None, + "enable_dhcp": True, + "ipv6_ra_mode": None, + "dns_nameservers": [ + + ], + "name": "testsubnet", + "ipv6_address_mode": None, + "ip_version": 4, + "gateway_ip": "172.16.10.1", + "network_id": "121c727b-6376-4a86-a5a8-793dfe7a8ef4", + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "allocation_pools": [ + { + "start": "172.16.10.2", + "end": "172.16.10.126" + } + ], + "id": "88442b4a-e62d-4d72-9d18-b8d6973eb3da", + "host_routes": [ + + ], + "cidr": "172.16.10.0/25" + } + }, + "subnet_ids": [ + "88442b4a-e62d-4d72-9d18-b8d6973eb3da" + ], + "tenant_id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "type": "network" +} diff --git a/app/test/event_based_scan/test_data/event_payload_subnet_update.py b/app/test/event_based_scan/test_data/event_payload_subnet_update.py new file mode 100644 index 0000000..5f547c5 --- /dev/null +++ b/app/test/event_based_scan/test_data/event_payload_subnet_update.py @@ -0,0 +1,76 @@ +############################################################################### +# 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 test.event_based_scan.config.test_config import ENV_CONFIG + +NETWORK_DOC = { + 'port_security_enabled': True, 'status': 'ACTIVE', + 'subnets_id': ['393a1f80-4277-4c9a-b44c-0bc05a5121c6'], 'parent_type': 'networks_folder', + 'parent_id': '75c0eb79ff4a42b0ae4973c8375ddf40-networks', 'parent_text': 'Networks', + 'subnets': {'test': {'name': 'test', 'subnetpool_id': None, 'id': '393a1f80-4277-4c9a-b44c-0bc05a5121c6', + 'network_id': '0abe6331-0d74-4bbd-ad89-a5719c3793e4', 'gateway_ip': '172.16.12.1', + 'ipv6_address_mode': None, 'dns_nameservers': [], 'ipv6_ra_mode': None, 'cidr': '172.16.12.0/24', + 'allocation_pools': [{'start': '172.16.12.2', 'end': '172.16.12.254'}], 'enable_dhcp': True, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'host_routes': [], 'ip_version': 4}, + }, + 'admin_state_up': True, 'show_in_tree': True, 'project': 'calipso-project', + 'name_path': '/'+ENV_CONFIG+'/Projects/calipso-project/Networks/testsubnetadd', 'router:external': False, + 'provider:physical_network': None, + 'id_path': '/'+ENV_CONFIG+'/'+ENV_CONFIG+'-projects/75c0eb79ff4a42b0ae4973c8375ddf40/75c0eb79ff4a42b0'+ + 'ae4973c8375ddf40-networks/0abe6331-0d74-4bbd-ad89-a5719c3793e4', + 'object_name': 'testsubnetadd', 'provider:segmentation_id': 46, 'provider:network_type': 'vxlan', + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'environment': ENV_CONFIG, 'name': 'testsubnetadd', + 'last_scanned': '2016-10-13 00:20:59.280329', 'id': '0abe6331-0d74-4bbd-ad89-a5719c3793e4', + 'cidrs': ['172.16.12.0/24'], + 'type': 'network', 'network': '0abe6331-0d74-4bbd-ad89-a5719c3793e4', 'shared': False, 'mtu': 1400} + + +EVENT_PAYLOAD_SUBNET_UPDATE = { + 'publisher_id': 'network.node-6.cisco.com', '_context_show_deleted': False, '_context_project_domain': None, + '_context_resource_uuid': None, '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'message_id': '548650b4-2cba-45b6-9b3b-b87cb5c3246e', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_unique_id': '9ffd93fe355141d9976c6808a9ce9b7d', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_read_only': False, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_timestamp': '2016-10-25 00:00:18.505443', + 'priority': 'INFO', '_context_roles': ['_member_', 'admin'], '_context_project_name': 'calipso-project', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_user_name': 'admin', + 'timestamp': '2016-10-25 00:00:19.354342', '_context_request_id': 'req-62945d8f-a233-44c8-aa53-f608ad92fd56', + '_context_tenant_name': 'calipso-project', '_context_domain': None, 'payload': { + 'subnet': {'name': 'port', 'subnetpool_id': None, 'id': '393a1f80-4277-4c9a-b44c-0bc05a5121c6', + 'network_id': '0abe6331-0d74-4bbd-ad89-a5719c3793e4', 'gateway_ip': '172.16.12.1', + 'ipv6_address_mode': None, 'dns_nameservers': [], 'ipv6_ra_mode': None, 'cidr': '172.16.12.0/24', + 'allocation_pools': [{'start': '172.16.12.2', 'end': '172.16.12.254'}], 'enable_dhcp': True, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'host_routes': [], 'ip_version': 4}}, + '_context_is_admin': True, '_context_user_domain': None, 'event_type': 'subnet.update.end', + '_context_auth_token': 'gAAAAABYDp0ZacwkUNIRvtiS-3qjLQFZKbkOtTmvuoKX9yM8yCIvl-eZmMC_SPjwPAMJcd8qckE77lLpQ' + + 'Sx0lWB67mT5jQA-tmp8bcz26kXXr8KlGCicxxjkYTYkJQhC9w8BbGc36CpbRBzIKlOrPtPXUYZrUmPgInQ' + + 'qCNA-eDeMyJ-AiA1zmNSZK3R43YIJtnDYieLQvX2P'} + +EVENT_PAYLOAD_SUBNET_UPDATE_1 = { + 'publisher_id': 'network.node-6.cisco.com', '_context_show_deleted': False, '_context_project_domain': None, + '_context_resource_uuid': None, '_context_tenant': '75c0eb79ff4a42b0ae4973c8375ddf40', + 'message_id': 'd0f7545f-a2d6-4b0e-a658-01e4de4ecd19', + '_context_user_identity': '13baa553aae44adca6615e711fd2f6d9 75c0eb79ff4a42b0ae4973c8375ddf40 - - -', + '_context_tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_unique_id': '1ca167b1317d4523a31b2ae99b25d67c', + '_context_project_id': '75c0eb79ff4a42b0ae4973c8375ddf40', '_context_read_only': False, + '_context_user_id': '13baa553aae44adca6615e711fd2f6d9', '_context_timestamp': '2016-10-25 00:03:21.079403', + 'priority': 'INFO', '_context_roles': ['_member_', 'admin'], '_context_project_name': 'calipso-project', + '_context_user': '13baa553aae44adca6615e711fd2f6d9', '_context_user_name': 'admin', + 'timestamp': '2016-10-25 00:03:22.689115', '_context_request_id': 'req-7a19e8d7-51f6-470e-9035-5e007c9b1f89', + '_context_tenant_name': 'calipso-project', '_context_domain': None, 'payload': { + 'subnet': {'name': 'port', 'subnetpool_id': None, 'id': '393a1f80-4277-4c9a-b44c-0bc05a5121c6', + 'network_id': '0abe6331-0d74-4bbd-ad89-a5719c3793e4', 'gateway_ip': None, 'ipv6_address_mode': None, + 'dns_nameservers': [], 'ipv6_ra_mode': None, 'cidr': '172.16.12.0/24', + 'allocation_pools': [{'start': '172.16.12.2', 'end': '172.16.12.254'}], 'enable_dhcp': True, + 'tenant_id': '75c0eb79ff4a42b0ae4973c8375ddf40', 'host_routes': [], 'ip_version': 4}}, + '_context_is_admin': True, '_context_user_domain': None, 'event_type': 'subnet.update.end', + '_context_auth_token': 'gAAAAABYDp0ZacwkUNIRvtiS-3qjLQFZKbkOtTmvuoKX9yM8yCIvl-eZmMC_SPjwPAMJcd8qckE77lLpQSx0l'+ + 'WB67mT5jQA-tmp8bcz26kXXr8KlGCicxxjkYTYkJQhC9w8BbGc36CpbRBzIKlOrPtPXUYZrUmPgInQqCNA-eD'+ + 'eMyJ-AiA1zmNSZK3R43YIJtnDYieLQvX2P'} diff --git a/app/test/event_based_scan/test_event.py b/app/test/event_based_scan/test_event.py new file mode 100644 index 0000000..e3e8ab9 --- /dev/null +++ b/app/test/event_based_scan/test_event.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 # +############################################################################### +import re +import unittest + +from discover.configuration import Configuration +from test.event_based_scan.config.test_config \ + import MONGODB_CONFIG, ENV_CONFIG, COLLECTION_CONFIG +from utils.inventory_mgr import InventoryMgr +from utils.logging.console_logger import ConsoleLogger +from utils.mongo_access import MongoAccess + + +class TestEvent(unittest.TestCase): + def setUp(self): + self.log = ConsoleLogger() + self.mongo_config = MONGODB_CONFIG + self.env = ENV_CONFIG + self.collection = COLLECTION_CONFIG + + MongoAccess.set_config_file(self.mongo_config) + self.conf = Configuration() + self.conf.use_env(self.env) + + self.inv = InventoryMgr() + self.inv.set_collections(self.collection) + self.item_ids = [] + + def set_item(self, document): + self.inv.set(document) + self.item_ids.append(document['id']) + + def assert_empty_by_id(self, object_id): + doc = self.inv.get_by_id(self.env, object_id) + self.assertIsNone(doc) + + def tearDown(self): + for item_id in self.item_ids: + item = self.inv.get_by_id(self.env, item_id) + # delete children + if item: + regexp = re.compile('^{}/'.format(item['id_path'])) + self.inv.delete('inventory', {'id_path': {'$regex': regexp}}) + + # delete target item + self.inv.delete('inventory', {'id': item_id}) + item = self.inv.get_by_id(self.env, item_id) + self.assertIsNone(item) diff --git a/app/test/event_based_scan/test_event_delete_base.py b/app/test/event_based_scan/test_event_delete_base.py new file mode 100644 index 0000000..1ccabb3 --- /dev/null +++ b/app/test/event_based_scan/test_event_delete_base.py @@ -0,0 +1,64 @@ +############################################################################### +# 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 import ObjectId + +from discover.clique_finder import CliqueFinder +from discover.events.event_base import EventBase +from test.event_based_scan.test_event import TestEvent + + +class TestEventDeleteBase(TestEvent): + + def setUp(self): + super().setUp() + self.values = {} + + def set_item_for_deletion(self, object_type, document): + + payload = self.values['payload'] + self.item_id = payload['{}_id'.format(object_type)] + if object_type == 'router': + host_id = self.values['publisher_id'].replace("network.", "", 1) + self.item_id = "-".join([host_id, "qrouter", self.item_id]) + + self.assertEqual(document['id'], self.item_id, msg="Document id and payload id are different") + + item = self.inv.get_by_id(self.env, self.item_id) + if not item: + self.log.info('{} document is not found, add document for deleting.'.format(object_type)) + + # add network document for deleting. + self.set_item(document) + item = self.inv.get_by_id(self.env, self.item_id) + self.assertIsNotNone(item) + + def handle_delete(self, handler: EventBase): + + item = self.inv.get_by_id(self.env, self.item_id) + db_id = ObjectId(item['_id']) + clique_finder = CliqueFinder() + + # delete item + event_result = handler.handle(self.env, self.values) + self.assertTrue(event_result.result) + + # check instance delete result. + item = self.inv.get_by_id(self.env, self.item_id) + self.assertIsNone(item) + + # check links + matched_links_source = clique_finder.find_links_by_source(db_id) + matched_links_target = clique_finder.find_links_by_target(db_id) + self.assertEqual(matched_links_source.count(), 0) + self.assertEqual(matched_links_target.count(), 0) + + # check children + matched_children = self.inv.get_children(self.env, None, self.item_id) + self.assertEqual(len(matched_children), 0) diff --git a/app/test/event_based_scan/test_instance_add.py b/app/test/event_based_scan/test_instance_add.py new file mode 100644 index 0000000..24c29b2 --- /dev/null +++ b/app/test/event_based_scan/test_instance_add.py @@ -0,0 +1,61 @@ +############################################################################### +# 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 + +from discover.events.event_instance_add import EventInstanceAdd +from test.event_based_scan.test_data.event_payload_instance_add \ + import EVENT_PAYLOAD_INSTANCE_ADD, INSTANCES_ROOT, HOST, INSTANCE_DOCUMENT +from test.event_based_scan.test_event import TestEvent + + +class TestInstanceAdd(TestEvent): + + def insert_instance(self): + self.set_item(INSTANCE_DOCUMENT) + + # Patch ScanHost entirely to negate its side effects and supply our own + @patch("discover.events.event_instance_add.ScanHost") + def test_handle_instance_add(self, scan_host_mock): + self.values = EVENT_PAYLOAD_INSTANCE_ADD + payload = self.values['payload'] + self.instance_id = payload['instance_id'] + host_id = payload['host'] + + # prepare instances root, in case it's not there + self.set_item(INSTANCES_ROOT) + + # prepare host, in case it's not existed. + self.set_item(HOST) + + # check instance document + instance = self.inv.get_by_id(self.env, self.instance_id) + if instance: + self.log.info('instance document exists, delete it first.') + self.inv.delete('inventory', {'id': self.instance_id}) + + instance = self.inv.get_by_id(self.env, self.instance_id) + self.assertIsNone(instance) + + # simulate instance insertion after host scan + scan_host_mock.return_value.scan_links.side_effect = self.insert_instance + + # check the return of instance handler. + handler = EventInstanceAdd() + ret = handler.handle(self.env, self.values) + + self.assertEqual(ret.result, True) + + # check host document + host = self.inv.get_by_id(self.env, host_id) + self.assertIsNotNone(host) + + # check instance document + instance_document = self.inv.get_by_id(self.env, self.instance_id) + self.assertIsNotNone(instance_document) diff --git a/app/test/event_based_scan/test_instance_delete.py b/app/test/event_based_scan/test_instance_delete.py new file mode 100644 index 0000000..1572e9d --- /dev/null +++ b/app/test/event_based_scan/test_instance_delete.py @@ -0,0 +1,24 @@ +############################################################################### +# 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.events.event_instance_delete import EventInstanceDelete +from test.event_based_scan.test_data.event_payload_instance_delete import EVENT_PAYLOAD_INSTANCE_DELETE, \ + INSTANCE_DOCUMENT +from test.event_based_scan.test_event_delete_base import TestEventDeleteBase + + +class TestInstanceDelete(TestEventDeleteBase): + + def setUp(self): + super().setUp() + self.values = EVENT_PAYLOAD_INSTANCE_DELETE + self.set_item_for_deletion(object_type="instance", document=INSTANCE_DOCUMENT) + + def test_handle_instance_delete(self): + self.handle_delete(handler=EventInstanceDelete()) diff --git a/app/test/event_based_scan/test_instance_update.py b/app/test/event_based_scan/test_instance_update.py new file mode 100644 index 0000000..6abccb5 --- /dev/null +++ b/app/test/event_based_scan/test_instance_update.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 # +############################################################################### +from discover.events.event_instance_update import EventInstanceUpdate +from test.event_based_scan.test_data.event_payload_instance_update import EVENT_PAYLOAD_INSTANCE_UPDATE, INSTANCE_DOCUMENT +from test.event_based_scan.test_event import TestEvent + + +class TestInstanceUpdate(TestEvent): + + def test_handle_normal_situation(self): + self.values = EVENT_PAYLOAD_INSTANCE_UPDATE + payload = self.values['payload'] + self.instance_id = payload['instance_id'] + self.item_ids.append(self.instance_id) + new_name = payload['display_name'] + + # preparing instance to be updated + instance = self.inv.get_by_id(self.env, self.instance_id) + if not instance: + self.log.info("instance document is not found, add document for updating") + + # add instance document for updating + self.set_item(INSTANCE_DOCUMENT) + instance = self.inv.get_by_id(self.env, self.instance_id) + self.assertIsNotNone(instance) + self.assertEqual(instance['name'], INSTANCE_DOCUMENT['name']) + + name_path = instance['name_path'] + new_name_path = name_path[:name_path.rindex('/') + 1] + new_name + + # update instance document + EventInstanceUpdate().handle(self.env, self.values) + + # get new document + instance = self.inv.get_by_id(self.env, self.instance_id) + + # check update result. + self.assertEqual(instance['name'], new_name) + self.assertEqual(instance['name_path'], new_name_path) diff --git a/app/test/event_based_scan/test_interface_add.py b/app/test/event_based_scan/test_interface_add.py new file mode 100644 index 0000000..a9eaac8 --- /dev/null +++ b/app/test/event_based_scan/test_interface_add.py @@ -0,0 +1,74 @@ +############################################################################### +# 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.events.event_interface_add import EventInterfaceAdd +from discover.fetchers.api.api_access import ApiAccess +from discover.fetchers.api.api_fetch_port import ApiFetchPort +from discover.fetchers.cli.cli_fetch_host_vservice import CliFetchHostVservice +from discover.fetchers.cli.cli_fetch_vservice_vnics import CliFetchVserviceVnics +from discover.find_links_for_vservice_vnics import FindLinksForVserviceVnics +from test.event_based_scan.test_data.event_payload_interface_add import EVENT_PAYLOAD_INTERFACE_ADD, NETWORK_DOC, \ + EVENT_PAYLOAD_REGION, PORT_DOC, ROUTER_DOCUMENT, HOST, VNIC_DOCS +from test.event_based_scan.test_event import TestEvent +from utils.util import encode_router_id + + +class TestInterfaceAdd(TestEvent): + def test_handle_interface_add(self): + self.values = EVENT_PAYLOAD_INTERFACE_ADD + self.payload = self.values['payload'] + self.interface = self.payload['router_interface'] + + self.port_id = self.interface['port_id'] + self.host_id = self.values["publisher_id"].replace("network.", "", 1) + self.router_id = encode_router_id(self.host_id, self.interface['id']) + + self.set_item(NETWORK_DOC) + ApiAccess.regions = EVENT_PAYLOAD_REGION + + # mock port data, + original_api_get_port = ApiFetchPort.get + ApiFetchPort.get = MagicMock(return_value=[PORT_DOC]) + self.item_ids.append(PORT_DOC['id']) + + # set router document + self.set_item(ROUTER_DOCUMENT) + + # set host document + self.set_item(HOST) + + # mock add_links + original_add_links = FindLinksForVserviceVnics.add_links + FindLinksForVserviceVnics.add_links = MagicMock() + + # mock get_vservice + original_get_vservice = CliFetchHostVservice.get_vservice + CliFetchHostVservice.get_vservice = MagicMock(return_value=ROUTER_DOCUMENT) + + # mock handle_vservice + original_handle_service = CliFetchVserviceVnics.handle_service + CliFetchVserviceVnics.handle_service = MagicMock(return_value=VNIC_DOCS) + + # handle the notification + EventInterfaceAdd().handle(self.env, self.values) + + # reset the method. + ApiFetchPort.get = original_api_get_port + FindLinksForVserviceVnics.add_links = original_add_links + CliFetchHostVservice.get_vservice = original_get_vservice + CliFetchVserviceVnics.handle_service = original_handle_service + + # check port and router document + port_doc = self.inv.get_by_id(self.env, self.port_id) + self.assertIsNotNone(port_doc) + + router_doc = self.inv.get_by_id(self.env, self.router_id) + self.assertIn(NETWORK_DOC['id'], router_doc['network']) diff --git a/app/test/event_based_scan/test_interface_delete.py b/app/test/event_based_scan/test_interface_delete.py new file mode 100644 index 0000000..b156758 --- /dev/null +++ b/app/test/event_based_scan/test_interface_delete.py @@ -0,0 +1,44 @@ +############################################################################### +# 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.events.event_interface_delete import EventInterfaceDelete +from discover.fetchers.api.api_access import ApiAccess +from test.event_based_scan.test_data.event_payload_interface_delete import EVENT_PAYLOAD_INTERFACE_DELETE, NETWORK_DOC, \ + EVENT_PAYLOAD_REGION, PORT_DOC, ROUTER_DOCUMENT, HOST, VNIC_DOCS +from test.event_based_scan.test_event import TestEvent +from utils.util import encode_router_id + + +class TestInterfaceDelete(TestEvent): + def test_handle_interface_delete(self): + self.values = EVENT_PAYLOAD_INTERFACE_DELETE + self.payload = self.values['payload'] + self.interface = self.payload['router_interface'] + + self.port_id = self.interface['port_id'] + self.host_id = self.values["publisher_id"].replace("network.", "", 1) + self.router_id = encode_router_id(self.host_id, self.interface['id']) + + # set document for instance deleting. + self.set_item(NETWORK_DOC) + self.set_item(PORT_DOC) + self.set_item(ROUTER_DOCUMENT) + self.set_item(HOST) + self.set_item(VNIC_DOCS[0]) + ApiAccess.regions = EVENT_PAYLOAD_REGION + + # delete interface + EventInterfaceDelete().handle(self.env, self.values) + + # assert data + router_doc = self.inv.get_by_id(self.env, ROUTER_DOCUMENT['id']) + self.assertNotIn(NETWORK_DOC['id'], router_doc['network']) + + self.assert_empty_by_id(PORT_DOC['id']) + self.assert_empty_by_id(VNIC_DOCS[0]['id']) diff --git a/app/test/event_based_scan/test_network_add.py b/app/test/event_based_scan/test_network_add.py new file mode 100644 index 0000000..08be9e1 --- /dev/null +++ b/app/test/event_based_scan/test_network_add.py @@ -0,0 +1,47 @@ +############################################################################### +# 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.events.event_network_add import EventNetworkAdd +from test.event_based_scan.test_data.event_payload_network_add import EVENT_PAYLOAD_NETWORK_ADD +from test.event_based_scan.test_event import TestEvent + + +class TestNetworkAdd(TestEvent): + + def test_handle_network_add(self): + self.values = EVENT_PAYLOAD_NETWORK_ADD + self.payload = self.values['payload'] + self.network = self.payload['network'] + self.network_id = self.network['id'] + self.item_ids.append(self.network_id) + + network_document = self.inv.get_by_id(self.env, self.network_id) + if network_document: + self.log.info('network document existed already, deleting it first.') + self.inv.delete('inventory', {'id': self.network_id}) + + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIsNone(network_document) + + # build network document for adding network + project_name = self.values['_context_project_name'] + project_id = self.values['_context_project_id'] + parent_id = project_id + '-networks' + network_name = self.network['name'] + + # add network document + EventNetworkAdd().handle(self.env, self.values) + + # check network document + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIsNotNone(network_document) + self.assertEqual(network_document["project"], project_name) + self.assertEqual(network_document["parent_id"], parent_id) + self.assertEqual(network_document["name"], network_name) + diff --git a/app/test/event_based_scan/test_network_delete.py b/app/test/event_based_scan/test_network_delete.py new file mode 100644 index 0000000..3e08af1 --- /dev/null +++ b/app/test/event_based_scan/test_network_delete.py @@ -0,0 +1,24 @@ +############################################################################### +# 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.events.event_network_delete import EventNetworkDelete +from test.event_based_scan.test_data.event_payload_network_delete import EVENT_PAYLOAD_NETWORK_DELETE, \ + EVENT_PAYLOAD_NETWORK +from test.event_based_scan.test_event_delete_base import TestEventDeleteBase + + +class TestNetworkDelete(TestEventDeleteBase): + + def setUp(self): + super().setUp() + self.values = EVENT_PAYLOAD_NETWORK_DELETE + self.set_item_for_deletion(object_type="network", document=EVENT_PAYLOAD_NETWORK) + + def test_handle_network_delete(self): + self.handle_delete(handler=EventNetworkDelete()) diff --git a/app/test/event_based_scan/test_network_update.py b/app/test/event_based_scan/test_network_update.py new file mode 100644 index 0000000..bf9eee4 --- /dev/null +++ b/app/test/event_based_scan/test_network_update.py @@ -0,0 +1,33 @@ +############################################################################### +# 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.events.event_network_update import EventNetworkUpdate +from test.event_based_scan.test_data.event_payload_network_update import EVENT_PAYLOAD_NETWORK_UPDATE, \ + NETWORK_DOCUMENT +from test.event_based_scan.test_event import TestEvent + + +class TestNetworkUpdate(TestEvent): + + def test_handle_network_update(self): + self.values = EVENT_PAYLOAD_NETWORK_UPDATE + self.payload = self.values['payload'] + self.network = self.payload['network'] + name = self.network['name'] + status = self.network['admin_state_up'] + + self.network_id = self.network['id'] + self.item_ids.append(self.network_id) + self.set_item(NETWORK_DOCUMENT) + + EventNetworkUpdate().handle(self.env, self.values) + + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertEqual(network_document['name'], name) + self.assertEqual(network_document['admin_state_up'], status) diff --git a/app/test/event_based_scan/test_port_add.py b/app/test/event_based_scan/test_port_add.py new file mode 100644 index 0000000..8bf2553 --- /dev/null +++ b/app/test/event_based_scan/test_port_add.py @@ -0,0 +1,75 @@ +############################################################################### +# 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.events.event_port_add import EventPortAdd +from discover.fetchers.api.api_fetch_host_instances import ApiFetchHostInstances +from discover.fetchers.cli.cli_fetch_instance_vnics import CliFetchInstanceVnics +from discover.find_links_for_instance_vnics import FindLinksForInstanceVnics +from discover.find_links_for_vedges import FindLinksForVedges +from discover.scanner import Scanner +from test.event_based_scan.test_data.event_payload_port_add import EVENT_PAYLOAD_PORT_INSTANCE_ADD, NETWORK_DOC, \ + INSTANCE_DOC, INSTANCES_ROOT, VNIC_DOCS, INSTANCE_DOCS +from test.event_based_scan.test_event import TestEvent + + +class TestPortAdd(TestEvent): + def test_handle_port_add(self): + self.values = EVENT_PAYLOAD_PORT_INSTANCE_ADD + self.payload = self.values['payload'] + self.port = self.payload['port'] + self.port_id = self.port['id'] + self.item_ids.append(self.port_id) + + # prepare data for test + self.set_item(NETWORK_DOC) + self.set_item(INSTANCE_DOC) + self.set_item(INSTANCES_ROOT) + self.item_ids.append(VNIC_DOCS[0]['id']) + + # mock methods + original_get_instance = ApiFetchHostInstances.get + ApiFetchHostInstances.get = MagicMock(return_value=INSTANCE_DOCS) + + original_get_vnic = CliFetchInstanceVnics.get + CliFetchInstanceVnics.get = MagicMock(return_value=VNIC_DOCS) + + original_find_link_instance = FindLinksForInstanceVnics.add_links + original_find_link_vedge = FindLinksForVedges.add_links + original_scan = Scanner.scan_cliques + + FindLinksForInstanceVnics.add_links = MagicMock(return_value=None) + FindLinksForVedges.add_links = MagicMock(return_value=None) + Scanner.scan_cliques = MagicMock(return_value=None) + + # add network document + EventPortAdd().handle(self.env, self.values) + + # check network document + port_document = self.inv.get_by_id(self.env, self.port_id) + self.assertIsNotNone(port_document) + self.assertEqual(port_document["name"], self.port['name']) + + instance = self.inv.get_by_id(self.env, INSTANCE_DOC['id']) + self.assertEqual(instance["network_info"][0]['devname'], + INSTANCE_DOCS[0]["network_info"][0]['devname']) + self.assertEqual(instance["network_info"], + INSTANCE_DOCS[0]["network_info"]) + self.assertEqual(instance["network"], INSTANCE_DOCS[0]["network"]) + + vnic = self.inv.get_by_field(self.env, 'vnic', 'mac_address', + self.port['mac_address']) + self.assertIsNotNone(vnic) + + FindLinksForVedges.add_links = original_find_link_vedge + FindLinksForInstanceVnics.add_links = original_find_link_instance + Scanner.scan_cliques = original_scan + CliFetchInstanceVnics.get = original_get_vnic + ApiFetchHostInstances.get = original_get_instance diff --git a/app/test/event_based_scan/test_port_delete.py b/app/test/event_based_scan/test_port_delete.py new file mode 100644 index 0000000..78fa1d2 --- /dev/null +++ b/app/test/event_based_scan/test_port_delete.py @@ -0,0 +1,47 @@ +############################################################################### +# 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.events.event_port_delete import EventPortDelete +from discover.fetchers.api.api_fetch_host_instances import ApiFetchHostInstances +from test.event_based_scan.test_data.event_payload_port_delete import EVENT_PAYLOAD_PORT_DELETE, PORT_DOC, VNIC_DOCS, \ + INSTANCE_DOC, INSTANCE_DOCS +from test.event_based_scan.test_event import TestEvent + + +class TestPortDelete(TestEvent): + def test_handle_port_delete(self): + self.values = EVENT_PAYLOAD_PORT_DELETE + self.payload = self.values['payload'] + self.port_id = self.payload['port_id'] + self.item_ids.append(self.port_id) + + # set port data firstly. + self.set_item(PORT_DOC) + self.set_item(VNIC_DOCS[0]) + self.set_item(INSTANCE_DOC) + + # mock methods + original_get_instance = ApiFetchHostInstances.get + ApiFetchHostInstances.get = MagicMock(return_value=INSTANCE_DOCS) + self.item_ids.append(INSTANCE_DOCS[0]['id']) + + # delete port + EventPortDelete().handle(self.env, self.values) + + # assert data + self.assert_empty_by_id(self.port_id) + self.assert_empty_by_id(VNIC_DOCS[0]['id']) + instance = self.inv.get_by_id(self.env, INSTANCE_DOC['id']) + self.assertEqual(instance['mac_address'], None) + self.assertEqual(instance['network'], []) + self.assertEqual(instance['network_info'], []) + + ApiFetchHostInstances.get = original_get_instance diff --git a/app/test/event_based_scan/test_port_update.py b/app/test/event_based_scan/test_port_update.py new file mode 100644 index 0000000..889bb93 --- /dev/null +++ b/app/test/event_based_scan/test_port_update.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.events.event_port_update import EventPortUpdate +from test.event_based_scan.test_data.event_payload_port_update import EVENT_PAYLOAD_PORT_UPDATE, PORT_DOCUMENT +from test.event_based_scan.test_event import TestEvent + + +class TestPortUpdate(TestEvent): + + def test_handle_port_update(self): + self.values = EVENT_PAYLOAD_PORT_UPDATE + self.payload = self.values['payload'] + self.port = self.payload['port'] + self.port_id = self.port['id'] + + # set port data firstly. + self.inv.set(PORT_DOCUMENT) + + # add network document + EventPortUpdate().handle(self.env, self.values) + + # check network document + port_document = self.inv.get_by_id(self.env, self.port_id) + self.assertIsNotNone(port_document) + self.assertEqual(port_document["name"], self.port['name']) + self.assertEqual(port_document['admin_state_up'], self.port['admin_state_up']) + self.assertEqual(port_document['binding:vnic_type'], self.port['binding:vnic_type']) diff --git a/app/test/event_based_scan/test_router_add.py b/app/test/event_based_scan/test_router_add.py new file mode 100644 index 0000000..0a24901 --- /dev/null +++ b/app/test/event_based_scan/test_router_add.py @@ -0,0 +1,79 @@ +############################################################################### +# 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.events.event_port_add import EventPortAdd +from discover.events.event_router_add import EventRouterAdd +from discover.events.event_subnet_add import EventSubnetAdd +from discover.fetchers.cli.cli_fetch_host_vservice import CliFetchHostVservice +from test.event_based_scan.test_data.event_payload_router_add import EVENT_PAYLOAD_ROUTER_ADD, ROUTER_DOCUMENT, \ + HOST_DOC, NETWORK_DOC +from test.event_based_scan.test_event import TestEvent +from utils.util import encode_router_id + + +class TestRouterAdd(TestEvent): + def test_handle_router_add(self): + self.values = EVENT_PAYLOAD_ROUTER_ADD + self.payload = self.values['payload'] + self.router = self.payload['router'] + self.host_id = self.values["publisher_id"].replace("network.", "", 1) + self.router_id = encode_router_id(self.host_id, self.router['id']) + + self.set_item(HOST_DOC) + self.host_id = HOST_DOC['id'] + gateway_info = self.router['external_gateway_info'] + if gateway_info: + self.network_id = self.router['external_gateway_info']['network_id'] + self.inv.set(NETWORK_DOC) + + original_get_vservice = CliFetchHostVservice.get_vservice + CliFetchHostVservice.get_vservice = MagicMock(return_value=ROUTER_DOCUMENT) + self.gw_port_id = ROUTER_DOCUMENT['gw_port_id'] + + original_add_port = EventSubnetAdd.add_port_document + EventSubnetAdd.add_port_document = MagicMock() + + original_add_vnic = EventPortAdd.add_vnic_document + EventPortAdd.add_vnic_document = MagicMock() + + handler = EventRouterAdd() + handler.update_links_and_cliques = MagicMock() + + handler.handle(self.env, self.values) + + # reset the methods back + CliFetchHostVservice.get_vservice = original_get_vservice + EventSubnetAdd.add_port_document = original_add_port + EventPortAdd.add_vnic_document = original_add_vnic + + # assert router document + router_doc = self.inv.get_by_id(self.env, self.router_id) + self.assertIsNotNone(router_doc, msg="router_doc not found.") + self.assertEqual(ROUTER_DOCUMENT['name'], router_doc['name']) + self.assertEqual(ROUTER_DOCUMENT['gw_port_id'], router_doc['gw_port_id']) + + # assert children documents + vnics_id = '-'.join(['qrouter', self.router['id'], 'vnics']) + vnics_folder = self.inv.get_by_id(self.env, vnics_id) + self.assertIsNotNone(vnics_folder, msg="Vnics folder not found.") + + def tearDown(self): + self.item_ids = [self.network_id, self.host_id, self.network_id+"-ports", self.gw_port_id, + self.router_id+'-vnics', self.router_id] + for item_id in self.item_ids: + self.inv.delete('inventory', {'id': item_id}) + item = self.inv.get_by_id(self.env, item_id) + self.assertIsNone(item) + + # delete vnics document + self.inv.delete('inventory', {'parent_id': self.router_id+'-vnics'}) + item = self.inv.get_by_field(self.env, 'vnic', 'parent_id', self.router_id+'-vnics', get_single=True) + self.assertIsNone(item) diff --git a/app/test/event_based_scan/test_router_delete.py b/app/test/event_based_scan/test_router_delete.py new file mode 100644 index 0000000..9d5c13f --- /dev/null +++ b/app/test/event_based_scan/test_router_delete.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.events.event_router_delete import EventRouterDelete +from test.event_based_scan.test_data.event_payload_router_delete import EVENT_PAYLOAD_ROUTER_DELETE, ROUTER_DOCUMENT +from test.event_based_scan.test_event_delete_base import TestEventDeleteBase + + +class TestRouterDelete(TestEventDeleteBase): + + def setUp(self): + super().setUp() + self.values = EVENT_PAYLOAD_ROUTER_DELETE + self.set_item_for_deletion(object_type="router", document=ROUTER_DOCUMENT) + + def test_handle_router_delete(self): + self.handle_delete(handler=EventRouterDelete()) diff --git a/app/test/event_based_scan/test_router_update.py b/app/test/event_based_scan/test_router_update.py new file mode 100644 index 0000000..72e8edd --- /dev/null +++ b/app/test/event_based_scan/test_router_update.py @@ -0,0 +1,62 @@ +############################################################################### +# 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.events.event_router_update import EventRouterUpdate +from discover.fetchers.api.api_fetch_port import ApiFetchPort +from discover.fetchers.cli.cli_fetch_host_vservice import CliFetchHostVservice +from test.event_based_scan.test_data.event_payload_router_update import EVENT_PAYLOAD_ROUTER_UPDATE, ROUTER_DOCUMENT, \ + EVENT_PAYLOAD_ROUTER_SET_GATEWAY, EVENT_PAYLOAD_ROUTER_DEL_GATEWAY, ROUTER_VSERVICE, PORTS, NETWORK_DOC, HOST_DOC +from test.event_based_scan.test_event import TestEvent +from utils.util import encode_router_id + + +class TestRouterUpdate(TestEvent): + def test_handle_router_update(self): + for values in [EVENT_PAYLOAD_ROUTER_UPDATE, EVENT_PAYLOAD_ROUTER_SET_GATEWAY, EVENT_PAYLOAD_ROUTER_DEL_GATEWAY]: + self.values = values + self.payload = self.values['payload'] + self.router = self.payload['router'] + host_id = self.values['publisher_id'].replace("network.", "", 1) + self.router_id = encode_router_id(host_id, self.router['id']) + self.item_ids.append(self.router_id) + + # add document for testing + self.set_item(ROUTER_DOCUMENT) + self.set_item(PORTS) + self.set_item(NETWORK_DOC) + self.set_item(HOST_DOC) + + # mock the router document. + original_get_vservice = CliFetchHostVservice.get_vservice + CliFetchHostVservice.get_vservice = MagicMock(return_value=ROUTER_VSERVICE) + self.gw_port_id = ROUTER_DOCUMENT['gw_port_id'] + + # mock + original_get_port = ApiFetchPort.get + ApiFetchPort.get = MagicMock(return_value=[PORTS]) + + handler = EventRouterUpdate() + handler.handle(self.env, self.values) + + # reset the methods back + CliFetchHostVservice.get_vservice = original_get_vservice + ApiFetchPort.get = original_get_port + # assert router document + router_doc = self.inv.get_by_id(self.env, self.router_id) + self.assertIsNotNone(router_doc, msg="router_doc not found.") + self.assertEqual(self.router['name'], router_doc['name']) + self.assertEqual(self.router['admin_state_up'], router_doc['admin_state_up']) + + if self.router['external_gateway_info'] is None: + self.assertEqual(router_doc['gw_port_id'], None) + self.assertEqual(router_doc['network'], []) + else: + self.assertIn(self.router['external_gateway_info']['network_id'], router_doc['network']) diff --git a/app/test/event_based_scan/test_subnet_add.py b/app/test/event_based_scan/test_subnet_add.py new file mode 100644 index 0000000..a8794ef --- /dev/null +++ b/app/test/event_based_scan/test_subnet_add.py @@ -0,0 +1,68 @@ +############################################################################### +# 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.events.event_subnet_add import EventSubnetAdd +from discover.fetchers.api.api_access import ApiAccess +from discover.find_links_for_pnics import FindLinksForPnics +from discover.find_links_for_vservice_vnics import FindLinksForVserviceVnics +from test.event_based_scan.test_data.event_payload_subnet_add import EVENT_PAYLOAD_SUBNET_ADD,\ + EVENT_PAYLOAD_REGION, NETWORK_DOC +from test.event_based_scan.test_event import TestEvent + + +class TestSubnetAdd(TestEvent): + + def test_handle_subnet_add(self): + self.values = EVENT_PAYLOAD_SUBNET_ADD + self.payload = self.values['payload'] + self.subnet = self.payload['subnet'] + self.subnet_id = self.subnet['id'] + self.network_id = self.subnet['network_id'] + self.item_ids.append(self.network_id) + + network_document = self.inv.get_by_id(self.env, self.network_id) + if network_document: + # check subnet in network first. + self.assertNotIn(self.subnet['cidr'], network_document['cidrs']) + else: + self.log.info("network document is not found, add it first.") + self.set_item(NETWORK_DOC) + # check network document + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIsNotNone(network_document) + + # check region data. + if not ApiAccess.regions: + ApiAccess.regions = EVENT_PAYLOAD_REGION + + # Mock function instead of get children data. They should be test in their unit test. + # add subnet document for updating network + handler = EventSubnetAdd() + handler.add_children_documents = MagicMock() + + original_add_pnic_links = FindLinksForPnics.add_links + FindLinksForPnics.add_links = MagicMock() + + original_add_vservice_links = FindLinksForVserviceVnics.add_links + FindLinksForVserviceVnics.add_links = MagicMock() + + handler.handle(self.env, self.values) + + # reset the methods back + FindLinksForPnics.add_links = original_add_pnic_links + FindLinksForVserviceVnics.add_links = original_add_vservice_links + + # check network document + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIn(self.subnet['cidr'], network_document['cidrs']) + self.assertIn(self.subnet['name'], network_document['subnets']) + + #tearDown method has been implemented in class testEvent. diff --git a/app/test/event_based_scan/test_subnet_delete.py b/app/test/event_based_scan/test_subnet_delete.py new file mode 100644 index 0000000..742b9d9 --- /dev/null +++ b/app/test/event_based_scan/test_subnet_delete.py @@ -0,0 +1,54 @@ +############################################################################### +# 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.events.event_subnet_delete import EventSubnetDelete +from test.event_based_scan.test_event import TestEvent +from test.event_based_scan.test_data.event_payload_subnet_delete import EVENT_PAYLOAD_SUBNET_DELETE, \ + EVENT_PAYLOAD_NETWORK + + +class TestSubnetDelete(TestEvent): + + def test_handle_subnet_delete(self): + self.values = EVENT_PAYLOAD_SUBNET_DELETE + self.subnet_id = self.values['payload']['subnet_id'] + self.network_doc = EVENT_PAYLOAD_NETWORK + self.network_id = self.network_doc['id'] + self.item_ids.append(self.network_id) + + self.subnet_name = None + self.cidr = None + + for subnet in self.network_doc['subnets'].values(): + if subnet['id'] == self.subnet_id: + self.subnet_name = subnet['name'] + self.cidr = subnet['cidr'] + break + + # add document for subnet deleting test. + self.set_item(self.network_doc) + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIsNotNone(network_document, "add network document failed") + + # delete subnet + EventSubnetDelete().handle(self.env, self.values) + + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertNotIn(self.subnet_id, network_document['subnet_ids']) + self.assertNotIn(self.cidr, network_document['cidrs']) + self.assertNotIn(self.subnet_name, network_document['subnets']) + + # assert children documents + vservice_dhcp_id = 'qdhcp-' + network_document['id'] + dhcp_doc = self.inv.get_by_id(self.env, vservice_dhcp_id) + self.assertIsNone(dhcp_doc) + + vnic_parent_id = vservice_dhcp_id + '-vnics' + vnic = self.inv.get_by_field(self.env, 'vnic', 'parent_id', vnic_parent_id, get_single=True) + self.assertIsNone(vnic) diff --git a/app/test/event_based_scan/test_subnet_update.py b/app/test/event_based_scan/test_subnet_update.py new file mode 100644 index 0000000..eddfe84 --- /dev/null +++ b/app/test/event_based_scan/test_subnet_update.py @@ -0,0 +1,45 @@ +############################################################################### +# 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.events.event_subnet_update import EventSubnetUpdate +from discover.fetchers.api.api_access import ApiAccess +from test.event_based_scan.test_data.event_payload_subnet_add import \ + EVENT_PAYLOAD_REGION +from test.event_based_scan.test_data.event_payload_subnet_update import EVENT_PAYLOAD_SUBNET_UPDATE, NETWORK_DOC +from test.event_based_scan.test_event import TestEvent + + +class TestSubnetUpdate(TestEvent): + + def test_handle_subnet_add(self): + self.values = EVENT_PAYLOAD_SUBNET_UPDATE + self.payload = self.values['payload'] + self.subnet = self.payload['subnet'] + self.subnet_id = self.subnet['id'] + self.network_id = self.subnet['network_id'] + self.item_ids.append(self.network_id) + + #add network document for subnet. + self.set_item(NETWORK_DOC) + + # check network document + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIsNotNone(network_document) + + # check region data. + if not ApiAccess.regions: + ApiAccess.regions = EVENT_PAYLOAD_REGION + + handler = EventSubnetUpdate() + handler.handle(self.env, self.values) + + # check network document + network_document = self.inv.get_by_id(self.env, self.network_id) + self.assertIn(self.subnet['name'], network_document['subnets']) + self.assertEqual(self.subnet['gateway_ip'], network_document['subnets'][self.subnet['name']]['gateway_ip']) 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 diff --git a/app/test/scan/__init__.py b/app/test/scan/__init__.py new file mode 100644 index 0000000..1e85a2a --- /dev/null +++ b/app/test/scan/__init__.py @@ -0,0 +1,10 @@ +############################################################################### +# 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/scan/config/__init__.py b/app/test/scan/config/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/scan/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/scan/config/test_config.py b/app/test/scan/config/test_config.py new file mode 100644 index 0000000..176fd48 --- /dev/null +++ b/app/test/scan/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/scan/main.py b/app/test/scan/main.py new file mode 100644 index 0000000..fb8c4b5 --- /dev/null +++ b/app/test/scan/main.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 # +############################################################################### +import unittest + +from test.scan.test_scanner import TestScanner +from test.scan.test_scan_controller import TestScanController +from test.scan.test_scan_metadata_parser import TestScanMetadataParser + +if __name__=='__main__': + unittest.main() diff --git a/app/test/scan/mock_module.py b/app/test/scan/mock_module.py new file mode 100644 index 0000000..e7aeb13 --- /dev/null +++ b/app/test/scan/mock_module.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 # +############################################################################### +class ScanEnvironment: + + run_scan_count = 0 + scan_links_count = 0 + scan_cliques_count = 0 + result = [] + + def set_result(self, result): + self.result = result + + def run_scan(self, *args): + ScanEnvironment.run_scan_count += 1 + return self.result + + def scan_links(self, *args): + ScanEnvironment.scan_links_count += 1 + + def scan_cliques(self, *args): + ScanEnvironment.scan_cliques_count += 1 + + def set_env(self, env): + pass + + @classmethod + def reset_counts(cls): + cls.run_scan_count = 0 + cls.scan_cliques_count = 0 + cls.scan_links_count = 0
\ No newline at end of file diff --git a/app/test/scan/test_data/__init__.py b/app/test/scan/test_data/__init__.py new file mode 100644 index 0000000..b0637e9 --- /dev/null +++ b/app/test/scan/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/scan/test_data/configurations.py b/app/test/scan/test_data/configurations.py new file mode 100644 index 0000000..da68dd1 --- /dev/null +++ b/app/test/scan/test_data/configurations.py @@ -0,0 +1,69 @@ +############################################################################### +# 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 = { + "app_path": "/home/scan/calipso_prod/app/", + "scanners_file": "/home/yarony/osdna_dev/app/discover/scanners.json", + "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/ngrandhi/.ssh/id_rsa", + "name": "CLI", + "pwd": "", + "user": "root" + }, + { + "name": "AMQP", + "host": "10.56.20.239", + "port": "5673", + "user": "nova", + "password": "NF2nSv3SisooxPkCTr8fbfOa" + }, + { + "config_folder": "/tmp/sensu_config", + "provision": "Deploy", + "env_type": "development", + "name": "Monitoring", + "rabbitmq_port": "5672", + "rabbitmq_pass": "osdna", + "rabbitmq_user": "sensu", + "ssh_port": "20022", + "ssh_user": "scan", + "ssh_password": "scan", + "server_ip": "korlev-osdna-staging1.cisco.com", + "server_name": "osdna-sensu", + "type": "Sensu" + } + ], + "distribution": "Mirantis-8.0", + "last_scanned:": "5/8/16", + "name": "Mirantis-Liberty-Nvn", + "mechanism_drivers": [ + "OVS" + ], + "operational": "yes", + "type": "environment" +} diff --git a/app/test/scan/test_data/metadata.py b/app/test/scan/test_data/metadata.py new file mode 100644 index 0000000..ed47c80 --- /dev/null +++ b/app/test/scan/test_data/metadata.py @@ -0,0 +1,318 @@ +############################################################################### +# 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 # +############################################################################### +METADATA_EMPTY = {} + +METADATA_SCANNERS_MISSING = {"scanners_package": "discover.fetchers"} + +METADATA_NO_PACKAGE = { + "scanners": {} +} + +METADATA_NO_SCANNERS = { + "scanners_package": "discover.fetchers" +} + +METADATA_ZERO_SCANNERS = { + "scanners_package": "discover.fetchers", + "scanners": {} +} + +METADATA_SIMPLE_SCANNER = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "type": "host_ref", + "fetcher": "DbFetchAggregateHosts" + } + ] + } +} + +METADATA_SCANNER_UNKNOWN_ATTRIBUTE = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "xyz": "123", + "type": "host_ref", + "fetcher": "DbFetchAggregateHosts" + } + ] + } +} + +METADATA_SCANNER_NO_TYPE = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "fetcher": "DbFetchAggregateHosts" + } + ] + } +} + +METADATA_SCANNER_NO_FETCHER = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "type": "host_ref" + } + ] + } +} + +METADATA_SCANNER_INCORRECT_TYPE = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "type": "t1", + "fetcher": "DbFetchAggregateHosts" + } + ] + } +} + +METADATA_SCANNER_INCORRECT_FETCHER = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregate": [ + { + "type": "host_ref", + "fetcher": "f1" + } + ] + } +} + +METADATA_SCANNER_WITH_CHILD = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregatesRoot": [ + { + "type": "aggregate", + "fetcher": "DbFetchAggregates", + "children_scanner": "ScanAggregate" + } + ], + "ScanAggregate": [ + { + "type": "host_ref", + "fetcher": "DbFetchAggregateHosts" + } + ] + } +} + +METADATA_SCANNER_WITH_INCORRECT_CHILD = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregatesRoot": [ + { + "type": "aggregate", + "fetcher": "DbFetchAggregates", + "children_scanner": 1 + } + ] + } +} + +METADATA_SCANNER_WITH_MISSING_CHILD = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanAggregatesRoot": [ + { + "type": "aggregate", + "fetcher": "DbFetchAggregates", + "children_scanner": "ScanAggregate" + } + ] + } +} + +METADATA_SCANNER_FETCHER_INVALID_DICT = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanEnvironment": [ + { + "type": "regions_folder", + "fetcher": { + "types_name": "regions", + "parent_type": "environment" + } + }, + ] + + } +} + +METADATA_SCANNER_WITH_FOLDER = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanEnvironment": [ + { + "type": "regions_folder", + "fetcher": { + "folder": 1, + "types_name": "regions", + "parent_type": "environment" + } + }, + { + "type": "projects_folder", + "fetcher": { + "folder": 1, + "types_name": "projects", + "parent_type": "environment" + } + } + ] + } +} + +METADATA_SCANNER_WITH_INVALID_CONDITION = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanHost": [ + { + "type": "pnics_folder", + "fetcher": "DbFetchAggregateHosts", + "environment_condition": 1 + } + ] + } +} + +METADATA_SCANNER_WITH_INVALID_MECHANISM_DRIVER_CONDITION = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanHost": [ + { + "type": "pnics_folder", + "fetcher": { + "folder": 1, + "types_name": "pnics", + "parent_type": "host", + "text": "pNICs" + }, + "environment_condition": { + "mechanism_drivers": "" + } + } + ] + } +} + +METADATA_SCANNER_WITH_INVALID_MECHANISM_DRIVER = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanHost": [ + { + "type": "pnics_folder", + "fetcher": { + "folder": 1, + "types_name": "pnics", + "parent_type": "host", + "text": "pNICs" + }, + "environment_condition": { + "mechanism_drivers": [ 1, 2] + } + } + ] + } +} + +METADATA_SCANNER_WITH_CONDITION = { + "scanners_package": "discover.fetchers", + "scanners": { + "ScanHost": [ + { + "type": "pnics_folder", + "fetcher": { + "folder": 1, + "types_name": "pnics", + "parent_type": "host", + "text": "pNICs" + }, + "environment_condition": { + "mechanism_drivers": [ + "OVS", + "LXB" + ] + } + } + ] + } +} + +CONSTANTS = { + "scan_object_types": { + "name": "scan_object_types", + "data": [ + { + "value": "regions_folder", + "label": "regions_folder" + }, + { + "value": "pnics_folder", + "label": "pnics_folder" + }, + { + "value": "projects_folder", + "label": "projects_folder" + }, + { + "value": "aggregate", + "label": "aggregate" + }, + { + "value": "host", + "label": "host" + }, + { + "value": "region", + "label": "region" + }, + { + "value": "host_ref", + "label": "host_ref" + } + ] + }, + "mechanism_drivers": { + "data": [ + { + "label": "OVS", + "value": "OVS" + }, + { + "label": "VPP", + "value": "VPP" + }, + { + "label": "LXB", + "value": "LXB" + }, + { + "label": "Arista", + "value": "Arista" + }, + { + "label": "Nexus", + "value": "Nexus" + } + ], + "name": "mechanism_drivers" + } +} diff --git a/app/test/scan/test_data/scan.py b/app/test/scan/test_data/scan.py new file mode 100644 index 0000000..fa36c3e --- /dev/null +++ b/app/test/scan/test_data/scan.py @@ -0,0 +1,435 @@ +############################################################################### +# 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 # +############################################################################### +UNIT_TESTS_ENV = "WebEX-Mirantis@Cisco" +UNIT_TESTS_INVENTORY = 'unit_tests' + +MONGO_CONFIG = 'mongo_config_file.txt' + +DEFAULT_ARGUMENTS = { + "MONGO_CONFIG": "", + "ENV": UNIT_TESTS_ENV, + "TYPE": "environment", + "INVENTORY": "inventory", + "SCAN_SELF": False, + "ID": UNIT_TESTS_ENV, + "PARENT_ID": "", + "PARENT_TYPE": "", + "ID_FIELD": "id", + "LOGLEVEL": "INFO", + "INVENTORY_ONLY": False, + "LINKS_ONLY": False, + "CLIQUES_ONLY": False, + "CLEAR": False +} + +SHORT_FLAGS_ARGUMENTS = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR" +} + +ARGUMENTS_FULL = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR", + "INVENTORY_ONLY": False, + "LINKS_ONLY": False, + "CLIQUES_ONLY": False, + "CLEAR": True, + "CLEAR_ALL": False +} + +ARGUMENTS_FULL_CLEAR_ALL = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR", + "INVENTORY_ONLY": False, + "LINKS_ONLY": False, + "CLIQUES_ONLY": False, + "CLEAR": False, + "CLEAR_ALL": True +} + +ARGUMENTS_FULL_INVENTORY_ONLY = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR", + "INVENTORY_ONLY": True, + "LINKS_ONLY": False, + "CLIQUES_ONLY": False, + "CLEAR": True, + "CLEAR_ALL": False +} + +ARGUMENTS_FULL_LINKS_ONLY = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR", + "INVENTORY_ONLY": False, + "LINKS_ONLY": True, + "CLIQUES_ONLY": False, + "CLEAR": True, + "CLEAR_ALL": False +} + +ARGUMENTS_FULL_CLIQUES_ONLY = { + "MONGO_CONFIG": "mongo_config_file", + "ENV": UNIT_TESTS_ENV, + "TYPE": "project", + "INVENTORY": UNIT_TESTS_INVENTORY, + "SCAN_SELF": True, + "ID": "admin", + "PARENT_ID": "RegionOne", + "PARENT_TYPE": "Region", + "ID_FIELD": "name", + "LOGLEVEL": "ERROR", + "INVENTORY_ONLY": False, + "LINKS_ONLY": False, + "CLIQUES_ONLY": True, + "CLEAR": True, + "CLEAR_ALL": False +} + +FORM = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": False, + "clear": True, + "type": "region", + "env": UNIT_TESTS_ENV, + "id": "RegionOne", + "parent_id": UNIT_TESTS_ENV + "-regions", + "parent_type": "regions_folder", + "id_field": "id", + "scan_self": False, + "child_type": "region", + "child_id": None +} + + +SCAN_ENV_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": False, + "clear": True, + "object_type": "environment", + "env": UNIT_TESTS_ENV, + "id": "", + "parent_id": "", + "type_to_scan": "", + "id_field": "id", + "scan_self": False, + "child_type": "environment", + "child_id": None +} + +SCAN_ENV_INVENTORY_ONLY_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": True, + "links_only": False, + "cliques_only": False, + "clear": True, + "object_type": "environment", + "env": UNIT_TESTS_ENV, + "id": '', + "parent_id": "", + "type_to_scan": "", + "id_field": "id", + "scan_self": False, + "child_type": "environment", + "child_id": None +} + +SCAN_ENV_LINKS_ONLY_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": True, + "cliques_only": False, + "clear": True, + "object_type": "environment", + "env": UNIT_TESTS_ENV, + "id": '', + "parent_id": "", + "type_to_scan": "", + "id_field": "id", + "scan_self": False, + "child_type": "environment", + "child_id": None +} + +SCAN_ENV_CLIQUES_ONLY_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": True, + "clear": True, + "object_type": "environment", + "env": UNIT_TESTS_ENV, + "id": '', + "parent_id": "", + "type_to_scan": "", + "id_field": "id", + "scan_self": False, + "child_type": "environment", + "child_id": None +} + +PREPARED_ENV_PLAN = { + 'obj': { + 'id': UNIT_TESTS_ENV + }, + 'child_id': None, + 'environment': UNIT_TESTS_ENV, + 'inventory_only': False, + 'clear': True, + 'links_only': False, + 'scanner_class': 'ScanEnvironment', + 'object_type': 'environment', + 'id': UNIT_TESTS_ENV, + 'inventory': UNIT_TESTS_INVENTORY, + 'loglevel': 'INFO', + 'child_type': None, + 'type_to_scan': '', + 'cliques_only': False, + 'id_field': 'id', + 'parent_id': '', + 'scan_self': False, + 'env': UNIT_TESTS_ENV +} + +SCANNER_CLASS = "ScanEnvironment" +SCANNER_TYPE_FOR_ENV = "ScanEnvironment" +OBJ_ID_FOR_ENV = "" +CHILD_TYPE_FOR_ENV = None +CHILD_ID_FOR_ENV = None + +PREPARED_ENV_INVENTORY_ONLY_PLAN = { + 'obj': { + 'id': UNIT_TESTS_ENV + }, + 'child_id': None, + 'clear': True, + 'inventory_only': True, + 'links_only': False, + 'scanner_class': 'ScanEnvironment', + 'object_type': 'environment', + 'id': UNIT_TESTS_ENV, + 'inventory': UNIT_TESTS_INVENTORY, + 'loglevel': 'INFO', + 'child_type': None, + 'type_to_scan': '', + 'cliques_only': False, + 'id_field': 'id', + 'parent_id': '', + 'scan_self': False, + 'env': UNIT_TESTS_ENV +} + +PREPARED_ENV_LINKS_ONLY_PLAN = { + 'obj': { + 'id': UNIT_TESTS_ENV + }, + 'child_id': None, + 'clear': True, + 'inventory_only': False, + 'links_only': True, + 'cliques_only': False, + 'scanner_class': 'ScanEnvironment', + 'object_type': 'environment', + 'id': UNIT_TESTS_ENV, + 'inventory': UNIT_TESTS_INVENTORY, + 'loglevel': 'INFO', + 'child_type': None, + 'type_to_scan': '', + 'id_field': 'id', + 'parent_id': '', + 'scan_self': False, + 'env': UNIT_TESTS_ENV +} + +PREPARED_ENV_CLIQUES_ONLY_PLAN = { + 'obj': { + 'id': UNIT_TESTS_ENV + }, + 'child_id': None, + 'clear': True, + 'inventory_only': False, + 'links_only': False, + 'cliques_only': True, + 'scanner_class': 'ScanEnvironment', + 'object_type': 'environment', + 'id': UNIT_TESTS_ENV, + 'inventory': UNIT_TESTS_INVENTORY, + 'loglevel': 'INFO', + 'child_type': None, + 'type_to_scan': '', + 'id_field': 'id', + 'parent_id': '', + 'scan_self': False, + 'env': UNIT_TESTS_ENV +} + +SCAN_REGION_FOLDER_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": False, + "clear": True, + "object_type": "regions_folder", + "env": UNIT_TESTS_ENV, + "id": UNIT_TESTS_ENV + "-regions", + "parent_id": UNIT_TESTS_ENV, + "parent_type": "environment", + "type_to_scan": "regions_folder", + "id_field": "id", + "scan_self": False, + "type": "regions_folder" +} + +SCAN_REGION_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": False, + "clear": True, + "object_type": "region", + "env": UNIT_TESTS_ENV, + "id": "RegionOne", + "parent_id": UNIT_TESTS_ENV + "-regions", + "parent_type": "regions_folder", + "type_to_scan": "region", + "id_field": "id", + "scan_self": False, + "type": "region", +} + +SCANNER_TYPE_FOR_REGION = "ScanRegionsRoot" +OBJ_ID_FOR_REGION = UNIT_TESTS_ENV + "-regions" +CHILD_TYPE_FOR_REGION = "region" +CHILD_ID_FOR_REGION = "RegionOne" + +REGIONS_FOLDER = { + "id": OBJ_ID_FOR_REGION, + "type": "regions_folder", + "parent_type": "environment", + "object_name": "Regions", + "parent_id": UNIT_TESTS_ENV, + "name": "Regions", + "create_object": True, + "text": "Regions" +} + +SCAN_PROJECT_FOLDER_PLAN_TO_BE_PREPARED = { + "loglevel": "INFO", + "inventory_only": False, + "links_only": False, + "cliques_only": False, + "clear": True, + "object_type": "projects_folder", + "env": UNIT_TESTS_ENV, + "object_id": UNIT_TESTS_ENV + "-projects", + "parent_id": UNIT_TESTS_ENV, + "type_to_scan": "project", + "id_field": "id", + "scan_self": False, + "child_type": "regions_folder", + "child_id": None +} + +SCANNER_CLASS_FOR_REGION_FOLDER = "ScanEnvironment" +OBJ_ID_FOR_REGION_FOLDER = UNIT_TESTS_ENV +CHILD_TYPE_FOR_REGION_FOLDER = "regions_folder" +CHILD_ID_FOR_REGION_FOLDER = UNIT_TESTS_ENV + "-regions" + +DEFAULT_COMMAND_ARGS = ["scanner.py"] + +SHORT_COMMAND_ARGS = ["scanner.py", "-m", "mongo_config_file", + "-e", UNIT_TESTS_ENV, "-t", "project", + "-y", UNIT_TESTS_INVENTORY, "-s", "-i", "admin", + "-p", "RegionOne", "-a", "Region", "-f", "name", + "-l", "ERROR"] + +LONG_COMMAND_ARGS = [ + "scanner.py", "--mongo_config", "mongo_config_file", + "--env", UNIT_TESTS_ENV, "--type", "project", + "--inventory", UNIT_TESTS_INVENTORY, "--scan_self", "--id", "admin", + "--parent_id", "RegionOne", "--parent_type", "Region", + "--id_field", "name", "--loglevel", "ERROR", + "--clear"] + +LONG_COMMAND_ARGS_CLEAR_ALL = [ + "scanner.py", "--mongo_config", "mongo_config_file", + "--env", UNIT_TESTS_ENV, "--type", "project", + "--inventory", UNIT_TESTS_INVENTORY, "--scan_self", "--id", "admin", + "--parent_id", "RegionOne", "--parent_type", "Region", + "--id_field", "name", "--loglevel", "ERROR", + "--clear_all"] + +LONG_COMMAND_ARGS_INVENTORY_ONLY = [ + "scanner.py", "--mongo_config", "mongo_config_file", + "--env", UNIT_TESTS_ENV, "--type", "project", + "--inventory", UNIT_TESTS_INVENTORY, "--scan_self", "--id", "admin", + "--parent_id", "RegionOne", "--parent_type", "Region", + "--id_field", "name", "--loglevel", "ERROR", "--inventory_only", + "--clear"] + +LONG_COMMAND_ARGS_LINKS_ONLY = [ + "scanner.py", "--mongo_config", "mongo_config_file", + "--env", UNIT_TESTS_ENV, "--type", "project", + "--inventory", UNIT_TESTS_INVENTORY, "--scan_self", "--id", "admin", + "--parent_id", "RegionOne", "--parent_type", "Region", + "--id_field", "name", "--loglevel", "ERROR", "--links_only", + "--clear"] + +LONG_COMMAND_ARGS_CLIQUES_ONLY = [ + "scanner.py", "--mongo_config", "mongo_config_file", + "--env", UNIT_TESTS_ENV, "--type", "project", + "--inventory", UNIT_TESTS_INVENTORY, "--scan_self", "--id", "admin", + "--parent_id", "RegionOne", "--parent_type", "Region", + "--id_field", "name", "--loglevel", "ERROR", "--cliques_only", + "--clear"] + diff --git a/app/test/scan/test_data/scanner.py b/app/test/scan/test_data/scanner.py new file mode 100644 index 0000000..cebeca2 --- /dev/null +++ b/app/test/scan/test_data/scanner.py @@ -0,0 +1,355 @@ +############################################################################### +# 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 queue +from discover.fetchers.folder_fetcher import FolderFetcher + + +SCANNER_TYPE_FOR_ENV = "ScanEnvironment" + +METADATA = { + "scanners_package": "discover", + "scanners": {} +} + +TYPE_TO_FETCH = { + "type": "pnic", + "fetcher": "CliFetchHostPnicsVpp", + "environment_condition": {"mechanism_drivers": "OVS"}, + "children_scanner": "ScanOteps" +} + +TYPE_TO_FETCH_WITH_WRONG_ENVIRONMENT_CONDITION = { + "type": "pnic", + "fetcher": "CliFetchHostPnicsVpp", + "environment_condition": {"mechanism_drivers": "VPP"}, + "children_scanner": "ScanOteps" +} + +TYPE_TO_FETCH_WITH_ERROR_VALUE = { + "environment_condition": { + "distribution": "Mirantis-7.0" + } +} + +TYPE_TO_FETCH_WITHOUT_ENV_CON = { + "type": "pnic", + "fetcher": "CliFetchHostPnicsVpp", + "children_scanner": "ScanOteps" +} + +TYPES_TO_FETCH = [ + { + "type": "ports_folder", + "fetcher": FolderFetcher("ports", "network") + }, + { + "type": "network_services_folder", + "fetcher": FolderFetcher("network_services", "network", "Network vServices") + } +] + +ID_FIELD = "id" + +PROJECT1 = { + "object": { + "description": "", + "enabled": True, + "id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "name": "OSDNA-project" + }, + "child_id_field": ID_FIELD, + "scanner": "ScanProject" +} + +PROJECT2 = { + "object": { + "description": "admin tenant", + "enabled": True, + "id": "8c1751e0ce714736a63fee3c776164da", + "name": "admin" + }, + "child_id_field": ID_FIELD, + "scanner": "ScanProject" +} + +SCAN_QUEUE = queue.Queue() +SCAN_QUEUE.put(PROJECT1) +SCAN_QUEUE.put(PROJECT2) +QUEUE_SIZE = 2 + +LIMIT_TO_CHILD_TYPE = "ports_folder" + +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/ngrandhi/.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-Nvn", + "mechanism_drivers": [ + "OVS" + ], + "operational": "yes", + "type": "environment" +} + +TYPES_TO_FETCHES_FOR_PNIC = { + "type": "pnic", + "fetcher": "CliFetchHostPnicsVpp", + "environment_condition": {"mechanism_drivers": "VPP"}, + "children_scanner": "ScanOteps" +} + +TYPES_TO_FETCHES_FOR_PNIC_WITHOUT_ENV_CON = { + "type": "pnic", + "fetcher": "CliFetchHostPnicsVpp", + "children_scanner": "ScanOteps" +} + +TYPES_TO_FETCHES_FOR_SCAN_AGGREGATE = [{ + "type": "host_ref", + "fetcher": "DbFetchAggregateHosts" +}] + + + + +# id = 'RegionOne-aggregates' +# obj = self.inv.get_by_id(self.env, id) +obj = {'id': 'Mirantis-Liberty-Nvn'} +id_field = 'id' +child_id = '', +child_type = '' + + +child_data = [ + { + 'id_path': '/Mirantis-Liberty-Nvn/Mirantis-Liberty-Nvn-regions', + 'object_name': 'Regions', + 'parent_id': 'Mirantis-Liberty-Nvn', + 'environment': 'Mirantis-Liberty-Nvn', + 'id': 'Mirantis-Liberty-Nvn-regions', + 'show_in_tree': True, + 'text': 'Regions', + 'type': 'regions_folder', + 'name': 'Regions', + 'create_object': True, + 'name_path': '/Mirantis-Liberty-Nvn/Regions', + 'parent_type': 'environment' + } +] + +PARENT = { + "environment" : "Mirantis-Liberty-Xiaocong", + "id" : "node-6.cisco.com-vservices-dhcps", + "name" : "node-6.cisco.com-vservices-dhcps", + "object_name" : "DHCP servers", + "parent_id" : "node-6.cisco.com-vservices", + "parent_type" : "vservices_folder", + "show_in_tree" : True, + "text" : "DHCP servers", + "type" : "vservice_dhcps_folder" +} + +PARENT_WITHOUT_ID = { + 'id': '' +} + +TYPE_TO_FETCH_FOR_ENVIRONMENT = { + "type": "regions_folder", + "fetcher": FolderFetcher("regions", "environment"), + "children_scanner": "ScanRegionsRoot" +} + +TYPE_TO_FETCH_FOR_ENV_WITHOUT_CHILDREN_FETCHER = { + "type": "regions_folder", + "fetcher": FolderFetcher("regions", "environment") +} + +DB_RESULTS_WITH_CREATE_OBJECT = [ + { + "name": "Mirantis-Liberty-Xiaocong-regions", + "parent_type": "environment", + "parent_id": "Mirantis-Liberty-Xiaocong", + "text": "Regions", + "create_object": True, + "type": "regions_folder", + "id": "Mirantis-Liberty-Xiaocong-regions" + } +] + +DB_RESULTS_WITHOUT_CREATE_OBJECT = [ + { + "name": "Mirantis-Liberty-Xiaocong-regions", + "parent_type": "environment", + "parent_id": "Mirantis-Liberty-Xiaocong", + "text": "Regions", + "create_object": False, + "type": "regions_folder", + "id": "Mirantis-Liberty-Xiaocong-regions" + } +] + +DB_RESULTS_WITH_PROJECT = [ + { + "name": "Mirantis-Liberty-Xiaocong-regions", + "parent_type": "environment", + "parent_id": "Mirantis-Liberty-Xiaocong", + "text": "Regions", "create_object": True, + "type": "regions_folder", + "id": "Mirantis-Liberty-Xiaocong-regions", + "in_project-OSDNA-project": "1", + } +] + +PROJECT_KEY = "in_project-OSDNA-project" + +DB_RESULTS_WITH_MASTER_PARENT_IN_DB = [ + { + "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" + } +] + +DB_RESULTS_WITHOUT_MASTER_PARENT_IN_DB = [ + { + "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" + } +] + + +DICTIONARY_DB_RESULTS = { + "name": "Mirantis-Liberty-Xiaocong-regions", + "parent_type": "environment", + "parent_id": "Mirantis-Liberty-Xiaocong", + "text": "Regions", "create_object": True, + "type": "regions_folder", + "id": "Mirantis-Liberty-Xiaocong-regions" +} + +MASTER_PARENT = { + "create_object" : True, + "environment" : "Mirantis-Liberty-Xiaocong", + "id" : "node-6.cisco.com-vservices", + "id_path" : "/Mirantis-Liberty/Mirantis-Liberty-regions/RegionOne/RegionOne-availability_zones/internal/node-6.cisco.com/node-6.cisco.com-vservices", + "name" : "Vservices", + "name_path" : "/Mirantis-Liberty/Regions/RegionOne/Availability Zones/internal/node-6.cisco.com/Vservices", + "object_name" : "Vservices", + "parent_id" : "node-6.cisco.com", + "parent_type" : "host", + "show_in_tree" : True, + "text" : "Vservices", + "type" : "vservices_folder" +} + +CONFIGURATIONS_WITHOUT_MECHANISM_DRIVERS = { + "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/ngrandhi/.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-Nvn", + "operational": "yes", + "type": "environment" +} + +SCAN_TYPE_RESULTS = [ + { + "description": "", + "enabled": True, + "id": "75c0eb79ff4a42b0ae4973c8375ddf40", + "name": "OSDNA-project" + }, + { + "description": "admin tenant", + "enabled": True, + "id": "8c1751e0ce714736a63fee3c776164da", + "name": "admin" + } +] + +LIMIT_TO_CHILD_ID = "75c0eb79ff4a42b0ae4973c8375ddf40" diff --git a/app/test/scan/test_scan.py b/app/test/scan/test_scan.py new file mode 100644 index 0000000..a01083e --- /dev/null +++ b/app/test/scan/test_scan.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 unittest.mock import MagicMock + +from discover.configuration import Configuration +from monitoring.setup.monitoring_setup_manager import MonitoringSetupManager +from test.scan.config.test_config \ + import MONGODB_CONFIG, ENV_CONFIG, COLLECTION_CONFIG +from test.scan.test_data.configurations import CONFIGURATIONS +from utils.inventory_mgr import InventoryMgr +from utils.mongo_access import MongoAccess +from utils.logging.full_logger import FullLogger + + +class TestScan(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() + # mock log + FullLogger.info = MagicMock() + + self.conf = Configuration() + self.conf.use_env = MagicMock() + self.conf.environment = CONFIGURATIONS + self.conf.configuration = CONFIGURATIONS["configuration"] + + self.inv = InventoryMgr() + self.inv.clear = MagicMock() + self.inv.set_collections(self.inventory_collection) + + MonitoringSetupManager.server_setup = MagicMock() + + def setUp(self): + self.configure_environment() diff --git a/app/test/scan/test_scan_controller.py b/app/test/scan/test_scan_controller.py new file mode 100644 index 0000000..f3bcc9a --- /dev/null +++ b/app/test/scan/test_scan_controller.py @@ -0,0 +1,215 @@ +############################################################################### +# 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 sys +from unittest.mock import MagicMock + +from discover.scan import ScanController, ScanPlan +from discover.scanner import Scanner +from test.scan.test_scan import TestScan +from test.scan.test_data.scan import * +from utils.inventory_mgr import InventoryMgr + + +class TestScanController(TestScan): + + def setUp(self): + super().setUp() + self.scan_controller = ScanController() + + def arg_validate(self, args, expected, key, err=None): + if key not in expected: + return + err = err if err else 'The value of {} is wrong'.format(key) + self.assertEqual(args.get(key, None), expected[key.upper()], err) + + def check_args_values(self, args, expected): + self.arg_validate(args, expected, 'env', + 'The value of environment is wrong') + keys = ['mongo_config', 'mongo_config', 'type', 'inventory', + 'scan_self', 'id', 'parent_id', 'parent_type', 'id_field', + 'loglevel', 'inventory_only', 'links_only', 'cliques_only', + 'clear'] + for key in keys: + self.arg_validate(args, expected, key) + + def test_get_args_with_default_arguments(self): + sys.argv = DEFAULT_COMMAND_ARGS + args = self.scan_controller.get_args() + # check the default value of each argument + self.check_args_values(args, DEFAULT_ARGUMENTS) + + def test_get_args_with_short_command_args(self): + sys.argv = SHORT_COMMAND_ARGS + args = self.scan_controller.get_args() + # check the value parsed by short arguments + self.check_args_values(args, SHORT_FLAGS_ARGUMENTS) + + def test_get_args_with_full_command_args(self): + sys.argv = LONG_COMMAND_ARGS + args = self.scan_controller.get_args() + # check the value parsed by long arguments + self.check_args_values(args, ARGUMENTS_FULL) + + def test_get_args_with_full_command_args_clear_all(self): + sys.argv = LONG_COMMAND_ARGS_CLEAR_ALL + args = self.scan_controller.get_args() + # check the value parsed by long arguments + self.check_args_values(args, ARGUMENTS_FULL_CLEAR_ALL) + + def test_get_args_with_full_command_args_inventory_only(self): + sys.argv = LONG_COMMAND_ARGS_INVENTORY_ONLY + args = self.scan_controller.get_args() + # check the value parsed by long arguments + self.check_args_values(args, ARGUMENTS_FULL_INVENTORY_ONLY) + + def test_get_args_with_full_command_args_links_only(self): + sys.argv = LONG_COMMAND_ARGS_LINKS_ONLY + args = self.scan_controller.get_args() + # check the value parsed by long arguments + self.check_args_values(args, ARGUMENTS_FULL_LINKS_ONLY) + + def test_get_args_with_full_command_args_cliques_only(self): + sys.argv = LONG_COMMAND_ARGS_CLIQUES_ONLY + args = self.scan_controller.get_args() + # check the value parsed by long arguments + self.check_args_values(args, ARGUMENTS_FULL_CLIQUES_ONLY) + + def side_effect(self, key, default): + if key in FORM.keys(): + return FORM[key] + else: + return default + + def check_plan_values(self, plan, scanner_type, obj_id, + child_type, child_id): + self.assertEqual(scanner_type, plan.scanner_type, + 'The scanner class is wrong') + self.assertEqual(child_type, plan.child_type, + 'The child type is wrong') + self.assertEqual(child_id, plan.child_id, + 'The child id is wrong') + self.assertEqual(obj_id, plan.object_id, 'The object is wrong') + + def test_prepare_scan_plan(self): + scan_plan = ScanPlan(SCAN_ENV_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + self.check_plan_values(plan, SCANNER_TYPE_FOR_ENV, + OBJ_ID_FOR_ENV, CHILD_TYPE_FOR_ENV, + CHILD_ID_FOR_ENV) + + def test_prepare_scan_region_plan(self): + original_get_by_id = self.inv.get_by_id + self.inv.get_by_id = MagicMock(return_value=REGIONS_FOLDER) + + self.scan_controller.inv = self.inv + scan_plan = ScanPlan(SCAN_REGION_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + + self.check_plan_values(plan, SCANNER_TYPE_FOR_REGION, + OBJ_ID_FOR_REGION, CHILD_TYPE_FOR_REGION, + CHILD_ID_FOR_REGION) + self.inv.get_by_id = original_get_by_id + + def test_prepare_scan_region_folder_plan(self): + scan_plan = ScanPlan(SCAN_REGION_FOLDER_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + self.check_plan_values(plan, SCANNER_CLASS_FOR_REGION_FOLDER, + OBJ_ID_FOR_REGION_FOLDER, + CHILD_TYPE_FOR_REGION_FOLDER, + CHILD_ID_FOR_REGION_FOLDER) + + def check_scan_method_calls(self, mock, count): + if count: + self.assertTrue(mock.called) + else: + mock.assert_not_called() + + def check_scan_counts(self, run_scan_count, scan_links_count, + scan_cliques_count, deploy_monitoring_setup_count): + self.check_scan_method_calls(Scanner.scan, run_scan_count) + self.check_scan_method_calls(Scanner.scan_links, scan_links_count) + self.check_scan_method_calls(Scanner.scan_cliques, scan_cliques_count) + self.check_scan_method_calls(Scanner.deploy_monitoring_setup, + deploy_monitoring_setup_count) + + def prepare_scan_mocks(self): + self.load_metadata = Scanner.load_metadata + self.scan = Scanner.scan + self.scan_links = Scanner.scan_links + self.scan_cliques = Scanner.scan_cliques + self.deploy_monitoring_setup = Scanner.deploy_monitoring_setup + + Scanner.load_metadata = MagicMock() + Scanner.scan = MagicMock() + Scanner.scan_links = MagicMock() + Scanner.scan_cliques = MagicMock() + Scanner.deploy_monitoring_setup = MagicMock() + + def reset_methods(self): + Scanner.load_metadata = self.load_metadata + Scanner.scan = self.scan + Scanner.scan_links = self.scan_links + Scanner.scan_cliques = self.scan_cliques + Scanner.deploy_monitoring_setup = self.deploy_monitoring_setup + + def test_scan(self): + self.scan_controller.get_args = MagicMock() + InventoryMgr.is_feature_supported = MagicMock(return_value=False) + plan = self.scan_controller.prepare_scan_plan(ScanPlan(SCAN_ENV_PLAN_TO_BE_PREPARED)) + self.scan_controller.get_scan_plan = MagicMock(return_value=plan) + self.prepare_scan_mocks() + + self.scan_controller.run() + self.check_scan_counts(1, 1, 1, 0) + self.reset_methods() + + def test_scan_with_monitoring_setup(self): + self.scan_controller.get_args = MagicMock() + InventoryMgr.is_feature_supported = MagicMock(return_value=True) + plan = self.scan_controller.prepare_scan_plan(ScanPlan(SCAN_ENV_PLAN_TO_BE_PREPARED)) + self.scan_controller.get_scan_plan = MagicMock(return_value=plan) + self.prepare_scan_mocks() + + self.scan_controller.run() + self.check_scan_counts(1, 1, 1, 1) + self.reset_methods() + + def test_scan_with_inventory_only(self): + self.scan_controller.get_args = MagicMock() + scan_plan = ScanPlan(SCAN_ENV_INVENTORY_ONLY_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + self.scan_controller.get_scan_plan = MagicMock(return_value=plan) + self.prepare_scan_mocks() + + self.scan_controller.run() + self.check_scan_counts(1, 0, 0, 0) + self.reset_methods() + + def test_scan_with_links_only(self): + self.scan_controller.get_args = MagicMock() + scan_plan = ScanPlan(SCAN_ENV_LINKS_ONLY_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + self.scan_controller.get_scan_plan = MagicMock(return_value=plan) + self.prepare_scan_mocks() + + self.scan_controller.run() + self.check_scan_counts(0, 1, 0, 0) + self.reset_methods() + + def test_scan_with_cliques_only(self): + self.scan_controller.get_args = MagicMock() + scan_plan = ScanPlan(SCAN_ENV_CLIQUES_ONLY_PLAN_TO_BE_PREPARED) + plan = self.scan_controller.prepare_scan_plan(scan_plan) + self.scan_controller.get_scan_plan = MagicMock(return_value=plan) + self.prepare_scan_mocks() + + self.scan_controller.run() + self.check_scan_counts(0, 0, 1, 0) + self.reset_methods() diff --git a/app/test/scan/test_scan_metadata_parser.py b/app/test/scan/test_scan_metadata_parser.py new file mode 100644 index 0000000..91c11ef --- /dev/null +++ b/app/test/scan/test_scan_metadata_parser.py @@ -0,0 +1,152 @@ +############################################################################### +# 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 discover.scan_metadata_parser import ScanMetadataParser +from test.scan.test_scan import TestScan +from test.scan.test_data.metadata import * +from unittest import mock +from utils.mongo_access import MongoAccess + + +SCANNERS_FILE = 'scanners.json' + +JSON_REQUIRED_FIELDS_ERROR = 'Metadata json should contain all the ' + \ + 'following fields: scanners_package, scanners' + +JSON_NO_SCANNERS = 'no scanners found in scanners list' +JSON_ERRORS_FOUND = 'Errors encountered during metadata file parsing:\n' + + +class TestScanMetadataParser(TestScan): + def setUp(self): + super().setUp() + DbAccess.conn = mock.MagicMock() + self.prepare_constants() + self.parser = ScanMetadataParser(self.inv) + + self.parser.check_metadata_file_ok = mock.MagicMock() + + def prepare_metadata(self, content): + self.parser._load_json_file = mock.MagicMock(return_value=content) + + def prepare_constants(self): + MongoAccess.db = mock.MagicMock() + MongoAccess.db["constants"].find_one = mock.MagicMock(side_effect= + lambda input: + CONSTANTS[input["name"]] + if CONSTANTS.get(input["name"]) + else [] + ) + + def handle_error_scenario(self, input_content, expected_error, + add_errors_encountered_pretext=True): + self.prepare_metadata(input_content) + found_exception = False + expected_message = expected_error + metadata = None + try: + metadata = self.parser.parse_metadata_file(SCANNERS_FILE) + except ValueError as e: + found_exception = True + expected_message = expected_error \ + if not add_errors_encountered_pretext \ + else JSON_ERRORS_FOUND + expected_error + self.assertEqual(str(e), expected_message) + self.assertTrue(found_exception, + 'failed to throw exception, expected_message: {}' + .format(expected_message)) + self.assertIsNone(metadata) + + def handle_json_missing_field(self, json_content): + self.handle_error_scenario(json_content, JSON_REQUIRED_FIELDS_ERROR, + add_errors_encountered_pretext=False) + + def test_missing_field(self): + for content in [METADATA_EMPTY, METADATA_NO_PACKAGE, + METADATA_NO_SCANNERS]: + self.handle_json_missing_field(content) + + def test_json_no_scanners(self): + self.handle_error_scenario(METADATA_ZERO_SCANNERS, JSON_NO_SCANNERS) + + def test_json_scanner_errors(self): + errors_scenarios = [ + { + 'input': METADATA_ZERO_SCANNERS, + 'msg': JSON_NO_SCANNERS + }, + { + 'input': METADATA_SCANNER_UNKNOWN_ATTRIBUTE, + 'msg': 'unknown attribute xyz in scanner ScanAggregate, type #1' + }, + { + 'input': METADATA_SCANNER_NO_TYPE, + 'msg': 'scanner ScanAggregate, type #1: ' + + 'missing attribute "type"' + }, + { + 'input': METADATA_SCANNER_NO_FETCHER, + 'msg': 'scanner ScanAggregate, type #1: ' + + 'missing attribute "fetcher"' + }, + { + 'input': METADATA_SCANNER_INCORRECT_TYPE, + 'msg': 'scanner ScanAggregate: value not in types: t1' + }, + { + 'input': METADATA_SCANNER_INCORRECT_FETCHER, + 'msg': 'failed to find fetcher class f1 ' + 'in scanner ScanAggregate type #1' + }, + { + 'input': METADATA_SCANNER_WITH_INCORRECT_CHILD, + 'msg': 'scanner ScanAggregatesRoot type #1: ' + 'children_scanner must be a string' + }, + { + 'input': METADATA_SCANNER_WITH_MISSING_CHILD, + 'msg': 'scanner ScanAggregatesRoot type #1: ' + 'children_scanner ScanAggregate not found ' + }, + { + 'input': METADATA_SCANNER_FETCHER_INVALID_DICT, + 'msg': 'scanner ScanEnvironment type #1: ' + 'only folder dict accepted in fetcher' + }, + { + 'input': METADATA_SCANNER_WITH_INVALID_CONDITION, + 'msg': 'scanner ScanHost type #1: condition must be dict' + } + ] + for scenario in errors_scenarios: + self.handle_error_scenario(scenario['input'], scenario['msg']) + + def check_json_is_ok(self, json_content): + self.prepare_metadata(json_content) + found_exception = False + metadata = None + msg = None + try: + metadata = self.parser.parse_metadata_file(SCANNERS_FILE) + except ValueError as e: + found_exception = True + msg = str(e) + self.assertFalse(found_exception, 'Exception: {}'.format(msg)) + self.assertIsNotNone(metadata) + + def test_json_valid_content(self): + valid_content = [ + METADATA_SIMPLE_SCANNER, + METADATA_SCANNER_WITH_CHILD, + METADATA_SCANNER_WITH_FOLDER, + METADATA_SCANNER_WITH_CONDITION + ] + for content in valid_content: + self.check_json_is_ok(content) diff --git a/app/test/scan/test_scanner.py b/app/test/scan/test_scanner.py new file mode 100644 index 0000000..4a7536e --- /dev/null +++ b/app/test/scan/test_scanner.py @@ -0,0 +1,355 @@ +############################################################################### +# 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.scanner import Scanner +from test.scan.test_scan import TestScan +from unittest.mock import MagicMock, patch +from discover.scan_metadata_parser import ScanMetadataParser +from test.scan.test_data.scanner import * +from monitoring.setup.monitoring_setup_manager import MonitoringSetupManager + + +class TestScanner(TestScan): + + def setUp(self): + super().setUp() + ScanMetadataParser.parse_metadata_file = MagicMock(return_value=METADATA) + self.scanner = Scanner() + self.scanner.set_env(self.env) + MonitoringSetupManager.create_setup = MagicMock() + self.scanner.inv.monitoring_setup_manager = \ + MonitoringSetupManager(self.env) + + def test_check_type_env_without_environment_condition(self): + result = self.scanner.check_type_env(TYPE_TO_FETCH_WITHOUT_ENV_CON) + + self.assertEqual(result, True, + "Can't get true when the type_to_fetch " + + "doesn't contain environment condition") + + def test_check_type_with_error_value(self): + # store original method + original_get_env_config = self.scanner.config.get_env_config + + # mock get_env_config method + self.scanner.config.get_env_config =\ + MagicMock(return_value=CONFIGURATIONS) + + result = self.scanner.check_type_env(TYPE_TO_FETCH_WITH_ERROR_VALUE) + + # reset get_env_config method + self.scanner.config.get_env_config = original_get_env_config + + self.assertEqual(result, False, + "Can't get false when the type_to_fetch " + + "contain error value") + + def test_check_type_env_without_mechanism_drivers_in_env_config(self): + # store original method + original_get_env_config = self.scanner.config.get_env_config + + # mock get_env_config_method + self.scanner.config.get_env_config =\ + MagicMock(return_value=CONFIGURATIONS_WITHOUT_MECHANISM_DRIVERS) + + result = self.scanner.check_type_env(TYPE_TO_FETCH) + # reset get_env_config method + self.scanner.check_type_env = original_get_env_config + + self.assertEqual(result, False, + "Can't get false when configuration " + + "doesn't contain mechanism drivers") + + def test_check_type_env_with_wrong_mech_drivers_in_env_condition(self): + # store original method + original_get_env_config = self.scanner.config.get_env_config + + # mock get_env_config_method + self.scanner.config.get_env_config =\ + MagicMock(return_value=CONFIGURATIONS) + + result = self.scanner.\ + check_type_env(TYPE_TO_FETCH_WITH_WRONG_ENVIRONMENT_CONDITION) + # reset get_env_config method + self.scanner.check_type_env = original_get_env_config + + self.assertEqual(result, False, "Can't get false when the mechanism " + + "drivers in type_to_fetch " + + "don't exist in configurations") + + def test_check_type_env(self): + # store original method + original_get_env_config = self.scanner.config.get_env_config + + # mock method + self.scanner.config.get_env_config =\ + MagicMock(return_value=CONFIGURATIONS) + + result = self.scanner.check_type_env(TYPE_TO_FETCH) + + # reset method + self.scanner.config.get_env_config = original_get_env_config + + self.assertEqual(result, True, + "Can't get True when the type_to_fetch is correct") + + def test_scan_error_type(self): + # store original method + original_check_type_env = self.scanner.check_type_env + + # mock method + self.scanner.check_type_env = MagicMock(return_value=False) + + result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, + ID_FIELD) + + # reset method + self.scanner.check_type_env = original_check_type_env + + self.assertEqual(result, [], + "Can't get [], when the type_to_fetch is wrong") + + def test_scan_type_without_parent_id(self): + try: + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, + PARENT_WITHOUT_ID, ID_FIELD) + self.fail("Can't get error when the parent " + + "doesn't contain id attribute") + except: + pass + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_with_get_exception(self, fetcher_get): + fetcher_get.side_effect = Exception("get exception") + + try: + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, + PARENT, ID_FIELD) + self.fail("Can't get exception when fetcher.get throws an exception") + except: + pass + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_without_master_parent(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITHOUT_MASTER_PARENT_IN_DB + + # store original get_by_id + original_get_by_id = self.scanner.inv.get_by_id + original_set = self.scanner.inv.set + + # mock methods + self.scanner.inv.get_by_id = MagicMock(return_value=[]) + + result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, + ID_FIELD) + + # reset methods + self.scanner.inv.get_by_id = original_get_by_id + self.scanner.inv.set = original_set + self.assertEqual(result, [], "Can't get [], when the master parent " + + "doesn't exist in database") + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_with_master_parent(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_MASTER_PARENT_IN_DB + + # store original methods + original_get_by_id = self.scanner.inv.get_by_id + original_set = self.scanner.inv.set + + # mock methods + self.scanner.inv.get_by_id = MagicMock(return_value=MASTER_PARENT) + self.scanner.inv.set = MagicMock() + + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) + self.assertEqual(self.scanner.inv.set.call_count, 2, "Can't create additional folder") + self.assertNotIn("master_parent_type", DB_RESULTS_WITH_MASTER_PARENT_IN_DB, "Can't delete the master_parent_type") + self.assertNotIn("master_parent_id", DB_RESULTS_WITH_MASTER_PARENT_IN_DB, "Can't delete the master_parent_id") + + # reset methods + self.scanner.inv.get_by_id = original_get_by_id + self.scanner.inv.set = original_set + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_with_in_project(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_PROJECT + + # store original method + original_set = self.scanner.inv.set + + # mock method + self.scanner.inv.set = MagicMock() + + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) + self.assertIn("projects", DB_RESULTS_WITH_PROJECT[0], + "Can't get the projects from DB result") + self.assertNotIn(PROJECT_KEY, DB_RESULTS_WITH_PROJECT[0], + "Can't delete the project key in the object") + + self.scanner.inv.set = original_set + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_without_create_object(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITHOUT_CREATE_OBJECT + + original_set = self.scanner.inv.set + + self.scanner.inv.set = MagicMock() + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) + + self.assertEqual(self.scanner.inv.set.call_count, 0, + "Set the object when the create object is false") + + self.scanner.inv.set = original_set + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_with_create_object(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT + + original_set = self.scanner.inv.set + + self.scanner.inv.set = MagicMock() + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) + + self.assertEqual(self.scanner.inv.set.call_count, 1, + "Set the object when the create object is false") + + self.scanner.inv.set = original_set + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_with_children_scanner(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT + + original_set = self.scanner.inv.set + original_queue_for_scan = self.scanner.queue_for_scan + + self.scanner.inv.set = MagicMock() + self.scanner.queue_for_scan = MagicMock() + + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, ID_FIELD) + + self.assertEqual(self.scanner.queue_for_scan.call_count, 1, + "Can't put children scanner in the queue") + + self.scanner.inv.set = original_set + self.scanner.queue_for_scan = original_queue_for_scan + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type_without_children_scanner(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT + + original_set = self.scanner.inv.set + original_queue_for_scan = self.scanner.queue_for_scan + + self.scanner.inv.set = MagicMock() + self.scanner.queue_for_scan = MagicMock() + + self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENV_WITHOUT_CHILDREN_FETCHER, + PARENT, ID_FIELD) + + self.assertEqual(self.scanner.queue_for_scan.call_count, 0, + "Can't put children scanner in the queue") + + self.scanner.inv.set = original_set + self.scanner.queue_for_scan = original_queue_for_scan + + @patch("discover.fetchers.folder_fetcher.FolderFetcher.get") + def test_scan_type(self, fetcher_get): + fetcher_get.return_value = DB_RESULTS_WITH_CREATE_OBJECT + + original_set = self.scanner.inv.set + original_queue_for_scan = self.scanner.queue_for_scan + + self.scanner.inv.set = MagicMock() + self.scanner.queue_for_scan = MagicMock() + + result = self.scanner.scan_type(TYPE_TO_FETCH_FOR_ENVIRONMENT, PARENT, + ID_FIELD) + + self.assertNotEqual(result, [], "Can't get children form scan_type") + + self.scanner.inv.set = original_set + self.scanner.queue_for_scan = original_queue_for_scan + + def test_scan_with_limit_to_child_type(self): + original_scan_type = self.scanner.scan_type + original_get_scanner = self.scanner.get_scanner + + self.scanner.scan_type = MagicMock(return_value=[]) + self.scanner.get_scanner = MagicMock(return_value=TYPES_TO_FETCH) + + limit_to_child_type = TYPES_TO_FETCH[0]['type'] + + self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT, limit_to_child_type=limit_to_child_type) + + # only scan the limit child type + self.scanner.scan_type.assert_called_with(TYPES_TO_FETCH[0], PARENT, + ID_FIELD) + + self.scanner.scan_type = original_scan_type + self.scanner.get_scanner = original_get_scanner + + def test_scan_with_limit_to_child_id(self): + original_scan_type = self.scanner.scan_type + original_get_scanner = self.scanner.get_scanner + + self.scanner.get_scanner = MagicMock(return_value=TYPES_TO_FETCH) + limit_to_child_id = SCAN_TYPE_RESULTS[0][ID_FIELD] + + self.scanner.scan_type = MagicMock(return_value=SCAN_TYPE_RESULTS) + + children = self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT, id_field=ID_FIELD, + limit_to_child_id=limit_to_child_id) + + # only get the limit child + self.assertEqual(children, SCAN_TYPE_RESULTS[0]) + + self.scanner.scan_type = original_scan_type + self.scanner.get_scanner = original_get_scanner + + def test_scan(self): + original_scan_type = self.scanner.scan_type + original_get_scanner = self.scanner.get_scanner + + self.scanner.get_scanner = MagicMock(return_values=TYPES_TO_FETCH) + result = self.scanner.scan(SCANNER_TYPE_FOR_ENV, PARENT) + + self.assertEqual(PARENT, result, + "Can't get the original parent after the scan") + + self.scanner.get_scanner = original_get_scanner + self.scanner.scan_type = original_scan_type + + def test_run_scan(self): + original_scan = self.scanner.scan + original_scan_from_queue = self.scanner.scan_from_queue + + self.scanner.scan = MagicMock() + self.scanner.scan_from_queue = MagicMock() + + self.scanner.run_scan(SCANNER_TYPE_FOR_ENV, PARENT, ID_FIELD, LIMIT_TO_CHILD_ID, + LIMIT_TO_CHILD_TYPE) + + self.scanner.scan.assert_called_with(SCANNER_TYPE_FOR_ENV, PARENT, ID_FIELD, + LIMIT_TO_CHILD_ID, + LIMIT_TO_CHILD_TYPE) + self.scanner.scan_from_queue.assert_any_call() + + self.scanner.scan = original_scan + self.scanner.scan_from_queue = original_scan_from_queue + + @patch("discover.scanner.Scanner.scan") + def test_scan_from_queue(self, scan): + scan.return_value = [] + Scanner.scan_queue = SCAN_QUEUE + + self.scanner.scan_from_queue() + + self.assertEqual(self.scanner.scan.call_count, QUEUE_SIZE, + "Can't scan all the objects in the queue") diff --git a/app/test/test_suite.py b/app/test/test_suite.py new file mode 100644 index 0000000..00e7492 --- /dev/null +++ b/app/test/test_suite.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 # +############################################################################### +import argparse +import unittest + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument("-d", "--dir", dest="start_dir", nargs="?", + type=str, default=".", + help="Name of root directory for test cases discovery") + + return parser.parse_args() + +if __name__ == "__main__": + args = get_args() + suite = unittest.TestLoader().discover(start_dir=args.start_dir) + unittest.TextTestRunner(verbosity=2).run(suite)
\ No newline at end of file |