def test_volume_put_minimal_body(self, etcd_client, volume_raw_ok_ready, volume_raw_requested_ok, flask_app): volume = etcd_client.write(VolumeManager.KEY, volume_raw_ok_ready, append=True) id = flask_app.volume_manager.get_id_from_key(volume.key) volume = flask_app.volume_manager._load_from_etcd([volume])[0] expected, errors = VolumeSchema().dump(volume) assert errors == {} expected['state'] = 'pending' expected['requested'], errors = VolumeAttributeSchema().loads( volume_raw_requested_ok) assert errors == {} with flask_app.test_client() as c: response = c.put('/volumes/{}'.format(id), data=volume_raw_requested_ok, content_type='application/json') result, errors = VolumeSchema().loads(response.data.decode()) assert errors == {} assert result['id'] == id assert response.status_code == 202 assert expected == result assert response.headers[ 'Location'] == 'http://localhost/volumes/{}'.format(id)
def post(): """It will create a volume with the given input as a starting point. Returns: tuple: payload, http status code, headers """ manager = app.volume_manager request_json = request.get_json(force=True) request_id = request_json.get('id', '') fields = ( 'name', 'meta', 'requested', ) data, errors = VolumeSchema(only=fields).load(request_json) if errors: return {'message': errors}, 400 data['node'] = '' data['state'] = 'scheduling' data['actual'] = {} data['control'] = { 'error': '', 'error_count': 0, 'parent_id': request_id } lock = manager.get_lock(request_id, 'clone') if request_id: lock.acquire(timeout=0, lock_ttl=10) data['state'] = 'pending' parent = manager.by_id(request_id) if not parent: lock.release() return { 'message': 'Parent does not exist. Clone not created' }, 400 parent_state = parent.value['state'] if parent_state in ['deleting', 'scheduling']: lock.release() return { 'message': 'Parent can\'t have state {} ' 'in order to clone'.format(parent_state) }, 400 volume = manager.create(data) if request_id: lock.release() result, _ = VolumeSchema().dump(volume) return result, 202, { 'Location': app.api.url_for(Volume, volume_id=result['id']) }
def get(): """It will return a list of all the volumes Returns: tuple: payload, http status code """ result, _ = VolumeSchema().dump(app.volume_manager.all()[1], many=True) return result
def test_volume_get(self, etcd_client, volume_raw_ok_ready, flask_app): volume = etcd_client.write(VolumeManager.KEY, volume_raw_ok_ready, append=True) id = flask_app.volume_manager.get_id_from_key(volume.key) volume = flask_app.volume_manager._load_from_etcd([volume])[0] expected, errors = VolumeSchema().dump(volume) assert errors == {} with flask_app.test_client() as c: response = c.get('/volumes/{}'.format(id)) actual = json.loads(response.data.decode()) assert actual == expected assert response.status_code == 200
def delete(volume_id): """Deletes the volume pointed by the id. Args: volume_id (str): The id parsed from the URL Returns: tuple: payload, http status code, headers """ manager = app.volume_manager target_volume = manager.by_id(volume_id) if target_volume is None: return {'message': 'Not Found'}, 404 if target_volume.value['state'] != 'ready': return { 'message': 'Resource not in ready state, can\'t delete.' }, 409 lock = manager.get_lock(volume_id, 'clone') lock.acquire(timeout=0, lock_ttl=10) pending_clones = [] for volume in manager.all()[1]: if volume.value['control']['parent_id'] == volume_id: pending_clones.append(manager.get_id_from_key(volume.key)) if pending_clones: lock.release() return { 'message': 'Resource has pending clones, can\'t delete.', 'clones': pending_clones }, 409 target_volume.value['state'] = 'deleting' target_volume = manager.update(target_volume) lock.release() if not target_volume: return {'message': 'Resource changed during transition.'}, 409 result, _ = VolumeSchema().dump(target_volume) return result, 202, { 'Location': app.api.url_for(Volume, volume_id=result['id']) }
def get(volume_id): """Returns a volume dict as a json response or 404 if not found. Args: volume_id (str): The id parsed from the URL Returns: tuple: payload, http status code """ manager = app.volume_manager volume = manager.by_id(volume_id) if volume is None: return {'message': 'Not Found'}, 404 result, _ = VolumeSchema().dump(volume) return result, 200
def put(volume_id): """Edits a volume dict based on the given representation. Expects to receive a json payload with a complete new version of the volume to be edited Args: volume_id (str): The id parsed from the URL Returns: tuple: payload, http status code, headers """ manager = app.volume_manager volume = manager.by_id(volume_id) if volume is None: return {'message': 'Not Found'}, 404 if volume.value['state'] != 'ready': return { 'message': 'Resource not in ready state, can\'t update.' }, 409 new_volume, errors = VolumeAttributeSchema().load( request.get_json(force=True)) if errors: return {'message': errors}, 400 if volume.value['requested'] == new_volume: return '', 304 volume.value['requested'] = new_volume volume.value['state'] = 'pending' volume = manager.update(volume) if not volume: return {'message': 'Resource changed during transition.'}, 409 result, _ = VolumeSchema().dump(volume) return result, 202, { 'Location': app.api.url_for(Volume, volume_id=result['id']) }
def test_volume_list_get(self, etcd_client, volume_raw_ok_ready, flask_app): generators = [volume_raw_ok_ready, volume_raw_ok_ready] volume_writes = [] for generator in generators: volume_writes.append( etcd_client.write(VolumeManager.KEY, generator, append=True)) volume_writes = flask_app.volume_manager._load_from_etcd(volume_writes) expected, errors = VolumeSchema().dump(volume_writes, many=True) assert errors == {} with flask_app.test_client() as c: response = c.get('/volumes') assert response.status_code == 200 actual = json.loads(response.data.decode()) assert len(actual) == len(expected) assert actual == expected