Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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}')
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    def test_execute_dict_success(self):
        # Setup: Create a mock server connection that will return a result set
        mock_cursor = utils.MockCursor(utils.get_mock_results())
        mock_conn = utils.MockConnection(mock_cursor)
        # noinspection PyTypeChecker
        server_conn = pgsmo_utils.querying.ServerConnection(mock_conn)

        # If: I execute a query as a dictionary
        results = server_conn.execute_dict('SELECT * FROM pg_class')

        # Then:
        # ... Both the columns and the results should be returned
        self.assertIsInstance(results, tuple)
        self.assertEqual(len(results), 2)

        # ... I should get a list of columns returned to me
        cols = results[0]
        self.assertIsInstance(cols, list)
        self.assertListEqual(cols, mock_cursor.description)

        # ... I should get the results formatted as a list of dictionaries
        rows = results[1]
        self.assertIsInstance(rows, list)
        for idx, row in enumerate(rows):
            self.assertDictEqual(row, mock_cursor._results[1][idx])

        # ... The cursor should be closed
        mock_cursor.close.assert_called_once()
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
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
Exemplo n.º 12
0
    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'])
Exemplo n.º 13
0
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
Exemplo n.º 14
0
 def setUp(self):
     mock_server = Server(utils.MockConnection(None))
     db = Database(mock_server, mock_server.maintenance_db_name)
     mock_server._child_objects[
         Database.__name__] = self._as_node_collection([db])
     mock_server._search_path = self._as_node_collection([MYSCHEMA])
     self.schema1 = Schema(mock_server, db, MYSCHEMA)
     self.schema2 = Schema(mock_server, db, MYSCHEMA2)
     db._schemas = self._as_node_collection([self.schema1, self.schema2])
     self.mock_server = mock_server
     self.executor: MetadataExecutor = MetadataExecutor(mock_server)
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
    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))
Exemplo n.º 18
0
    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')
Exemplo n.º 19
0
    def test_get_nodes_for_parent_with_parent(self):
        # Setup:
        # ... Create a server connection that will return some mock node rows
        mock_server, mock_executor, mock_objs = _get_node_for_parents_mock_connection(
        )

        # ... Create a mock _from_node generator (so we can validate calls)
        mock_obj = {}
        mock_from_node = mock.MagicMock(return_value=mock_obj)

        # ... Create a mock template rendered
        mock_render = mock.MagicMock(return_value="SQL")
        mock_template_path = mock.MagicMock(return_value="path")

        # ... Create an object that will be the parent of these nodes
        name = 'postgres'
        parent = Database(mock_server, name)
        parent._oid = 123
        parent._connection = utils.MockConnection(None, version="10101")
        parent._connection.execute_dict = mock_executor

        # ... Patch the template rendering, and the _from_node_query
        patch_render_template = 'pgsmo.objects.node_object.templating.render_template'
        patch_template_path = 'pgsmo.objects.node_object.templating.get_template_path'
        patch_from_node_query = 'tests.pgsmo_tests.utils.MockNodeObject._from_node_query'

        with mock.patch(patch_render_template, mock_render, create=True), \
                mock.patch(patch_template_path, mock_template_path, create=True), \
                mock.patch(patch_from_node_query, mock_from_node, create=True):
            # If: I ask for a collection of nodes *with a parent object*
            nodes = utils.MockNodeObject.get_nodes_for_parent(
                mock_server, parent)

        # Then:
        # ... The template path and template renderer should have been called once
        mock_template_path.assert_called_once_with('template_root',
                                                   'nodes.sql',
                                                   mock_server.version)
        mock_render.assert_called_once_with('path',
                                            macro_roots=None,
                                            **{'parent_id': 123})

        # ... A query should have been executed
        mock_executor.assert_called_once_with('SQL')

        # ... The _from_node should have been called twice with the results of the query
        mock_from_node.assert_any_call(mock_server, parent, **mock_objs[0])
        mock_from_node.assert_any_call(mock_server, parent, **mock_objs[1])

        # ... The output should be a list of objects the _from_node returned
        self.assertIsInstance(nodes, list)
        self.assertListEqual(nodes, [mock_obj, mock_obj])
Exemplo n.º 20
0
    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)
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
    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)
Exemplo n.º 23
0
    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)
Exemplo n.º 24
0
    def test_execute_dict_fail(self):
        # Setup: Create a mock server connection that will raise an exception
        mock_cursor = utils.MockCursor(None, throw_on_execute=True)
        mock_conn = utils.MockConnection(mock_cursor)
        # noinspection PyTypeChecker
        server_conn = pgsmo_utils.querying.ServerConnection(mock_conn)

        # If: I execute a query as a dictionary
        # Then:
        # ... I should get an exception
        with self.assertRaises(Exception):
            server_conn.execute_dict('SELECT * FROM pg_class')

        # ... The cursor should be closed
        mock_cursor.close.assert_called_once()
Exemplo n.º 25
0
    def test_urn_base(self):
        # Setup:
        # ... Create a server object that has a connection
        server = Server(utils.MockConnection(None))

        # 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.dsn_parameters['user'])
        self.assertEqual(urn_base_match.groupdict()['host'], server.host)
        self.assertEqual(int(urn_base_match.groupdict()['port']), server.port)
Exemplo n.º 26
0
    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)
Exemplo n.º 27
0
    def test_maintenance_db(self):
        # Setup:
        # ... Create a server object that has a connection
        obj = Server(utils.MockConnection(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')
Exemplo n.º 28
0
    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)
Exemplo n.º 29
0
    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()
Exemplo n.º 30
0
    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)