async def delete_parent_category(request): """ Args: request: category_name Returns: remove the link b/w parent-child category for the parent :Example: curl -X DELETE http://localhost:8081/fledge/category/{category_name}/parent """ category_name = request.match_info.get('category_name', None) category_name = urllib.parse.unquote( category_name) if category_name is not None else None cf_mgr = ConfigurationManager(connect.get_storage_async()) try: await cf_mgr.delete_parent_category(category_name) except TypeError as ex: raise web.HTTPBadRequest(reason=str(ex)) except ValueError as ex: raise web.HTTPNotFound(reason=str(ex)) return web.json_response({ "message": "Parent-child relationship for the parent-{} is deleted".format( category_name) })
async def get_category(request): """ Args: request: category_name is required Returns: the configuration items in the given category. :Example: curl -X GET http://localhost:8081/fledge/category/PURGE_READ """ category_name = request.match_info.get('category_name', None) category_name = urllib.parse.unquote( category_name) if category_name is not None else None cf_mgr = ConfigurationManager(connect.get_storage_async()) category = await cf_mgr.get_category_all_items(category_name) if category is None: raise web.HTTPNotFound( reason="No such Category found for {}".format(category_name)) try: request.is_core_mgt except AttributeError: category = hide_password(category) return web.json_response(category)
async def delete_child_category(request): """ Args: request: category_name, child_category are required Returns: remove the link b/w child category and its parent :Example: curl -X DELETE http://localhost:8081/fledge/category/{category_name}/children/{child_category} """ category_name = request.match_info.get('category_name', None) child_category = request.match_info.get('child_category', None) category_name = urllib.parse.unquote( category_name) if category_name is not None else None cf_mgr = ConfigurationManager(connect.get_storage_async()) try: result = await cf_mgr.delete_child_category(category_name, child_category) except TypeError as ex: raise web.HTTPBadRequest(reason=str(ex)) except ValueError as ex: raise web.HTTPNotFound(reason=str(ex)) return web.json_response({"children": result})
async def test_delete_cert(self, client, certs_path, cert_name='server.cert'): async def async_mock(): return {'value': 'test'} storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(certificate_store, '_get_certs_dir', return_value=str(certs_path / 'certs') + '/'): with patch('os.walk') as mockwalk: mockwalk.return_value = [(str(certs_path / 'certs'), [], [cert_name])] with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_item', return_value=async_mock()): with patch('os.remove', return_value=True) as patch_remove: resp = await client.delete( '/fledge/certificate/{}'.format(cert_name)) assert 200 == resp.status result = await resp.text() json_response = json.loads(result) assert '{} has been deleted successfully'.format( cert_name) == json_response['result'] assert 1 == patch_remove.call_count
async def get_filter_pipeline(request: web.Request) -> web.Response: """ GET filter pipeline :Example: curl -X GET http://localhost:8081/fledge/filter/<user_name>/pipeline """ user_name = request.match_info.get('user_name', None) try: storage = connect.get_storage_async() cf_mgr = ConfigurationManager(storage) # Fetch the filter items: get category items category_info = await cf_mgr.get_category_all_items( category_name=user_name) if category_info is None: raise ValueError("No such '{}' category found.".format(user_name)) filter_value_from_storage = json.loads( category_info['filter']['value']) except KeyError: msg = "No filter pipeline exists for {}".format(user_name) _LOGGER.info(msg) raise web.HTTPNotFound(reason=msg) except StorageServerError as ex: _LOGGER.exception("Get pipeline: %s, caught exception: %s", user_name, str(ex.error)) raise web.HTTPInternalServerError(reason=str(ex.error)) except ValueError as ex: raise web.HTTPNotFound(reason=ex) except Exception as ex: raise web.HTTPInternalServerError(reason=ex) else: return web.json_response({'result': filter_value_from_storage})
async def test_dupe_category_name_add_service(self, client): mock_plugin_info = { 'name': "furnace4", 'version': "1.1", 'type': "south", 'interface': "1.0", 'mode': "async", 'config': { 'plugin': { 'description': "DHT11", 'type': 'string', 'default': 'dht11' } } } data = {"name": "furnace4", "type": "south", "plugin": "dht11"} storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(common, 'load_and_fetch_python_plugin_info', side_effect=[mock_plugin_info]): with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_all_items', return_value=self.async_mock(mock_plugin_info)) as patch_get_cat_info: resp = await client.post('/fledge/service', data=json.dumps(data)) assert 400 == resp.status assert "The '{}' category already exists".format(data['name']) == resp.reason patch_get_cat_info.assert_called_once_with(category_name=data['name'])
async def create_child_category(request): """ Args: request: category_name is required and JSON object that defines the child category Returns: parent of the children being added :Example: curl -d '{"children": ["coap", "http", "sinusoid"]}' -X POST http://localhost:8081/fledge/category/south/children """ cf_mgr = ConfigurationManager(connect.get_storage_async()) data = await request.json() if not isinstance(data, dict): raise ValueError('Data payload must be a dictionary') category_name = request.match_info.get('category_name', None) category_name = urllib.parse.unquote( category_name) if category_name is not None else None children = data.get('children') try: r = await cf_mgr.create_child_category(category_name, children) except TypeError as ex: raise web.HTTPBadRequest(reason=str(ex)) except ValueError as ex: raise web.HTTPNotFound(reason=str(ex)) return web.json_response(r)
async def get_south_services(request): """ Args: request: Returns: list of all south services with tracked assets and readings count :Example: curl -X GET http://localhost:8081/fledge/south """ if 'cached' in request.query and request.query['cached'].lower( ) == 'false': _get_installed_plugins.cache_clear() storage_client = connect.get_storage_async() cf_mgr = ConfigurationManager(storage_client) try: south_cat = await cf_mgr.get_category_child("South") south_categories = [nc["key"] for nc in south_cat] except: return web.json_response({'services': []}) response = await _services_with_assets(storage_client, south_categories) return web.json_response({'services': response})
async def get_notifications(request): """ GET list of notifications :Example: curl -X GET http://localhost:8081/fledge/notification """ try: storage = connect.get_storage_async() config_mgr = ConfigurationManager(storage) all_notifications = await config_mgr._read_all_child_category_names( "Notifications") notifications = [] for notification in all_notifications: notification_config = await config_mgr._read_category_val( notification['child']) notification = { "name": notification_config['name']['value'], "rule": notification_config['rule']['value'], "channel": notification_config['channel']['value'], "notificationType": notification_config['notification_type']['value'], "enable": notification_config['enable']['value'], } notifications.append(notification) except Exception as ex: raise web.HTTPInternalServerError(reason=ex) else: return web.json_response({'notifications': notifications})
async def delete_category(request): """ Args: request: category_name required Returns: Success message on successful deletion Raises: TypeError/ValueError/Exception on error :Example: curl -X DELETE http://localhost:8081/fledge/category/{category_name} """ category_name = request.match_info.get('category_name', None) category_name = urllib.parse.unquote( category_name) if category_name is not None else None try: cf_mgr = ConfigurationManager(connect.get_storage_async()) await cf_mgr.delete_category_and_children_recursively(category_name) except (ValueError, TypeError) as ex: raise web.HTTPBadRequest(reason=ex) except Exception as ex: raise web.HTTPInternalServerError(reason=ex) else: return web.json_response({ 'result': 'Category {} deleted successfully.'.format(category_name) })
def do_update(request): _logger.info("{} plugin update started...".format(request._name)) code, link = update_repo_sources_and_plugin(request._type, request._name) if code != 0: _logger.error("{} plugin update failed. Logs available at {}".format( request._name, link)) else: _logger.info("{} plugin update completed. Logs available at {}".format( request._name, link)) # PKGUP audit log entry storage_client = connect.get_storage_async() audit = AuditLogger(storage_client) audit_detail = { 'packageName': "fledge-{}-{}".format(request._type, request._name.replace("_", "-")) } asyncio.ensure_future(audit.information('PKGUP', audit_detail)) # Restart the services which were disabled before plugin update for s in request._sch_list: asyncio.ensure_future( server.Server.scheduler.enable_schedule(uuid.UUID(s))) # Below case is applicable for the notification plugins ONLY # Enabled back configuration categories which were disabled during update process if request._type in ['notify', 'rule']: storage_client = connect.get_storage_async() config_mgr = ConfigurationManager(storage_client) for n in request._notification_list: asyncio.ensure_future( config_mgr.set_category_item_value_entry(n, "enable", "true"))
async def test_delete_notification(self, mocker, client): mocker.patch.object(ServiceRegistry, 'get', return_value=mock_registry) mocker.patch.object(notification, '_hit_get_url', return_value=mock_get_url("/fledge/notification/plugin")) storage_client_mock = mocker.patch.object(connect, 'get_storage_async') mocker.patch.object(ConfigurationManager, '__init__', return_value=None) mocker.patch.object(ConfigurationManager, '_read_category_val', return_value=mock_read_category_val("Test Notification")) mocker.patch.object(AuditLogger, "__init__", return_value=None) audit_logger = mocker.patch.object(AuditLogger, "information", return_value=asyncio.sleep(.1)) c_mgr = ConfigurationManager(storage_client_mock) delete_configuration = mocker.patch.object(ConfigurationManager, "delete_category_and_children_recursively", return_value=asyncio.sleep(.1)) audit_logger = mocker.patch.object(AuditLogger, "information", return_value=asyncio.sleep(.1)) mocker.patch.object(notification, '_hit_delete_url', side_effect=[mock_delete_url("/notification/Test Notification")]) resp = await client.delete("/fledge/notification/Test Notification") assert 200 == resp.status result = await resp.json() assert result['result'].endswith("Notification {} deleted successfully.".format("Test Notification")) args, kwargs = delete_configuration.call_args_list[0] assert "Test Notification" in args assert 1 == audit_logger.call_count print(audit_logger.call_args_list) audit_logger_calls = [call('NTFDL', {'name': 'Test Notification'})] audit_logger.assert_has_calls(audit_logger_calls, any_order=True)
async def test_set_configuration(self): """Test that purge's set_configuration returns configuration item with key 'PURGE_READ' """ @asyncio.coroutine def mock_cm_return(): return "" mockStorageClientAsync = MagicMock(spec=StorageClientAsync) mockAuditLogger = AuditLogger(mockStorageClientAsync) with patch.object(FledgeProcess, '__init__'): with patch.object(mockAuditLogger, "__init__", return_value=None): p = Purge() p._storage = MagicMock(spec=StorageClientAsync) mock_cm = ConfigurationManager(p._storage) with patch.object( mock_cm, 'create_category', return_value=mock_cm_return()) as mock_create_cat: with patch.object(mock_cm, 'create_child_category', return_value=mock_cm_return() ) as mock_create_child_cat: with patch.object( mock_cm, 'get_category_all_items', return_value=mock_cm_return()) as mock_get_cat: await p.set_configuration() mock_get_cat.assert_called_once_with('PURGE_READ') mock_create_child_cat.assert_called_once_with( 'Utilities', ['PURGE_READ']) args, kwargs = mock_create_cat.call_args assert 4 == len(args) assert 5 == len(args[1].keys()) assert 'PURGE_READ' == args[0] assert 'Purge the readings, log, statistics history table' == args[ 2] assert args[3] is True
async def _delete_configuration_category(storage: StorageClientAsync, key: str) -> None: payload = PayloadBuilder().WHERE(['key', '=', key]).payload() await storage.delete_from_tbl('configuration', payload) # Removed category from configuration cache and other related stuff e.g. script files config_mgr = ConfigurationManager(storage) config_mgr.delete_category_related_things(key) config_mgr._cacheManager.remove(key)
async def test_get_interest_exception(self, client, params, message, expected_kwargs): Server._storage_client = MagicMock(StorageClientAsync) Server._configuration_manager = ConfigurationManager(Server._storage_client) Server._interest_registry = InterestRegistry(Server._configuration_manager) with patch.object(Server._interest_registry, 'get', side_effect=interest_registry_exceptions.DoesNotExist) as patch_get_interest_reg: resp = await client.get('/fledge/interest{}'.format(params)) assert 404 == resp.status assert message == resp.reason args, kwargs = patch_get_interest_reg.call_args assert expected_kwargs == kwargs
async def delete_service(request): """ Delete an existing service :Example: curl -X DELETE http://localhost:8081/fledge/service/<svc name> """ try: svc = request.match_info.get('service_name', None) storage = connect.get_storage_async() result = await get_schedule(storage, svc) if result['count'] == 0: return web.HTTPNotFound( reason='{} service does not exist.'.format(svc)) config_mgr = ConfigurationManager(storage) # In case of notification service, if notifications exists, then deletion is not allowed if 'notification' in result['rows'][0]['process_name']: notf_children = await config_mgr.get_category_child( category_name="Notifications") children = [x['key'] for x in notf_children] if len(notf_children) > 0: return web.HTTPBadRequest( reason= 'Notification service `{}` can not be deleted, as {} notification instances exist.' .format(svc, children)) # First disable the schedule svc_schedule = result['rows'][0] sch_id = uuid.UUID(svc_schedule['id']) if svc_schedule['enabled'].lower() == 't': await server.Server.scheduler.disable_schedule(sch_id) # return control to event loop await asyncio.sleep(1) # Delete all configuration for the service name await config_mgr.delete_category_and_children_recursively(svc) # Remove from registry as it has been already shutdown via disable_schedule() and since # we intend to delete the schedule also, there is no use of its Service registry entry try: services = ServiceRegistry.get(name=svc) ServiceRegistry.remove_from_registry(services[0]._id) except service_registry_exceptions.DoesNotExist: pass # Delete schedule await server.Server.scheduler.delete_schedule(sch_id) except Exception as ex: raise web.HTTPInternalServerError(reason=str(ex)) else: return web.json_response( {'result': 'Service {} deleted successfully.'.format(svc)})
async def test_bad_type_delete_cert(self, client): async def async_mock(): return {'value': 'fledge'} storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_item', return_value=async_mock()) as patch_cfg: resp = await client.delete('/fledge/certificate/server.cert?type=pem') assert 400 == resp.status assert 'Only cert and key are allowed for the value of type param' == resp.reason assert 1 == patch_cfg.call_count
async def test_bad_delete_cert_with_invalid_filename(self, client, cert_name, actual_code, actual_reason): async def async_mock(): return {'value': 'fledge'} storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_item', return_value=async_mock()) as patch_cfg: resp = await client.delete('/fledge/certificate/{}'.format(cert_name)) assert actual_code == resp.status assert actual_reason == resp.reason assert 1 == patch_cfg.call_count
async def test_get_interest_with_filter(self, client, params, expected_kwargs): Server._storage_client = MagicMock(StorageClientAsync) Server._configuration_manager = ConfigurationManager(Server._storage_client) Server._interest_registry = InterestRegistry(Server._configuration_manager) with patch.object(Server._interest_registry, 'get', return_value=[]) as patch_get_interest_reg: resp = await client.get('/fledge/interest{}'.format(params)) assert 200 == resp.status r = await resp.text() json_response = json.loads(r) assert {'interests': []} == json_response args, kwargs = patch_get_interest_reg.call_args assert expected_kwargs == kwargs
async def test_unregister_interest_exception(self, client): Server._storage_client = MagicMock(StorageClientAsync) Server._configuration_manager = ConfigurationManager(Server._storage_client) Server._interest_registry = InterestRegistry(Server._configuration_manager) reg_id = 'c6bbf3c8-f43c-4b0f-ac48-f597f510da0b' with patch.object(Server._interest_registry, 'get', side_effect=interest_registry_exceptions.DoesNotExist) as patch_get_interest_reg: resp = await client.delete('/fledge/interest/{}'.format(reg_id)) assert 404 == resp.status assert 'InterestRecord with registration_id {} does not exist'.format(reg_id) == resp.reason args, kwargs = patch_get_interest_reg.call_args assert {'registration_id': reg_id} == kwargs
async def test_register_interest_exceptions(self, client): Server._storage_client = MagicMock(StorageClientAsync) Server._configuration_manager = ConfigurationManager(Server._storage_client) Server._interest_registry = InterestRegistry(Server._configuration_manager) request_data = {"category": "COAP", "service": "c6bbf3c8-f43c-4b0f-ac48-f597f510da0b"} with patch.object(Server._interest_registry, 'register', side_effect=interest_registry_exceptions.ErrorInterestRegistrationAlreadyExists) as patch_reg_interest_reg: resp = await client.post('/fledge/interest', data=json.dumps(request_data)) assert 400 == resp.status assert 'An InterestRecord already exists by microservice_uuid {} for category_name {}'.format(request_data['service'], request_data['category']) == resp.reason args, kwargs = patch_reg_interest_reg.call_args assert (request_data['service'], request_data['category']) == args
async def test_bad_register_interest(self, client): Server._storage_client = MagicMock(StorageClientAsync) Server._configuration_manager = ConfigurationManager(Server._storage_client) Server._interest_registry = InterestRegistry(Server._configuration_manager) request_data = {"category": "COAP", "service": "c6bbf3c8-f43c-4b0f-ac48-f597f510da0b"} with patch.object(Server._interest_registry, 'register', return_value=None) as patch_reg_interest_reg: resp = await client.post('/fledge/interest', data=json.dumps(request_data)) assert 400 == resp.status assert 'Interest by microservice_uuid {} for category_name {} could not be registered'.format(request_data['service'], request_data['category']) == resp.reason args, kwargs = patch_reg_interest_reg.call_args assert (request_data['service'], request_data['category']) == args
async def test_add_notification_service(self, client, payload): data = json.loads(payload) sch_id = '45876056-e04c-4cde-8a82-1d8dbbbe6d72' async def async_mock_get_schedule(): schedule = StartUpSchedule() schedule.schedule_id = sch_id return schedule @asyncio.coroutine def q_result(*arg): table = arg[0] _payload = json.loads(arg[1]) if table == 'schedules': if _payload['return'][0] == 'process_name': assert {"return": ["process_name"]} == _payload return {'rows': [{'process_name': 'purge'}, {'process_name': 'stats collector'}], 'count': 2} else: assert {"return": ["schedule_name"], "where": {"column": "schedule_name", "condition": "=", "value": data['name']}} == _payload return {'count': 0, 'rows': []} if table == 'scheduled_processes': assert {"return": ["name"], "where": {"column": "name", "condition": "=", "value": "notification_c"}} == _payload return {'count': 0, 'rows': []} expected_insert_resp = {'rows_affected': 1, "response": "inserted"} server.Server.scheduler = Scheduler(None, None) storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_all_items', return_value=self.async_mock(None)) as patch_get_cat_info: with patch.object(storage_client_mock, 'query_tbl_with_payload', side_effect=q_result): with patch.object(storage_client_mock, 'insert_into_tbl', return_value=self.async_mock(expected_insert_resp)) as insert_table_patch: with patch.object(server.Server.scheduler, 'save_schedule', return_value=self.async_mock("")) as patch_save_schedule: with patch.object(server.Server.scheduler, 'get_schedule_by_name', return_value=async_mock_get_schedule()) as patch_get_schedule: resp = await client.post('/fledge/service', data=payload) server.Server.scheduler = None assert 200 == resp.status result = await resp.text() json_response = json.loads(result) assert {'id': sch_id, 'name': data['name']} == json_response patch_get_schedule.assert_called_once_with(data['name']) patch_save_schedule.called_once_with() args, kwargs = insert_table_patch.call_args assert 'scheduled_processes' == args[0] p = json.loads(args[1]) assert {'name': 'notification_c', 'script': '["services/notification_c"]'} == p patch_get_cat_info.assert_called_once_with(category_name=data['name'])
async def verify_certificate(cls, cert): certs_dir = _FLEDGE_DATA + '/etc/certs' if _FLEDGE_DATA else _FLEDGE_ROOT + "/data/etc/certs" storage_client = connect.get_storage_async() cfg_mgr = ConfigurationManager(storage_client) ca_cert_item = await cfg_mgr.get_category_item( 'rest_api', 'authCertificateName') ca_cert_file = "{}/{}.cert".format(certs_dir, ca_cert_item['value']) SSLVerifier.set_ca_cert(ca_cert_file) SSLVerifier.set_user_cert(cert) SSLVerifier.verify( ) # raises OSError, SSLVerifier.VerificationError
async def login(cls, username, password, host): """ Args: username: username password: password host: IP address Returns: return token """ # check password change configuration storage_client = connect.get_storage_async() cfg_mgr = ConfigurationManager(storage_client) category_item = await cfg_mgr.get_category_item( 'rest_api', 'passwordChange') age = int(category_item['value']) # get user info on the basis of username payload = PayloadBuilder().SELECT("pwd", "id", "role_id", "pwd_last_changed").WHERE(['uname', '=', username])\ .ALIAS("return", ("pwd_last_changed", 'pwd_last_changed'))\ .FORMAT("return", ("pwd_last_changed", "YYYY-MM-DD HH24:MI:SS.MS"))\ .AND_WHERE(['enabled', '=', 't']).payload() result = await storage_client.query_tbl_with_payload( 'users', payload) if len(result['rows']) == 0: raise User.DoesNotExist('User does not exist') found_user = result['rows'][0] # check age of password t1 = datetime.now() t2 = datetime.strptime(found_user['pwd_last_changed'], "%Y-%m-%d %H:%M:%S.%f") delta = t1 - t2 if age == 0: # user will not be forced to change their password. pass elif age <= delta.days: # user will be forced to change their password. raise User.PasswordExpired(found_user['id']) # validate password is_valid_pwd = cls.check_password(found_user['pwd'], str(password)) if not is_valid_pwd: raise User.PasswordDoesNotMatch( 'Username or Password do not match') uid, jwt_token, is_admin = await cls._get_new_token( storage_client, found_user, host) return uid, jwt_token, is_admin
async def _read_config(self): """Reads configuration""" default_config = { "sleep_interval": { "description": "Time in seconds to sleep between health checks. (must be greater than 5)", "type": "integer", "default": str(self._DEFAULT_SLEEP_INTERVAL), "displayName": "Health Check Interval (In seconds)", "minimum": "5" }, "ping_timeout": { "description": "Timeout for a response from any given micro-service. (must be greater than 0)", "type": "integer", "default": str(self._DEFAULT_PING_TIMEOUT), "displayName": "Ping Timeout", "minimum": "1", "maximum": "5" }, "max_attempts": { "description": "Maximum number of attempts for finding a heartbeat of service", "type": "integer", "default": str(self._DEFAULT_MAX_ATTEMPTS), "displayName": "Max Attempts To Check Heartbeat", "minimum": "1" }, "restart_failed": { "description": "Restart failed microservice - manual/auto", "type": "enumeration", 'options': ['auto', 'manual'], "default": self._DEFAULT_RESTART_FAILED, "displayName": "Restart Failed" } } storage_client = connect.get_storage_async() cfg_manager = ConfigurationManager(storage_client) await cfg_manager.create_category('SMNTR', default_config, 'Service Monitor', display_name='Service Monitor') config = await cfg_manager.get_category_all_items('SMNTR') self._sleep_interval = int(config['sleep_interval']['value']) self._ping_timeout = int(config['ping_timeout']['value']) self._max_attempts = int(config['max_attempts']['value']) self._restart_failed = config['restart_failed']['value']
async def test_dupe_category_name_add_task(self, client): @asyncio.coroutine def q_result(*arg): table = arg[0] if table == 'tasks': return {'count': 0, 'rows': []} mock_plugin_info = { 'name': "north bound", 'version': "1.1", 'type': "north", 'interface': "1.0", 'config': { 'plugin': { 'description': "North OMF plugin", 'type': 'string', 'default': 'omf' } } } data = { "name": "north bound", "plugin": "omf", "type": "north", "schedule_type": 3, "schedule_repeat": 30 } storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch.object(common, 'load_and_fetch_python_plugin_info', side_effect=[mock_plugin_info]): with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_all_items', return_value=self.async_mock( mock_plugin_info)) as patch_get_cat_info: with patch.object(storage_client_mock, 'query_tbl_with_payload', side_effect=q_result): resp = await client.post('/fledge/scheduled/task', data=json.dumps(data)) assert 400 == resp.status assert "The '{}' category already exists".format( data['name']) == resp.reason patch_get_cat_info.assert_called_once_with( category_name=data['name'])
async def test_run_general_exception(self): storage_client_mock = MagicMock(spec=StorageClientAsync) cfg_mgr = ConfigurationManager(storage_client_mock) with patch.object(ServiceRegistry._logger, 'info') as log_info: s_id_1 = ServiceRegistry.register('sname1', 'Storage', 'saddress1', 1, 1, 'http') assert 1 == log_info.call_count args, kwargs = log_info.call_args assert args[0].startswith('Registered service instance id=') assert args[0].endswith( ': <sname1, type=Storage, protocol=http, address=saddress1, service port=1, management port=1, status=1>' ) i_reg = InterestRegistry(cfg_mgr) i_reg.register(s_id_1, 'catname1') # used to mock client session context manager async def async_mock(return_value): return return_value class AsyncSessionContextManagerMock(MagicMock): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) async def __aenter__(self): raise Exception async def __aexit__(self, *args): return None with patch.object(ConfigurationManager, 'get_category_all_items', return_value=async_mock(None)) as cm_get_patch: with patch.object(aiohttp.ClientSession, 'post', return_value=AsyncSessionContextManagerMock() ) as post_patch: with patch.object(cb._LOGGER, 'exception') as exception_patch: await cb.run('catname1') exception_patch.assert_called_once_with( 'Unable to notify microservice with uuid %s due to exception: %s', s_id_1, '') post_patch.assert_has_calls([ call('http://saddress1:1/fledge/change', data='{"category": "catname1", "items": null}', headers={'content-type': 'application/json'}) ]) cm_get_patch.assert_called_once_with('catname1')
async def test_bad_delete_cert_if_in_use(self, client): async def async_mock(): return {'value': 'fledge'} storage_client_mock = MagicMock(StorageClientAsync) c_mgr = ConfigurationManager(storage_client_mock) with patch('os.path.isfile', return_value=True): with patch.object(connect, 'get_storage_async', return_value=storage_client_mock): with patch.object(c_mgr, 'get_category_item', return_value=async_mock()) as patch_cfg: resp = await client.delete('/fledge/certificate/fledge.cert') assert 409 == resp.status assert 'Certificate with name fledge.cert is already in use, you can not delete' == resp.reason assert 1 == patch_cfg.call_count args, kwargs = patch_cfg.call_args assert ({'item_name': 'certificateName', 'category_name': 'rest_api'}) == kwargs
async def test__installation_config(self): async def async_mock(return_value): return return_value storage_client_mock = MagicMock(spec=StorageClientAsync) Server._configuration_manager = ConfigurationManager(storage_client_mock) with patch.object(Server._configuration_manager, 'create_category', return_value=async_mock([])) as patch_create_cat: with patch.object(Server._configuration_manager, 'get_category_all_items', return_value=async_mock([])) as patch_get_all_cat: await Server.installation_config() patch_get_all_cat.assert_called_once_with('Installation') patch_create_cat.assert_called_once_with('Installation', Server._INSTALLATION_DEFAULT_CONFIG, 'Installation', True, display_name='Installation')