def test_event_service_updated_image_updated_config(self, overseer: Overseer, service): scale_config = copy.deepcopy(service['scale_config']) scale_config['max'] = 4 overseer.scaler_docker.fetch_image_config.return_value = scale_config overseer.check_new_scale_config({'diff': self.DIFF_IMAGE, 'service': filter_dict(service)}) overseer.mongo.services.update_one.assert_called() overseer.dispatch.assert_called()
def run_available_upgrade(self): resolved = self.resolve_upgrade_and_steps() """ result: best_phase: Phase steps: - #Step errors: step: error: $remoteerror catalog: $catalog """ result_ = resolved['result'] if result_ and result_['steps']: sched = { "state": RUNNING, "steps": [{ "service": step.service, "from": step.from_, "to": step.to, "state": WAITING } for step in result_['steps']] } self._run_step(sched['steps'][0], sched) # disable all scheduled self.mongo.scheduling.update_many({"state": RUNNING}, {"$set": { "state": ABORDED }}) self.mongo.scheduling.insert_one(sched) return filter_dict(sched) return None
def test_new_version(self, overseer: Overseer, service_data, service): overseer.mongo.versions.find.return_value = [ {'digest': 'sha256:40c6c8b1a244746d4c351f9079848cf6325342a9023b8bf143a59201b8e0b789', 'image': 'maiev', 'repository': 'localhost:5000', 'species': 'producer', 'tag': 'producer-1.0.1', 'version': '1.0.1'} ] overseer.scaler_docker.list_tags.return_value = ['producer-1.0.1', 'producer-1.0.2'] overseer.mongo.services.find.return_value = [service] overseer.recheck_new_version() overseer.dispatch.assert_called_with('new_image', { "service": filter_dict(service), "image": {'repository': 'localhost:5000', 'image': 'maiev', 'tag': 'producer-1.0.2', 'species': 'producer', 'version': '1.0.2', 'digest': None}, "scale_config": service['scale_config'] }) overseer.mongo.versions.insert.assert_called_with({ 'repository': 'localhost:5000', 'image': 'maiev', 'tag': 'producer-1.0.2', 'species': 'producer', 'version': '1.0.2', 'digest': None})
def test_event_service_updated_with_diff(self, overseer: Overseer, service_data, service): overseer.mongo.services.find_one.return_value = service service_data['tag'] = 'producer-1.0.18' overseer.on_service_updated({'service': service_data, 'attributes': {}}) overseer.dispatch.assert_called_once_with('service_updated', { 'service': filter_dict(service), 'diff': self.DIFF_IMAGE})
def get_service(self, service_name): """ return all current state for the given service. :param service_name: the service's name :return: all internal data from db """ service = self._get_service(service_name) return service and filter_dict(service)
def _serialize_service(self, service): """ change data in service to make it compatible for mongodb :param service: dict :return: dict """ s = filter_dict(service) s['versions_list'] = list(s['versions'].values()) del s['versions'] return s
def list(self, _filter=None, **filter): """ return all ruleset matching the given filters. the filters can be given via keyword, or via the positonal argument _filter. :param dict _filter: like keywords: the search term compatible with pymongo :keyword: like _filter: the search term compatible with pymongo :return: the list of filtered RuleSet :rtype: list[RuleSet] """ return [ filter_dict(ruleset) for ruleset in (self.mongo.rulesets.find(_filter or filter) or ()) ]
def test_new_image_notified(self, overseer: Overseer, service): overseer.mongo.services.find.return_value = [service] overseer.on_image_updated({ 'from': 'scaler_docker', 'digest': 'sha256:aaa', 'image': 'maiev', 'repository': 'localhost:5000', 'tag': 'consumer-1.0.1', 'full_image_id': 'localhost:5000/maiev@sha256:aaa', 'scale_config': None }) overseer.dispatch.assert_called_with('new_image', { "service": filter_dict(service), "image": {'repository': 'localhost:5000', 'image': 'maiev', 'tag': 'consumer-1.0.1', 'species': 'consumer', 'version': '1.0.1', 'digest': 'sha256:aaa'}, "scale_config": service['scale_config'] })
def on_new_version(self, payload): logger.debug("new image: %s", payload) assert { 'service', 'image', 'scale_config' } <= set(payload), "missing data in payload: %s" % str(set(payload)) service_name_ = payload['service']['name'] service = self._get_service(service_name_) version_number = payload['image']['version'] image_info_ = payload['service']['image']['image_info'] scale_config_ = payload['scale_config'] or {} if service: existing_version = service['versions'].get(version_number) if existing_version and existing_version['available'] and \ existing_version.get('dependencies') == scale_config_.get('dependencies'): return # same image for same dep: this is same call for same image else: service = { "name": service_name_, "service": payload['service'], "versions": {}, "version": image_info_['version'] } new_version = service['versions'][version_number] = { "version": version_number, "image_info": payload['image'], "dependencies": scale_config_.get('dependencies', {}), "available": True } self._save_service(service) logger.debug("upserted %s => %r", service_name_, service) self.dispatch("new_version", { "service": filter_dict(service), "new": new_version })
def test_cleaned_version(self, overseer: Overseer, service_data, service): overseer.mongo.versions.find.return_value = [ {'digest': 'sha256:40c6c8b1a244746d4c351f9079848cf6325342a9023b8bf143a59201b8e0b789', 'image': 'maiev', 'repository': 'localhost:5000', 'species': 'consumer', 'tag': 'consumer-1.0.1', 'version': '1.0.1', '_id': 'abcdef'}, {'digest': 'lolilol', 'image': 'maiev', 'repository': 'localhost:5000', 'species': 'producer', 'tag': 'producer-1.0.1', 'version': '1.0.1', '_id': 'abcdef' }, ] overseer.scaler_docker.list_tags.return_value = ['consumer-1.0.1'] overseer.mongo.services.find.return_value = [service] overseer.recheck_new_version() overseer.dispatch.assert_called_once_with('cleaned_image', { "service": filter_dict(service), 'image': { 'digest': 'lolilol', 'image': 'maiev', 'repository': 'localhost:5000', 'species': 'producer', 'tag': 'producer-1.0.1', 'version': '1.0.1' } }) overseer.mongo.versions.remove.assert_called_with({ '_id': 'abcdef' })
def list_phases(self, filter_=None): filter_ = filter_ or {} return [filter_dict(s) for s in self.mongo.phases.find(filter_)]
def list_scheduling(self, filter_=None): filter_ = filter_ or {} return [filter_dict(s) for s in self.mongo.scheduling.find(filter_)]
def list_catalog(self, filter_=None): filter_ = filter_ or {} return [ filter_dict(self._unserialize_service(res)) for res in self.mongo.catalog.find(filter_) ]
def list_service(self): """ list all registered services with their metadata :return: """ return [filter_dict(s) for s in self.mongo.services.find()]
def test_event_service_updated_image_same_config(self, overseer: Overseer, service): overseer.check_new_scale_config({'diff': self.DIFF_IMAGE, 'service': filter_dict(service)}) overseer.mongo.services.update_one.assert_not_called() overseer.dispatch.assert_not_called()
def test_event_service_updated_scale(self, overseer: Overseer, service): overseer.check_new_scale_config({'diff': {'scale': {'from': 0, 'to': 10}}, 'service': filter_dict(service)}) overseer.mongo.services.update_one.assert_not_called() overseer.dispatch.assert_not_called()