def test_get_obj_by_urn_wrong_server(self): # Setup: Create a server object server = Server(utils.MockConnection(None)) with self.assertRaises(ValueError): # If: I get an object by its URN with a URN that is invalid for the server # Then: I should get an exception invalid_urn = '//[email protected]:456/Database.123/' server.get_object_by_urn(invalid_urn)
def test_get_obj_by_urn_wrong_collection(self): # Setup: Create a server object server = Server(utils.MockConnection(None)) with self.assertRaises(ValueError): # If: I get an object by its URN with a URN that points to an invalid path off the server # Then: I should get an exception invalid_urn = parse.urljoin(server.urn_base, 'Datatype.123/') server.get_object_by_urn(invalid_urn)
def test_get_obj_by_urn_empty(self): # Setup: Create a server object server = Server(utils.MockConnection(None)) test_cases = [None, '', '\t \n\r'] for test_case in test_cases: with self.assertRaises(ValueError): # If: I get an object by its URN without providing a URN # Then: I should get an exception server.get_object_by_urn(test_case)
def test_template_path_pg(self): # Setup: Create a mock connection that has PG as the server type mock_server = Server(utils.MockConnection(None)) mock_server._ServerConnection__server_type = mock.MagicMock( return_value='pg') # If: I ask for the template path of the class path = self.class_for_test._template_root(mock_server) # Then: The path should be a string that exists NodeObjectTestBase.unittest.assertIsInstance(path, str) NodeObjectTestBase.unittest.assertTrue(os.path.exists(path))
def test_get_obj_by_urn_success(self): # Setup: Create a server with a database under it server = Server(utils.MockConnection(None)) mock_db = Database(server, 'test_db') mock_db._oid = 123 server._child_objects[Database.__name__] = {123: mock_db} # If: I get an object by its URN urn = parse.urljoin(server.urn_base, '/Database.123/') obj = server.get_object_by_urn(urn) # Then: The object I get back should be the same as the object I provided self.assertIs(obj, mock_db)
def test_from_node_query(self): # If: I create a new object from a node row with the expected parent type mock_server = Server(utils.MockConnection(None)) mock_parent = utils.MockNodeObject( mock_server, None, 'parent') if not self.parent_expected_to_be_none else None obj = self.class_for_test._from_node_query(mock_server, mock_parent, **self.node_query) # Then: # ... The returned object must be an instance of the class NodeObjectTestBase.unittest.assertIsInstance(obj, NodeObject) NodeObjectTestBase.unittest.assertIsInstance(obj, self.class_for_test) # ... Validate the node object properties utils.assert_threeway_equals(mock_server, obj._server, obj.server) utils.assert_threeway_equals(self.node_query['oid'], obj._oid, obj.oid) utils.assert_threeway_equals(self.node_query['name'], obj._name, obj.name) # ... Validate the basic properties for attr, value in self.basic_properties.items(): NodeObjectTestBase.unittest.assertEqual(getattr(obj, attr), value) # ... Validate the collections for attr in self.collections: NodeObjectTestBase.unittest.assertIsInstance( getattr(obj, attr), NodeCollection) # ... Call the validation function self._custom_validate_from_node(obj, mock_server)
def test_urn_recursive(self): # Setup: # ... Create a node object with a parent server = Server(utils.MockConnection(None)) node_obj1 = utils.MockNodeObject(server, None, 'parent_name') node_obj1._oid = 123 node_obj2 = utils.MockNodeObject(server, node_obj1, 'obj_name') node_obj2._oid = 456 # If: I get the URN for the child node object urn = node_obj2.urn # Then: # ... I expect it to be formatted as a URL parsed_url = parse.urlparse(urn) # ... The netlocation should be equal to the urn base (with added slashes) # NOTE: Server URN Base is tested in the server class unit tests self.assertEqual(f'//{parsed_url.netloc}/', server.urn_base) # ... The path should have multiple folders under it (list comprehension removes empty strings) split_path = [x for x in parsed_url.path.split('/') if x] self.assertEqual(len(split_path), 2) # ... The parent path should be first self.assertEqual(split_path[0], f'{node_obj1.__class__.__name__}.{node_obj1.oid}') # ... The child path should be second self.assertEqual(split_path[1], f'{node_obj2.__class__.__name__}.{node_obj2.oid}')
def test_register_property_collection(self): # Setup: Create a node object server = Server(utils.MockConnection(None)) node_obj = utils.MockNodeObject(server, None, 'obj_name') # If: I register a property collection generator = mock.MagicMock() collection1 = node_obj._register_property_collection(generator) # Then: # ... The returned collection should be a collection with the provided generator self.assertIsInstance(collection1, node.NodeLazyPropertyCollection) self.assertIs(collection1._generator, generator) # ... The collection should be added to the list of registered collections self.assertEqual(len(node_obj._property_collections), 2) self.assertIn(collection1, node_obj._property_collections) # If: I add another one collection2 = node_obj._register_property_collection(generator) # Then: The collection should be appended to the list of registered collections self.assertEqual(len(node_obj._property_collections), 3) self.assertIn(collection1, node_obj._property_collections) self.assertIn(collection2, node_obj._property_collections)
def test_init(self): # If: I construct a new server object host = 'host' port = '1234' dbname = 'dbname' mock_conn = utils.MockConnection(None, name=dbname, host=host, port=port) server = Server(mock_conn) # Then: # ... The assigned properties should be assigned self.assertIsInstance(server._conn, ServerConnection) self.assertIsInstance(server.connection, ServerConnection) self.assertIs(server.connection.connection, mock_conn) self.assertEqual(server._host, host) self.assertEqual(server.host, host) self.assertEqual(server._port, int(port)) self.assertEqual(server.port, int(port)) self.assertEqual(server._maintenance_db_name, dbname) self.assertEqual(server.maintenance_db_name, dbname) self.assertTupleEqual(server.version, server._conn.version) # ... Recovery options should be a lazily loaded thing self.assertIsInstance(server._recovery_props, NodeLazyPropertyCollection) for key, collection in server._child_objects.items(): # ... The child object collection a NodeCollection self.assertIsInstance(collection, NodeCollection) # ... There should be a property mapped to the node collection prop = getattr(server, inflection.pluralize(key.lower())) self.assertIs(prop, collection)
def test_register_child_collection(self): # Setup: Create a node object server = Server(utils.MockConnection(None)) node_obj = utils.MockNodeObject(server, None, 'obj_name') # If: I register a child collection mock_class1 = mock.MagicMock() mock_class1.__name__ = 'mock_class1' mock_class1.get_nodes_for_parent = mock.MagicMock() collection1 = node_obj._register_child_collection(mock_class1) # Then # ... The returned collection should be a collection with the given generator self.assertIsInstance(collection1, node.NodeCollection) # ... The collection should be added to the list of registered collections self.assertEqual(len(node_obj._child_collections), 1) # If: I add another one mock_class2 = mock.MagicMock() mock_class2.__name__ = 'mock_class2' mock_class2.get_nodes_for_parent = mock.MagicMock() collection2 = node_obj._register_child_collection(mock_class2) # Then: The collection should be appended to the list of registered collections self.assertEqual(len(node_obj._child_collections), 2) self.assertTrue( mock_class1.__name__ in node_obj._child_collections.keys()) self.assertTrue( mock_class2.__name__ in node_obj._child_collections.keys()) self.assertIs(node_obj._child_collections[mock_class1.__name__], collection1) self.assertIs(node_obj._child_collections[mock_class2.__name__], collection2)
def test_get_obj_by_urn_invalid_collection(self): # Setup: Create a node object (without any collections under it) server = Server(utils.MockConnection(None)) node_obj = utils.MockNodeObject(server, None, 'obj_name') with self.assertRaises(ValueError): # If: I have a URN fragment that goes into a collection that doesn't exist # Then: I should get an exception fragment = '/Database.123/' node_obj.get_object_by_urn(fragment)
def test_refresh(self): # Setup: # ... Create a server object that has a connection obj = Server(utils.MockConnection(None)) # ... Mock out the reset methods on the various collections obj.databases.reset = mock.MagicMock() obj.roles.reset = mock.MagicMock() obj.tablespaces.reset = mock.MagicMock() obj._recovery_props.reset = mock.MagicMock() # If: I refresh the server obj.refresh() # Then: The collections should have been reset obj.databases.reset.assert_called_once() obj.roles.reset.assert_called_once() obj.tablespaces.reset.assert_called_once() obj._recovery_props.reset.assert_called_once()
def _get_node_for_parents_mock_connection(): # ... Create a mockup of a server connection with a mock executor mock_action = mock.Mock() mock_objs = [{'name': 'abc', 'oid': 123}, {'name': 'def', 'oid': 456}] mock_executor = mock.MagicMock(return_value=([{}, {}], mock_objs)) mock_server = Server(utils.MockConnection(None, version="10101"), mock_action) mock_server.connection.execute_dict = mock_executor return mock_server, mock_executor, mock_objs
def test_recovery_properties(self): # Setup: # NOTE: We're *not* mocking out the template rendering b/c this will verify that there's a template # ... Create a mock query execution that will return the properties mock_exec_dict = mock.MagicMock( return_value=([], [TestServer.CHECK_RECOVERY_ROW])) # ... Create an instance of the class and override the connection mock_conn = ServerConnection(utils.MockConnection(None)) mock_conn.execute_dict = mock_exec_dict obj = Server(utils.MockConnection(None)) obj._conn = mock_conn # If: I retrieve all the values in the recovery properties # Then: # ... The properties based on the properties should be availble self.assertEqual(obj.in_recovery, TestServer.CHECK_RECOVERY_ROW['inrecovery']) self.assertEqual(obj.wal_paused, TestServer.CHECK_RECOVERY_ROW['isreplaypaused'])
def test_get_obj_by_urn_base_case(self): # Setup: Create a node object server = Server(utils.MockConnection(None)) node_obj = utils.MockNodeObject(server, None, 'obj_name') # If: I have a URN fragment that returns the object fragment = '/' obj = node_obj.get_object_by_urn(fragment) # Then: I should get that object back self.assertIs(obj, node_obj)
def _get_mock_node_generator(): server = Server(utils.MockConnection(None)) mock_object1 = utils.MockNodeObject(server, None, 'a') mock_object1._oid = 123 mock_object2 = utils.MockNodeObject(server, None, 'b') mock_object2._oid = 456 mock_objects = [mock_object1, mock_object2] return mock.MagicMock(return_value=mock_objects), mock_objects
def test_role_get_database_node(self): # If: I create a DB that is connected name = 'dbname' mock_server = Server(utils.MockConnection(None, name='not_connected')) db = Role(mock_server, name) # Then: node = db.get_database_node() # assert: self.assertIsNone(node)
def test_database_get_database_node(self): # If: I create a DB that is connected name = 'dbname' mock_server = Server(utils.MockConnection(None, name='not_connected')) db = Database(mock_server, name) # Then: node = db.get_database_node() # assert: self.assertIsNotNone(node) self.assertEqual(node.__class__.__name__, 'Database')
def test_init_connected(self): # If: I create a DB that is connected name = 'dbname' mock_server = Server(utils.MockConnection(None, name=name)) db = Database(mock_server, name) # Then: # ... Default validation should pass self._init_validation(db, mock_server, None, name) # ... The schema node collection should be defined self.assertIsInstance(db._schemas, NodeCollection) self.assertIs(db.schemas, db._schemas)
def test_get_obj_by_urn_recurses(self): # Setup: Create a node object with a collection under it server = Server(utils.MockConnection(None)) db_obj = utils.MockNodeObject(server, None, 'db_name') sc_obj = utils.MockNodeObject(server, db_obj, 'schema_name') db_obj._child_collections = {'Schema': {123: sc_obj}} # If: I ask for an object that recurses fragment = '/Schema.123/' obj = db_obj.get_object_by_urn(fragment) # Then: The object I get back should be the same as the one I created self.assertIs(obj, sc_obj)
def test_init_not_connected(self): # If: I create a DB that is connected name = 'dbname' mock_conn = Server(utils.MockConnection(None, name='not_connected')) db = Database(mock_conn, name) # Then: # ... Default validation should pass self._init_validation(db, mock_conn, None, name) # ... The schema node collection should not be defined self.assertIsNotNone(db._schemas) self.assertIsNotNone(db.schemas)
def test_urn_base(self): # Setup: # ... Create a server object that has a connection server = Server(MockPGServerConnection()) # If: I get the URN base for the server urn_base = server.urn_base # Then: The urn base should match the expected outcome urn_base_regex = re.compile(r'//(?P<user>.+)@(?P<host>.+):(?P<port>\d+)') urn_base_match = urn_base_regex.match(urn_base) self.assertIsNotNone(urn_base_match) self.assertEqual(urn_base_match.groupdict()['user'], server.connection.user_name) self.assertEqual(urn_base_match.groupdict()['host'], server.host) self.assertEqual(urn_base_match.groupdict()['port'], server.port)
def test_init(self): # If: I create an instance of the provided class mock_server = Server(utils.MockConnection(None)) mock_parent = utils.MockNodeObject( mock_server, None, 'parent') if not self.parent_expected_to_be_none else None name = 'test' obj = self.init_lambda(mock_server, mock_parent, name) # Then: # ... Perform the init validation # noinspection PyTypeChecker self._init_validation(obj, mock_server, mock_parent, name) # ... Call the custom validation function self._custom_validate_init(obj, mock_server)
def test_maintenance_db(self): # Setup: # ... Create a server object that has a connection obj = Server(MockPGServerConnection(None, name='dbname')) # ... Mock out the database lazy loader's indexer mock_db = {} mock_db_collection = mock.Mock() mock_db_collection.__getitem__ = mock.MagicMock(return_value=mock_db) obj._child_objects[Database.__name__] = mock_db_collection # If: I retrieve the maintenance db for the server maintenance_db = obj.maintenance_db # Then: # ... It must have come from the mock handler self.assertIs(maintenance_db, mock_db) obj._child_objects[Database.__name__].__getitem__.assert_called_once_with('dbname')
def test_recovery_properties(self): # Setup: # NOTE: We're *not* mocking out the template rendering b/c this will verify that there's a template # ... Create a mock query execution that will return the properties mock_exec_dict = mock.MagicMock(return_value=([], [TestServer.CHECK_RECOVERY_ROW])) # ... Create an instance of the class and override the connection mock_connection = MockPsycopgConnection({'host': 'host', 'dbname': 'dbname'}) with mock.patch('psycopg2.connect', new=mock.Mock(return_value=mock_connection)): pg_connection = PostgreSQLConnection({}) pg_connection.execute_dict = mock_exec_dict obj = Server(pg_connection) # If: I retrieve all the values in the recovery properties # Then: # ... The properties based on the properties should be availble self.assertEqual(obj.in_recovery, TestServer.CHECK_RECOVERY_ROW['inrecovery']) self.assertEqual(obj.wal_paused, TestServer.CHECK_RECOVERY_ROW['isreplaypaused'])
def test_init(self): # If: I create a node object server = Server(utils.MockConnection(None)) parent = utils.MockNodeObject(server, None, 'parent') node_obj = utils.MockNodeObject(server, parent, 'abc') # Then: The properties should be assigned as defined utils.assert_threeway_equals(None, node_obj._oid, node_obj.oid) utils.assert_threeway_equals('abc', node_obj._name, node_obj.name) utils.assert_threeway_equals(server, node_obj._server, node_obj.server) utils.assert_threeway_equals(parent, node_obj._parent, node_obj.parent) self.assertDictEqual(node_obj._child_collections, {}) self.assertEqual(len(node_obj._property_collections), 1) self.assertIsInstance(node_obj._full_properties, node.NodeLazyPropertyCollection) self.assertEqual(node_obj._full_properties._generator, node_obj._property_generator)
def _test_scripting_mixins(self): # Setup: Create an instance of the object mock_server = Server(utils.MockConnection(None)) mock_grand_parent = utils.MockNodeObject( mock_server, None, 'grandparent') if not self.parent_expected_to_be_none else None mock_parent = utils.MockNodeObject( mock_server, mock_grand_parent, 'parent') if not self.parent_expected_to_be_none else None name = 'test' obj = self.init_lambda(mock_server, mock_parent, name) obj._full_properties = self.property_query if isinstance(obj, ScriptableCreate): # If: I script for create script = obj.create_script() # Then: The script should successfully return utils.assert_is_not_none_or_whitespace(script) if isinstance(obj, ScriptableDelete): # If: I script for delete script = obj.delete_script() # Then: The script should successfully return utils.assert_is_not_none_or_whitespace(script) if isinstance(obj, ScriptableUpdate): # If: I script for update script = obj.update_script() # Then: The script should successfully return utils.assert_is_not_none_or_whitespace(script) if isinstance(obj, ScriptableSelect): # If: I script for select script = obj.select_script() # Then: The script should successfully return utils.assert_is_not_none_or_whitespace(script)
def setUp(self): # Setup: Create an OE service and add a session to it self.cs = ConnectionService() self.mock_connection = {} self.oe = ObjectExplorerService() params, session_uri = _connection_details() self.session = ObjectExplorerSession(session_uri, params) self.oe._session_map[session_uri] = self.session name = 'dbname' self.mock_server = Server(MockConnection(name)) self.session.server = self.mock_server self.db = Database(self.mock_server, name) self.db._connection = MockConnection(name) self.session.server._child_objects[Database.__name__] = [self.db] self.cs.get_connection = mock.MagicMock( return_value=self.mock_connection) self.cs.disconnect = mock.MagicMock(return_value=True) self.oe._service_provider = utils.get_mock_service_provider( {constants.CONNECTION_SERVICE_NAME: self.cs})
def test_table_get_database_node(self): # If: I create a DB that is connected mock_server = Server(utils.MockConnection(None, name='not_connected')) db = Database(mock_server, 'dbname') schema = Schema(mock_server, db, 'schema') table = Table(mock_server, schema, 'table') # check for schema: node = schema.get_database_node() # assert: self.assertIsNotNone(node) self.assertEqual(node.__class__.__name__, 'Database') # check for table: node = table.get_database_node() # assert: self.assertIsNotNone(node) self.assertEqual(node.__class__.__name__, 'Database')
def test_urn_basecase(self): # Setup: # ... Create a node object server = Server(utils.MockConnection(None)) node_obj = utils.MockNodeObject(server, None, 'obj_name') node_obj._oid = 123 # If: I get the URN for a node object urn = node_obj.urn # Then: # ... I expect it to be formatted as a URL parsed_url = parse.urlparse(urn) # ... The netlocation should be equal to the urn base (with added slashes) # NOTE: Server URN Base is tested in the server class unit tests self.assertEqual(f'//{parsed_url.netloc}/', server.urn_base) # ... The path should match Class.OID (with added slashes) self.assertEqual(parsed_url.path, f'/{node_obj.__class__.__name__}.{node_obj.oid}/')