dkist-header-validator 5.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,402 @@
1
+ from io import BytesIO
2
+ from pathlib import Path
3
+
4
+ from astropy.io import fits
5
+ from dkist_fits_specifications.utils.formatter import reformat_spec214_header
6
+
7
+ from dkist_header_validator import spec214_l0_validator
8
+ from dkist_header_validator import spec214_validator
9
+
10
+
11
+ def test_spec214l0(valid_spec_214l0_object):
12
+ """
13
+ Validates a fits header against the SPEC-0214 schema
14
+ Given: A valid SPEC-0214l0 fits header
15
+ When: Validating headers
16
+ Then: return validated HDUList and do not raise an exception
17
+ """
18
+ # raises exception on failure
19
+ spec214_l0_validator.validate(valid_spec_214l0_object, extra=False)
20
+
21
+
22
+ def test_spec214(valid_spec_214_object):
23
+ """
24
+ Validates a fits header against the SPEC-0214 schema
25
+ Given: A valid SPEC-0214 fits header
26
+ When: Validating headers
27
+ Then: return validated HDUList and do not raise an exception
28
+ """
29
+ # raises exception on failure
30
+ spec214_validator.validate(valid_spec_214_object, extra=False)
31
+
32
+
33
+ def test_spec214l0_return_dictionary(valid_spec_214l0_object):
34
+ """
35
+ Validates a fits header against the SPEC-0214 schema
36
+ Given: A valid SPEC-0214 fits header
37
+ When: Validating headers
38
+ Then: return validated dictionary and do not raise an exception
39
+ """
40
+ # raises exception on failure
41
+ result = spec214_l0_validator.validate(valid_spec_214l0_object, return_type=dict, extra=False)
42
+ assert isinstance(result, dict)
43
+
44
+
45
+ def test_spec214_return_dictionary(valid_spec_214_object):
46
+ """
47
+ Validates a fits header against the SPEC-0214 schema
48
+ Given: A valid SPEC-0214 fits header
49
+ When: Validating headers
50
+ Then: return validated dictionary and do not raise an exception
51
+ """
52
+ # raises exception on failure
53
+ result = spec214_validator.validate(valid_spec_214_object, return_type=dict, extra=False)
54
+ assert isinstance(result, dict)
55
+
56
+
57
+ def test_spec214l0_return_fits_header(valid_spec_214l0_object):
58
+ """
59
+ Validates a fits header against the SPEC-0214 schema
60
+ Given: A valid SPEC-0214 fits header
61
+ When: Validating headers
62
+ Then: return validated fits.header.Header object and do not raise an exception
63
+ """
64
+ # raises exception on failure
65
+ result = spec214_l0_validator.validate(
66
+ valid_spec_214l0_object, return_type=fits.header.Header, extra=False
67
+ )
68
+ assert isinstance(result, fits.header.Header)
69
+
70
+
71
+ def test_spec214_return_fits_header(valid_spec_214_object):
72
+ """
73
+ Validates a fits header against the SPEC-0214 schema
74
+ Given: A valid SPEC-0214 fits header
75
+ When: Validating headers
76
+ Then: return validated fits.header.Header object and do not raise an exception
77
+ """
78
+ # raises exception on failure
79
+ result = spec214_validator.validate(
80
+ valid_spec_214_object, return_type=fits.header.Header, extra=False
81
+ )
82
+ assert isinstance(result, fits.header.Header)
83
+
84
+
85
+ def test_spec214l0_return_HDU(valid_spec_214l0_file):
86
+ """
87
+ Validates a fits header against the SPEC-0214 schema
88
+ Given: A valid SPEC-0214 fits header
89
+ When: Validating headers
90
+ Then: return validated fits.PrimaryHDU object and do not raise an exception
91
+ """
92
+ # raises exception on failure
93
+ result = spec214_l0_validator.validate(
94
+ valid_spec_214l0_file, return_type=fits.PrimaryHDU, extra=False
95
+ )
96
+ assert isinstance(result, fits.PrimaryHDU)
97
+
98
+
99
+ def test_spec214_return_HDU(valid_spec_214_file):
100
+ """
101
+ Validates a fits header against the SPEC-0214 schema
102
+ Given: A valid SPEC-0214 fits header
103
+ When: Validating headers
104
+ Then: return validated fits.PrimaryHDU object and do not raise an exception
105
+ """
106
+ # raises exception on failure
107
+ result = spec214_validator.validate(
108
+ valid_spec_214_file, return_type=fits.PrimaryHDU, extra=False
109
+ )
110
+ assert isinstance(result, fits.PrimaryHDU)
111
+
112
+
113
+ def test_spec214l0_return_BytesIO(valid_spec_214l0_file):
114
+ """
115
+ Validates a fits header against the SPEC-0214 schema
116
+ Given: A valid SPEC-0214 fits header
117
+ When: Validating headers
118
+ Then: return validated BytesIO object and do not raise an exception
119
+ """
120
+ # raises exception on failure
121
+ result = spec214_l0_validator.validate(valid_spec_214l0_file, return_type=BytesIO, extra=False)
122
+ assert isinstance(result, BytesIO)
123
+
124
+
125
+ def test_spec214_return_BytesIO(valid_spec_214_file):
126
+ """
127
+ Validates a fits header against the SPEC-0214 schema
128
+ Given: A valid SPEC-0214 fits header
129
+ When: Validating headers
130
+ Then: return validated BytesIO object and do not raise an exception
131
+ """
132
+ # raises exception on failure
133
+ result = spec214_validator.validate(valid_spec_214_file, return_type=BytesIO, extra=False)
134
+ assert isinstance(result, BytesIO)
135
+
136
+
137
+ def test_spec214l0_return_file(valid_spec_214l0_file):
138
+ """
139
+ Validates a fits header against the SPEC-0214 schema
140
+ Given: A valid SPEC-0214 fits header
141
+ When: Validating headers
142
+ Then: return validated file and do not raise an exception
143
+ """
144
+ # raises exception on failure
145
+ result = spec214_l0_validator.validate(valid_spec_214l0_file, return_type=Path, extra=False)
146
+ assert isinstance(result, Path)
147
+
148
+
149
+ def test_spec214_return_file(valid_spec_214_file):
150
+ """
151
+ Validates a fits header against the SPEC-0214 schema
152
+ Given: A valid SPEC-0214 fits header
153
+ When: Validating headers
154
+ Then: return validated file and do not raise an exception
155
+ """
156
+ # raises exception on failure
157
+ result = spec214_validator.validate(valid_spec_214_file, return_type=Path, extra=False)
158
+ assert isinstance(result, Path)
159
+
160
+
161
+ def test_spec214l0_extraheaders_allowed(valid_spec_214l0_object_extra_keys):
162
+ """
163
+ Validates a fits header against the SPEC-0214 schema
164
+ Given: A valid SPEC-0214 fits header
165
+ When: Validating headers
166
+ Then: return validated HDUList and do not raise an exception
167
+ """
168
+ # raises exception on failure
169
+ spec214_l0_validator.validate(valid_spec_214l0_object_extra_keys)
170
+
171
+
172
+ def test_spec214_extraheaders_allowed(valid_spec_214_object_extra_keys):
173
+ """
174
+ Validates a fits header against the SPEC-0214 schema
175
+ Given: A valid SPEC-0214 fits header
176
+ When: Validating headers
177
+ Then: return validated HDUList and do not raise an exception
178
+ """
179
+ # raises exception on failure
180
+ spec214_validator.validate(valid_spec_214_object_extra_keys)
181
+
182
+
183
+ def test_validatel0_required_only_headers(valid_spec_214l0_object_required_only):
184
+ """
185
+ Validates a spec214l0 compliant header with only the keywords required by the DC
186
+ Given: A spec214l0 compliant header with only required keywords
187
+ When: Validating headers
188
+ Then: return a validated HDUList and do not raise an exception
189
+ """
190
+ spec214_l0_validator.validate(valid_spec_214l0_object_required_only)
191
+
192
+
193
+ def test_validate_required_only_headers(valid_spec_214_object_required_only):
194
+ """
195
+ Validates a spec214 compliant header with only the keywords required by the DC
196
+ Given: A spec214 compliant header with only required keywords
197
+ When: Validating headers
198
+ Then: return a validated HDUList and do not raise an exception
199
+ """
200
+ spec214_validator.validate(valid_spec_214_object_required_only)
201
+
202
+
203
+ def test_validatel0_expected_only_headers(valid_spec_214l0_object_expected_only):
204
+ """
205
+ Validates a spec214l0 compliant header with only the keywords required by the DC
206
+ Given: A spec214l0 compliant header with only required keywords
207
+ When: Validating headers
208
+ Then: return a validated HDUList and do not raise an exception
209
+ """
210
+ spec214_l0_validator.validate(valid_spec_214l0_object_expected_only)
211
+
212
+
213
+ def test_validate_expected_only_headers(valid_spec_214_object_expected_only):
214
+ """
215
+ Validates a spec214 compliant header with only the keywords required by the DC
216
+ Given: A spec214 compliant header with only required keywords
217
+ When: Validating headers
218
+ Then: return a validated HDUList and do not raise an exception
219
+ """
220
+ spec214_validator.validate(valid_spec_214_object_expected_only)
221
+
222
+
223
+ def test_compressed_spec214l0(valid_spec_214l0_compressed):
224
+ """
225
+ Validates a compressed spec214 compliant file
226
+ Given: A valid compressed SPEC-0214 file
227
+ When: Validating headers
228
+ Then: return validated HDUList and do not raise an exception
229
+ """
230
+ spec214_l0_validator.validate(valid_spec_214l0_compressed)
231
+
232
+
233
+ def test_compressed_spec214(valid_spec_214_compressed):
234
+ """
235
+ Validates a compressed spec214 compliant file
236
+ Given: A valid compressed SPEC-0214 file
237
+ When: Validating headers
238
+ Then: return validated HDUList and do not raise an exception
239
+ """
240
+ spec214_validator.validate(valid_spec_214_compressed)
241
+
242
+
243
+ def test_validatel0_datainsecondHDU(valid_spec_214l0_second_hdu):
244
+ """
245
+ Validates headers with data stored in second HDU
246
+ Given: A valid SPEC-214 file or with data stored in second HDU
247
+ When: Validating headers
248
+ Then: Raise an exception
249
+ """
250
+ # raises exception on failure
251
+ spec214_l0_validator.validate(valid_spec_214l0_second_hdu, return_type=Path)
252
+
253
+
254
+ def test_validate_datainsecondHDU(valid_spec_214_second_hdu):
255
+ """
256
+ Validates headers with data stored in second HDU
257
+ Given: A valid SPEC-214 file or with data stored in second HDU
258
+ When: Validating headers
259
+ Then: Do not raise an exception
260
+ """
261
+ # raises exception on failure
262
+ spec214_validator.validate(valid_spec_214_second_hdu, return_type=Path)
263
+
264
+
265
+ def test_validate_s214l0_visp(valid_spec_214l0_visp):
266
+ """
267
+ Validates headers with visp headers and data
268
+ Given: A valid SPEC-214 visp file
269
+ When: Validating headers
270
+ Then: Do not raise an exception
271
+ """
272
+ # raises exception on failure
273
+ spec214_l0_validator.validate(valid_spec_214l0_visp)
274
+
275
+
276
+ def test_validate_s214_visp(valid_spec_214_visp):
277
+ """
278
+ Validates headers with visp headers and data
279
+ Given: A valid SPEC-214 visp file
280
+ When: Validating headers
281
+ Then: Do not raise an exception
282
+ """
283
+ # raises exception on failure
284
+ spec214_validator.validate(valid_spec_214_visp)
285
+
286
+
287
+ def test_validate_s214l0_no_file(valid_spec_214l0_no_file):
288
+ """
289
+ Validates headers of the type hdulist, dict, or fits.Header
290
+ Given: A valid SPEC-214 header
291
+ When: Validating headers
292
+ Then: Do not raise an exception
293
+ """
294
+ # raises exception on failure
295
+ spec214_l0_validator.validate(valid_spec_214l0_no_file)
296
+
297
+
298
+ def test_validate_s214_no_file(valid_spec_214_no_file):
299
+ """
300
+ Validates headers of the type hdulist, dict, or fits.Header
301
+ Given: A valid SPEC-214 header
302
+ When: Validating headers
303
+ Then: Do not raise an exception
304
+ """
305
+ # raises exception on failure
306
+ spec214_validator.validate(valid_spec_214_no_file)
307
+
308
+
309
+ def test_validate_s214l0_dict_only(valid_spec_214l0_dict_only):
310
+ """
311
+ Validates a dict of input S214 headers
312
+ Given: A valid SPEC-214 header
313
+ When: Validating headers
314
+ Then: Do not raise an exception
315
+ """
316
+ # raises exception on failure
317
+ spec214_l0_validator.validate(valid_spec_214l0_dict_only)
318
+
319
+
320
+ def test_validate_s214_dict_only(valid_spec_214_dict_only):
321
+ """
322
+ Validates a dict of input S214 headers
323
+ Given: A valid SPEC-214 header
324
+ When: Validating headers
325
+ Then: Do not raise an exception
326
+ """
327
+ # raises exception on failure
328
+ spec214_validator.validate(valid_spec_214_dict_only)
329
+
330
+
331
+ def test_validate_s214l0_hdulist_only(valid_spec_214l0_hdulist_only):
332
+ """
333
+ Validates an HDUList of input S214 headers
334
+ Given: A valid SPEC-214 header
335
+ When: Validating headers
336
+ Then: Do not raise an exception
337
+ """
338
+ # raises exception on failure
339
+ spec214_l0_validator.validate(valid_spec_214l0_hdulist_only)
340
+
341
+
342
+ def test_validate_s214_hdulist_only(valid_spec_214_hdulist_only):
343
+ """
344
+ Validates an HDUList of input S214 headers
345
+ Given: A valid SPEC-214 header
346
+ When: Validating headers
347
+ Then: Do not raise an exception
348
+ """
349
+ # raises exception on failure
350
+ spec214_validator.validate(valid_spec_214_hdulist_only)
351
+
352
+
353
+ def test_validate_s214l0_casesensitive(valid_spec_214l0_casesensitive):
354
+ """
355
+ Validates headers with a keyword that will need a case sensitive change
356
+ Given: S214 headers with a keyword that will need a case sensitive change
357
+ When: Validating headers
358
+ Then: Do not raise an exception
359
+ """
360
+ # raises exception on failure
361
+ spec214_l0_validator.validate(valid_spec_214l0_casesensitive)
362
+
363
+
364
+ def test_validate_s214_casesensitive(valid_spec_214_casesensitive):
365
+ """
366
+ Validates headers with a keyword that will need a case sensitive change
367
+ Given: S214 headers with a keyword that will need a case sensitive change
368
+ When: Validating headers
369
+ Then: Do not raise an exception
370
+ """
371
+ # raises exception on failure
372
+ spec214_validator.validate(valid_spec_214_casesensitive)
373
+
374
+
375
+ def test_validate_formatted_compressed_header(tmp_path):
376
+ """
377
+ Validates a header which has been pretty-formatted by the formatter.
378
+ Given: A formatted, compressed, fits file
379
+ When: Validating Headers
380
+ Then: Do not raise an exception.
381
+ """
382
+ from .conftest import BaseSpec214DatasetCaseSensitive, get_fits_object
383
+
384
+ fits_file = get_fits_object(
385
+ object_type="fits", tmpdir=tmp_path, ds=BaseSpec214DatasetCaseSensitive()
386
+ )
387
+ with fits.open(fits_file) as hdul:
388
+ plain_header = hdul[0].header
389
+ data = hdul[0].data
390
+
391
+ # Generate a header with the compression keys
392
+ hdu = fits.CompImageHDU(header=plain_header, data=data)
393
+ # Format this header
394
+ formatted_header = reformat_spec214_header(hdu._header)
395
+ # Make a new HDU with the formatted header
396
+ hdul = fits.HDUList(
397
+ [fits.PrimaryHDU(), fits.CompImageHDU(header=formatted_header, data=hdu.data)]
398
+ )
399
+ hdul.writeto(tmp_path / "test.fits")
400
+
401
+ # Validate the new formatted header
402
+ spec214_validator.validate(tmp_path / "test.fits")
@@ -0,0 +1,211 @@
1
+ from io import BytesIO
2
+ from pathlib import Path
3
+
4
+ import numpy as np
5
+ import pytest
6
+
7
+ from dkist_header_validator import spec214_l0_validator
8
+ from dkist_header_validator import spec214_validator
9
+ from dkist_header_validator import Spec214ValidationException
10
+ from dkist_header_validator.exceptions import ReturnTypeException
11
+ from dkist_header_validator.exceptions import ValidationException
12
+
13
+
14
+ def test_spec214l0_return_BytesIO_without_data(valid_spec_214l0_no_file):
15
+ """
16
+ Validates a fits header against the SPEC-0214 schema
17
+ Given: A valid SPEC-0214 fits header
18
+ When: Validating headers
19
+ Then: Raise return type exception
20
+ """
21
+ # raises exception on failure
22
+ with pytest.raises(ReturnTypeException):
23
+ result = spec214_l0_validator.validate(
24
+ valid_spec_214l0_no_file, return_type=BytesIO, extra=False
25
+ )
26
+ assert isinstance(result, BytesIO)
27
+
28
+
29
+ def test_spec214_return_BytesIO_without_data(valid_spec_214_no_file):
30
+ """
31
+ Validates a fits header against the SPEC-0214 schema
32
+ Given: A valid SPEC-0214 fits header
33
+ When: Validating headers
34
+ Then: Raise return type exception
35
+ """
36
+ # raises exception on failure
37
+ with pytest.raises(ReturnTypeException):
38
+ result = spec214_validator.validate(
39
+ valid_spec_214_no_file, return_type=BytesIO, extra=False
40
+ )
41
+ assert isinstance(result, BytesIO)
42
+
43
+
44
+ def test_spec214l0_return_file_without_data(valid_spec_214l0_no_file):
45
+ """
46
+ Validates a fits header against the SPEC-0214 schema
47
+ Given: A valid SPEC-0214 fits header
48
+ When: Validating headers
49
+ Then: raise a return type exception
50
+ """
51
+ # raises exception on failure
52
+ with pytest.raises(ReturnTypeException):
53
+ result = spec214_l0_validator.validate(
54
+ valid_spec_214l0_no_file, return_type=Path, extra=False
55
+ )
56
+ assert isinstance(result, Path)
57
+
58
+
59
+ def test_spec214_return_file_without_data(valid_spec_214_no_file):
60
+ """
61
+ Validates a fits header against the SPEC-0214 schema
62
+ Given: A valid SPEC-0214 fits header
63
+ When: Validating headers
64
+ Then: raise a return type exception
65
+ """
66
+ # raises exception on failure
67
+ with pytest.raises(ReturnTypeException):
68
+ result = spec214_validator.validate(valid_spec_214_no_file, return_type=Path, extra=False)
69
+ assert isinstance(result, Path)
70
+
71
+
72
+ def test_spec214l0_invalid_headers(invalid_spec_214l0_object):
73
+ """
74
+ Validates an invalid fits header against the SPEC-214 schema
75
+ Given: A invalid SPEC-214 fits header
76
+ When: Validating headers
77
+ Then: raise a Spec214ValidationException
78
+ """
79
+
80
+ with pytest.raises(Spec214ValidationException):
81
+ spec214_l0_validator.validate(invalid_spec_214l0_object)
82
+
83
+
84
+ def test_spec214_invalid_headers(invalid_spec_214_object):
85
+ """
86
+ Validates an invalid fits header against the SPEC-214 schema
87
+ Given: A invalid SPEC-214 fits header
88
+ When: Validating headers
89
+ Then: raise a Spec214ValidationException
90
+ """
91
+
92
+ with pytest.raises(Spec214ValidationException):
93
+ spec214_validator.validate(invalid_spec_214_object)
94
+
95
+
96
+ @pytest.mark.parametrize("instrument", ["cryo-nirsp", "dlnirsp", "vbi", "visp", "vtf"])
97
+ def test_spec214l0_instrument_required_key_missing(invalid_instrument_table_spec_214l0_object):
98
+ """
99
+ Given: Headers from a specific instrument, but with one of the required header keys removed
100
+ When: Validating headers
101
+ Then: The correct Error is raised
102
+ """
103
+ fits_object, missing_key = invalid_instrument_table_spec_214l0_object
104
+ with pytest.raises(
105
+ Spec214ValidationException, match=f"'{missing_key}': 'required key not provided"
106
+ ):
107
+ spec214_l0_validator.validate(fits_object)
108
+
109
+
110
+ @pytest.fixture(scope="module")
111
+ def invalid_file_params(tmpdir_factory):
112
+ """
113
+ Create a dict of invalid file params to be used in failing
114
+ tests below.
115
+ """
116
+ temp_dir = tmpdir_factory.mktemp("invalid_file_params_temp")
117
+ non_existent_file_name = temp_dir.join("tmp_fits_file.fits")
118
+ non_fits_file_name = temp_dir.join("tmp_this_is_not_a_fits_file.dat")
119
+ temp_array = np.ones(1, dtype=np.int16)
120
+ temp_array.tofile(str(non_fits_file_name))
121
+ yield {"file not found": non_existent_file_name, "file_not_fits": non_fits_file_name}
122
+
123
+
124
+ @pytest.fixture(scope="function", params=["file not found", "file_not_fits"])
125
+ def invalid_file_param(request, invalid_file_params):
126
+ yield invalid_file_params[request.param]
127
+
128
+
129
+ def test_file_errors(invalid_file_param):
130
+ """
131
+ Validates an invalid file spec
132
+ Given: A invalid file specification: non-existent file or non-fits file
133
+ When: Validating headers
134
+ Then: raise a Spec214ValidationException
135
+ """
136
+
137
+ with pytest.raises(ValidationException):
138
+ spec214_l0_validator.validate(invalid_file_param)
139
+
140
+
141
+ def test_invalid_compressed_spec214l0(invalid_spec_214l0_compressed):
142
+ """
143
+ Validates an invalid compressed spec214 compliant file
144
+ Given: An invalid compressed SPEC-0214 file
145
+ When: Validating headers
146
+ Then: Catch a warning and raise an exception
147
+ """
148
+ with pytest.raises(Spec214ValidationException):
149
+ spec214_l0_validator.validate(invalid_spec_214l0_compressed)
150
+
151
+
152
+ def test_invalid_compressed_spec214(invalid_spec_214_compressed):
153
+ """
154
+ Validates an invalid compressed spec214 compliant file
155
+ Given: An invalid compressed SPEC-0214 file
156
+ When: Validating headers
157
+ Then: Catch a warning and raise an exception
158
+ """
159
+ with pytest.raises(Spec214ValidationException):
160
+ spec214_validator.validate(invalid_spec_214_compressed)
161
+
162
+
163
+ def test_validatel0_toomanyHDUs(valid_spec_214_l0_too_many_HDUs):
164
+ """
165
+ Validates headers with too many (more than 2) HDUs
166
+ Given: A valid SPEC-214 file or HDUList with more than two headers
167
+ When: Validating headers
168
+ Then: Raise an exception
169
+ """
170
+ # raises exception on failure
171
+ with pytest.raises(ValidationException):
172
+ spec214_l0_validator.validate(valid_spec_214_l0_too_many_HDUs)
173
+
174
+
175
+ def test_validate_toomanyHDUs(valid_spec_214_too_many_HDUs):
176
+ """
177
+ Validates headers with too many (more than 2) HDUs
178
+ Given: A valid SPEC-214 file or HDUList with more than two headers
179
+ When: Validating headers
180
+ Then: Raise an exception
181
+ """
182
+ # raises exception on failure
183
+ with pytest.raises(ValidationException):
184
+ spec214_validator.validate(valid_spec_214_too_many_HDUs)
185
+
186
+
187
+ def test_polarimetric_required_key_missing(invalid_polarimetric_spec_214_object):
188
+ """
189
+ Given: Polarimetric headers with a missing `polarimetric_required` key
190
+ When: Validating headers
191
+ Then: The correct Error is raised
192
+ """
193
+ with pytest.raises(
194
+ Spec214ValidationException,
195
+ match="'POL_SENS': 'required key not provided. Required keyword not present'",
196
+ ):
197
+ spec214_validator.validate(invalid_polarimetric_spec_214_object)
198
+
199
+
200
+ @pytest.mark.parametrize("instrument", ["cryo-nirsp", "dlnirsp", "vbi", "visp", "vtf"])
201
+ def test_instrument_required_key_missing(invalid_instrument_table_spec_214_object):
202
+ """
203
+ Given: Headers from a specific instrument, but with one of the required header keys removed
204
+ When: Validating headers
205
+ Then: The correct Error is raised
206
+ """
207
+ fits_object, missing_key = invalid_instrument_table_spec_214_object
208
+ with pytest.raises(
209
+ Spec214ValidationException, match=f"'{missing_key}': 'required key not provided"
210
+ ):
211
+ spec214_validator.validate(fits_object)