def test_servicedir_service_list(temp_dir): #pylint: disable=redefined-outer-name """Test ServiceDirectory.service_list, ServiceDirectory.types""" count = 0 for service_dict in EXAMPLE_SERVICES.values(): service = services.Service(**service_dict['service']) temp_dir.publish(service=service) count += 1 output = temp_dir.service_list() assert service.name in [srv.name for srv in output] assert len(output) == count output = temp_dir.types() assert service.type in output for service_dict in EXAMPLE_SERVICES.values(): service = services.Service(**service_dict['service']) output = temp_dir.service_list(type=service.type) assert not [srv for srv in output if srv.type != service.type] for service_dict in EXAMPLE_SERVICES.values(): output = temp_dir.service_list() assert service_dict['service']['name'] in [srv.name for srv in output] temp_dir.unpublish(name=service_dict['service']['name']) count -= 1 output = temp_dir.service_list() assert service_dict['service']['name'] not in [ srv.name for srv in output ] assert len(output) == count assert len(temp_dir.types()) == 0
def test_servicedir_unpublish(temp_dir): #pylint: disable=redefined-outer-name """Test ServiceDirectory.unpublish""" for service_dict in EXAMPLE_SERVICES.values(): service = services.Service(**service_dict['service']) with pytest.raises(temp_dir.DoesNotExist): temp_dir.unpublish(name=service.name) temp_dir.publish(service=service) for service_dict in EXAMPLE_SERVICES.values(): service = services.Service(**service_dict['service']) temp_dir.unpublish(name=service.name) with pytest.raises(temp_dir.DoesNotExist): temp_dir.unpublish(name=service.name)
def coap_server_filled(coap_server_setup): #pylint: disable=redefined-outer-name """Yield a CoAP Server with some pre-populated services""" for testcase in EXAMPLE_SERVICES.values(): # Put some services in the registry coap_server_setup.directory_spy.real.publish(service=services.Service( **testcase['service'])) yield coap_server_setup
def test_Service(testcase): # pylint: disable=invalid-name """Test the Service constructor""" indata_dict = testcase[1]['service'] service = services.Service(**indata_dict) for attr in indata_dict.keys() - ['properties']: assert getattr(service, attr) == indata_dict[attr] for name, value in indata_dict['properties'].items(): assert getattr(service.properties, name) == value
def test_Service_eq(): # pylint: disable=invalid-name """Test Service comparison operations""" for lhs_case in EXAMPLE_SERVICES.values(): lhs_dict = lhs_case['service'] lhs_service = services.Service(**lhs_dict) for rhs_case in EXAMPLE_SERVICES.values(): rhs_service = services.Service(**rhs_case['service']) equal = True for attr in lhs_dict.keys() - ['properties']: if not getattr(rhs_service, attr) == lhs_dict[attr]: equal = False for prop in lhs_dict['properties'].keys(): if not getattr(rhs_service.properties, prop) == lhs_dict['properties'][prop]: equal = False if equal: assert lhs_service == rhs_service assert not lhs_service != rhs_service # pylint: disable=unneeded-not else: assert not lhs_service == rhs_service # pylint: disable=unneeded-not assert lhs_service != rhs_service
def test_coap_publish(test_format, coap_server_setup): #pylint: disable=redefined-outer-name """Test CoAP publish with known good payloads""" coap_server = coap_server_setup.coap_server dir_spy = coap_server_setup.directory_spy.spy content_format = aiocoap.numbers.media_types_rev['application/' + test_format] for testcase in EXAMPLE_SERVICES.values(): # Publish services dir_spy.reset_mock() payload = testcase['as_' + test_format].encode('utf-8') req = aiocoap.Message(code=Code.POST, payload=payload) req.opt.content_format = content_format req.opt.uri_path = URI_PATH_PUBLISH res = yield from coap_server.site.render(req) assert isinstance(res, aiocoap.Message) assert res.code in (Code.CREATED, ) assert dir_spy.publish.call_count == 1 for call in dir_spy.method_calls: if call[0] == 'publish': assert call == mock.call.publish(service=services.Service( **testcase['service'])) for testcase in EXAMPLE_SERVICES.values(): # Update the published service dir_spy.reset_mock() service = services.Service(**testcase['service']) service.port = int(service.port) + 111 service_to_payload = getattr(service, 'to_' + test_format) payload = service_to_payload() req = aiocoap.Message(code=Code.POST, payload=payload) req.opt.content_format = content_format req.opt.uri_path = URI_PATH_PUBLISH res = yield from coap_server.site.render(req) assert isinstance(res, aiocoap.Message) assert res.code in (Code.CHANGED, ) assert dir_spy.publish.call_count == 1 for call in dir_spy.method_calls: if call[0] == 'publish': assert call == mock.call.publish(service=service)
def test_servicelist_to_corelf(): '''Service.to_corelf should give a Link object''' slist = [ services.Service(**case['service']) for case in EXAMPLE_SERVICES.values() ] links = link_header.parse( str(services.servicelist_to_corelf(slist, '/uri/base'))) uris = {('uri', 'base') + (srv.name, ) for srv in slist} for link in links.links: assert tuple(link.href.strip('/').split('/')) in uris uris.remove(tuple(link.href.strip('/').split('/'))) assert len(uris) == 0
def test_service_to_xml(testcase): '''Service.to_xml should give an xml representation of the service''' # testcase is a tuple (testname, indata) indata_dict = testcase[1]['service'] expected_dict = indata_dict service_input = services.Service(**indata_dict) service_xml = service_input.to_xml() root = ET.fromstring(service_xml) assert root.tag == 'service' service = {} for node in root: assert not node.attrib assert not node.tail or node.tail.isspace() assert node.tag not in service if node.tag == 'properties': props = {} for child in node: assert child.tag == 'property' name = None value = None for prop in child: assert not list(prop) assert not prop.tail or prop.tail.isspace() assert prop.text.strip() assert prop.tag in ('name', 'value') if prop.tag == 'name': assert name is None name = prop.text.strip() elif prop.tag == 'value': assert value is None value = prop.text.strip() assert name not in props props[name] = value service['properties'] = props continue assert node.text.strip() assert node.text.strip() == str(indata_dict[node.tag]) service[node.tag] = node.text.strip() if node.tag == 'port': service[node.tag] = int(service[node.tag]) assert not list(node) # Check that there is no garbage text around assert not root.text or root.text.isspace() assert not root.tail or root.tail.isspace() for key in expected_dict.keys() - ['properties']: assert service[key] == expected_dict[key] for name, value in expected_dict['properties'].items(): assert name in service['properties'] assert value == service['properties'][name]
def test_servicedir_publish(): """Test ServiceDirectory.publish""" mock_database = mock.create_autospec(blitzdb.FileBackend) mydir = directory.ServiceDirectory(database=mock_database) for service_dict in EXAMPLE_SERVICES.values(): mock_database.reset_mock() service = services.Service(**service_dict['service']) expected_service_entry = mydir.Service(service_dict['service']) mydir.publish(service=service) assert mock_database.save.call_count == 1 assert mock_database.commit.call_count >= 1 # some white box testing here: examine what was passed to the database's # save method service_entry = mock_database.save.call_args[0][0] for key in service_dict['service'].keys(): assert getattr(service_entry, key) == getattr(expected_service_entry, key)
def test_servicedir_callbacks(temp_dir): #pylint: disable=redefined-outer-name """Test ServiceDirectory.add_notify_callback, ServiceDirectory.del_notify_callback""" callback = mock.MagicMock() temp_dir.add_notify_callback(callback) temp_dir.add_notify_callback(callback) temp_dir.add_notify_callback(callback) assert callback.call_count == 0 service = services.Service(name='testservice') temp_dir.publish(service=service) assert callback.call_count == 1 temp_dir.unpublish(name=service.name) assert callback.call_count == 2 temp_dir.del_notify_callback(callback) temp_dir.publish(service=service) assert callback.call_count == 2 temp_dir.del_notify_callback(callback) temp_dir.unpublish(name=service.name) assert callback.call_count == 2
def test_service_to_json(testcase): '''Loading the output from Service.to_json should give the same dict as the input data''' # testcase is a tuple (testname, indata) indata_dict = testcase[1]['service'] expected_dict = indata_dict service_input = services.Service(**indata_dict) service_json = service_input.to_json() service = json.loads(service_json) assert set(service.keys()) == set(expected_dict.keys()) for key in service.keys() - ['properties']: assert expected_dict[key] == service[key] props = {} for prop in service['properties']['property']: assert prop['name'] not in props props[prop['name']] = prop['value'] for name, value in expected_dict['properties'].items(): assert name in props assert props[name] == value
def test_coap_service(test_format, coap_server_filled): #pylint: disable=redefined-outer-name """Test CoAP service query""" coap_server = coap_server_filled.coap_server content_format = aiocoap.numbers.media_types_rev['application/' + test_format] for testcase in EXAMPLE_SERVICES.values(): service = services.Service(**testcase['service']) name = str(service.name) req = aiocoap.Message(code=Code.GET, payload=''.encode('utf-8')) req.opt.accept = content_format req.opt.uri_path = URI_PATH_SERVICE + (name, ) res = yield from coap_server.site.render(req) assert isinstance(res, aiocoap.Message) assert res.code in (Code.CONTENT, ) output = services.Service.from_message(res) assert output == service name = 'nonexistant.service._coap._udp' req = aiocoap.Message(code=Code.GET, payload=''.encode('utf-8')) req.opt.accept = content_format req.opt.uri_path = URI_PATH_SERVICE + (name, ) with pytest.raises(coap.NotFoundError): res = yield from coap_server.site.render(req)