Coverage for tests/test_translate_header.py: 13%
82 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-06 03:48 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-06 03:48 -0700
1# This file is part of astro_metadata_translator.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the LICENSE file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12import io
13import logging
14import os.path
15import unittest
17from astro_metadata_translator.bin.translate import translate_or_dump_headers
19TESTDIR = os.path.abspath(os.path.dirname(__file__))
20TESTDATA = os.path.join(TESTDIR, "data")
23class TestTranslateHeader(unittest.TestCase):
24 """Test that the astrometadata translate and dump logic works."""
26 def _readlines(self, stream):
27 """Return the lines written to the stream.
29 Parameters
30 ----------
31 stream : `io.StringIO`
32 The stream to read.
34 Returns
35 -------
36 lines : `list` of `str`
37 The lines contained in the stream.
38 """
39 stream.seek(0)
40 return [ll.rstrip() for ll in stream.readlines()]
42 def test_translate_header(self):
43 """Translate some header files."""
44 with io.StringIO() as out:
45 with self.assertLogs(level=logging.INFO) as cm:
46 okay, failed = translate_or_dump_headers(
47 [TESTDATA],
48 r"^fitsheader.*yaml$",
49 0,
50 False,
51 outstream=out,
52 output_mode="none",
53 )
54 self.assertEqual(self._readlines(out), [])
55 lines = [r.getMessage() for r in cm.records]
56 self.assertEqual(len(lines), 10)
57 self.assertTrue(lines[0].startswith("Analyzing"), f"Line: '{lines[0]}'")
59 self.assertEqual(len(okay), 10)
60 self.assertEqual(len(failed), 0)
62 def test_translate_header_table(self):
63 """Translate some header files with table output."""
64 with io.StringIO() as out:
65 with self.assertLogs(level=logging.WARNING) as cm:
66 logging.getLogger().warning("False warning")
67 okay, failed = translate_or_dump_headers(
68 [TESTDATA],
69 r"^fitsheader.*yaml$",
70 0,
71 False,
72 outstream=out,
73 )
74 output = self._readlines(out)
75 self.assertTrue(output[0].startswith("ObsId"))
76 self.assertTrue(output[1].startswith("-------"))
77 self.assertEqual(len(output), 12)
78 self.assertEqual(len(cm.output), 1) # Should only have the warning this test made.
80 self.assertEqual(len(okay), 10)
81 self.assertEqual(len(failed), 0)
83 def test_translate_header_fails(self):
84 """Translate some header files that fail."""
85 with io.StringIO() as out:
86 with self.assertLogs(level=logging.INFO) as cm:
87 okay, failed = translate_or_dump_headers(
88 [TESTDATA], r"^.*yaml$", 0, False, outstream=out, output_mode="none"
89 )
91 out_lines = self._readlines(out)
92 self.assertEqual(len(out_lines), len(failed))
93 self.assertTrue(out_lines[0].startswith("Failure processing"), f"Line: '{out_lines[0]}'")
94 self.assertIn("not a mapping", out_lines[0], f"Line: '{out_lines[0]}'")
96 err_lines = [r.getMessage() for r in cm.records]
97 self.assertEqual(len(err_lines), 13) # The number of files analyzed
98 self.assertTrue(err_lines[0].startswith("Analyzing"), f"Line: '{err_lines[0]}'")
100 # Form message to issue if the test fails.
101 newline = "\n" # f-string can not accept \ in string.
102 msg = f"""Converted successfully:
103{newline.join(okay)}
104Failed conversions:
105{newline.join(failed)}
106Standard output:
107{newline.join(out_lines)}
108"""
109 self.assertEqual((len(okay), len(failed)), (10, 3), msg=msg)
111 def test_translate_header_traceback(self):
112 """Translate some header files that fail and trigger traceback."""
113 with io.StringIO() as out:
114 with self.assertLogs(level=logging.INFO) as cm:
115 okay, failed = translate_or_dump_headers(
116 [TESTDATA], r"^.*yaml$", 0, True, outstream=out, output_mode="none"
117 )
119 lines = self._readlines(out)
120 self.assertGreaterEqual(len(lines), 22, "\n".join(lines))
121 self.assertTrue(lines[0].startswith("Traceback"), f"Line '{lines[0]}'")
123 lines = [r.getMessage() for r in cm.records]
124 self.assertGreaterEqual(len(lines), 13, "\n".join(lines))
125 self.assertTrue(lines[0].startswith("Analyzing"), f"Line: '{lines[0]}'")
127 self.assertEqual(len(okay), 10)
128 self.assertEqual(len(failed), 3)
130 def test_translate_header_dump(self):
131 """Check that a header is dumped."""
132 with io.StringIO() as out:
133 with self.assertLogs(level=logging.INFO) as cm:
134 okay, failed = translate_or_dump_headers(
135 [os.path.join(TESTDATA, "fitsheader-decam.yaml")],
136 r"^fitsheader.*yaml$",
137 0,
138 False,
139 outstream=out,
140 output_mode="yaml",
141 )
143 lines = self._readlines(out)
144 # Look for a DECam header in the output
145 header = "\n".join(lines)
146 self.assertIn("DTINSTRU", header)
148 lines = [r.getMessage() for r in cm.records]
149 self.assertEqual(len(lines), 1)
150 self.assertTrue(lines[0], "Analyzing tests/data/fitsheader-decam.yaml...")
152 self.assertEqual(len(okay), 1)
153 self.assertEqual(len(failed), 0)
155 def test_translate_header_loud(self):
156 """Check that ObservationInfo content is displayed."""
157 with io.StringIO() as out:
158 with self.assertLogs(level=logging.INFO) as cm:
159 okay, failed = translate_or_dump_headers(
160 [os.path.join(TESTDATA, "fitsheader-decam.yaml")],
161 r"^fitsheader.*yaml$",
162 0,
163 False,
164 outstream=out,
165 output_mode="verbose",
166 )
168 lines = self._readlines(out)
169 # Look for the translated DECam header in the output
170 self.assertEqual(lines[2], "datetime_begin: 2013-09-01T06:02:55.754")
172 lines = [r.getMessage() for r in cm.records]
173 self.assertEqual(len(lines), 1)
174 self.assertTrue(lines[0], "Analyzing tests/data/fitsheader-decam.yaml...")
176 self.assertEqual(len(okay), 1)
177 self.assertEqual(len(failed), 0)
180if __name__ == "__main__":
181 unittest.main()