5
5
import inspect
6
6
import subprocess
7
7
from pathlib import Path
8
- from typing import TYPE_CHECKING , Any
8
+ from typing import TYPE_CHECKING , Any , Literal
9
9
10
10
import numpy as np
11
11
import pandas as pd
21
21
22
22
23
23
class BackendTest (abc .ABC ):
24
- check_dtype = True
25
- check_names = True
26
- supports_arrays = True
27
- supports_arrays_outside_of_select = supports_arrays
28
- supports_window_operations = True
29
- supports_divide_by_zero = False
30
- returned_timestamp_unit = "us"
24
+ """
25
+ The base class for managing configuration and data loading for a backend
26
+ that does not require Docker for testing (this includes both in-process
27
+ backends and cloud backends like Snowflake and BigQuery).
28
+ """
29
+
30
+ check_dtype : bool = True
31
+ "Check that dtypes match when comparing Pandas Series"
32
+ check_names : bool = True
33
+ "Check that column name matches when comparing Pandas Series"
34
+ supports_arrays : bool = True
35
+ "Whether backend supports Arrays / Lists"
36
+ supports_arrays_outside_of_select : bool = supports_arrays
37
+ "Whether backend supports Arrays / Lists outside of Select Statements"
38
+ supports_window_operations : bool = True
39
+ "Whether backend supports Window Operations"
40
+ supports_divide_by_zero : bool = False
41
+ "Whether backend supports division by zero"
42
+ returned_timestamp_unit : str = "us"
31
43
supported_to_timestamp_units = {"s" , "ms" , "us" }
32
- supports_floating_modulus = True
33
- native_bool = True
34
- supports_structs = True
35
- supports_json = True
36
- supports_map = False # basically nothing does except trino and snowflake
44
+ supports_floating_modulus : bool = True
45
+ "Whether backend supports floating point in modulus operations"
46
+ native_bool : bool = True
47
+ "Whether backend has native boolean types"
48
+ supports_structs : bool = True
49
+ "Whether backend supports Structs"
50
+ supports_json : bool = True
51
+ "Whether backend supports operating on JSON"
52
+ supports_map : bool = False
53
+ "Whether backend supports mappings (currently DuckDB, Snowflake, and Trino)"
37
54
reduction_tolerance = 1e-7
55
+ "Used for a single test in `test_aggregation.py`. You should not need to touch this."
38
56
default_identifier_case_fn = staticmethod (toolz .identity )
57
+ "Function applied to all identifier names to change case as necessary (e.g. Snowflake ALL_CAPS)"
39
58
stateful = True
40
- service_name = None
41
- supports_tpch = False
59
+ "Whether special handling is needed for running a multi-process pytest run."
60
+ supports_tpch : bool = False
61
+ "Child class defines a `load_tpch` method that loads the required TPC-H tables into a connection."
42
62
force_sort_before_comparison = False
43
- rounding_method = "away_from_zero"
63
+ "Sort results before comparing against reference computation."
64
+ rounding_method : Literal ["away_from_zero" , "half_to_even" ] = "away_from_zero"
65
+ "Name of round method to use for rounding test comparisons."
44
66
45
67
@property
46
68
@abc .abstractmethod
@@ -62,6 +84,20 @@ def format_table(name: str) -> str:
62
84
return name
63
85
64
86
def __init__ (self , * , data_dir : Path , tmpdir , worker_id , ** kw ) -> None :
87
+ """
88
+ Initializes the test class -- note that none of the arguments are
89
+ required and will be provided by `pytest` or by fixtures defined in
90
+ `ibis/backends/conftest.py`.
91
+
92
+ data_dir
93
+ Directory where test data resides (will be provided by the
94
+ `data_dir` fixture in `ibis/backends/conftest.py`)
95
+ tmpdir
96
+ Pytest fixture providing a temporary directory location
97
+ worker_id
98
+ A unique identifier for each worker used for running test
99
+ concurrently via e.g. `pytest -n auto`
100
+ """
65
101
self .connection = self .connect (tmpdir = tmpdir , worker_id = worker_id , ** kw )
66
102
self .data_dir = data_dir
67
103
self .script_dir = data_dir .parent / "schema"
@@ -112,7 +148,7 @@ def load_data(
112
148
if worker_id != "master" :
113
149
root_tmp_dir = root_tmp_dir .parent
114
150
115
- fn = root_tmp_dir / ( getattr ( cls , "service_name" , None ) or cls .name () )
151
+ fn = root_tmp_dir / cls .name ()
116
152
with FileLock (f"{ fn } .lock" ):
117
153
cls .skip_if_missing_deps ()
118
154
@@ -295,7 +331,15 @@ def _tpch_table(self, name: str):
295
331
296
332
297
333
class ServiceBackendTest (BackendTest ):
334
+ """Parent class to use for backend test configuration if backend requires a
335
+ Docker container(s) in order to run locally.
336
+
337
+ """
338
+
339
+ service_name : str | None = None
340
+ "Name of service defined in docker-compose.yml corresponding to backend."
298
341
data_volume = "/data"
342
+ "Data volume defined in docker-compose.yml corresponding to backend."
299
343
300
344
@property
301
345
@abc .abstractmethod
0 commit comments