def test_DuplicateEntry_exception_raised_when_connecting_already_connected_port_to_a_resource(self): # GIVEN the following mesh # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |-------->| p1 | | # |______|______| |______|______| # # # [ Resource X ] # m = Mesh() m.add_component('A', needs_ports=['n1']) m.add_component('B', provides_ports=['p1']) m.add_resource('Resource X') m.add_connection('A', 'n1', 'B', 'p1') # WHEN attempting to create the following invalid connections # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |----+----->| p1 | | # |______|______| | |______|______| # | # INVALID # | # | # +----->[ Resource X ] # # # THEN an InvalidConnection exception is raised self.assertRaises(InvalidConnection, m.add_connection_to_resource, 'A', 'n1', 'Resource X')
def test_resource_can_be_highlighted(self): # GIVEN the following mesh # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |-------->| p1 | n2 |--------->[ Resource X ] # |______|______| |______|______| # # m = Mesh() m.add_component('A', needs_ports=['n1']) m.add_component('B', needs_ports=['n2'], provides_ports=['p1']) m.add_resource('Resource X') m.add_connection('A', 'n1', 'B', 'p1') m.add_connection_to_resource('B', 'n2', 'Resource X') # WHEN Resource X is highlighted m.highlight_resource('Resource X') # THEN this is reflected in the dict representation self.assertEqual({ 'components': [ {'name': 'A', 'needs_ports': ['n1'], 'provides_ports': []}, {'name': 'B', 'needs_ports': ['n2'], 'provides_ports': ['p1']} ], 'resources': ['Resource X'], 'highlighted_resources': ['Resource X'], 'connections': [ { 'consumer_component': 'A', 'consumer_port': 'n1', 'producer_component': 'B', 'producer_port': 'p1', }, { 'consumer_component': 'B', 'consumer_port': 'n2', 'resource': 'Resource X', }, ], }, m.as_dict())
def test_InvalidResource_exception_raised_when_highlighting_unknown_resource(self): # GIVEN a mesh with the following component and resource # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |-------->| p1 | n2 |--------->[ Resource X ] # |______|______| |______|______| # # m = Mesh() m.add_component('A', needs_ports=['n1']) m.add_component('B', needs_ports=['n2'], provides_ports=['p1']) m.add_resource('Resource X') m.add_connection('A', 'n1', 'B', 'p1') m.add_connection_to_resource('B', 'n2', 'Resource X') # WHEN unknown resource is highlighted # THEN an InvalidResource exception is raised self.assertRaises(InvalidResource, m.highlight_resource, 'Resource K')
def test_renderering_the_mesh_as_a_dot_file_to_be_parsed_by_graphviz(self): """ NOTE: This is a very artificial test. We've already tested the mesh building and the rendered in the tests above. All we're doing here is checking that the DOT template can be parsed an applied. Inspecting the output is non trivial and perhaps not worth the while? """ # GIVEN the following mesh # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |----------->| p1 | | # | |______| |______| | # | | n2 |-----+ +-->| p2 | | # |______|______| | | |______|______| # +- | -+ # | | # _____________ | | _____________ # | C | | | | D | # |-------------| | | |-------------| # | | nX |--+ +---->| pX | | # |______|______| |______|______| # m = Mesh() m.add_component('A', needs_ports=['n1', 'n2']) m.add_component('B', provides_ports=['p1', 'p2']) m.add_component('C', needs_ports=['nX']) m.add_component('D', provides_ports=['pX']) m.add_connection('A', 'n1', 'B', 'p1') m.add_connection('A', 'n2', 'D', 'pX') m.add_connection('C', 'nX', 'B', 'p2') # WHEN the dot representation is rendered # THEN the world does not come to an end ("WHAT??" you say? See docstring above) render_mesh_as_dot(m)
def test_adding_connection_between_two_ports(self): # GIVEN the following components # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 | | p1 | | # |______|______| |______|______| # m = Mesh() m.add_component('A', needs_ports=['n1']) m.add_component('B', provides_ports=['p1']) # WHEN we add a connection between A:n1 and B:p1 m.add_connection('A', 'n1', 'B', 'p1') # THEN we get the following mesh representation # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 | ---> | p1 | | # |______|______| |______|______| # self.assertEqual({ 'components': [ {'name': 'A', 'needs_ports': ['n1'], 'provides_ports': []}, {'name': 'B', 'needs_ports': [], 'provides_ports': ['p1']}, ], 'resources': [], 'connections': [ { 'consumer_component': 'A', 'consumer_port': 'n1', 'producer_component': 'B', 'producer_port': 'p1', }, ], }, m.as_dict())
def test_DuplicateEntry_exception_raised_when_assigning_multiple_connections_to_the_same_needs_port(self): # GIVEN the following mesh # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |-------->| p1 | | # |______|______| |______|______| # # _____________ # | D | # |-------------| # | pX | | # |______|______| # m = Mesh() m.add_component('A', needs_ports=['n1']) m.add_component('B', provides_ports=['p1']) m.add_component('D', provides_ports=['pX']) m.add_connection('A', 'n1', 'B', 'p1') # WHEN attempting to create the following invalid connections # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |----+----->| p1 | | # |______|______| | |______|______| # | # INVALID _____________ # | | D | # | |-------------| # +----->| pX | | # |______|______| # # THEN an InvalidConnection exception is raised self.assertRaises(InvalidConnection, m.add_connection, 'A', 'n1', 'D', 'pX')
def test_textual_representation_can_be_rendered_for_a_populated_mesh(self): # GIVEN the following mesh # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |----------->| p1 | | # | |______| |______| nY |----->[ Resource Y ] # | | n2 |-----+ +-->| p2 | | # |______|______| | | |______|______| # +- | -+ # | | # _____________ | | _____________ # | C | | | | D | # |-------------| | | |-------------| # | | nX |--+ +---->| pX | nX |------>[ Resource X ] # |______|______| |______|______| # m = Mesh() m.add_component('A', needs_ports=['n1', 'n2']) m.add_component('B', provides_ports=['p1', 'p2'], needs_ports=['nY']) m.add_component('C', needs_ports=['nX']) m.add_component('D', provides_ports=['pX'], needs_ports=['nX']) m.add_resource('Resource X') m.add_resource('Resource Y') m.add_connection('A', 'n1', 'B', 'p1') m.add_connection('A', 'n2', 'D', 'pX') m.add_connection('C', 'nX', 'B', 'p2') m.add_connection_to_resource('D', 'nX', 'Resource X') m.add_connection_to_resource('B', 'nY', 'Resource Y') # WHEN the textual representation is rendered out = render(m, self.JSON_TEMPLATE) # THEN the rendered output reflects that of the mesh out_data = json.loads(out) self.assertEqual({ 'components': [ {'name': 'A', 'needs_ports': ['n1', 'n2'], 'provides_ports': []}, {'name': 'B', 'needs_ports': ['nY'], 'provides_ports': ['p1', 'p2']}, {'name': 'C', 'needs_ports': ['nX'], 'provides_ports': []}, {'name': 'D', 'needs_ports': ['nX'], 'provides_ports': ['pX']}, ], 'resources': ['Resource X', 'Resource Y'], 'connections': [ { 'consumer_component': 'A', 'consumer_port': 'n1', 'producer_component': 'B', 'producer_port': 'p1', }, { 'consumer_component': 'A', 'consumer_port': 'n2', 'producer_component': 'D', 'producer_port': 'pX', }, { 'consumer_component': 'C', 'consumer_port': 'nX', 'producer_component': 'B', 'producer_port': 'p2', }, { 'consumer_component': 'D', 'consumer_port': 'nX', 'resource': 'Resource X', }, { 'consumer_component': 'B', 'consumer_port': 'nY', 'resource': 'Resource Y', }, ], }, out_data)
def test_multiple_connections_across_components_with_multiple_ports(self): # GIVEN the following components # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 | | p1 | | # | |______| |______| | # | | n2 | | p2 | | # |______|______| |______|______| # # # _____________ _____________ # | C | | D | # |-------------| |-------------| # | | nX | | pX | | # |______|______| |______|______| # m = Mesh() m.add_component('A', needs_ports=['n1', 'n2']) m.add_component('B', provides_ports=['p1', 'p2']) m.add_component('C', needs_ports=['nX']) m.add_component('D', provides_ports=['pX']) # WHEN we add a connection between A:n1 and B:p1 # WHEN we add a connection between C:nX and B:p1 m.add_connection('A', 'n1', 'B', 'p1') m.add_connection('A', 'n2', 'D', 'pX') m.add_connection('C', 'nX', 'B', 'p2') # THEN we get the following mesh representation # # _____________ _____________ # | A | | B | # |-------------| |-------------| # | | n1 |----------->| p1 | | # | |______| |______| | # | | n2 |-----+ +-->| p2 | | # |______|______| | | |______|______| # +- | -+ # | | # _____________ | | _____________ # | C | | | | D | # |-------------| | | |-------------| # | | nX |--+ +---->| pX | | # |______|______| |______|______| # self.assertEqual({ 'components': [ {'name': 'A', 'needs_ports': ['n1', 'n2'], 'provides_ports': []}, {'name': 'B', 'needs_ports': [], 'provides_ports': ['p1', 'p2']}, {'name': 'C', 'needs_ports': ['nX'], 'provides_ports': []}, {'name': 'D', 'needs_ports': [], 'provides_ports': ['pX']}, ], 'resources': [], 'connections': [ { 'consumer_component': 'A', 'consumer_port': 'n1', 'producer_component': 'B', 'producer_port': 'p1', }, { 'consumer_component': 'A', 'consumer_port': 'n2', 'producer_component': 'D', 'producer_port': 'pX', }, { 'consumer_component': 'C', 'consumer_port': 'nX', 'producer_component': 'B', 'producer_port': 'p2', }, ], }, m.as_dict())