Belle II Software  release-08-01-10
conditions_metadataprovider.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <framework/database/MetadataProvider.h>
10 #include <framework/logging/Logger.h>
11 #include <framework/utilities/testhelpers/Fixtures.h>
12 #include <gtest/gtest.h>
13 
14 using namespace Belle2;
15 using namespace Conditions;
16 
17 namespace {
20  class TestMetadataProvider final: public MetadataProvider {
22  std::vector<PayloadMetadata> m_testpayloads;
23  public:
25  explicit TestMetadataProvider(const std::vector<PayloadMetadata>& payloads): m_testpayloads(payloads) {}
29  std::string getGlobaltagStatus(const std::string& name) override
30  {
31  if (name.empty()) {
32  B2ERROR("This globaltag is missing" << LogVar("globaltag", "") << LogVar("error", "missing"));
33  }
34  // later we want to test payloads from different tags so if the tagname starts with "tag" assume valid;
35  if (name.substr(0, 3) == "tag") {
36  return "PUBLISHED";
37  }
38  // otherwise just treat the tag name as its status to allow testing tag states
39  return name;
40  }
44  bool updatePayloads(const std::string& globaltag, int exp, int run) override
45  {
46  IntervalOfValidity iov(exp, run, exp, run);
47  int count{0};
48  for (auto p : m_testpayloads) {
49  if (p.globaltag == globaltag and p.iov.contains(iov)) {
50  addPayload(std::move(p), "testprovider");
51  ++count;
52  }
53  }
54  return count > 0;
55  }
56  };
57 
59  using MetadataProviderTest = TestHelpers::LogMessageTest;
60 
62  TEST_F(MetadataProviderTest, tagstates)
63  {
64  TestMetadataProvider provider({});
65  EXPECT_TRUE(provider.setTags({"TESTING", "VALIDATED", "RUNNING", "PUBLISHED"}));
66  EXPECT_FALSE(provider.setTags({"OPEN"}));
67  // this will also conveniently fail if the first expect did produce an error
68  expectErrorWithVariables({{"globaltag", "OPEN"}, {"status", "OPEN"}});
69  EXPECT_FALSE(provider.setTags({"INVALID"}));
70  expectErrorWithVariables({{"globaltag", "INVALID"}, {"status", "INVALID"}});
71  // also fail if the OPEN one is somewhere in the middle
72  EXPECT_FALSE(provider.setTags({"TESTING", "VALIDATED", "OPEN", "RUNNING", "PUBLISHED"}));
73  expectErrorWithVariables({{"globaltag", "OPEN"}, {"status", "OPEN"}});
74  provider.setUsableTagStates({"OPEN", "INVALID"});
75  EXPECT_TRUE(provider.setTags({"OPEN"}));
76  EXPECT_FALSE(provider.setTags({"INVALID"}));
77  expectErrorWithVariables({{"globaltag", "INVALID"}, {"status", "INVALID"}});
78  EXPECT_FALSE(provider.setTags({""}));
79  expectErrorWithVariables({{"globaltag", ""}, {"error", "missing"}});
80  }
81 
83  TEST_F(MetadataProviderTest, exception)
84  {
85  TestMetadataProvider provider({});
86  std::vector<PayloadMetadata> query{PayloadMetadata{"A"}};
87  ASSERT_TRUE(provider.setTags({"tag1"}));
88  ASSERT_THROW(provider.getPayloads(0, 0, query), std::runtime_error);
89  }
90 
93  TEST_F(MetadataProviderTest, onlyfillneeded)
94  {
95  TestMetadataProvider provider({
96  //name, tag, ignore, ignore, ignore, exp, run, exp, run, revision
97  PayloadMetadata{"A", "tag1", "", "", "", 0, 0, -1, -1, 2},
98  });
99  std::vector<PayloadMetadata> query{PayloadMetadata{"A"}, PayloadMetadata{"B"}};
100  // A is in the tag but already set. B isn't in the tag but already set so no error
101  query[0].revision = 1;
102  query[1].revision = 1;
103  ASSERT_TRUE(provider.setTags({"tag1"}));
104  ASSERT_TRUE(provider.getPayloads(0, 0, query));
105  // so no log messages please
106  expectMessage(LogConfig::c_Error, 0, true);
107  // and everything as it was
108  EXPECT_EQ(query[0].name, "A");
109  EXPECT_EQ(query[0].revision, 1);
110  EXPECT_EQ(query[1].name, "B");
111  EXPECT_EQ(query[1].revision, 1);
112  }
113 
115  TEST_F(MetadataProviderTest, payloads)
116  {
117  TestMetadataProvider provider({
118  //name, tag, ignore, ignore, ignore, exp, run, exp, run, revision
119  PayloadMetadata{"A", "tag1", "", "", "", 0, 0, -1, -1, 1},
120  PayloadMetadata{"A", "tag1", "", "", "", 1, 0, 1, 10, 3},
121  PayloadMetadata{"A", "tag1", "", "", "", 1, 0, 1, 10, 2},
122  PayloadMetadata{"B", "tag1", "", "", "", 1, 0, 1, 10, 1},
123  });
124  std::vector<PayloadMetadata> query{PayloadMetadata{"A"}, PayloadMetadata{"B"}};
125  ASSERT_TRUE(provider.setTags({"tag1"}));
126  ASSERT_FALSE(provider.getPayloads(0, 0, query));
127  expectErrorWithVariables({{"globaltags", "tag1"}, {"name", "B"}, {"experiment", "0"}, {"run", "0"}});
128  EXPECT_EQ(query[0].revision, 1);
129  EXPECT_EQ(query[1].revision, 0);
130  // try for exp 1, there should be something for both payloads and A should be in revision 3.
131  // Howewer metadata provider only fills missing info so we need new query structure
132  query = {PayloadMetadata{"A"}, PayloadMetadata{"B"}};
133  EXPECT_TRUE(provider.getPayloads(1, 0, query));
134  EXPECT_EQ(query[0].revision, 3);
135  EXPECT_EQ(query[1].revision, 1);
136  // and back to exp 0 and we want the same result as before.
137  query = {PayloadMetadata{"A"}, PayloadMetadata{"B"}};
138  EXPECT_FALSE(provider.getPayloads(0, 0, query));
139  expectErrorWithVariables({{"globaltags", "tag1"}, {"name", "B"}, {"experiment", "0"}, {"run", "0"}});
140  EXPECT_EQ(query[0].revision, 1);
141  EXPECT_EQ(query[1].revision, 0);
142  // so let's try this again but mark B as optional. Same result but no error
143  query = {PayloadMetadata{"A"}, PayloadMetadata{"B", false}};
144  EXPECT_TRUE(provider.getPayloads(0, 0, query));
145  EXPECT_EQ(query[0].revision, 1);
146  EXPECT_EQ(query[1].revision, 0);
147  EXPECT_EQ(query[1].required, false);
148  }
149 
150  TEST_F(MetadataProviderTest, payloads_multiple_gt)
151  {
152  TestMetadataProvider provider({
153  //name, tag, ignore, ignore, ignore, exp, run, exp, run, revision
154  PayloadMetadata{"A", "tag1", "", "", "", 0, 0, -1, -1, 1},
155  PayloadMetadata{"A", "tag2", "", "", "", 0, 0, -1, -1, 2},
156  PayloadMetadata{"B", "tag2", "", "", "", 0, 0, -1, -1, 2},
157  });
158  // In this case A should be taken from tag1 even if it exists in tag2.
159  // But B can only come from tag2
160  ASSERT_TRUE(provider.setTags({"tag1", "tag2"}));
161  std::vector<PayloadMetadata> query = {PayloadMetadata{"A"}, PayloadMetadata{"B"}};
162  EXPECT_TRUE(provider.getPayloads(1, 0, query));
163  EXPECT_EQ(query[0].revision, 1);
164  EXPECT_EQ(query[1].revision, 2);
165  EXPECT_EQ(query[0].globaltag, "tag1");
166  EXPECT_EQ(query[1].globaltag, "tag2");
167  }
168 }
Base class for a payload metadata provider.
A class that describes the interval of experiments/runs for which an object in the database is valid.
@ c_Error
Error: for things that went wrong and have to be fixed.
Definition: LogConfig.h:30
Test fixture to be able to check the contents and types of emitted log messages in detail.
Definition: Fixtures.h:23
Class to store variables with their name which were sent to the logging service.
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
Abstract base class for different kinds of events.
Simple struct to group all information necessary for a single payload.