def test_delete_active_reservation(tables, client, active_reservation, permissive_restriction): permissive_restriction.save() active_reservation.save() resp = client.delete(ENDPOINT + '/' + str(active_reservation.id), headers=HEADERS) assert resp.status_code == HTTPStatus.OK with pytest.raises(NoResultFound): Reservation.get(active_reservation.id)
def test_create_reservation_with_an_indefinite_restriction( tables, client, new_user, restriction): new_user.save() # Create an indefinite restriction and assign it to the user restriction.starts_at = '2101-01-01T10:00:00.000Z' restriction.ends_at = None restriction.apply_to_user(new_user) # Create a resource and assign it to the restriction resource = Resource(id='0123456789012345678901234567890123456789') resource.save() restriction.apply_to_resource(resource) data = { 'title': 'Test reservation', 'description': 'Test reservation', 'resourceId': '0123456789012345678901234567890123456789', 'userId': new_user.id, 'start': '2101-01-02T10:00:00.000Z', 'end': '2101-01-03T12:00:00.000Z' } resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data)) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert Reservation.get(resp_json['reservation']['id']) is not None
def delete(id): try: current_user_id = get_jwt_identity() claims = get_jwt_claims() # Fetch the reservation reservation_to_destroy = Reservation.get(id) # Must be priviliged is_admin = 'admin' in claims['roles'] is_owner = reservation_to_destroy.user_id == current_user_id assert is_owner or is_admin, G['unpriviliged'] # Destroy reservation_to_destroy.destroy() except AssertionError as error_message: content, status = {'msg': str(error_message)}, 403 except NoResultFound: # FIXME It is theoretically posibble that User.get() could also raise this exception content, status = {'msg': R['not_found']}, 404 except Exception as e: content, status = {'msg': G['internal_error'] + str(e)}, 500 else: content, status = {'msg': R['delete']['success']}, 200 finally: return content, status
def test_update_past_reservation(tables, client, past_reservation, permissive_restriction): permissive_restriction.save() past_reservation.save() new_reservation_title = past_reservation.title + '111' resp = client.put(ENDPOINT + '/' + str(past_reservation.id), headers=HEADERS, data=json.dumps({'title': new_reservation_title})) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert resp_json['reservation']['title'] == new_reservation_title assert Reservation.get(past_reservation.id).title == new_reservation_title
def update(id: ReservationId, newValues: Dict[str, Any]) -> Tuple[Content, HttpStatusCode]: new_values = newValues allowed_fields = {'title', 'description', 'resourceId', 'end'} try: reservation = Reservation.get(id) if reservation.end < datetime.utcnow() and not is_admin(): raise ForbiddenException('reservation already finished') if reservation.start > datetime.utcnow() or is_admin(): allowed_fields.add('start') if not set(new_values.keys()).issubset(allowed_fields): raise ForbiddenException('invalid field is present') for field_name, new_value in new_values.items(): field_name = snakecase(field_name) assert (field_name is not None) and hasattr(reservation, field_name), \ 'reservation has no {} field'.format(field_name) setattr(reservation, field_name, new_value) user = User.get(get_jwt_identity()) if not (is_admin() or __is_reservation_owner(reservation)) or not \ ReservationVerifier.is_reservation_allowed(user, reservation): raise ForbiddenException("reservation not allowed") reservation.is_cancelled = False reservation.save() content, status = { 'msg': RESERVATION['update']['success'], 'reservation': reservation.as_dict() }, 201 except ForbiddenException as fe: content, status = { 'msg': RESERVATION['update']['failure']['forbidden'].format(reason=fe) }, 403 except NoResultFound: content, status = {'msg': RESERVATION['not_found']}, 404 except AssertionError as e: content, status = { 'msg': RESERVATION['update']['failure']['assertions'].format(reason=e) }, 422 except Exception as e: log.critical(e) content, status = {'msg': GENERAL['internal_error'] + str(e)}, 500 finally: return content, status
def test_update_future_reservation_start(tables, client, future_reservation, permissive_restriction): permissive_restriction.save() future_reservation.save() new_reservation_start = future_reservation.start + timedelta(hours=1) resp = client.put( ENDPOINT + '/' + str(future_reservation.id), headers=HEADERS, data=json.dumps({ 'start': DateUtils.stringify_datetime_to_api_format(new_reservation_start) })) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert resp_json['reservation']['start'] == DateUtils.stringify_datetime( new_reservation_start) assert Reservation.get( future_reservation.id).start == new_reservation_start
def delete(id: ReservationId) -> Tuple[Content, HttpStatusCode]: try: reservation_to_destroy = Reservation.get(id) assert (reservation_to_destroy.start > datetime.datetime.utcnow() and __is_reservation_owner(reservation_to_destroy) ) or is_admin(), GENERAL['unprivileged'] reservation_to_destroy.destroy() except AssertionError as error_message: content, status = {'msg': str(error_message)}, 403 except NoResultFound: # FIXME It is theoretically possible that User.get() could also raise this exception content, status = {'msg': RESERVATION['not_found']}, 404 except Exception as e: content, status = {'msg': GENERAL['internal_error'] + str(e)}, 500 else: content, status = {'msg': RESERVATION['delete']['success']}, 200 finally: return content, status
def handle_expired_logs(self): ''' Seeks for ordinary JSON log files related to expired reservations. It creates very simple summary (avg) and fills in existing reservation database record. ''' time_now = datetime.datetime.utcnow() # Get all files within given directory # Accept only files like: 10.json for item in self.log_dir.glob('[0-9]*.json'): if item.is_file(): try: log.debug('Processing file: {}'.format(item)) id_from_filename = int(item.stem) reservation = Reservation.get(id=id_from_filename) reservation_expired = reservation.ends_at < time_now if reservation_expired: log.debug('Reservation id={} has endend.'.format( id_from_filename)) # Generate and persist summary log_contents = JSONLogFile(path=item).read() reservation.gpu_util_avg = avg( log_contents['metrics']['gpu_util']['values']) reservation.mem_util_avg = avg( log_contents['metrics']['mem_util']['values']) log.debug('Saving summary...') reservation.save() # Clean up log immidiately self._clean_up_old_log_file(file=item) except NoResultFound: log.debug( 'Log file for inexisting reservation has been found, cleaning up the file...' ) self._clean_up_old_log_file(file=item) except Exception as e: log.debug(e)
def test_create_reservation_that_is_covered_by_two_separate_restrictions( tables, client, new_user): r1_start = '2101-01-01T00:00:00.000Z' r1_end = '2101-01-02T00:00:00.000Z' r2_start = '2101-01-02T00:00:00.000Z' r2_end = '2101-01-02T23:59:00.000Z' r1 = Restriction(name='FirstRestriction', starts_at=r1_start, ends_at=r1_end, is_global=False) r2 = Restriction(name='SecondRestriction', starts_at=r2_start, ends_at=r2_end, is_global=False) new_user.save() r1.apply_to_user(new_user) r2.apply_to_user(new_user) resource = Resource(id='0123456789012345678901234567890123456789') resource.save() r1.apply_to_resource(resource) r2.apply_to_resource(resource) data = { 'title': 'Test reservation', 'description': 'Test reservation', 'resourceId': '0123456789012345678901234567890123456789', 'userId': new_user.id, 'start': '2101-01-01T10:00:00.000Z', 'end': '2101-01-02T12:00:00.000Z' } resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data)) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert Reservation.get(resp_json['reservation']['id']) is not None
def test_after_updating_restriction_reservations_that_are_no_longer_valid_should_get_cancelled( tables, client, new_user, restriction): new_user.save() # Create a restriction, assign user and resource to it restriction.starts_at = '2101-01-01T10:00:00.000Z' restriction.ends_at = '2101-01-05T10:00:00.000Z' restriction.apply_to_user(new_user) resource = Resource(id='0123456789012345678901234567890123456789') resource.save() restriction.apply_to_resource(resource) # Create a reservation in allowed timeframe (should succeed) data = { 'title': 'Test reservation', 'description': 'Test reservation', 'resourceId': '0123456789012345678901234567890123456789', 'userId': new_user.id, 'start': '2101-01-02T10:00:00.000Z', 'end': '2101-01-03T12:00:00.000Z' } resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data)) resp_json = json.loads(resp.data.decode('utf-8')) reservation = Reservation.get(resp_json['reservation']['id']) assert reservation.is_cancelled is False # Update the restriction to make the reservation invalid data = {'startsAt': '2101-01-04T09:00:00.000Z'} resp = client.put(BASE_URI + '/restrictions/' + str(reservation.id), headers=HEADERS, data=json.dumps(data)) assert resp.status_code == HTTPStatus.OK assert reservation.is_cancelled is True
def test_create_reservation(tables, client, new_user, permissive_restriction): new_user.save() # Create a resource and assign it to the restriction resource = Resource(id='0123456789012345678901234567890123456789') resource.save() # Try to create reservation for a period that the user has access to, as specified by the restriction. # Should succeed. now = datetime.datetime.now() data = { 'title': 'Test reservation', 'description': 'Test reservation', 'resourceId': '0123456789012345678901234567890123456789', 'userId': new_user.id, 'start': DateUtils.stringify_datetime_to_api_format(now), 'end': DateUtils.stringify_datetime_to_api_format(now + timedelta(hours=1)) } resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data)) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert Reservation.get(resp_json['reservation']['id']) is not None
def test_create_reservation_starting_in_the_past(tables, client, new_user, permissive_restriction): new_user.save() # Create a resource and assign it to the restriction resource = Resource(id='0123456789012345678901234567890123456789') resource.save() past_time = datetime.datetime.now() - timedelta(minutes=2) end_time = past_time + timedelta(hours=1) data = { 'title': 'Test reservation', 'description': 'Test reservation', 'resourceId': '0123456789012345678901234567890123456789', 'userId': new_user.id, 'start': DateUtils.stringify_datetime_to_api_format(past_time), 'end': DateUtils.stringify_datetime_to_api_format(end_time) } resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data)) resp_json = json.loads(resp.data.decode('utf-8')) assert resp.status_code == HTTPStatus.CREATED assert Reservation.get(resp_json['reservation']['id']) is not None