Example #1
0
    def __init__(self, input_stream=None, output_stream=None):
        """
            Initializes the sql tools client.
            Input and output streams for JsonRpcClient are taken as optional params,
            Else a SqlToolsService process is started and its stdin and stdout is used.
        """
        self.current_id = 1
        self.tools_service_process = None

        if input_stream and output_stream:
            self.json_rpc_client = json_rpc_client.JsonRpcClient(
                input_stream, output_stream)
        else:
            self.tools_service_process = subprocess.Popen(
                sqltoolsservice_args,
                bufsize=0,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE)

            self.json_rpc_client = json_rpc_client.JsonRpcClient(
                self.tools_service_process.stdin,
                io.open(self.tools_service_process.stdout.fileno(),
                        u'rb',
                        buffering=0,
                        closefd=False))

            logger.info(u'SqlToolsService process id: {0}'.format(
                self.tools_service_process.pid))

        self.json_rpc_client.start()
        logger.info(u'Sql Tools Client Initialized')
Example #2
0
    def test_request_enqueued(self):
        """
            Verify requests are enqueued.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'sample output')

        test_client = json_rpc_client.JsonRpcClient(
            input_stream, output_stream)
        test_client.submit_request(
            u'scriptingService/ScriptDatabase', {u'ScriptDatabaseOptions': u'True'})

        test_client = json_rpc_client.JsonRpcClient(
            input_stream, output_stream)
        test_client.submit_request(
            u'scriptingService/ScriptDatabase', {u'ScriptDatabaseOptions': u'True'})

        request = test_client.request_queue.get()

        self.assertEqual(
            request[u'method'],
            u'scriptingService/ScriptDatabase')
        self.assertEqual(
            request[u'params'], {
                u'ScriptDatabaseOptions': u'True'})
    def test_submit_simple_request(self):
        """
            Verify simple request submitted.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 15\r\n\r\n{"key":"value"}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        time.sleep(.5)
        # Verify threads are alive and running.
        self.assertTrue(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())

        test_client.submit_request(u'scriptingService/ScriptDatabase',
                                   {u'ScriptDatabaseOptions': u'True'})

        JsonRpcClientTests.shutdown_background_threads(test_client)

        # check stream contents.
        input_stream.seek(0)
        expected = (
            b'Content-Length: 120\r\n\r\n{"id": null, "jsonrpc": "2.0", '
            b'"method": "scriptingService/ScriptDatabase", '
            b'"params": {"ScriptDatabaseOptions": "True"}}')

        self.assertEqual(input_stream.getvalue(), expected)
        self.assertFalse(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())
Example #4
0
    def test_query_retrieve_correct_response(self):
        """
            Verify a query execute request never retrieves query request
            responses for a different query.
        """
        with open(self.get_baseline(\
                  u'test_query_retrieve_correct_response.txt'),
                  u'r+b',
                  buffering=0) as response_file:
            request_stream = io.BytesIO()
            rpc_client = json_rpc_client.JsonRpcClient(
                in_stream=request_stream, out_stream=response_file)
            rpc_client.start()

            owner_uri = u'mismatchquerycompleteresponse_2'
            parameters = {
                u'OwnerUri': owner_uri,
                u'Query': "select * from HumanResources.Department"
            }
            request = queryservice.QueryExecuteStringRequest(
                request_id=u'3',
                owner_uri=owner_uri,
                json_rpc_client=rpc_client,
                parameters=parameters)

            # The baseline file contains responses for a different owner uri, which
            # this request should not receive. Receiving a query complete event with
            # a error message indicates we did not retrieve a wrong event.
            self.verify_query_service_response(request=request,
                                               expected_complete_event=1,
                                               expected_error_count=1)

            rpc_client.shutdown()
Example #5
0
 def test_malformed_query_AdventureWorks2014(self):
     """
         Verify a failed query execute response for "select * from [HumanResources.Department"
     """
     with open(self.get_baseline(\
               u'test_malformed_query.txt'),
               u'r+b',
               buffering=0) as response_file:
         request_stream = io.BytesIO()
         rpc_client = json_rpc_client.JsonRpcClient(
             in_stream=request_stream, out_stream=response_file)
         rpc_client.start()
         # Submit a dummy request.
         owner_uri = u'connectionservicetest'
         parameters = {
             u'OwnerUri': owner_uri,
             u'Query': "select * from [HumanResources.Department"
         }
         request = queryservice.QueryExecuteStringRequest(
             request_id=u'2',
             owner_uri=owner_uri,
             json_rpc_client=rpc_client,
             parameters=parameters)
         self.verify_query_service_response(request=request,
                                            expected_error_count=1)
         rpc_client.shutdown()
Example #6
0
    def test_successful_connection_AdventureWorks2014(self):
        """
            Verify a successful connection response
        """

        with open(self.get_baseline(\
                  u'test_simple_query.txt'),
                  u'r+b',
                  buffering=0) as response_file:

            request_stream = io.BytesIO()
            rpc_client = json_rpc_client.JsonRpcClient(
                in_stream=request_stream, out_stream=response_file)
            rpc_client.start()

            owner_uri = u'connectionservicetest'
            parameters = {
                u'OwnerUri': owner_uri,
                u'ServerName': u'bro-hb',
                u'DatabaseName': u'AdventureWorks2014',
                u'UserName': u'*',
                u'Password': u'*',
                u'AuthenticationType': u'Integrated',
                u'MultipleActiveResultSets': True
            }

            request = connectionservice.ConnectionRequest(
                request_id=u'1',
                owner_uri=owner_uri,
                json_rpc_client=rpc_client,
                parameters=parameters)
            self.verify_connection_service_response(request=request,
                                                    expected_response_event=1,
                                                    expected_complete_event=1)
            rpc_client.shutdown()
Example #7
0
 def test_query_execute_response_AdventureWorks2014(self):
     """
        Verify a successful query execute response for "select * from HumanResources.Department"
     """
     with open(self.get_baseline(\
               u'test_simple_query.txt'),
               u'r+b',
               buffering=0) as response_file:
         request_stream = io.BytesIO()
         rpc_client = json_rpc_client.JsonRpcClient(
             in_stream=request_stream, out_stream=response_file)
         rpc_client.start()
         # Submit a dummy request.
         owner_uri = u'connectionservicetest'
         parameters = {
             u'OwnerUri': owner_uri,
             u'Query': "select * from HumanResources.Department"
         }
         request = queryservice.QueryExecuteStringRequest(
             request_id=2,
             owner_uri=owner_uri,
             json_rpc_client=rpc_client,
             parameters=parameters)
         self.verify_query_service_response(request=request,
                                            expected_message_event=1,
                                            expected_complete_event=1,
                                            expected_batch_summaries=1,
                                            expected_result_set_summaries=1,
                                            expected_row_count=16)
         rpc_client.shutdown()
Example #8
0
 def test_query_subset_response_AdventureWorks2014(self):
     """
         Test the retrieval of the actual rows for "select * from HumanResources.Department"
     """
     with open(self.get_baseline(\
               u'test_simple_query.txt'),
               u'r+b',
               buffering=0) as response_file:
         request_stream = io.BytesIO()
         rpc_client = json_rpc_client.JsonRpcClient(request_stream,
                                                    response_file)
         rpc_client.start()
         # Submit a dummy request.
         owner_uri = u'connectionservicetest'
         parameters = {
             u'OwnerUri': u'connectionservicetest',
             u'BatchIndex': 0,
             u'ResultSetIndex': 0,
             u'RowsStartIndex': 0,
             u'RowCount': 16
         }
         request = queryservice.QuerySubsetRequest(
             request_id=u'3',
             owner_uri=owner_uri,
             json_rpc_client=rpc_client,
             parameters=parameters)
         self.verify_query_service_response(request=request,
                                            expected_result_subsets=1,
                                            expected_row_count=16)
         rpc_client.shutdown()
Example #9
0
    def test_successful_connection_AdventureWorks2014(self):
        """
            Verify a successful connection response
        """

        with open(self.get_test_baseline(
                u'select_from_humanresources_department_adventureworks2014.txt'
        ),
                  u'r+b',
                  buffering=0) as response_file:
            request_stream = io.BytesIO()
            rpc_client = json_rpc_client.JsonRpcClient(request_stream,
                                                       response_file)
            rpc_client.start()
            # Submit a dummy request.
            parameters = {
                u'OwnerUri': u'connectionservicetest',
                u'ServerName': u'bro-hb',
                u'DatabaseName': u'AdventureWorks2014',
                u'UserName': u'*',
                u'Password': u'*',
                u'AuthenticationType': u'Integrated',
                u'MultipleActiveResultSets': True
            }

            request = connectionservice.ConnectionRequest(
                1, rpc_client, parameters)
            self.verify_success_response(request=request)
            rpc_client.shutdown()
    def test_get_response_with_id(self):
        """
            Verify response retrieval with id returns global event or response.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 86\r\n\r\n{"params": {"Key": "Value"}, "jsonrpc": "2.0", '
            b'"method": "testMethod/DoThis", "id": 1}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()

        # Sleeping to give background threads a chance to process response.
        time.sleep(1)

        # Sleeping to give background threads a chance to process response.
        time.sleep(1)

        baseline = {
            u'jsonrpc': u'2.0',
            u'params': {
                u'Key': u'Value'
            },
            u'method': u'testMethod/DoThis',
            u'id': 1
        }
        response = test_client.get_response(request_id=1)
        self.assertEqual(response, baseline)
        test_client.shutdown()
    def test_stream_closed_during_process(self):
        """
            Verify request stream closed, exception returned and request thread died.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 15\r\n\r\n{"key":"value"}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        input_stream.close()
        test_client.submit_request('scriptingService/ScriptDatabase',
                                   {'ScriptLogins': 'True'})
        # sleep 1 second for request thread to process.
        time.sleep(1)

        try:
            test_client.get_response()
        except ValueError as exception:
            # Verify the background thread communicated the exception.
            self.assertEqual(str(exception), u'I/O operation on closed file.')
            # Verify response thread is dead.
            self.assertFalse(test_client.request_thread.is_alive())
            test_client.shutdown()
    def test_send_invalid_request(self):
        """
            Verifies that a request with a null method or parameter is not enqueued.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'sample output')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        with self.assertRaises(ValueError):
            test_client.submit_request(None, None)
Example #13
0
    def __init__(self,
                 input_stream=None,
                 output_stream=None,
                 enable_logging=False):
        """
            Initializes the sql tools client.
            Input and output streams for JsonRpcClient are taken as optional params,
            Else a SqlToolsService process is started and its stdin and stdout is used.
        """
        self.current_id = uuid.uuid4().int
        self.tools_service_process = None

        sqltoolsservice_args = [mssqltoolsservice.get_executable_path()]

        if enable_logging:
            sqltoolsservice_args.append('--enable-logging')
            sqltoolsservice_args.append('--log-dir')
            sqltoolsservice_args.append(config_location())

        if input_stream and output_stream:
            self.json_rpc_client = json_rpc_client.JsonRpcClient(
                input_stream, output_stream)
        else:
            self.tools_service_process = subprocess.Popen(
                sqltoolsservice_args,
                bufsize=0,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE)

            self.json_rpc_client = json_rpc_client.JsonRpcClient(
                self.tools_service_process.stdin,
                io.open(self.tools_service_process.stdout.fileno(),
                        u'rb',
                        buffering=0,
                        closefd=False))

            logger.info(u'SqlToolsService process id: {0}'.format(
                self.tools_service_process.pid))

        self.json_rpc_client.start()
        logger.info(u'Sql Tools Client Initialized')
    def test_send_multiple_request(self):
        """
            Verifies we can successfully submit multiple requests.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 15\r\n\r\n{"key":"value"}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        time.sleep(.5)
        # request thread is alive.
        # response thread is dead due to reaching EOF.
        self.assertTrue(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())

        test_client.submit_request(u'scriptingService/ScriptDatabase',
                                   {u'ScriptDatabaseOptions': u'True'})
        test_client.submit_request(u'scriptingService/ScriptDatabase',
                                   {u'ScriptCollations': u'True'})
        test_client.submit_request(u'scriptingService/ScriptDatabase',
                                   {u'ScriptDefaults': u'True'})

        # Minimum sleep time for main thread, so background threads can process
        # the requests.
        time.sleep(1)

        # Kill the threads so we can just verify the queues.
        JsonRpcClientTests.shutdown_background_threads(test_client)

        input_stream.seek(0)
        expected = (
            b'Content-Length: 120\r\n\r\n{"id": null, "jsonrpc": "2.0", '
            b'"method": "scriptingService/ScriptDatabase", '
            b'"params": {"ScriptDatabaseOptions": "True"}}'
            b'Content-Length: 115\r\n\r\n{"id": null, "jsonrpc": "2.0", '
            b'"method": "scriptingService/ScriptDatabase", "params": {"ScriptCollations": "True"}}'
            b'Content-Length: 113\r\n\r\n{"id": null, "jsonrpc": "2.0", '
            b'"method": "scriptingService/ScriptDatabase", "params": {"ScriptDefaults": "True"}}'
        )

        self.assertEqual(input_stream.getvalue(), expected)
        self.assertFalse(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())
Example #15
0
    def test_query_execute_response_AdventureWorks2014(self):
        """
            Verify a successful query execute response for "select * from HumanResources.Department"
        """

        with open(self.get_test_baseline(u'select_from_humanresources_department_adventureworks2014.txt'), u'r+b', buffering=0) as response_file:
            request_stream = io.BytesIO()
            rpc_client = json_rpc_client.JsonRpcClient(
                request_stream, response_file)
            rpc_client.start()
            # Submit a dummy request.
            parameters = {u'OwnerUri': u'connectionservicetest',
                          u'Query': "select * from HumanResources.Department"}

            request = queryservice.QueryExecuteStringRequest(
                2, rpc_client, parameters)
            self.verify_query_response(request=request)
            rpc_client.shutdown()
    def test_stream_has_no_response(self):
        """
            Verify response thread is alive while output stream has no output.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO()

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        response = test_client.get_response()

        self.assertEqual(response, None)
        self.assertTrue(test_client.request_thread.is_alive())
        self.assertTrue(test_client.response_thread.is_alive())
        test_client.shutdown()
        self.assertFalse(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())
Example #17
0
    def test_receive_invalid_response_exception(self):
        """
            Verify invalid response has exception queued and response thread dies.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'Cntent-Lenth:15\r\n\r\n')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()

        try:
            # Retrieve the latest response or earliest exception.
            test_client.get_response()
        except LookupError as exception:
            # Verify the background thread communicated the exception.
            self.assertEqual(
                str(exception),
                u'Content-Length was not found in headers received.')

            # flaky test fix: logic that waits until threads shut down
            count = 0
            while count < 5:
                active_threads = threading.enumerate()
                if test_client.request_thread not in active_threads or \
                    test_client.response_thread in active_threads:
                    time.sleep(5)
                    count += 1
                else:
                    break

            # Lookup exception for invalid content length spelling.
            self.assertTrue(test_client.request_thread.is_alive())
            self.assertFalse(test_client.response_thread.is_alive())
            test_client.shutdown()
            self.assertFalse(test_client.request_thread.is_alive())
        except Exception as exception:
            raise AssertionError("Expected LookupError but caught a different exception: {}"\
                                 .format(exception))
        else:
            raise AssertionError("LookupError should have been thrown.")
        finally:
            test_client.shutdown()
    def test_response_stream_closed_exception(self):
        """
            Verify response stream closed, exception returned and response thread died.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'Content-Lenth:15\r\n\r\n')
        output_stream.close()

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()

        try:
            test_client.get_response()
        except ValueError as exception:
            # Verify the background thread communicated the exception.
            self.assertEqual(str(exception), u'I/O operation on closed file.')

            test_client.shutdown()
    def test_response_dequeued(self):
        """
            Verify response was read.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 15\r\n\r\n{"key":"value"}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        time.sleep(.2)
        response = test_client.get_response()
        baseline = {u'key': u'value'}

        self.assertEqual(response, baseline)
        JsonRpcClientTests.shutdown_background_threads(test_client)
        # All background threads should be shut down.
        self.assertFalse(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())
Example #20
0
    def test_query_subset_response_AdventureWorks2014(self):
        """
            Test the retrieval of the actual rows for "select * from HumanResources.Department"
        """

        with open(self.get_test_baseline(u'select_from_humanresources_department_adventureworks2014.txt'), u'r+b', buffering=0) as response_file:
            request_stream = io.BytesIO()
            rpc_client = json_rpc_client.JsonRpcClient(
                request_stream, response_file)
            rpc_client.start()
            # Submit a dummy request.
            parameters = {u'OwnerUri': u'connectionservicetest',
                          u'BatchIndex': 0,
                          u'ResultSetIndex': 0,
                          u'RowsStartIndex': 0,
                          u'RowCount': 16}

            request = queryservice.QuerySubsetRequest(
                3, rpc_client, parameters)
            self.verify_subset_response(request=request)
            rpc_client.shutdown()
    def test_normal_shutdown(self):
        """
            Verify normal shutdown.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(
            b'Content-Length: 15\r\n\r\n{"key":"value"}')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()
        time.sleep(.5)
        # Verify threads alive.
        self.assertTrue(test_client.request_thread.is_alive())

        # Response thread is dead due to EOF.
        self.assertFalse(test_client.response_thread.is_alive())

        test_client.shutdown()

        self.assertFalse(test_client.request_thread.is_alive())
        self.assertFalse(test_client.response_thread.is_alive())
Example #22
0
    def test_response_stream_closed_exception(self):
        """
            Verify response stream closed, exception returned and response thread died.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'Content-Lenth:15\r\n\r\n')
        output_stream.close()

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()

        try:
            test_client.get_response()
        except ValueError as exception:
            # Verify the background thread communicated the exception.
            self.assertEqual(str(exception), u'I/O operation on closed file.')
        except Exception as exception:
            raise AssertionError("Expected ValueError but caught a different exception: {}"\
                                 .format(exception))
        else:
            raise AssertionError("ValueError should have been thrown.")
        finally:
            test_client.shutdown()
    def test_receive_invalid_response_exception(self):
        """
            Verify invalid response has exception queued and response thread dies.
        """
        input_stream = io.BytesIO()
        output_stream = io.BytesIO(b'Cntent-Lenth:15\r\n\r\n')

        test_client = json_rpc_client.JsonRpcClient(input_stream,
                                                    output_stream)
        test_client.start()

        try:
            # Retrieve the latest response or earliest exception.
            test_client.get_response()
        except LookupError as exception:
            # Verify the background thread communicated the exception.
            self.assertEqual(
                str(exception),
                u'Content-Length was not found in headers received.')
            # Lookup exception for invalid content length spelling.
            self.assertTrue(test_client.request_thread.is_alive())
            self.assertFalse(test_client.response_thread.is_alive())
            test_client.shutdown()
            self.assertFalse(test_client.request_thread.is_alive())