def test_GET_nodes_HTTP_response_status(self): """ Tests that GET /node/all gives a valid HTTP 200 response """ NodeSeeder.seed_node('ricefield') url = UrlHelper.get_url(flapp, 'nodes') response = requests.get(url) assert response.ok
def test_node_backwards_cascade(self): """ Deleting an object referenced by a node should NOT delete the node """ NodeSeeder.seed_ricefield_node() assert Node.query.count() == 1 assert Sensor.query.count() > 0 Sensor.query.delete() assert Node.query.count() == 1 assert Sensor.query.count() == 0
def test_GET_nodes_ApiResponse_status(self): """ Test that GET /node/all gives a JSON response that has no errors in it, and that an ApiResponse object can be instantiated from the response body. """ for i in range(5): NodeSeeder.seed_ricefield_node(n_readings = 3) url = UrlHelper.get_url(flapp, 'node', 'all') r = requests.get(url) api_response = ApiResponseHelper.assert_api_response(r) assert api_response.ok nodes = map(lambda n: n.json(), Node.query.all()) assert sorted(nodes) == sorted(api_response.objects)
def test_node_forward_cascade(self): """ Deleting a node should delete all the associated sensors """ NodeSeeder.seed_ricefield_node() assert Node.query.count() == 1 assert Sensor.query.count() > 0 Node.query.delete() assert Node.query.count() == 0 assert Sensor.query.count() == 0
def test_GET_readings_by_sensorid_with_nonexisting_sensor_response_empty(self): """ GET /reading?sensor_id=<int> This call should return no readings as sensor 100 does not exist """ NodeSeeder.seed_ricefield_node(n_readings = 3) url = UrlHelper.get_url(flapp, 'readings', **{'sensor_id' : 100}) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.first() == None
def test_GET_nodes_ApiResponse_status(self): """ Test that GET /node/all gives a JSON response that has no errors in it, and that an ApiResponse object can be instantiated from the response body. """ for i in range(5): NodeSeeder.seed_ricefield_node(n_readings=3) url = UrlHelper.get_url(flapp, 'node', 'all') r = requests.get(url) api_response = ApiResponseHelper.assert_api_response(r) assert api_response.ok nodes = map(lambda n: n.json(), Node.query.all()) assert sorted(nodes) == sorted(api_response.objects)
def test_sensor_forward_cascade(self): """ Deleting a sensor should delete all the associated readings """ n_readings = 5 NodeSeeder.seed_ricefield_node(n_readings = n_readings) assert Sensor.query.count() > 0 ## >0 in case number of sensors are changed in the seed method assert Reading.query.count() > 0 Sensor.query.delete() assert Sensor.query.count() == 0 assert Reading.query.count() == 0
def test_sensortype_backwards_cascade(self): """ Deleting an object referenced by a sensortype should NOT delete the sensortype """ n_readings = 5 NodeSeeder.seed_ricefield_node(n_readings = n_readings) n_sensortypes_before_delete = SensorType.query.count() assert SensorType.query.count() > 0 assert Sensor.query.count() > 0 Sensor.query.delete() assert Sensor.query.count() == 0 assert SensorType.query.count() == n_sensortypes_before_delete
def test_POST_nodes_populate(self): """ Test that populate options creates the valid number of readings data """ populate_number = 3 site = SiteSeeder.seed_empty_site() args = { 'site_id': site.id, 'latitude': 13.2, 'longitude': 23.2, 'populate': populate_number } node = NodeSeeder.seed_node('ricefield', **args) url = UrlHelper.get_url(flapp, 'nodes') r = requests.get(url) api_response = ApiResponseHelper.assert_api_response(r) assert api_response.ok nodes = map(lambda n: n.json(), Node.query.all()) # get readings?sensor_id=xxxx and check whether the number of the value of readings is equal to 3 for n in nodes: for s in n['sensors']: url = UrlHelper.get_url(flapp, 'readings', sensor_id=s['id']) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.ok assert len(api_response.objects) == populate_number
def test_add_obj_with_json_method(self): # node_dict = {'node_type_str': 'empty', 'alias': 'supernode'} node = NodeSeeder.seed_node('ricefield', alias='mynode') # node = Node.create(**node_dict) self.r += node assert len(self.r.objects) == 1 assert self.r.objects[0] == node.json()
def test_add_obj_with_json_method(self): # node_dict = {'node_type_str': 'empty', 'alias': 'supernode'} node = NodeSeeder.seed_node('ricefield', alias = 'mynode') # node = Node.create(**node_dict) self.r += node assert len(self.r.objects) == 1 assert self.r.objects[0] == node.json()
def test_seed_ricefield_node_has_correct_coordinates(self): latitude = 1.5 longitude = 2.5 node = NodeSeeder.seed_ricefield_node(latitude=latitude, longitude=longitude) assert node.latitude == latitude assert node.longitude == longitude
def post(self): """ Use a HTTP POST request to /node to create a new node inside the network Example in Python: >>> import requests >>> r = requests.post('http://localhost:8080/node', data = {'alias':'mynode', 'site_id':'1', 'latitude':'13.24234234', 'longitude':23.222, 'populate':3, 'node_type':'ricefield'}) """ response = ApiResponse(request) # RequestHelper.filter_valid_parameters(Node, response, request) node_alias = RequestHelper.get_form_data(response, 'alias', str) node_type = RequestHelper.get_form_data(response, 'node_type', str, default = 'empty') site_id = RequestHelper.get_form_data(response, 'site_id', int) longitude = RequestHelper.get_form_data(response, 'longitude', float) latitude = RequestHelper.get_form_data(response, 'latitude', float) populate = RequestHelper.get_form_data(response, 'populate', int, default = 0) site = Site.query.filter_by(id = site_id).first() if site: node = NodeSeeder.seed_node(node_type, alias = node_alias, site_id = site_id, latitude = latitude, longitude = longitude, populate = populate) response += node else: response += exc.MissingSiteException(site_id) return response.json()
def test_DELETE_node_by_id(self): node = NodeSeeder.seed_node('empty') url = UrlHelper.get_url(flapp, 'node', node.id) response = requests.delete(url) assert response.ok response = requests.get(url) assert response.ok ApiResponseHelper.assert_api_response(response, expect_success=False)
def test_DELETE_node_by_id(self): node = NodeSeeder.seed_node('empty') url = UrlHelper.get_url(flapp, 'node', node.id) response = requests.delete(url) assert response.ok response = requests.get(url) assert response.ok ApiResponseHelper.assert_api_response(response, expect_success = False)
def test_GET_reading_by_nodeid_but_no_sensoralias_failure(self): """ GET /reading?node_id=<int> This call should return an API error as specifying node_id but no sensor_alias is insuficcient to complete the query """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) url = UrlHelper.get_url(flapp, 'readings', **{'node_id' : node.id}) response = requests.get(url) assert response.ok ApiResponseHelper.assert_api_response(response, expect_success = False)
def test_GET_reading_by_sensoralias_but_no_nodeid_failure(self): """ GET /reading?sensor_alias=<str> This call should return an API error as specifying sensor_alias but no node_id is insufficient to complete the query """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] url = UrlHelper.get_url(flapp, 'readings', **{'sensor_alias' : sensor.alias}) response = requests.get(url) assert response.ok ApiResponseHelper.assert_api_response(response, expect_success = False)
def test_correct_post_reading(self): assert len(Reading.query.all()) == 0 node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] timestamp_str = datetime.now().strftime(DATETIME_FORMATS[0]) url = UrlHelper.get_url(flapp, 'reading') print url response = requests.post(url, data = {'sensor_id': sensor.id, 'value': 42, 'timestamp': timestamp_str}) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert len(Reading.query.all()) == 1
def test_GET_existing_node_by_id(self): """ GET /node/1 This call should return the node with id=1 """ node = NodeSeeder.seed_node('empty') url = UrlHelper.get_url(flapp, 'node', node.id) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.first() == node.json()
def test_GET_readings_by_nodeid_and_sensoralias_success(self): """ GET /reading?node_id=<int>&sensor_alias=<str> This call should return all readings belonging to the sensor in the specified node, in this case two readings """ node = NodeSeeder.seed_ricefield_node(n_readings = 3) sensor = node.sensors[0] url = UrlHelper.get_url(flapp, 'readings', **{'node_id' : node.id, 'sensor_alias' : sensor.alias}) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert sorted(map(lambda x: x.json(), sensor.readings)) == sorted(api_response.objects)
def test_GET_existing_reading_by_id_success(self): """ GET /reading/<int> """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] reading = Reading.create(sensor = sensor, value = 17) url = UrlHelper.get_url(flapp, 'reading', 1) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.first() == reading.json()
def test_GET_reading_by_sensorid_with_existing_sensor_success(self): """ GET /reading?sensor_id=<int> This call should return all the readings belonging to the sensor (in this case three readings) """ node = NodeSeeder.seed_ricefield_node(n_readings = 3) sensor = node.sensors[0] url = UrlHelper.get_url(flapp, 'readings', **{'sensor_id' : sensor.id}) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert sorted(map(lambda x: x.json(), sensor.readings)) == sorted(api_response.objects)
def test_ApiResponse_json_method(self): try: ### Empty ApiResponse json.dumps(self.r.json()) except Exception: assert False try: ### ApiResponse with object self.r += NodeSeeder.seed_node('ricefield') json.dumps(self.r.json()) except Exception, e: print e assert False
def test_GET_reading_by_sensor_id_with_until_date_filtering_success(self): """ GET /reading?sensor_id=<int>&from=2014-1-1&until=2014-2-1 """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] for day in range(20): Reading.create(sensor = sensor, value = 17, timestamp = datetime(2014, 12, 1) + timedelta(days=day)) url = UrlHelper.get_url(flapp, 'readings', **{'sensor_id' : sensor.id, 'until': '2014-12-1'}) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) readings_in_interval = map(lambda r: r.json(), filter(lambda r: r.timestamp <= datetime(2014,12,1), sensor.readings)) api_response = ApiResponseHelper.assert_api_response(response) assert sorted(readings_in_interval) == sorted(api_response.objects)
def test_GET_readings_by_sensor_id_with_nonsensical_time_parameters_returns_no_objects(self): """ GET /reading?node_id=<int>&sensor_alias=<str>&from=2014-12-10&until=2013-1-1 This call should return no objects as the specified until date is before the from_date """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] start_date = datetime(2014, 12, 1) for day in range(20): Reading.create(sensor = sensor, value = 17, timestamp = start_date + timedelta(days=day)) url = UrlHelper.get_url(flapp, 'readings', **{'node_id' : node.id, 'sensor_alias': sensor.alias, 'from': '2014-12-2', 'until': '2013-1-1'}) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.first() == None
def test_GET_reading_by_node_id_and_sensor_alias_with_interval_time_filtering_success(self): """ GET /reading?node_id=<int>&sensor_alias=<str>&from=2014-12-2&until=2014-12-11 This call should return all the readings created in the interval from 2014-12-2 until 2014-12-11 for a sensor in the specified node """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] start_date = datetime(2014, 12, 1) for day in range(20): Reading.create(sensor = sensor, value = 17, timestamp = start_date + timedelta(days=day)) url = UrlHelper.get_url(flapp, 'readings', **{'node_id' : node.id, 'sensor_alias': sensor.alias, 'from': '2014-12-2', 'until': '2014-12-11'}) response = requests.get(url) assert response.ok readings_in_interval = map(lambda r: r.json(), filter(lambda r: r.timestamp >= datetime(2014,12,2) and r.timestamp <= datetime(2014,12,11), sensor.readings)) api_response = ApiResponseHelper.assert_api_response(response) assert sorted(readings_in_interval) == sorted(api_response.objects)
def test_sensortype_forward_cascade(self): """ Deleting a sensortype should NOT delete any associated sensors """ node = NodeSeeder.seed_ricefield_node(n_readings = 5) n_sensors_before_delete = Sensor.query.count() assert SensorType.query.count() > 0 assert Sensor.query.count() > 0 n_deleted = SensorType.query.filter_by(id = node.sensors[0].sensortype.id).delete() assert n_deleted == 1 assert Sensor.query.count() == n_sensors_before_delete
def test_sensor_backward_cascade(self): """ Deleting an object referenced by a sensor should NOT delete the sensor """ n_readings = 5 node = NodeSeeder.seed_ricefield_node(n_readings = n_readings) n_sensors = len(node.sensors) assert Sensor.query.count() > 0 ## >0 in case number of sensors are changed in the seed method assert Reading.query.count() > 0 Reading.query.delete() assert Sensor.query.count() == n_sensors assert Reading.query.count() == 0
def test_post_reading_timestamp_integrity(self): """ Tests that timestamps are stored with the accuracy with which they were provided """ node = NodeSeeder.seed_ricefield_node(n_readings = 0) sensor = node.sensors[0] for timestamp_format in DATETIME_FORMATS: timestamp = datetime.now() timestamp_str = timestamp.strftime(timestamp_format) post_url = UrlHelper.get_url(flapp, 'reading') ### POST reading with timestamp to API post_response = requests.post(post_url, data = {'sensor_id': sensor.id, 'value': 42, 'timestamp': timestamp_str}) post_response = ApiResponseHelper.assert_api_response(post_response) reading_id = post_response.objects[0]['id'] ### GET that same reading and check that the timestamp is correct get_url = UrlHelper.get_url(flapp, 'reading', reading_id) get_response = requests.get(get_url) get_response = ApiResponseHelper.assert_api_response(get_response) received_timestamp_str = get_response.objects[0]['timestamp'] received_timestamp = DatetimeHelper.convert_timestamp_to_datetime(received_timestamp_str) assert datetime.strptime(timestamp_str, timestamp_format) == received_timestamp
def test_POST_nodes_populate(self): """ Test that populate options creates the valid number of readings data """ populate_number = 3 site = SiteSeeder.seed_empty_site() args = {'site_id': site.id, 'latitude': 13.2, 'longitude': 23.2, 'populate': populate_number} node = NodeSeeder.seed_node('ricefield', **args) url = UrlHelper.get_url(flapp, 'nodes') r = requests.get(url) api_response = ApiResponseHelper.assert_api_response(r) assert api_response.ok nodes = map(lambda n: n.json(), Node.query.all()) # get readings?sensor_id=xxxx and check whether the number of the value of readings is equal to 3 for n in nodes: for s in n['sensors']: url = UrlHelper.get_url(flapp, 'readings', sensor_id = s['id']) response = requests.get(url) assert response.ok api_response = ApiResponseHelper.assert_api_response(response) assert api_response.ok assert len(api_response.objects) == populate_number
def post(self): """ Use a HTTP POST request to /node to create a new node inside the network Example in Python: >>> import requests >>> r = requests.post('http://localhost:8080/node', data = {'alias':'mynode', 'site_id':'1', 'latitude':'13.24234234', 'longitude':23.222, 'populate':3, 'node_type':'ricefield'}) """ response = ApiResponse(request) # RequestHelper.filter_valid_parameters(Node, response, request) node_alias = RequestHelper.get_form_data(response, 'alias', str) node_type = RequestHelper.get_form_data(response, 'node_type', str, default='empty') site_id = RequestHelper.get_form_data(response, 'site_id', int) longitude = RequestHelper.get_form_data(response, 'longitude', float) latitude = RequestHelper.get_form_data(response, 'latitude', float) populate = RequestHelper.get_form_data(response, 'populate', int, default=0) site = Site.query.filter_by(id=site_id).first() if site: node = NodeSeeder.seed_node(node_type, alias=node_alias, site_id=site_id, latitude=latitude, longitude=longitude, populate=populate) response += node else: response += exc.MissingSiteException(site_id) return response.json()
def test_add_sensors_to_node(self): node_inserted = NodeSeeder.seed_node('empty') sensortype = SensorType(name = 'Sonar', unit = 'm') for i in range(3): Sensor.create(sensortype = sensortype, node = node_inserted) node_retrieved = Node.query.first() assert node_inserted.sensors == node_retrieved.sensors
def test_seed_ricefield_node_returns_one_node_with_four_sensors(self): node = NodeSeeder.seed_ricefield_node() assert isinstance(node, Node) assert len(node.sensors) == len(nodetypes['ricefield']['sensors'])
def test_seed_ricefield_node_has_correct_coordinates(self): latitude = 1.5 longitude = 2.5 node = NodeSeeder.seed_ricefield_node(latitude = latitude, longitude = longitude) assert node.latitude == latitude assert node.longitude == longitude
def test_node_insert(self): node_inserted = NodeSeeder.seed_node('ricefield', alias = uuid4().hex) node_retrieved = Node.query.first() assert node_inserted.id == node_retrieved.id assert node_inserted.alias == node_retrieved.alias
def test_node_json_method(self): node = NodeSeeder.seed_ricefield_node(n_readings = 3) node_json = node.json() JSONHelper.test_model_json_method(Node, node_json)
def test_sensor_insert(self): alias = uuid4().hex node = NodeSeeder.seed_node('ricefield') n_sensors_expected = nodetypes['ricefield']['sensors'].__len__() assert Sensor.all().__len__() == n_sensors_expected
def test_sensor_json_method(self): sensor = NodeSeeder.seed_ricefield_node(n_readings = 3).sensors[0] sensor_json = sensor.json() JSONHelper.test_model_json_method(Sensor, sensor_json)