xref: /openbmc/bios-bmc-smm-error-logger/test/rde_dictionary_manager_test.cpp (revision a1a69f19011cdbcf59c80a0a6996c920d469882c)
1*a1a69f19Skasunath #include "rde/rde_dictionary_manager.hpp"
2*a1a69f19Skasunath 
3*a1a69f19Skasunath #include <cstring>
4*a1a69f19Skasunath #include <memory>
5*a1a69f19Skasunath #include <optional>
6*a1a69f19Skasunath #include <span>
7*a1a69f19Skasunath 
8*a1a69f19Skasunath #include <gmock/gmock-matchers.h>
9*a1a69f19Skasunath #include <gmock/gmock.h>
10*a1a69f19Skasunath #include <gtest/gtest.h>
11*a1a69f19Skasunath 
12*a1a69f19Skasunath namespace bios_bmc_smm_error_logger
13*a1a69f19Skasunath {
14*a1a69f19Skasunath namespace rde
15*a1a69f19Skasunath {
16*a1a69f19Skasunath 
17*a1a69f19Skasunath constexpr std::array<uint8_t, 132> dummyDictionary1{
18*a1a69f19Skasunath     {0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x0,  0x0,
19*a1a69f19Skasunath      0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,  0x0,  0x0,  0x0,  0x0,
20*a1a69f19Skasunath      0x0,  0x16, 0x0,  0x5,  0x0,  0xc,  0x84, 0x0,  0x14, 0x0,  0x0,  0x48,
21*a1a69f19Skasunath      0x0,  0x1,  0x0,  0x13, 0x90, 0x0,  0x56, 0x1,  0x0,  0x0,  0x0,  0x0,
22*a1a69f19Skasunath      0x0,  0x3,  0xa3, 0x0,  0x74, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16,
23*a1a69f19Skasunath      0xa6, 0x0,  0x34, 0x3,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0xbc, 0x0,
24*a1a69f19Skasunath      0x64, 0x4,  0x0,  0x0,  0x0,  0x0,  0x0,  0x13, 0xd2, 0x0,  0x0,  0x0,
25*a1a69f19Skasunath      0x0,  0x52, 0x0,  0x2,  0x0,  0x0,  0x0,  0x0,  0x74, 0x0,  0x0,  0x0,
26*a1a69f19Skasunath      0x0,  0x0,  0x0,  0xf,  0xe5, 0x0,  0x46, 0x1,  0x0,  0x66, 0x0,  0x3,
27*a1a69f19Skasunath      0x0,  0xb,  0xf4, 0x0,  0x50, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x9,
28*a1a69f19Skasunath      0xff, 0x0,  0x50, 0x1,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0x8,  0x1}};
29*a1a69f19Skasunath 
30*a1a69f19Skasunath constexpr std::array<uint8_t, 14> dummyDictionary2{
31*a1a69f19Skasunath     {0x65, 0x0, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x41, 0x72, 0x72, 0x61, 0x79,
32*a1a69f19Skasunath      0x50, 0x72}};
33*a1a69f19Skasunath 
34*a1a69f19Skasunath class RdeDictionaryManagerTest : public ::testing::Test
35*a1a69f19Skasunath {
36*a1a69f19Skasunath   protected:
37*a1a69f19Skasunath     uint32_t resourceId = 1;
38*a1a69f19Skasunath     DictionaryManager dm;
39*a1a69f19Skasunath };
40*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionarySetTest)41*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionarySetTest)
42*a1a69f19Skasunath {
43*a1a69f19Skasunath     // Add a single dictionary.
44*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
45*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
46*a1a69f19Skasunath 
47*a1a69f19Skasunath     // Mark the dictionary as a valid dictionary.
48*a1a69f19Skasunath     dm.markDataComplete(resourceId);
49*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
50*a1a69f19Skasunath 
51*a1a69f19Skasunath     // Request the dictionary back and verify the data.
52*a1a69f19Skasunath     auto dataOrErr = dm.getDictionary(resourceId);
53*a1a69f19Skasunath     EXPECT_TRUE(dataOrErr);
54*a1a69f19Skasunath     EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary1.size());
55*a1a69f19Skasunath     EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary1.data(),
56*a1a69f19Skasunath                        dummyDictionary1.size()),
57*a1a69f19Skasunath                 0);
58*a1a69f19Skasunath }
59*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryNotSetTest)60*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryNotSetTest)
61*a1a69f19Skasunath {
62*a1a69f19Skasunath     // Add a single dictionary.
63*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
64*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
65*a1a69f19Skasunath     // Request the dictionary back without marking it complete. Request should
66*a1a69f19Skasunath     // fail.
67*a1a69f19Skasunath     EXPECT_FALSE(dm.getDictionary(resourceId));
68*a1a69f19Skasunath }
69*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryMultiSetTest)70*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryMultiSetTest)
71*a1a69f19Skasunath {
72*a1a69f19Skasunath     // Creates a dictionary
73*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
74*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
75*a1a69f19Skasunath     dm.markDataComplete(resourceId);
76*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
77*a1a69f19Skasunath 
78*a1a69f19Skasunath     // Creates a second dictionary.
79*a1a69f19Skasunath     dm.startDictionaryEntry(annotationResourceId, std::span(dummyDictionary2));
80*a1a69f19Skasunath     dm.markDataComplete(annotationResourceId);
81*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 2);
82*a1a69f19Skasunath 
83*a1a69f19Skasunath     auto data1OrErr = dm.getDictionary(resourceId);
84*a1a69f19Skasunath     EXPECT_TRUE(data1OrErr);
85*a1a69f19Skasunath     EXPECT_THAT((*data1OrErr).size_bytes(), dummyDictionary1.size());
86*a1a69f19Skasunath     EXPECT_THAT(memcmp((*data1OrErr).data(), dummyDictionary1.data(),
87*a1a69f19Skasunath                        dummyDictionary1.size()),
88*a1a69f19Skasunath                 0);
89*a1a69f19Skasunath 
90*a1a69f19Skasunath     auto data2OrErr = dm.getDictionary(annotationResourceId);
91*a1a69f19Skasunath     EXPECT_TRUE(data2OrErr);
92*a1a69f19Skasunath     EXPECT_THAT((*data2OrErr).size_bytes(), dummyDictionary2.size());
93*a1a69f19Skasunath     EXPECT_THAT(memcmp((*data2OrErr).data(), dummyDictionary2.data(),
94*a1a69f19Skasunath                        dummyDictionary2.size()),
95*a1a69f19Skasunath                 0);
96*a1a69f19Skasunath }
97*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryOverwriteTest)98*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryOverwriteTest)
99*a1a69f19Skasunath {
100*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary2));
101*a1a69f19Skasunath 
102*a1a69f19Skasunath     // Recreate another one on the same location.
103*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
104*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
105*a1a69f19Skasunath     dm.markDataComplete(resourceId);
106*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
107*a1a69f19Skasunath 
108*a1a69f19Skasunath     auto dataOrErr = dm.getDictionary(resourceId);
109*a1a69f19Skasunath     EXPECT_TRUE(dataOrErr);
110*a1a69f19Skasunath     EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary1.size());
111*a1a69f19Skasunath     EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary1.data(),
112*a1a69f19Skasunath                        dummyDictionary1.size()),
113*a1a69f19Skasunath                 0);
114*a1a69f19Skasunath 
115*a1a69f19Skasunath     // Recreate another one on the same location.
116*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary2));
117*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
118*a1a69f19Skasunath     dm.markDataComplete(resourceId);
119*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
120*a1a69f19Skasunath 
121*a1a69f19Skasunath     auto newDataOrErr = dm.getDictionary(resourceId);
122*a1a69f19Skasunath     EXPECT_TRUE(newDataOrErr);
123*a1a69f19Skasunath     EXPECT_THAT((*newDataOrErr).size_bytes(), dummyDictionary2.size());
124*a1a69f19Skasunath     EXPECT_THAT(memcmp((*newDataOrErr).data(), dummyDictionary2.data(),
125*a1a69f19Skasunath                        dummyDictionary2.size()),
126*a1a69f19Skasunath                 0);
127*a1a69f19Skasunath }
128*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryAppendDataTest)129*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryAppendDataTest)
130*a1a69f19Skasunath {
131*a1a69f19Skasunath     // Creates a dictionary
132*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
133*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
134*a1a69f19Skasunath 
135*a1a69f19Skasunath     // Lets copy the dictionary in two sizes.
136*a1a69f19Skasunath     const uint32_t copySize1 = dummyDictionary2.size() / 2;
137*a1a69f19Skasunath     const uint32_t copySize2 = dummyDictionary2.size() - copySize1;
138*a1a69f19Skasunath 
139*a1a69f19Skasunath     // Overwrite on the same location as before.
140*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId,
141*a1a69f19Skasunath                             std::span(dummyDictionary2.data(), copySize1));
142*a1a69f19Skasunath     dm.addDictionaryData(
143*a1a69f19Skasunath         resourceId, std::span(dummyDictionary2.data() + copySize1, copySize2));
144*a1a69f19Skasunath     dm.markDataComplete(resourceId);
145*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
146*a1a69f19Skasunath 
147*a1a69f19Skasunath     auto dataOrErr = dm.getDictionary(resourceId);
148*a1a69f19Skasunath     EXPECT_TRUE(dataOrErr);
149*a1a69f19Skasunath     EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary2.size());
150*a1a69f19Skasunath     EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary2.data(),
151*a1a69f19Skasunath                        dummyDictionary2.size()),
152*a1a69f19Skasunath                 0);
153*a1a69f19Skasunath }
154*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryOverrideWithAddDataTest)155*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryOverrideWithAddDataTest)
156*a1a69f19Skasunath {
157*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
158*a1a69f19Skasunath     dm.markDataComplete(resourceId);
159*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
160*a1a69f19Skasunath 
161*a1a69f19Skasunath     dm.addDictionaryData(resourceId, std::span(dummyDictionary2));
162*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
163*a1a69f19Skasunath     dm.markDataComplete(resourceId);
164*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
165*a1a69f19Skasunath }
166*a1a69f19Skasunath 
TEST_F(RdeDictionaryManagerTest,DictionaryInvalidateTest)167*a1a69f19Skasunath TEST_F(RdeDictionaryManagerTest, DictionaryInvalidateTest)
168*a1a69f19Skasunath {
169*a1a69f19Skasunath     dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
170*a1a69f19Skasunath     dm.markDataComplete(resourceId);
171*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 1);
172*a1a69f19Skasunath 
173*a1a69f19Skasunath     dm.invalidateDictionaries();
174*a1a69f19Skasunath     EXPECT_THAT(dm.getDictionaryCount(), 0);
175*a1a69f19Skasunath }
176*a1a69f19Skasunath 
177*a1a69f19Skasunath } // namespace rde
178*a1a69f19Skasunath } // namespace bios_bmc_smm_error_logger
179