Esempio n. 1
0
    def _handle_er_incomplete_params(method: TEventHandler):
        # Setup:
        # ... Create an OE service
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})

        # ... Create a set of invalid parameters to test
        param_sets = [
            None,
            ExpandParameters.from_dict({
                'session_id': None,
                'node_path': '/'
            }),
            ExpandParameters.from_dict({
                'session_id': 'session',
                'node_path': None
            })
        ]

        for params in param_sets:
            # If: I expand with an invalid set of parameters
            rc = RequestFlowValidator().add_expected_error(
                type(None), RequestFlowValidator.basic_error_validation)
            method(oe, rc.request_context, params)

            # Then: I should get an error response
            rc.validate()
Esempio n. 2
0
    def test_handle_create_session_threading_fail(self):
        # Setup:
        # ... Create an OE service
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})

        # ... Patch the threading to throw
        patch_mock = mock.MagicMock(side_effect=Exception('Boom!'))
        patch_path = 'pgsqltoolsservice.object_explorer.object_explorer_service.threading.Thread'
        with mock.patch(patch_path, patch_mock):
            # If: I create a new session
            params, session_uri = _connection_details()

            rc = RequestFlowValidator()
            rc.add_expected_response(
                CreateSessionResponse,
                lambda param: self.assertEqual(param.session_id, session_uri))
            rc.add_expected_notification(
                SessionCreatedParameters, SESSION_CREATED_METHOD,
                lambda param: self._validate_init_error(param, session_uri))
            oe._handle_create_session_request(rc.request_context, params)

        # Then:
        # ... The error notification should have been returned
        rc.validate()

        # ... The session should have been cleaned up
        self.assertDictEqual(oe._session_map, {})
Esempio n. 3
0
    def _handle_er_exception_expanding(self, method: TEventHandler,
                                       get_tasks: TGetTask):
        # Setup: Create an OE service with a session preloaded
        oe, session, session_uri = self._preloaded_oe_service()

        # ... Patch the route_request to throw
        # ... Patch the threading to throw
        patch_mock = mock.MagicMock(side_effect=Exception('Boom!'))
        patch_path = 'pgsqltoolsservice.object_explorer.object_explorer_service.route_request'
        with mock.patch(patch_path, patch_mock):
            # If: I expand a node (with route_request that throws)
            rc = RequestFlowValidator()
            rc.add_expected_response(bool, self.assertTrue)
            rc.add_expected_notification(
                ExpandCompletedParameters, EXPAND_COMPLETED_METHOD,
                lambda param: self._validate_expand_error(
                    param, session_uri, '/'))
            params = ExpandParameters.from_dict({
                'session_id': session_uri,
                'node_path': '/'
            })
            method(oe, rc.request_context, params)

        # Joining the threads to avoid rc.validate failure
        for task in session.expand_tasks.values():
            task.join()
        for task in session.refresh_tasks.values():
            task.join()
        # Then:
        # ... An error notification should have been sent
        rc.validate()

        # ... The thread should be attached to the session
        self.assertEqual(len(get_tasks(session)), 1)
Esempio n. 4
0
    def _handle_er_threading_fail(self, method: TEventHandler):
        # Setup: Create an OE service with a session preloaded
        oe, session, session_uri = self._preloaded_oe_service()

        # ... Patch the threading to throw
        patch_mock = mock.MagicMock(side_effect=Exception('Boom!'))
        patch_path = 'pgsqltoolsservice.object_explorer.object_explorer_service.threading.Thread'
        with mock.patch(patch_path, patch_mock):
            # If: I expand a node (with threading that throws)
            rc = RequestFlowValidator()
            rc.add_expected_response(bool, self.assertTrue)
            rc.add_expected_notification(
                ExpandCompletedParameters, EXPAND_COMPLETED_METHOD,
                lambda param: self._validate_expand_error(
                    param, session_uri, '/'))
            params = ExpandParameters.from_dict({
                'session_id': session_uri,
                'node_path': '/'
            })
            method(oe, rc.request_context, params)

        # Then:
        # ... The error notification should have been returned
        rc.validate()

        # ... The session should not have an expand task defined
        self.assertDictEqual(session.expand_tasks, {})
        self.assertDictEqual(session.refresh_tasks, {})
 def setUp(self):
     """Constructor"""
     self.default_uri = 'file://my.sql'
     self.flow_validator = RequestFlowValidator()
     self.mock_server_set_request = mock.MagicMock()
     self.mock_server = JSONRPCServer(None, None)
     self.mock_server.set_request_handler = self.mock_server_set_request
     self.mock_workspace_service = WorkspaceService()
     self.mock_connection_service = ConnectionService()
     self.mock_service_provider = ServiceProvider(self.mock_server, {},
                                                  PG_PROVIDER_NAME, None)
     self.mock_service_provider._services[
         constants.WORKSPACE_SERVICE_NAME] = self.mock_workspace_service
     self.mock_service_provider._services[
         constants.CONNECTION_SERVICE_NAME] = self.mock_connection_service
     self.mock_service_provider._is_initialized = True
     self.default_text_position = TextDocumentPosition.from_dict({
         'text_document': {
             'uri': self.default_uri
         },
         'position': {
             'line': 3,
             'character': 10
         }
     })
     self.default_text_document_id = TextDocumentIdentifier.from_dict(
         {'uri': self.default_uri})
Esempio n. 6
0
    def test_init_session_failed_connection(self):
        # Setup:
        # ... Create OE service with mock connection service that returns a failed connection response
        cs = ConnectionService()
        connect_response = ConnectionCompleteParams()
        connect_response.error_message = 'Boom!'
        cs.connect = mock.MagicMock(return_value=connect_response)
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider(
            {constants.CONNECTION_SERVICE_NAME: cs})

        # If: I initialize a session (NOTE: We're bypassing request handler to avoid threading issues)
        params, session_uri = _connection_details()
        session = ObjectExplorerSession(session_uri, params)
        oe._session_map[session_uri] = session

        rc = RequestFlowValidator()
        rc.add_expected_notification(
            SessionCreatedParameters, SESSION_CREATED_METHOD,
            lambda param: self._validate_init_error(param, session_uri))
        oe._initialize_session(rc.request_context, session)

        # Then:
        # ... Error notification should have been returned, session should be cleaned up from OE service
        rc.validate()
        self.assertDictEqual(oe._session_map, {})
    def test_handle_create_session_successful(self):
        # Setup:
        # ... Create OE service with mock connection service that returns a successful connection response
        mock_connection = MockPGServerConnection(cur=None,
                                                 host='myserver',
                                                 name='postgres',
                                                 user='******',
                                                 port=123)
        cs = ConnectionService()
        cs.connect = mock.MagicMock(return_value=ConnectionCompleteParams())
        cs.get_connection = mock.MagicMock(return_value=mock_connection)
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider(
            {constants.CONNECTION_SERVICE_NAME: cs})
        oe._provider = constants.PG_PROVIDER_NAME
        oe._server = Server

        # ... Create parameters, session, request context validator
        params, session_uri = _connection_details()

        # ... Create validation of success notification
        def validate_success_notification(response: SessionCreatedParameters):
            self.assertTrue(response.success)
            self.assertEqual(response.session_id, session_uri)
            self.assertIsNone(response.error_message)

            self.assertIsInstance(response.root_node, NodeInfo)
            self.assertEqual(response.root_node.label, TEST_DBNAME)
            self.assertEqual(response.root_node.node_path, session_uri)
            self.assertEqual(response.root_node.node_type, 'Database')
            self.assertIsInstance(response.root_node.metadata, ObjectMetadata)
            self.assertEqual(response.root_node.metadata.urn,
                             oe._session_map[session_uri].server.urn_base)
            self.assertEqual(
                response.root_node.metadata.name,
                oe._session_map[session_uri].server.maintenance_db_name)
            self.assertEqual(response.root_node.metadata.metadata_type_name,
                             'Database')
            self.assertFalse(response.root_node.is_leaf)

        rc = RequestFlowValidator()
        rc.add_expected_response(
            CreateSessionResponse,
            lambda param: self.assertEqual(param.session_id, session_uri))
        rc.add_expected_notification(SessionCreatedParameters,
                                     SESSION_CREATED_METHOD,
                                     validate_success_notification)

        # If: I create a session
        oe._handle_create_session_request(rc.request_context, params)
        oe._session_map[session_uri].init_task.join()

        # Then:
        # ... Error notification should have been returned, session should be cleaned up from OE service
        rc.validate()

        # ... The session should still exist and should have connection and server setup
        self.assertIn(session_uri, oe._session_map)
        self.assertIsInstance(oe._session_map[session_uri].server, Server)
        self.assertTrue(oe._session_map[session_uri].is_ready)
Esempio n. 8
0
    def test_handle_scriptas_successful_operation(self):
        # NOTE: There's no need to test all types here, the scripter tests should handle this

        # Setup:
        # ... Create a scripting service
        mock_connection = MockPGServerConnection()
        cs = ConnectionService()
        cs.connect = mock.MagicMock(return_value=ConnectionCompleteParams())
        cs.get_connection = mock.MagicMock(return_value=mock_connection)
        ss = ScriptingService()
        ss._service_provider = utils.get_mock_service_provider(
            {CONNECTION_SERVICE_NAME: cs})

        # ... Create validation logic for responses
        def validate_response(response: ScriptAsResponse) -> None:
            self.assertEqual(response.owner_uri, TestScriptingService.MOCK_URI)
            self.assertEqual(response.script, TestScriptingService.MOCK_SCRIPT)

        # ... Create a scripter with mocked out calls
        patch_path = 'ossdbtoolsservice.scripting.scripting_service.Scripter'
        with mock.patch(patch_path) as scripter_patch:
            mock_scripter: Scripter = Scripter(mock_connection)
            mock_scripter.script = mock.MagicMock(
                return_value=TestScriptingService.MOCK_SCRIPT)
            scripter_patch.return_value = mock_scripter

            scripting_object = {
                'type': 'Table',
                'name': 'test_table',
                'schema': 'test_schema'
            }

            # For each operation supported
            for operation in ScriptOperation:
                # If: I request to script
                rc: RequestFlowValidator = RequestFlowValidator()
                rc.add_expected_response(ScriptAsResponse, validate_response)

                params = ScriptAsParameters.from_dict({
                    'ownerUri':
                    TestScriptingService.MOCK_URI,
                    'operation':
                    operation,
                    'scripting_objects': [scripting_object]
                })

                ss._handle_scriptas_request(rc.request_context, params)

                # Then:
                # ... The request should have been handled correctly
                rc.validate()

            # ... All of the scripter methods should have been called once
            matches = {operation: 0 for operation in ScriptOperation}
            for call_args in mock_scripter.script.call_args_list:
                matches[call_args[0][0]] += 1

            for calls in matches.values():
                self.assertEqual(calls, 1)
Esempio n. 9
0
    def test_handle_close_session_missing_params(self):
        # If: I close an OE session with missing params
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        self.oe._handle_close_session_request(rc.request_context, None)

        # Then: I should get an error response
        rc.validate()
Esempio n. 10
0
 def setUp(self):
     self.task_service = TaskService()
     self.service_provider = ServiceProviderMock({constants.TASK_SERVICE_NAME: self.task_service})
     self.request_validator = RequestFlowValidator()
     self.mock_task_1 = Task(None, None, None, None, None, self.request_validator.request_context, mock.Mock(), mock.Mock())
     self.request_validator.add_expected_notification(TaskInfo, 'tasks/newtaskcreated')
     self.mock_task_1.start = mock.Mock()
     self.mock_task_2 = Task(None, None, None, None, None, self.request_validator.request_context, mock.Mock(), mock.Mock())
     self.request_validator.add_expected_notification(TaskInfo, 'tasks/newtaskcreated')
     self.mock_task_2.start = mock.Mock()
Esempio n. 11
0
    def test_handle_close_session_incomplete_params(self):
        # If: I close an OE session for with missing params
        # NOTE: We only need to get the generate uri method to throw, we make sure it throws in all
        #       scenarios in a different test
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        params = ConnectionDetails.from_data({})
        self.oe._handle_close_session_request(rc.request_context, params)

        # Then:
        # ... I should get an error response
        rc.validate()
Esempio n. 12
0
    def test_handle_close_session_throwsException(self):
        # setup to throw exception on disconnect
        self.cs.disconnect = mock.MagicMock(side_effect=Exception)

        # If: I close an OE session that doesn't exist
        rc = RequestFlowValidator().add_expected_error(type(None))
        session_id = _connection_details()[1]
        params = _close_session_params()
        params.session_id = session_id
        self.oe._handle_close_session_request(rc.request_context, params)

        # Then: I should get a successful response
        rc.validate()
        self.oe._service_provider.logger.error.assert_called_once()
Esempio n. 13
0
    def test_handle_close_session_nosession(self):
        # Setup: Create an empty session dictionary
        self.oe._session_map = {}

        # If: I close an OE session that doesn't exist
        rc = RequestFlowValidator().add_expected_response(
            bool, self.assertFalse)
        session_id = _connection_details()[1]
        params = _close_session_params()
        params.session_id = session_id
        self.oe._handle_close_session_request(rc.request_context, params)

        # Then: I should get a successful response
        rc.validate()
Esempio n. 14
0
    def test_handle_scriptas_missing_params(self):
        # Setup: Create a scripting service
        ss = ScriptingService()
        ss._service_provider = utils.get_mock_service_provider({})

        # If: I make a scripting request missing params
        rc: RequestFlowValidator = RequestFlowValidator()
        rc.add_expected_error(type(None),
                              RequestFlowValidator.basic_error_validation)
        ss._handle_scriptas_request(rc.request_context, None)

        # Then:
        # ... I should get an error response
        rc.validate()
Esempio n. 15
0
    def _handle_er_session_not_ready(self, method: TEventHandler):
        # Setup: Create an OE service with a session that is not ready
        oe, session, session_uri = self._preloaded_oe_service()
        session.is_ready = False

        # If: I expand a node on a session that isn't ready
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        params = ExpandParameters.from_dict({
            'session_id': session_uri,
            'node_path': None
        })
        method(oe, rc.request_context, params)

        # Then: I should get an error back
        rc.validate()
Esempio n. 16
0
    def test_handle_close_session_successful(self):

        # If: I close a session
        rc = RequestFlowValidator().add_expected_response(
            bool, self.assertTrue)
        session_id = _connection_details()[1]
        params = _close_session_params()
        params.session_id = session_id
        self.oe._handle_close_session_request(rc.request_context, params)

        # Then:
        # ... I should get a successful response
        rc.validate()

        # ... The session should no longer be in the
        self.assertDictEqual(self.oe._session_map, {})
Esempio n. 17
0
    def test_handle_close_session_unsuccessful(self):
        self.cs.disconnect = mock.MagicMock(return_value=False)

        # If: I close an OE session that doesn't exist
        rc = RequestFlowValidator().add_expected_response(
            bool, self.assertFalse)
        session_id = _connection_details()[1]
        params = _close_session_params()
        params.session_id = session_id
        self.oe._handle_close_session_request(rc.request_context, params)

        # Then: I should get a successful response
        rc.validate()
        self.oe._service_provider.logger.info.assert_called_with(
            'Could not close the OE session with Id objectexplorer://testuser@testhost:testdb/'
        )
Esempio n. 18
0
    def test_handle_create_session_missing_params(self):
        # Setup: Create an OE service
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})

        # If: I create an OE session with missing params
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        oe._handle_create_session_request(rc.request_context, None)

        # Then:
        # ... I should get an error response
        rc.validate()

        # ... A session should not have been created
        self.assertDictEqual(oe._session_map, {})
Esempio n. 19
0
    def _handle_er_no_session_match(method: TEventHandler):
        # Setup: Create an OE service
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})

        # If: I expand a node on a session that doesn't exist
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        params = ExpandParameters.from_dict({
            'session_id': 'session',
            'node_path': None
        })
        method(oe, rc.request_context, params)

        # Then: I should get an error back
        rc.validate()
Esempio n. 20
0
    def test_handle_scriptas_invalid_operation(self):
        # Setup: Create a scripting service
        mock_connection = {}
        cs = ConnectionService()
        cs.connect = mock.MagicMock(return_value=ConnectionCompleteParams())
        cs.get_connection = mock.MagicMock(return_value=mock_connection)
        ss = ScriptingService()
        ss._service_provider = utils.get_mock_service_provider(
            {CONNECTION_SERVICE_NAME: cs})

        # If: I create an OE session with missing params
        rc: RequestFlowValidator = RequestFlowValidator()
        rc.add_expected_error(type(None),
                              RequestFlowValidator.basic_error_validation)
        ss._handle_scriptas_request(rc.request_context, None)

        # Then:
        # ... I should get an error response
        rc.validate()
Esempio n. 21
0
    def test_handle_create_session_incomplete_params(self):
        # Setup: Create an OE service
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})

        # If: I create an OE session for with missing params
        # NOTE: We only need to get the generate uri method to throw, we make sure it throws in all
        #       scenarios in a different test
        rc = RequestFlowValidator().add_expected_error(
            type(None), RequestFlowValidator.basic_error_validation)
        params = ConnectionDetails.from_data({})
        oe._handle_create_session_request(rc.request_context, params)

        # Then:
        # ... I should get an error response
        rc.validate()

        # ... A session should not have been created
        self.assertDictEqual(oe._session_map, {})
Esempio n. 22
0
    def test_handle_create_session_session_exists(self):
        # Setup: Create an OE service and pre-load a session
        oe = ObjectExplorerService()
        oe._service_provider = utils.get_mock_service_provider({})
        params, session_uri = _connection_details()
        session = ObjectExplorerSession(session_uri, params)
        oe._session_map[session_uri] = session

        # If: I attempt to create an OE session that already exists
        rc = RequestFlowValidator().add_expected_response(
            bool, self.assertFalse)
        oe._handle_create_session_request(rc.request_context, params)

        # Then:
        # ... I should get a response as False
        rc.validate()

        # ... The old session should remain
        self.assertIs(oe._session_map[session_uri], session)
Esempio n. 23
0
    def _handle_er_node_alivetasksuccessful(self, method: TEventHandler,
                                            get_tasks: TGetTask):
        # Setup: Create an OE service with a session preloaded
        oe, session, session_uri = self._preloaded_oe_service()

        # ... Define validation for the return notification
        def validate_success_notification(response: ExpandCompletedParameters):
            self.assertIsNone(response.error_message)
            self.assertEqual(response.session_id, session_uri)
            self.assertEqual(response.node_path, '/')
            self.assertIsInstance(response.nodes, list)
            for node in response.nodes:
                self.assertIsInstance(node, NodeInfo)

        def myfunc(e):
            while not e.isSet():
                pass

        # If: I expand a node
        rc = RequestFlowValidator()
        rc.add_expected_response(bool, self.assertTrue)
        params = ExpandParameters.from_dict({
            'session_id': session_uri,
            'node_path': '/'
        })
        testevent = threading.Event()
        testtask = threading.Thread(target=myfunc, args=(testevent, ))
        session.expand_tasks[params.node_path] = testtask
        session.refresh_tasks[params.node_path] = testtask
        testtask.start()
        method(oe, rc.request_context, params)

        # Then:
        # ... I should have gotten a completed successfully message
        rc.validate()

        # ... The thread should be attached to the session
        self.assertEqual(len(get_tasks(session)), 1)
        testevent.set()
Esempio n. 24
0
    def _handle_er_node_successful(self, method: TEventHandler,
                                   get_tasks: TGetTask):
        # Setup: Create an OE service with a session preloaded
        oe, session, session_uri = self._preloaded_oe_service()

        # ... Define validation for the return notification
        def validate_success_notification(response: ExpandCompletedParameters):
            self.assertIsNone(response.error_message)
            self.assertEqual(response.session_id, session_uri)
            self.assertEqual(response.node_path, '/')
            self.assertIsInstance(response.nodes, list)
            for node in response.nodes:
                self.assertIsInstance(node, NodeInfo)

        # If: I expand a node
        rc = RequestFlowValidator()
        rc.add_expected_response(bool, self.assertTrue)
        rc.add_expected_notification(ExpandCompletedParameters,
                                     EXPAND_COMPLETED_METHOD,
                                     validate_success_notification)
        params = ExpandParameters.from_dict({
            'session_id': session_uri,
            'node_path': '/'
        })
        method(oe, rc.request_context, params)

        # Joining the threads to avoid rc.validate failure
        for task in session.expand_tasks.values():
            task.join()
        for task in session.refresh_tasks.values():
            task.join()
        # Then:
        # ... I should have gotten a completed successfully message
        rc.validate()

        # ... The thread should be attached to the session
        self.assertEqual(len(get_tasks(session)), 1)