ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
testMerge.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq_dpm_merge_test
4 * @copyright ESO - European Southern Observatory
5 */
6#include "merge.hpp"
7
8#include <fmt/format.h>
9#include <gmock/gmock.h>
10#include <gtest/gtest.h>
11#include <log4cplus/loggingmacros.h>
12
13#include <daq/fits/cfitsio.hpp>
14
15using namespace ::testing;
16
17namespace daq::dpm::merge {
18
20 MOCK_METHOD(void, PostAlert, (std::string const& id, std::string const& message), (override));
21};
22
25};
26
28 MOCK_METHOD(void, SortKeywords, (std::vector<fits::LiteralKeyword> & keywords), ());
29};
30
33 Process,
35 (const, override));
36};
37
38/**
39 * Fixture that sets up a in-place target FITS file with standard HDU keywords
40 * - SIMPLE
41 * - BITPIX
42 * - NAXIS
43 * - EXTEND
44 */
45class TestMergeKeywords : public Test {
46public:
48 : Test()
49 , m_dry_run(false)
53 , m_logger(log4cplus::Logger::getInstance("test.dpm.merge"))
55 , m_params{"arcfile.fits", "origfile.fits"}
56 , m_target_buffer(4096u)
57 , m_target("target",
58 "fakefile.fits",
59 std::nullopt,
60 std::make_unique<StandardKeywordRuleProcessor>(),
61 std::move(m_target_buffer).GetOwnedFile()) {
62 }
63
64 void SetUp() override {
66
67 // clang-format off
68 ON_CALL(m_mock_formatter, FormatKeyword(_))
69 .WillByDefault(
70 Invoke([](auto const& kw) {
71 return fits::Format(kw);
72 }
73 )
74 );
75 // clang-format on
76 }
77 void TearDown() override {
78 }
79 void ExpectStandardKeywords(std::vector<fits::LiteralKeyword>& kws) {
80 auto datasum = kws.back();
81 kws.pop_back();
82 auto checksum = kws.back();
83 kws.pop_back();
84 EXPECT_EQ("DATASUM", datasum.GetName().name);
85 EXPECT_EQ("CHECKSUM", checksum.GetName().name);
86
87 auto arcfile = kws.back();
88 kws.pop_back();
89 auto origfile = kws.back();
90 kws.pop_back();
91
92 EXPECT_EQ("ORIGFILE", origfile.GetName().name);
93 EXPECT_EQ(fmt::format("'{}'", m_params.origfile), origfile.GetComponents().value);
94 EXPECT_EQ("ARCFILE", arcfile.GetName().name);
95 EXPECT_EQ(fmt::format("'{}'", m_params.arcfile), arcfile.GetComponents().value);
96 }
97
102
103 log4cplus::Logger m_logger;
104
108
110};
111
112TEST_F(TestMergeKeywords, MergeEmptyStillSortsKeywords) {
113 // Setup
114 std::vector<SourceTypes> sources;
115
116 auto before = fits::ReadKeywords(m_target.GetFitsFile(), 1);
117 EXPECT_CALL(m_mock_formatter, FormatKeyword(_)).WillRepeatedly(DoDefault());
118 EXPECT_CALL(m_mock_sorter, SortKeywords(_));
119
120 // Test
121 Merge(m_ops, m_params, m_target, sources, m_dry_run);
122 auto after = fits::ReadKeywords(m_target.GetFitsFile(), 1);
123 ASSERT_EQ(after.size(), before.size() + 4u)
124 << "4 keywords should be added by DPM (2x checksum, ARCFILE, ORIFILE)";
125 ExpectStandardKeywords(after);
126 EXPECT_THAT(after, ContainerEq(before));
127}
128
129/** Test that primary HDU keywords are sorted */
130TEST_F(TestMergeKeywords, NoSourceStillSortsPrimaryHdu) {
131 // Setup
132 std::vector<SourceTypes> sources;
133 auto before = fits::ReadKeywords(m_target.GetFitsFile(), 1);
134
135 EXPECT_CALL(m_mock_formatter, FormatKeyword(_)).WillRepeatedly(DoDefault());
136 EXPECT_CALL(m_mock_sorter, SortKeywords(_));
137
138 // Test
139 Merge(m_ops, m_params, m_target, sources, m_dry_run);
140 auto after = fits::ReadKeywords(m_target.GetFitsFile(), 1);
141 ASSERT_EQ(after.size(), before.size() + 4u)
142 << "4 keywords should be added by DPM (2x checksum, ARCFILE, ORIFILE)";
143 ExpectStandardKeywords(after);
144
145 EXPECT_THAT(after, ContainerEq(before));
146}
147
148/** Test merging some keywords from a single source */
149TEST_F(TestMergeKeywords, MergeSingleKeywordList) {
150 // Setup
151 std::vector<SourceTypes> sources;
152 auto kw1 = fits::LiteralKeyword("HIERARCH ESO UNKN A = T / Comment");
153 auto kw2 = fits::LiteralKeyword("HIERARCH ESO UNKN B = T / Comment");
154 fits::KeywordVector kws = {kw1, kw2};
155
156 sources.emplace_back(std::in_place_type<FitsKeywordsSource>,
157 "tcs",
158 kws,
159 std::nullopt,
160 std::make_unique<StandardKeywordRuleProcessor>());
161 auto expected_kws = fits::ReadKeywords(m_target.GetFitsFile(), 1);
162 expected_kws.push_back(kw1);
163 expected_kws.push_back(kw2);
164
165 EXPECT_CALL(m_mock_formatter, FormatKeyword(_)).WillRepeatedly(DoDefault());
166 EXPECT_CALL(m_mock_sorter, SortKeywords(_));
167
168 // Test
169 Merge(m_ops, m_params, m_target, sources, m_dry_run);
170
171 auto after = fits::ReadKeywords(m_target.GetFitsFile(), 1);
172 // Two checksum keywords are added
173 ASSERT_EQ(after.size(), expected_kws.size() + 4u);
174 ExpectStandardKeywords(after);
175
176 EXPECT_THAT(after, ContainerEq(expected_kws));
177}
178
179TEST_F(TestMergeKeywords, MergeFailsIfTransformsCauseInvalidKeyword) {
180 // Setup
181 std::vector<SourceTypes> sources;
182 auto kw1 = fits::LiteralKeyword("HIERARCH ESO UNKN A = T / Comment");
183 fits::KeywordVector kws = {kw1};
184
185 auto kw_processor = std::make_unique<MockKeywordProcessor>();
186 EXPECT_CALL(*kw_processor, Process(_, _))
187 .WillRepeatedly(Throw(std::invalid_argument("keyword too long")));
188 sources.emplace_back(
189 std::in_place_type<FitsKeywordsSource>, "tcs", kws, std::nullopt, std::move(kw_processor));
190 auto expected_kws = fits::ReadKeywords(m_target.GetFitsFile(), 1);
191 expected_kws.push_back(kw1);
192
193 EXPECT_CALL(m_mock_formatter, FormatKeyword(_)).Times(0);
194 EXPECT_CALL(m_mock_sorter, SortKeywords(_)).Times(0);
195
196 // Test
197 EXPECT_THROW(Merge(m_ops, m_params, m_target, sources, m_dry_run), std::runtime_error);
198}
199
200} // namespace daq::dpm::merge
Contains functions and data structures related to cfitsio.
Interface for keyword rule processors.
Definition: keywordRule.hpp:18
virtual fits::KeywordVector Process(fits::KeywordVector const &, DefaultRule default_rule) const =0
virtual fits::LiteralKeyword FormatKeyword(fits::KeywordVariant const &keyword)=0
Format keyword.
virtual void SortKeywords(std::vector< fits::LiteralKeyword > &keywords)=0
Sort keywords.
Interface to reporter (implementations exist for JSON or human readable)
Definition: merge.hpp:26
virtual void PostAlert(std::string const &id, std::string const &message)=0
Post event.
Fixture that sets up a in-place target FITS file with standard HDU keywords.
Definition: testMerge.cpp:45
void ExpectStandardKeywords(std::vector< fits::LiteralKeyword > &kws)
Definition: testMerge.cpp:79
fits::MemoryFitsFile m_target_buffer
Definition: testMerge.cpp:107
Represents the literal 80-character FITS keyword record.
Definition: keyword.hpp:129
In-memory FITS file.
Definition: cfitsio.hpp:44
std::string arcfile
Definition: merge.hpp:101
std::string origfile
Definition: merge.hpp:102
void Merge(Operations ops, Params const &params, TargetSource &target, std::vector< SourceTypes > const &sources, bool dry_run)
Merge sources into the target target.
Definition: merge.cpp:351
TEST_F(TestMergeKeywords, MergeEmptyStillSortsKeywords)
Definition: testMerge.cpp:112
LiteralKeyword Format(KeywordVariant const &keyword)
Definition: keyword.cpp:782
void InitPrimaryHduNoImage(fitsfile *ptr)
Initializes an empty FITS file with a primary HDU.
Definition: cfitsio.cpp:144
std::vector< KeywordVariant > KeywordVector
Vector of keywords.
Definition: keyword.hpp:423
std::variant< ValueKeyword, EsoKeyword, LiteralKeyword > KeywordVariant
The different variants of keywords that are supported.
Definition: keyword.hpp:409
std::vector< LiteralKeyword > ReadKeywords(fitsfile *ptr, int hdu_num)
Read keywords from HDU identifed by absolute position hdu_num.
Definition: cfitsio.cpp:200
MOCK_METHOD(fits::LiteralKeyword, FormatKeyword,(fits::KeywordVariant const &keyword),())
MOCK_METHOD(fits::KeywordVector, Process,(fits::KeywordVector const &, KeywordRuleProcessor::DefaultRule),(const, override))
MOCK_METHOD(void, PostAlert,(std::string const &id, std::string const &message),(override))
MOCK_METHOD(void, SortKeywords,(std::vector< fits::LiteralKeyword > &keywords),())
EXPECT_EQ(meta.rr_uri, "zpb.rr://meta")
ASSERT_EQ(meta.keyword_rules.size(), 1u)