1+ import dataclasses
2+ import os
3+ import os .path
4+ from typing import List
5+
6+ import pandas as pd
7+ import pytest
8+
9+ from hipscat .catalog import PartitionInfo
10+ from hipscat .catalog .association_catalog .association_catalog_info import AssociationCatalogInfo
11+ from hipscat .catalog .association_catalog .partition_join_info import PartitionJoinInfo
12+ from hipscat .catalog .catalog_info import CatalogInfo
13+ from hipscat .catalog .dataset .base_catalog_info import BaseCatalogInfo
14+ from hipscat .inspection .almanac import Almanac
15+ from hipscat .pixel_math import HealpixPixel
16+
17+ DATA_DIR_NAME = "data"
18+ ALMANAC_DIR_NAME = "almanac"
19+ SMALL_SKY_DIR_NAME = "small_sky"
20+ SMALL_SKY_ORDER1_DIR_NAME = "small_sky_order1"
21+ SMALL_SKY_TO_SMALL_SKY_ORDER1_DIR_NAME = "small_sky_to_small_sky_order1"
22+ TEST_DIR = os .path .dirname (__file__ )
23+
24+ # pylint: disable=missing-function-docstring, redefined-outer-name
25+
26+ def pytest_addoption (parser ):
27+ parser .addoption ("--cloud" , action = "store" , default = "abfs" )
28+
29+
30+ def pytest_generate_tests (metafunc ):
31+ # This is called for every test. Only get/set command line arguments
32+ # if the argument is specified in the list of test "fixturenames".
33+ option_value = metafunc .config .option .cloud
34+ if 'cloud' in metafunc .fixturenames and option_value is not None :
35+ metafunc .parametrize ("cloud" , [option_value ])
36+
37+
38+ @pytest .fixture
39+ def example_cloud_path (cloud ):
40+ if cloud == "abfs" :
41+ return "abfs:///hipscat/pytests/hipscat"
42+
43+ else :
44+ raise NotImplementedError ("Cloud format not implemented for hipscat tests!" )
45+
46+ @pytest .fixture
47+ def example_cloud_storage_options (cloud ):
48+ if cloud == "abfs" :
49+ storage_options = {
50+ "account_key" : os .environ .get ("ABFS_LINCCDATA_ACCOUNT_KEY" ),
51+ "account_name" : os .environ .get ("ABFS_LINCCDATA_ACCOUNT_NAME" )
52+ }
53+ return storage_options
54+
55+ return {}
56+
57+
58+ @pytest .fixture
59+ def tmp_dir_cloud (example_cloud_path ):
60+ return os .path .join (example_cloud_path , "tmp" )
61+
62+
63+ @pytest .fixture
64+ def test_data_dir_cloud (example_cloud_path ):
65+ return os .path .join (example_cloud_path , DATA_DIR_NAME )
66+
67+
68+ @pytest .fixture
69+ def almanac_dir_cloud (test_data_dir_cloud ):
70+ return os .path .join (test_data_dir_cloud , ALMANAC_DIR_NAME )
71+
72+
73+ @pytest .fixture
74+ def small_sky_dir_cloud (test_data_dir_cloud ):
75+ return os .path .join (test_data_dir_cloud , SMALL_SKY_DIR_NAME )
76+
77+
78+ @pytest .fixture
79+ def small_sky_order1_dir_cloud (test_data_dir_cloud ):
80+ return os .path .join (test_data_dir_cloud , SMALL_SKY_ORDER1_DIR_NAME )
81+
82+
83+ @pytest .fixture
84+ def small_sky_to_small_sky_order1_dir_cloud (test_data_dir_cloud ):
85+ return os .path .join (test_data_dir_cloud , SMALL_SKY_TO_SMALL_SKY_ORDER1_DIR_NAME )
86+
87+
88+ @pytest .fixture
89+ def catalog_pixels () -> List [HealpixPixel ]:
90+ return [HealpixPixel (1 , 0 ), HealpixPixel (1 , 1 ), HealpixPixel (2 , 8 )]
91+
92+
93+ @pytest .fixture
94+ def association_catalog_path_cloud (test_data_dir_cloud ) -> str :
95+ return os .path .join (test_data_dir_cloud , "small_sky_to_small_sky_order1" )
96+
97+
98+ @pytest .fixture
99+ def association_catalog_info_file_cloud (association_catalog_path_cloud ) -> str :
100+ return os .path .join (association_catalog_path_cloud , "catalog_info.json" )
101+
102+
103+ @pytest .fixture
104+ def index_catalog_info_file_cloud (test_data_dir_cloud ) -> str :
105+ return os .path .join (test_data_dir_cloud , "index_catalog" , "catalog_info.json" )
106+
107+
108+ @pytest .fixture
109+ def margin_cache_catalog_info_file_cloud (test_data_dir_cloud ) -> str :
110+ return os .path .join (test_data_dir_cloud , "margin_cache" , "catalog_info.json" )
111+
112+
113+ @pytest .fixture
114+ def source_catalog_info_file_cloud (test_data_dir_cloud ) -> str :
115+ return os .path .join (test_data_dir_cloud , "small_sky_source" , "catalog_info.json" )
116+
117+
118+ @pytest .fixture
119+ def association_catalog_info (association_catalog_info_data ) -> AssociationCatalogInfo :
120+ return AssociationCatalogInfo (** association_catalog_info_data )
121+
122+
123+ @pytest .fixture
124+ def association_catalog_partition_join_file_cloud (association_catalog_path_cloud ) -> str :
125+ return os .path .join (association_catalog_path_cloud , "partition_join_info.csv" )
126+
127+
128+ @pytest .fixture
129+ def dataset_path_cloud (test_data_dir_cloud ) -> str :
130+ return os .path .join (test_data_dir_cloud , "dataset" )
131+
132+
133+ @pytest .fixture
134+ def base_catalog_info_file_cloud (dataset_path_cloud ) -> str :
135+ return os .path .join (dataset_path_cloud , "catalog_info.json" )
136+
137+
138+ @pytest .fixture
139+ def base_catalog_info (base_catalog_info_data ) -> BaseCatalogInfo :
140+ return BaseCatalogInfo (** base_catalog_info_data )
141+
142+
143+ @pytest .fixture
144+ def catalog_path_cloud (test_data_dir_cloud ) -> str :
145+ return os .path .join (test_data_dir_cloud , "catalog" )
146+
147+
148+ @pytest .fixture
149+ def catalog_info_file_cloud (catalog_path_cloud ) -> str :
150+ return os .path .join (catalog_path_cloud , "catalog_info.json" )
151+
152+ @pytest .fixture
153+ def test_data_dir ():
154+ return os .path .join (TEST_DIR , DATA_DIR_NAME )
155+
156+
157+ @pytest .fixture
158+ def small_sky_dir_local (test_data_dir ):
159+ return os .path .join (test_data_dir , SMALL_SKY_DIR_NAME )
160+
161+
162+ @pytest .fixture
163+ def small_sky_order1_dir_local (test_data_dir ):
164+ return os .path .join (test_data_dir , SMALL_SKY_ORDER1_DIR_NAME )
165+
166+
167+ @pytest .fixture
168+ def assert_catalog_info_matches_dict ():
169+ def assert_match (catalog_info : BaseCatalogInfo , dictionary : dict ):
170+ """Check that all members of the catalog_info object match dictionary
171+ elements, where specified."""
172+ catalog_info_dict = dataclasses .asdict (catalog_info )
173+ for key , value in dictionary .items ():
174+ assert catalog_info_dict [key ] == value
175+
176+ return assert_match
177+
178+
179+ @pytest .fixture
180+ def base_catalog_info_data () -> dict :
181+ return {
182+ "catalog_name" : "test_name" ,
183+ "catalog_type" : "object" ,
184+ "total_rows" : 10 ,
185+ }
186+
187+
188+ @pytest .fixture
189+ def catalog_info_data () -> dict :
190+ return {
191+ "catalog_name" : "test_name" ,
192+ "catalog_type" : "object" ,
193+ "total_rows" : 10 ,
194+ "epoch" : "J2000" ,
195+ "ra_column" : "ra" ,
196+ "dec_column" : "dec" ,
197+ }
198+
199+
200+ @pytest .fixture
201+ def association_catalog_info_data () -> dict :
202+ return {
203+ "catalog_name" : "test_name" ,
204+ "catalog_type" : "association" ,
205+ "total_rows" : 10 ,
206+ "primary_catalog" : "small_sky" ,
207+ "primary_column" : "id" ,
208+ "join_catalog" : "small_sky_order1" ,
209+ "join_column" : "id" ,
210+ }
211+
212+
213+ @pytest .fixture
214+ def source_catalog_info () -> dict :
215+ return {
216+ "catalog_name" : "test_source" ,
217+ "catalog_type" : "source" ,
218+ "total_rows" : 100 ,
219+ "epoch" : "J2000" ,
220+ "ra_column" : "source_ra" ,
221+ "dec_column" : "source_dec" ,
222+ }
223+
224+
225+ @pytest .fixture
226+ def source_catalog_info_with_extra () -> dict :
227+ return {
228+ "catalog_name" : "test_source" ,
229+ "catalog_type" : "source" ,
230+ "total_rows" : 100 ,
231+ "epoch" : "J2000" ,
232+ "ra_column" : "source_ra" ,
233+ "dec_column" : "source_dec" ,
234+ "primary_catalog" : "test_name" ,
235+ "mjd_column" : "mjd" ,
236+ "band_column" : "band" ,
237+ "mag_column" : "mag" ,
238+ "mag_err_column" : "" ,
239+ }
240+
241+
242+ @pytest .fixture
243+ def margin_cache_catalog_info () -> dict :
244+ return {
245+ "catalog_name" : "test_margin" ,
246+ "catalog_type" : "margin" ,
247+ "total_rows" : 100 ,
248+ "primary_catalog" : "test_name" ,
249+ "margin_threshold" : 0.5 ,
250+ }
251+
252+
253+ @pytest .fixture
254+ def index_catalog_info () -> dict :
255+ return {
256+ "catalog_name" : "test_index" ,
257+ "catalog_type" : "index" ,
258+ "total_rows" : 100 ,
259+ "primary_catalog" : "test_name" ,
260+ "indexing_column" : "id" ,
261+ }
262+
263+
264+ @pytest .fixture
265+ def index_catalog_info_with_extra () -> dict :
266+ return {
267+ "catalog_name" : "test_index" ,
268+ "catalog_type" : "index" ,
269+ "total_rows" : 100 ,
270+ "primary_catalog" : "test_name" ,
271+ "indexing_column" : "id" ,
272+ "extra_columns" : ["foo" , "bar" ],
273+ }
274+
275+
276+
277+ @pytest .fixture
278+ def catalog_info (catalog_info_data ) -> CatalogInfo :
279+ return CatalogInfo (** catalog_info_data )
280+
281+
282+ @pytest .fixture
283+ def catalog_pixels_df () -> pd .DataFrame :
284+ return pd .DataFrame .from_dict (
285+ {
286+ PartitionInfo .METADATA_ORDER_COLUMN_NAME : [1 , 1 , 2 ],
287+ PartitionInfo .METADATA_DIR_COLUMN_NAME : [0 , 0 , 0 ],
288+ PartitionInfo .METADATA_PIXEL_COLUMN_NAME : [0 , 1 , 8 ],
289+ }
290+ )
291+
292+
293+ @pytest .fixture
294+ def association_catalog_join_pixels () -> pd .DataFrame :
295+ return pd .DataFrame .from_dict (
296+ {
297+ PartitionJoinInfo .PRIMARY_ORDER_COLUMN_NAME : [0 , 0 , 0 , 0 ],
298+ PartitionJoinInfo .PRIMARY_PIXEL_COLUMN_NAME : [11 , 11 , 11 , 11 ],
299+ PartitionJoinInfo .JOIN_ORDER_COLUMN_NAME : [1 , 1 , 1 , 1 ],
300+ PartitionJoinInfo .JOIN_PIXEL_COLUMN_NAME : [44 , 45 , 46 , 47 ],
301+ }
302+ )
303+
304+
305+ @pytest .fixture
306+ def default_almanac_cloud (example_cloud_path , example_cloud_storage_options ):
307+ """Set up default environment variables and fetch default almanac data."""
308+
309+ test_data_dir = os .path .join (example_cloud_path , "data" )
310+ almanac_dir = os .path .join (example_cloud_path , "data" , "almanac" )
311+
312+ os .environ ["HIPSCAT_ALMANAC_DIR" ] = almanac_dir
313+ os .environ ["HIPSCAT_DEFAULT_DIR" ] = test_data_dir
314+
315+ return Almanac (storage_options = example_cloud_storage_options )
0 commit comments