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(
71         sdEvent, std::bind(std::mem_fn(&CreateHelper::create), &ch,
72                            std::placeholders::_1, std::placeholders::_2,
73                            std::placeholders::_3));
74 
75     ch._eventLogger = &eventLogger;
76 
77     AdditionalData ad;
78     ad.add("key1", "value1");
79 
80     eventLogger.log("one", Entry::Level::Error, ad);
81     EXPECT_EQ(eventLogger.queueSize(), 1);
82 
83     runEvents(sdEvent, 1);
84 
85     // Verify 1 event was created
86     EXPECT_EQ(eventLogger.queueSize(), 0);
87     EXPECT_EQ(ch._prevName, "one");
88     EXPECT_EQ(ch._prevLevel, Entry::Level::Error);
89     EXPECT_EQ(ch._prevAD, ad.getData());
90     EXPECT_EQ(ch._createCount, 1);
91 
92     // Create 2 more, and run 1 event loop at a time and check the results
93     eventLogger.log("two", Entry::Level::Error, ad);
94     eventLogger.log("three", Entry::Level::Error, ad);
95 
96     EXPECT_EQ(eventLogger.queueSize(), 2);
97 
98     runEvents(sdEvent, 1);
99 
100     EXPECT_EQ(ch._createCount, 2);
101     EXPECT_EQ(ch._prevName, "two");
102     EXPECT_EQ(eventLogger.queueSize(), 1);
103 
104     runEvents(sdEvent, 1);
105     EXPECT_EQ(ch._createCount, 3);
106     EXPECT_EQ(ch._prevName, "three");
107     EXPECT_EQ(eventLogger.queueSize(), 0);
108 
109     // Add them all again and run them all at once
110     eventLogger.log("three", Entry::Level::Error, ad);
111     eventLogger.log("two", Entry::Level::Error, ad);
112     eventLogger.log("one", Entry::Level::Error, ad);
113     runEvents(sdEvent, 3);
114 
115     EXPECT_EQ(ch._createCount, 6);
116     EXPECT_EQ(ch._prevName, "one");
117     EXPECT_EQ(eventLogger.queueSize(), 0);
118 
119     // Run extra events - doesn't do anything
120     runEvents(sdEvent, 1);
121     EXPECT_EQ(ch._createCount, 6);
122     EXPECT_EQ(ch._prevName, "one");
123     EXPECT_EQ(eventLogger.queueSize(), 0);
124 
125     sd_event_unref(sdEvent);
126 }
127