Example #1
0
 def test_column_fetch(self):
     mock_kusto_client = MockKustoClient(
         columns_response=mock_columns_response([('foo', _KustoType.STRING),
                                                 ('bar', _KustoType.INT)]),
         record_metadata=True,
     )
     table = PyKustoClient(mock_kusto_client,
                           fetch_by_default=False)['test_db']['mock_table']
     table.blocking_refresh()
     # Fetch query
     self.assertEqual(
         [
             RecordedQuery(
                 'test_db',
                 '.show table mock_table | project AttributeName, AttributeType | limit 10000'
             )
         ],
         mock_kusto_client.recorded_queries,
     )
     # Dot notation
     self.assertEqual(type(table.foo), _StringColumn)
     self.assertEqual(type(table.bar), _NumberColumn)
     # Bracket notation
     self.assertEqual(type(table['foo']), _StringColumn)
     self.assertEqual(type(table['bar']), _NumberColumn)
     self.assertEqual(type(table['baz']), _AnyTypeColumn)
Example #2
0
 def test_table_fetch(self):
     mock_kusto_client = MockKustoClient(
         tables_response=mock_tables_response([
             ('mock_table', [('foo', _KustoType.STRING),
                             ('bar', _KustoType.INT)])
         ]),
         record_metadata=True,
     )
     db = PyKustoClient(mock_kusto_client,
                        fetch_by_default=False)['test_db']
     db.blocking_refresh()
     self.assertEqual(
         [
             RecordedQuery(
                 'test_db',
                 '.show database schema | project TableName, ColumnName, ColumnType | limit 10000'
             )
         ],
         mock_kusto_client.recorded_queries,
     )
     table = db.mock_table
     # Table columns
     self.assertEqual(type(table.foo), _StringColumn)
     self.assertEqual(type(table.bar), _NumberColumn)
     self.assertEqual(type(table['baz']), _AnyTypeColumn)
     # Bracket notation
     self.assertEqual(type(db['other_table']['foo']), _AnyTypeColumn)
     # Dot notation error
     self.assertRaises(
         AttributeError(
             "PyKustoClient(test_cluster.kusto.windows.net).Database(test_db) has no attribute 'test_table_1'"
         ), lambda: db.test_table_1)
Example #3
0
 def test_union_wildcard_one_table(self):
     mock_kusto_client = MockKustoClient(
         tables_response=mock_tables_response([
             ('test_table_1', [('foo', _KustoType.STRING),
                               ('bar', _KustoType.INT)]),
             ('other_table_2', [('baz', _KustoType.BOOL)])
         ]),
         record_metadata=True,
     )
     db = PyKustoClient(mock_kusto_client,
                        fetch_by_default=False)['test_db']
     db.blocking_refresh()
     self.assertEqual(
         [
             RecordedQuery(
                 'test_db',
                 '.show database schema | project TableName, ColumnName, ColumnType | limit 10000'
             )
         ],
         mock_kusto_client.recorded_queries,
     )
     table = db.get_table('test_table_*')
     self.assertEqual(type(table.foo), _StringColumn)
     self.assertEqual(type(table.bar), _NumberColumn)
     self.assertEqual(type(table['baz']), _AnyTypeColumn)
Example #4
0
 def test_union_column_name_conflict(self):
     mock_client = MockKustoClient(
         tables_response=mock_tables_response([
             ('test_table_1', [('foo', _KustoType.STRING), ('bar', _KustoType.INT)]),
             ('test_table_2', [('foo', _KustoType.BOOL)])
         ]),
         getschema_response=mock_getschema_response([
             ('foo_string', _KustoType.STRING), ('bar', _KustoType.INT), ('foo_bool', _KustoType.BOOL)
         ]),
         record_metadata=True,
     )
     db = PyKustoClient(mock_client, fetch_by_default=False)['test_db']
     db.blocking_refresh()
     table = db.get_table('test_table_*')
     table.blocking_refresh()  # To trigger name conflict resolution
     self.assertEqual(
         [
             # First trying the usual fetch
             RecordedQuery('test_db', '.show database schema | project TableName, ColumnName, ColumnType | limit 10000'),
             # Fallback for name conflict resolution
             RecordedQuery('test_db', 'union test_table_* | getschema | project ColumnName, DataType | limit 10000')
         ],
         mock_client.recorded_queries,
     )
     self.assertType(table.foo_string, _StringColumn)
     self.assertType(table.bar, _NumberColumn)
     self.assertType(table.foo_bool, _BooleanColumn)
Example #5
0
 def test_client_for_cluster_with_azure_cli_auth(self):
     with self.assertLogs(_logger, logging.INFO) as cm:
         client = PyKustoClient('https://help.kusto.windows.net',
                                fetch_by_default=False)
         self.assertIsInstance(client._PyKustoClient__client, KustoClient)
         self.assertEqual('https://help.kusto.windows.net',
                          client.get_cluster_name())
     self.assertEqual([], cm.output)
Example #6
0
    def test_client_instances_cached(self):
        with patch('pykusto._src.client.PyKustoClient._get_client_for_cluster', MockKustoClient):
            client_1 = PyKustoClient('https://help.kusto.windows.net/', use_global_cache=True)
            client_2 = PyKustoClient('https://help.kusto.windows.net/', use_global_cache=True)

        self.assertIs(
            client_1._PyKustoClient__client,
            client_2._PyKustoClient__client,
        )
Example #7
0
    def test_client_instances(self):
        with patch('pykusto._src.client.PyKustoClient._get_client_for_cluster', MockKustoClient):
            client_1 = PyKustoClient('https://help.kusto.windows.net/')
            client_2 = PyKustoClient('https://help.kusto.windows.net/')

        self.assertIsNot(
            client_1._PyKustoClient__client,
            client_2._PyKustoClient__client,
        )
Example #8
0
 def test_client_for_cluster_fallback_to_aad_device_auth(self):
     with patch('pykusto._src.client._get_azure_cli_auth_token', lambda: None), self.assertLogs(_logger, logging.INFO) as cm:
         client = PyKustoClient('https://help.kusto.windows.net', fetch_by_default=False)
         self.assertIsInstance(client._PyKustoClient__client, KustoClient)
         self.assertEqual('https://help.kusto.windows.net', client.get_cluster_name())
     self.assertEqual(
         ['INFO:pykusto:Failed to get Azure CLI token, falling back to AAD device authentication'],
         cm.output
     )
Example #9
0
 def test_block_until_fetch_is_done(self):
     mock_client = MockKustoClient(block=True, record_metadata=True)
     client = PyKustoClient(mock_client)
     self.query_in_background(client.get_databases_names)
     mock_client.release()
     client.wait_for_items()
     # Make sure the fetch query was indeed called
     assert not mock_client.blocked()
     self.assertEqual(self.get_background_query_result(), ('test_db', ))
Example #10
0
 def test_cross_cluster_join_with_union(self):
     client1 = MockKustoClient("https://one.kusto.windows.net")
     client2 = MockKustoClient("https://two.kusto.windows.net")
     table1 = PyKustoClient(client1)['test_db_1']['test_table_1']
     table2 = PyKustoClient(client2)['test_db_2'].get_table('test_table_2_*')
     Query(table1).take(5).join(Query(table2).take(6)).on(col.foo).execute()
     self.assertEqual(
         [RecordedQuery('test_db_1', 'test_table_1 | take 5 | join  (union cluster("two.kusto.windows.net").database("test_db_2").table("test_table_2_*") | take 6) on foo')],
         client1.recorded_queries,
     )
Example #11
0
 def test_dir_before_fetch_is_done(self):
     mock_client = MockKustoClient(block=True, record_metadata=True)
     client = PyKustoClient(mock_client)
     self.query_in_background(lambda: dir(client))
     # Return the fetch
     mock_client.release()
     client.wait_for_items()
     # Make sure the fetch query was indeed called
     assert not mock_client.blocked()
     self.assertIn('test_db', self.get_background_query_result())
Example #12
0
 def test_client_for_cluster_with_aad_device_auth(self):
     with self.assertLogs(_logger, logging.INFO) as cm:
         client = PyKustoClient('https://help.kusto.windows.net',
                                fetch_by_default=False,
                                auth_method=KustoConnectionStringBuilder.
                                with_aad_device_authentication)
         self.assertIsInstance(client._PyKustoClient__client, KustoClient)
         self.assertEqual('https://help.kusto.windows.net',
                          client.get_cluster_name())
     self.assertEqual([], cm.output)
Example #13
0
 def test_union_wildcard_one_table(self):
     mock_client = MockKustoClient(record_metadata=True)
     db = PyKustoClient(mock_client, fetch_by_default=False)['test_db']
     db.blocking_refresh()
     self.assertEqual(
         [RecordedQuery('test_db', '.show database schema | project TableName, ColumnName, ColumnType | limit 10000')],
         mock_client.recorded_queries,
     )
     table = db.get_table('mock_table_*')
     self.assertType(table.foo, _AnyTypeColumn)
     self.assertType(table.bar, _AnyTypeColumn)
     self.assertType(table['baz'], _BooleanColumn)
Example #14
0
 def test_autocomplete_with_dot(self):
     mock_client = MockKustoClient(
         databases_response=mock_databases_response([('test_db', [('mock_table', [('foo', _KustoType.STRING), ('bar.baz', _KustoType.INT)])])]),
     )
     client = PyKustoClient(mock_client)
     client.wait_for_items()
     # Table columns
     table = client.test_db.mock_table
     self.assertType(table.foo, _StringColumn)
     self.assertType(table.bar, _AnyTypeColumn)
     self.assertType(table['bar.baz'], _NumberColumn)
     autocomplete_list = set(dir(client.test_db.mock_table))
     self.assertIn('foo', autocomplete_list)
     self.assertNotIn('bar.baz', autocomplete_list)
Example #15
0
 def test_empty_database(self):
     mock_client = MockKustoClient(
         databases_response=mock_databases_response([
             ('test_db', [('mock_table', [('foo', _KustoType.STRING), ('bar', _KustoType.INT)])]),
             ('', [('test_table1', [('foo1', _KustoType.STRING), ('bar1', _KustoType.INT)])])
         ]),
         record_metadata=True,
     )
     client = PyKustoClient(mock_client)
     client.wait_for_items()
     self.assertEqual(
         [RecordedQuery('', '.show databases schema | project DatabaseName, TableName, ColumnName, ColumnType | limit 100000')],
         mock_client.recorded_queries,
     )
     self.assertType(client.test_db.mock_table.foo, _StringColumn)
Example #16
0
 def test_table_fetch_slower_than_timeout(self):
     mock_client = MockKustoClient(block=True)
     try:
         PyKustoClient(mock_client)['test_db']['mock_table']
     finally:
         # # Return the fetch
         mock_client.release()
Example #17
0
 def test_to_dataframe(self):
     rows = (['foo', 10], ['bar', 20], ['baz', 30])
     columns = ('stringField', 'numField')
     client = PyKustoClient(
         MockKustoClient(
             databases_response=mock_databases_response([('test_db', [
                 ('mock_table', [('stringField', _KustoType.STRING),
                                 ('numField', _KustoType.INT)])
             ])]),
             main_response=mock_response(rows, columns),
         ))
     client.wait_for_items()
     table = client.test_db.mock_table
     actual_df = Query(table).take(10).to_dataframe()
     expected_df = pd.DataFrame(rows, columns=columns)
     self.assertTrue(expected_df.equals(actual_df))
Example #18
0
    def test_execute_already_bound(self):
        mock_kusto_client = MockKustoClient()
        table = PyKustoClient(mock_kusto_client)['test_db']['mock_table']

        self.assertRaises(
            RuntimeError("This table is already bound to a query"),
            Query(table).take(5).execute, table)
Example #19
0
 def test_union_table_with_wildcard(self):
     mock_kusto_client = MockKustoClient()
     table = PyKustoClient(mock_kusto_client)['test_db']['test_table_*']
     Query(table).take(5).execute()
     self.assertEqual(
         [RecordedQuery('test_db', 'union test_table_* | take 5')],
         mock_kusto_client.recorded_queries,
     )
Example #20
0
 def test_single_table_on_execute(self):
     mock_kusto_client = MockKustoClient()
     table = PyKustoClient(mock_kusto_client)['test_db']['mock_table']
     Query().take(5).execute(table)
     self.assertEqual(
         [RecordedQuery('test_db', 'mock_table | take 5')],
         mock_kusto_client.recorded_queries,
     )
Example #21
0
 def test_union_table(self):
     mock_kusto_client = MockKustoClient()
     table = PyKustoClient(mock_kusto_client)['test_db'].get_table('test_table1', 'test_table2')
     Query(table).take(5).execute()
     self.assertEqual(
         [RecordedQuery('test_db', 'union test_table1, test_table2 | take 5')],
         mock_kusto_client.recorded_queries,
     )
Example #22
0
 def test_missing_retries(self):
     mock_kusto_client = self.unreliable_mock_kusto_client(1)
     table = PyKustoClient(mock_kusto_client,
                           fetch_by_default=False,
                           retry_config=NO_RETRIES)['test_db']['mock_table']
     self.assertRaises(
         KustoServiceError("Mock exception for test", None),
         lambda: Query(table).take(5).execute(),
     )
Example #23
0
 def test_non_transient_exception(self):
     mock_kusto_client = self.unreliable_mock_kusto_client(1, KustoError)
     table = PyKustoClient(
         mock_kusto_client,
         fetch_by_default=False,
         retry_config=RetryConfig(2, sleep_time=0.1,
                                  jitter=0))['test_db']['mock_table']
     self.assertRaises(
         KustoError("Mock exception for test", None),
         lambda: Query(table).take(5).execute(),
     )
Example #24
0
    def test_column_fetch_slow(self):
        mock_response_future = Future()
        mock_response_future.executed = False

        # noinspection PyUnusedLocal
        def upon_execute(
            query
        ):  # Parameter required since function is passed as Callable[[RecordedQuery], None]
            mock_response_future.result()
            mock_response_future.executed = True

        try:
            mock_kusto_client = MockKustoClient(upon_execute=upon_execute,
                                                record_metadata=True)
            table = PyKustoClient(
                mock_kusto_client,
                fetch_by_default=False)['test_db']['mock_table']
            table.refresh()
            self.assertEqual(type(table['foo']), _AnyTypeColumn)
            self.assertEqual(type(table['bar']), _AnyTypeColumn)
            self.assertEqual(type(table['baz']), _AnyTypeColumn)
            # Make sure above lines were called while the fetch query was still waiting
            assert not mock_response_future.executed
        finally:
            # Return the fetch
            mock_response_future.set_result(None)

        table.wait_for_items()
        # Make sure the fetch query was indeed called
        assert mock_response_future.executed
Example #25
0
    def test_request_properties(self):
        properties = ClientRequestProperties()
        properties.set_option(
            ClientRequestProperties.
            results_defer_partial_query_failures_option_name, False)
        properties.set_parameter('xIntValue', 11)

        mock_kusto_client = MockKustoClient()
        table = PyKustoClient(mock_kusto_client)['test_db']['mock_table']
        Query(table).take(5).execute(properties=properties)
        self.assertEqual(
            [RecordedQuery('test_db', 'mock_table | take 5', properties)],
            mock_kusto_client.recorded_queries)
Example #26
0
 def test_join_with_table(self):
     table = PyKustoClient(
         MockKustoClient(columns_response=mock_columns_response([(
             'tableStringField',
             _KustoType.STRING), (
                 'numField', _KustoType.INT)])))['test_db']['mock_table']
     self.assertEqual(
         'mock_table | where numField > 4 | take 5 | join kind=inner (cluster("test_cluster.kusto.windows.net").database("test_db").table("mock_table")) '
         'on numField, $left.stringField==$right.tableStringField',
         (Query(t).where(t.numField > 4).take(5).join(
             Query(table), kind=JoinKind.INNER).on(
                 t.numField,
                 (t.stringField, table.tableStringField)).render()))
Example #27
0
 def test_default_authentication(self):
     mock_kusto_client = MockKustoClient()
     with patch('pykusto._src.client.PyKustoClient._get_client_for_cluster', lambda s, cluster: mock_kusto_client):
         table = PyKustoClient('https://help.kusto.windows.net/')['test_db']['mock_table']
         Query().take(5).execute(table)
     self.assertIs(
         mock_kusto_client,
         table._Table__database._Database__client._PyKustoClient__client,
     )
     self.assertEqual(
         [RecordedQuery('test_db', 'mock_table | take 5')],
         mock_kusto_client.recorded_queries,
     )
Example #28
0
    def test_join_chained_on(self):
        mock_client = PyKustoClient(
            MockKustoClient(columns_response=mock_columns_response([(
                'tableStringField',
                _KustoType.STRING), ('numField', _KustoType.INT)])))
        mock_table = mock_client['test_db']['mock_table']

        expected_query = (
            'mock_table | where numField > 4 | take 5 | join kind=inner '
            '(cluster("test_cluster.kusto.windows.net").database("test_db").table("mock_table")'
            ' | where numField == 2 | take 6) on numField, $left.stringField==$right.tableStringField'
        )
        actual_query = (Query(t).where(t.numField > 4).take(5).join(
            Query(mock_table).where(mock_table.numField == 2).take(6),
            kind=JoinKind.INNER).on(t.numField).on(
                (t.stringField, mock_table.tableStringField)).render())

        self.assertEqual(expected_query, actual_query)
Example #29
0
 def retries_base(self, number_of_retries: int):
     mock_kusto_client = self.unreliable_mock_kusto_client(
         number_of_retries - 1)
     table = PyKustoClient(
         mock_kusto_client,
         fetch_by_default=False,
         retry_config=RetryConfig(number_of_retries,
                                  sleep_time=0.1,
                                  jitter=0))['test_db']['mock_table']
     with self.assertLogs(_logger, logging.INFO) as cm:
         Query(table).take(5).execute()
     self.assertEqual([RecordedQuery('test_db', 'mock_table | take 5')] *
                      number_of_retries, mock_kusto_client.recorded_queries)
     self.assertEqual([
         f"INFO:pykusto:Attempt number {i} out of {number_of_retries} failed, "
         f"previous sleep time was 0.1 seconds. Exception: KustoServiceError('Mock exception for test')"
         for i in range(1, number_of_retries)
     ], cm.output)
Example #30
0
    def test_query_before_fetch_returned(self):
        mock_response_future = Future()
        mock_response_future.returned_queries = []
        mock_response_future.called = False
        mock_response_future.executed = False
        future_called_lock = Lock()

        def upon_execute(query):
            with future_called_lock:
                if mock_response_future.called:
                    first_run = False
                else:
                    mock_response_future.called = True
                    first_run = True
            if first_run:
                mock_response_future.result()
                mock_response_future.executed = True
            mock_response_future.returned_queries.append(query)

        try:
            mock_kusto_client = MockKustoClient(upon_execute=upon_execute,
                                                record_metadata=True)
            table = PyKustoClient(
                mock_kusto_client,
                fetch_by_default=False)['test_db']['mock_table']
            table.refresh()

            # Executing a query in a separate thread, because it is supposed to block until the fetch returns
            query_thread = Thread(target=Query(table).take(5).execute)
            query_thread.start()

            # Make sure above lines were called while the fetch query was still waiting
            assert not mock_response_future.executed
        finally:
            # Return the fetch
            mock_response_future.set_result(None)

        table.wait_for_items()
        query_thread.join()
        # Make sure the fetch query was indeed called
        assert mock_response_future.executed
        # Before the fix the order of returned query was reversed
        self.assertEqual(
            [
                RecordedQuery(
                    'test_db',
                    '.show table mock_table | project AttributeName, AttributeType | limit 10000'
                ),
                RecordedQuery('test_db', 'mock_table | take 5'),
            ],
            mock_response_future.returned_queries,
        )