1 /**
2  * Copyright © 2019 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "extensions/openpower-pels/event_logger.hpp"
17 #include "log_manager.hpp"
18 
19 #include <gtest/gtest.h>
20 
21 using namespace openpower::pels;
22 using namespace phosphor::logging;
23 
24 class CreateHelper
25 {
26   public:
27     void create(const std::string& name, Entry::Level level,
28                 const EventLogger::ADMap& ad)
29     {
30         _createCount++;
31         _prevName = name;
32         _prevLevel = level;
33         _prevAD = ad;
34 
35         // Try to create another event from within the creation
36         // function.  Should never work or else we could get stuck
37         // infinitely creating events.
38         if (_eventLogger)
39         {
40             AdditionalData d;
41             _eventLogger->log(name, level, d);
42         }
43     }
44 
45     size_t _createCount = 0;
46     std::string _prevName;
47     Entry::Level _prevLevel;
48     EventLogger::ADMap _prevAD;
49     EventLogger* _eventLogger = nullptr;
50 };
51 
52 void runEvents(sd_event* event, size_t numEvents)
53 {
54     sdeventplus::Event e{event};
55 
56     for (size_t i = 0; i < numEvents; i++)
57     {
58         e.run(std::chrono::milliseconds(1));
59     }
60 }
61 
62 TEST(EventLoggerTest, TestCreateEvents)
63 {
64     sd_event* sdEvent = nullptr;
65     auto r = sd_event_default(&sdEvent);
66     ASSERT_TRUE(r >= 0);
67 
68     CreateHelper ch;
69 
70     EventLogger eventLogger(std::bind(
71         std::mem_fn(&CreateHelper::create), &ch, std::placeholders::_1,
72         std::placeholders::_2, std::placeholders::_3));
73 
74     ch._eventLogger = &eventLogger;
75 
76     AdditionalData ad;
77     ad.add("key1", "value1");
78 
79     eventLogger.log("one", Entry::Level::Error, ad);
80     EXPECT_EQ(eventLogger.queueSize(), 1);
81 
82     runEvents(sdEvent, 1);
83 
84     // Verify 1 event was created
85     EXPECT_EQ(eventLogger.queueSize(), 0);
86     EXPECT_EQ(ch._prevName, "one");
87     EXPECT_EQ(ch._prevLevel, Entry::Level::Error);
88     EXPECT_EQ(ch._prevAD, ad.getData());
89     EXPECT_EQ(ch._createCount, 1);
90 
91     // Create 2 more, and run 1 event loop at a time and check the results
92     eventLogger.log("two", Entry::Level::Error, ad);
93     eventLogger.log("three", Entry::Level::Error, ad);
94 
95     EXPECT_EQ(eventLogger.queueSize(), 2);
96 
97     runEvents(sdEvent, 1);
98 
99     EXPECT_EQ(ch._createCount, 2);
100     EXPECT_EQ(ch._prevName, "two");
101     EXPECT_EQ(eventLogger.queueSize(), 1);
102 
103     runEvents(sdEvent, 1);
104     EXPECT_EQ(ch._createCount, 3);
105     EXPECT_EQ(ch._prevName, "three");
106     EXPECT_EQ(eventLogger.queueSize(), 0);
107 
108     // Add them all again and run them all at once
109     eventLogger.log("three", Entry::Level::Error, ad);
110     eventLogger.log("two", Entry::Level::Error, ad);
111     eventLogger.log("one", Entry::Level::Error, ad);
112     runEvents(sdEvent, 3);
113 
114     EXPECT_EQ(ch._createCount, 6);
115     EXPECT_EQ(ch._prevName, "one");
116     EXPECT_EQ(eventLogger.queueSize(), 0);
117 
118     // Run extra events - doesn't do anything
119     runEvents(sdEvent, 1);
120     EXPECT_EQ(ch._createCount, 6);
121     EXPECT_EQ(ch._prevName, "one");
122     EXPECT_EQ(eventLogger.queueSize(), 0);
123 
124     sd_event_unref(sdEvent);
125 }
126