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