libicsneo/test/eventmanagertest.cpp

749 lines
31 KiB
C++

#include <thread>
#include <memory>
#include <mutex>
#include "icsneo/icsneocpp.h"
#include "gtest/gtest.h"
using namespace icsneo;
class EventManagerTest : public ::testing::Test {
protected:
// Start with a clean instance of eventmanager for every test
void SetUp() override {
EventManager::GetInstance().ResetInstance();
}
};
/**
* Tests behavior of adding event callbacks on multiple threads.
* The order in which they are called is not guaranteed, but we check for the correct amount of calls.
* Each callback also flushes the event buffer upon call.
*/
TEST_F(EventManagerTest, MultithreadedEventCallbacksTest) {
int callCounter = 0;
std::mutex mutex;
std::thread t1([&callCounter, &mutex]() {
// increments counter when baudrate events show up
int id1 = EventManager::GetInstance().addEventCallback(EventCallback([&callCounter, &mutex](std::shared_ptr<APIEvent>){
std::lock_guard<std::mutex> lk(mutex);
callCounter++;
EventManager::GetInstance().get();
}, EventFilter(APIEvent::Type::BaudrateNotFound)));
// shouldn't add anything
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventWarning));
// should add 1
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventWarning));
EventManager::GetInstance().removeEventCallback(id1);
});
std::thread t2([&callCounter, &mutex]() {
// increments counter when infos show up
int id2 = EventManager::GetInstance().addEventCallback(EventCallback([&callCounter, &mutex](std::shared_ptr<APIEvent>) {
std::lock_guard<std::mutex> lk(mutex);
callCounter++;
EventManager::GetInstance().get();
}, EventFilter(APIEvent::Severity::EventInfo)));
// shouldn't add anything
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventWarning));
// should add 1
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventInfo));
EventManager::GetInstance().removeEventCallback(id2);
});
t1.join();
t2.join();
EXPECT_EQ(EventCount(), 0);
EXPECT_EQ(callCounter, 2);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 1);
EXPECT_EQ(callCounter, 2);
}
/**
* Tests behavior of adding and removing multiple event callbacks on a single thread.
*/
TEST_F(EventManagerTest, SingleThreadEventCallbacksTest) {
int callCounter = 0;
// increments counter when baudrate events show up
int id1 = EventManager::GetInstance().addEventCallback(EventCallback([&callCounter](std::shared_ptr<APIEvent>){
callCounter++;
}, EventFilter(APIEvent::Type::BaudrateNotFound)));
// increments counter when infos show up
int id2 = EventManager::GetInstance().addEventCallback(EventCallback([&callCounter](std::shared_ptr<APIEvent>) {
callCounter++;
}, EventFilter(APIEvent::Severity::EventInfo)));
EXPECT_EQ(callCounter, 0);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventWarning));
EXPECT_EQ(callCounter, 0);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventWarning));
EXPECT_EQ(callCounter, 1);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 2);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 4);
EXPECT_EQ(EventManager::GetInstance().removeEventCallback(id2), true);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 4);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 5);
// increments counter when device currently open shows up
int id3 = EventManager::GetInstance().addEventCallback(EventCallback([&callCounter](std::shared_ptr<APIEvent>) {
callCounter++;
}, EventFilter(APIEvent::Type::DeviceCurrentlyOpen)));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 6);
EXPECT_EQ(EventManager::GetInstance().removeEventCallback(id2), false);
EXPECT_EQ(EventManager::GetInstance().removeEventCallback(id1), true);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 6);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 7);
EXPECT_EQ(EventManager::GetInstance().removeEventCallback(id3), true);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::EventInfo));
EXPECT_EQ(callCounter, 7);
}
/**
* Checks that error downgrading is functioning appropriately when downgrading and canceling downgrading.
* Also checks that error downgrading is thread-specific.
*/
TEST_F(EventManagerTest, ErrorDowngradingTest) {
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Adds 500 {OutputTruncated, Warning} and 500 {OutputTruncated, Info}
// Also adds errors in both downgraded and non-downgraded states, and checks for appropriate behavior.
std::thread t1([]() {
for(int i = 0; i < 500; i++) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
}
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::OutputTruncated);
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
auto events = GetEvents(EventFilter(APIEvent::Type::BufferInsufficient, APIEvent::Severity::EventWarning));
EXPECT_EQ(events.empty(), false);
EventManager::GetInstance().cancelErrorDowngradingOnCurrentThread();
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::OutputTruncated);
});
// Adds 500 {OutputTruncated, Warning} and 500 {OutputTruncated, Info}
// Adds and checks errors as well.
std::thread t2([]() {
for(int i = 0; i < 500; i++) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
}
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::BufferInsufficient);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::OutputTruncated);
});
t1.join();
t2.join();
}
/**
* Adds a total of 3000 events from 3 different threads, checking that all were correctly added after all threads are joined.
* Also adds errors from each of the 3 threads, checking that the last error is correct for that thread and that the main thread has no errors.
*/
TEST_F(EventManagerTest, MultithreadedTest) {
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Adds 500 {OutputTruncated, Warning} and 500 {OutputTruncated, Info}
// Adds and checks errors as well.
std::thread t1( []() {
for(int i = 0; i < 500; i++) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
}
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::BufferInsufficient);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::OutputTruncated);
});
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Adds 500 {CANFDNotSupported, Warning} and 500 {CANFDSettingsNotAvailable, Info}
// Adds and checks errors as well.
std::thread t2( []() {
for(int i = 0; i < 500; i++) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::CANFDNotSupported, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::EventInfo));
}
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::DeviceCurrentlyOffline);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::DeviceCurrentlyOnline, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::DeviceCurrentlyOnline);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error));
});
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Adds 500 {CANFDNotSupported, Warning} and 500 {FailedToWrite, Info}
// Adds and checks errors as well.
std::thread t3( []() {
for(int i = 0; i < 500; i++) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::CANFDNotSupported, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToWrite, APIEvent::Severity::EventInfo));
}
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::NoSerialNumber, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::SettingsChecksumError);
EventManager::GetInstance().add(APIEvent(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::SWCANSettingsNotAvailable);
});
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Wait for threads to finish
t1.join();
t2.join();
t3.join();
// Check that main thread has no errors
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::NoErrorFound);
// Should be 500 {OutputTruncated, Warning}, 500 {OutputTruncated, Info}, 1000 {CANFDNotSupported, Warning}, 500 {CANFDSettingsNotAvailable, Info}, 500 {FailedToWrite, Info}
EXPECT_EQ(EventCount(), 3000);
auto events = GetEvents(EventFilter(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EXPECT_EQ(EventCount(), 2500);
EXPECT_EQ(events.size(), 500);
events = GetEvents(EventFilter(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 2000);
EXPECT_EQ(events.size(), 500);
events = GetEvents(EventFilter(APIEvent::Type::CANFDNotSupported, APIEvent::Severity::EventWarning));
EXPECT_EQ(EventCount(), 1000);
EXPECT_EQ(events.size(), 1000);
events = GetEvents(EventFilter(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 500);
EXPECT_EQ(events.size(), 500);
events = GetEvents(EventFilter(APIEvent::Type::FailedToWrite, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 0);
EXPECT_EQ(events.size(), 500);
}
/**
* Checks that errors do not go into the events list, and that TooManyEvents events are not added either.
* Checks that EventCount() updates accordingly, even when overflowing (trying to add 11000 events when the limit is 10000)
*/
TEST_F(EventManagerTest, CountTest) {
// Add an error event, should not go into events list.
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(EventCount(), 0);
// Adds actual event
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
// Manually tries to add some TooManyEvents, these should not be added.
EventManager::GetInstance().add(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 1);
// Add another actual event
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 2);
// Take all info events (1)
GetEvents(EventFilter(APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 1);
// Take all events
GetEvents();
EXPECT_EQ(EventCount(), 0);
// default limit is 10000
for(int i = 0; i < 11000; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EXPECT_EQ(EventCount(), 10000);
}
/**
* Checks that the default get() clears out and returns all events.
*/
TEST_F(EventManagerTest, GetDefaultTest) {
for(int i = 0; i < 5; i++) {
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::EventInfo);
// errors should not go in events
EventManager::GetInstance().add(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
}
auto events = EventManager::GetInstance().get();
EXPECT_EQ(events.size(), 10);
EXPECT_EQ(EventCount(), 0);
for(int i = 0; i < 5; i++) {
EXPECT_EQ(events.at(2 * i).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2 * i).getSeverity(), APIEvent::Severity::EventWarning);
EXPECT_EQ(events.at(2 * i + 1).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(2 * i + 1).getSeverity(), APIEvent::Severity::EventInfo);
}
// Check getting when 0 events exist doesn't break
events = EventManager::GetInstance().get();
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks that get() with a size param only flushes and returns the desired amount, even when requesting too many.
*/
TEST_F(EventManagerTest, GetSizeTest) {
// Add 10 events
for(int i = 0; i < 5; i++) {
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::EventInfo);
// errors should not go in events
EventManager::GetInstance().add(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
}
// Take 3 events, 7 left
auto events = EventManager::GetInstance().get(3);
EXPECT_EQ(events.size(), 3);
EXPECT_EQ(EventCount(), 7);
EXPECT_EQ(events.at(0).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(0).getSeverity(), APIEvent::Severity::EventWarning);
EXPECT_EQ(events.at(1).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(1).getSeverity(), APIEvent::Severity::EventInfo);
EXPECT_EQ(events.at(2).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2).getSeverity(), APIEvent::Severity::EventWarning);
// Take 1 event, 6 left
events = EventManager::GetInstance().get(1);
EXPECT_EQ(events.size(), 1);
EXPECT_EQ(EventCount(), 6);
EXPECT_EQ(events.at(0).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(0).getSeverity(), APIEvent::Severity::EventInfo);
// Try to take 8 events, should actually take the 6 remaining. 0 left.
events = EventManager::GetInstance().get(8);
EXPECT_EQ(events.size(), 6);
EXPECT_EQ(EventCount(), 0);
for(int i = 0; i < 3; i++) {
EXPECT_EQ(events.at(2 * i).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2 * i).getSeverity(), APIEvent::Severity::EventWarning);
EXPECT_EQ(events.at(2 * i + 1).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(2 * i + 1).getSeverity(), APIEvent::Severity::EventInfo);
}
// Check getting when 0 events exist doesn't break
events = EventManager::GetInstance().get(5);
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks that get() with a filter param only flushes and returns the events matching the filter.
*/
TEST_F(EventManagerTest, GetFilterTest) {
// Add 20 events
for(int i = 0; i < 5; i++) {
// {network, warning}, {settings, info}, {network, info}, {mismatch, warning}
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::SettingsStructureMismatch, APIEvent::Severity::EventWarning);
// errors should not go in events
EventManager::GetInstance().add(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
}
// Get all 5 {network, warning}. 15 left.
auto events = EventManager::GetInstance().get(EventFilter(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning));
EXPECT_EQ(events.size(), 5);
EXPECT_EQ(EventCount(), 15);
for(APIEvent event : events) {
EXPECT_EQ(event.getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(event.getSeverity(), APIEvent::Severity::EventWarning);
}
// Get all 10 infos. 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(EventFilter(APIEvent::Severity::EventInfo));
EXPECT_EQ(events.size(), 10);
EXPECT_EQ(EventCount(), 5);
for(int i = 0; i < 5; i++) {
EXPECT_EQ(events.at(2 * i).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(2 * i).getSeverity(), APIEvent::Severity::EventInfo);
EXPECT_EQ(events.at(2 * i + 1).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2 * i + 1).getSeverity(), APIEvent::Severity::EventInfo);
}
// (Incorrectly) try to get settings type again. 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(EventFilter(APIEvent::Type::SWCANSettingsNotAvailable));
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 5);
// Get the 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(EventFilter(APIEvent::Type::SettingsStructureMismatch));
EXPECT_EQ(events.size(), 5);
EXPECT_EQ(EventCount(), 0);
for(APIEvent event : events) {
EXPECT_EQ(event.getType(), APIEvent::Type::SettingsStructureMismatch);
EXPECT_EQ(event.getSeverity(), APIEvent::Severity::EventWarning);
}
// Check getting when 0 events exist doesn't break
events = EventManager::GetInstance().get(EventFilter(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning));
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks that get() with both a size and filter param only flushes and returns the desired amount of events matching the filter.
*/
TEST_F(EventManagerTest, GetSizeFilterTest) {
// Add 20 events
for(int i = 0; i < 5; i++) {
// {network, warning}, {settings, info}, {network, info}, {mismatch, warning}
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::SettingsStructureMismatch, APIEvent::Severity::EventWarning);
// errors should not go in events
EventManager::GetInstance().add(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
}
// Get all 5 {network, warning}. 15 left.
auto events = EventManager::GetInstance().get(6, EventFilter(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning));
EXPECT_EQ(events.size(), 5);
EXPECT_EQ(EventCount(), 15);
for(APIEvent event : events) {
EXPECT_EQ(event.getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(event.getSeverity(), APIEvent::Severity::EventWarning);
}
// Get 6 infos. 4 infos and 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(6, EventFilter(APIEvent::Severity::EventInfo));
EXPECT_EQ(events.size(), 6);
EXPECT_EQ(EventCount(), 9);
for(int i = 0; i < 3; i++) {
EXPECT_EQ(events.at(2 * i).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(2 * i).getSeverity(), APIEvent::Severity::EventInfo);
EXPECT_EQ(events.at(2 * i + 1).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2 * i + 1).getSeverity(), APIEvent::Severity::EventInfo);
}
// Get 4 remaining infos. 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(4, EventFilter(APIEvent::Severity::EventInfo));
EXPECT_EQ(events.size(), 4);
EXPECT_EQ(EventCount(), 5);
for(int i = 0; i < 2; i++) {
EXPECT_EQ(events.at(2 * i).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(2 * i).getSeverity(), APIEvent::Severity::EventInfo);
EXPECT_EQ(events.at(2 * i + 1).getType(), APIEvent::Type::UnexpectedNetworkType);
EXPECT_EQ(events.at(2 * i + 1).getSeverity(), APIEvent::Severity::EventInfo);
}
// (Incorrectly) try to get settings type again. 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(-1, EventFilter(APIEvent::Type::SWCANSettingsNotAvailable));
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 5);
// Get the 5 {mismatch, warning} remaining.
events = EventManager::GetInstance().get(5, EventFilter(APIEvent::Type::SettingsStructureMismatch));
EXPECT_EQ(events.size(), 5);
EXPECT_EQ(EventCount(), 0);
for(APIEvent event : events) {
EXPECT_EQ(event.getType(), APIEvent::Type::SettingsStructureMismatch);
EXPECT_EQ(event.getSeverity(), APIEvent::Severity::EventWarning);
}
// Check getting when 0 events exist doesn't break
events = EventManager::GetInstance().get(2, EventFilter(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::EventWarning));
EXPECT_EQ(events.size(), 0);
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks that adding 1 error and calling GetLastError() twice will first return the error then return a NoErrorFound info message. Singlethreaded.
*/
TEST_F(EventManagerTest, GetLastErrorSingleTest) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::OutputTruncated);
auto err = GetLastError();
EXPECT_EQ(err.getType(), APIEvent::Type::NoErrorFound);
EXPECT_EQ(err.getSeverity(), APIEvent::Severity::EventInfo);
}
/**
* Checks that adding multiple errors and calling GetLastError() twice will first return the last error then return a NoErrorFound info message. Singlethreaded.
*/
TEST_F(EventManagerTest, GetLastErrorMultipleTest) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error));
EventManager::GetInstance().add(APIEvent(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error));
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::SettingsNotAvailable);
auto err = GetLastError();
EXPECT_EQ(err.getType(), APIEvent::Type::NoErrorFound);
EXPECT_EQ(err.getSeverity(), APIEvent::Severity::EventInfo);
}
/**
* Adds 52 events when the limit is 50 (49 normal, 1 reserved)
* Checks that only the latest 49 are kept, and a TooManyEvents warning exists at the end.
*/
TEST_F(EventManagerTest, TestAddWarningsOverflow) {
// space for 49 normal events, 1 reserved for TooManyEvents
SetEventLimit(50);
// 3 of these
for(int i = 0; i < 3; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
// 1 info
EventManager::GetInstance().add(APIEvent(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::EventInfo));
// 48 of these
for(int i = 0; i < 48; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::EventWarning));
auto events = GetEvents();
EXPECT_EQ(events.at(0).getType(), APIEvent::Type::SWCANSettingsNotAvailable);
EXPECT_EQ(events.at(0).getSeverity(), APIEvent::Severity::EventInfo);
for(int i = 1; i < 49; i++) {
EXPECT_EQ(events.at(i).getType(), APIEvent::Type::ParameterOutOfRange);
EXPECT_EQ(events.at(i).getSeverity(), APIEvent::Severity::EventWarning);
}
EXPECT_EQ(events.at(49).getType(), APIEvent::Type::TooManyEvents);
EXPECT_EQ(events.at(49).getSeverity(), APIEvent::Severity::EventWarning);
}
/**
* Adds 1 warning, 3 info, and 47 warning events, in that order, when the limit is 50 (49 normal, 1 reserved)
* Checks that only the latest 49 are kept, and a TOoManyEvents warning exists at the end.
*/
TEST_F(EventManagerTest, TestAddWarningsInfoOverflow) {
// space for 49 normal events, 1 reserved for TooManyEvents
SetEventLimit(50);
// Event list filling: 1 warning, 3 info, 47 warning.
// Expect to see: 2 info, 47 warning, 1 TooManyEvents
EventManager::GetInstance().add(APIEvent(APIEvent::Type::SettingsVersionError, APIEvent::Severity::EventWarning));
// 3 of these
for(int i = 0; i < 3; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventInfo));
// 47 of these
for(int i = 0; i < 47; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::EventWarning));
auto events = GetEvents();
for(int i = 0; i < 2; i++) {
EXPECT_EQ(events.at(i).getType(), APIEvent::Type::OutputTruncated);
}
for(int i = 2; i < 49; i++)
EXPECT_EQ(events.at(i).getType(), APIEvent::Type::ParameterOutOfRange);
EXPECT_EQ(events.at(49).getType(), APIEvent::Type::TooManyEvents);
}
/**
* Checks that discarding with no params flushes every event.
*/
TEST_F(EventManagerTest, DiscardDefault) {
for(int i = 0; i < 3000; i++) {
EventManager::GetInstance().add(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::EventWarning);
}
EXPECT_EQ(EventCount(), 9000);
DiscardEvents();
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks that discarding with a filter only flushes events matching the filter.
*/
TEST_F(EventManagerTest, DiscardFilter) {
for(int i = 0; i < 3000; i++) {
EventManager::GetInstance().add(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo);
EventManager::GetInstance().add(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventWarning);
EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::EventWarning);
}
EXPECT_EQ(EventCount(), 9000);
DiscardEvents(EventFilter(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 6000);
DiscardEvents(EventFilter(APIEvent::Type::BufferInsufficient, APIEvent::Severity::EventInfo));
EXPECT_EQ(EventCount(), 6000);
DiscardEvents(EventFilter(APIEvent::Severity::EventWarning));
EXPECT_EQ(EventCount(), 0);
}
/**
* Checks setting the event limit when truncating is not required, when the new limit is < 10, and when the new limit < num events.
*/
TEST_F(EventManagerTest, SetEventLimitTest) {
// Test if event limit too low to be set
EventManager::GetInstance().setEventLimit(9);
EXPECT_EQ(GetEventLimit(), 10000);
EXPECT_EQ(GetLastError().getType(), APIEvent::Type::ParameterOutOfRange);
// Test truncating existing list when new limit set
for(int i = 0; i < 9001; i++)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning));
EXPECT_EQ(EventCount(), 9001);
// Sets new limit to be exactly full.
SetEventLimit(9002);
EXPECT_EQ(GetEventLimit(), 9002);
EXPECT_EQ(EventCount(), 9001);
// 1 overflowed.
SetEventLimit(9001);
EXPECT_EQ(GetEventLimit(), 9001);
EXPECT_EQ(EventCount(), 9001);
// Truncate a lot
SetEventLimit(5000);
EXPECT_EQ(GetEventLimit(), 5000);
EXPECT_EQ(EventCount(), 5000);
auto events = GetEvents();
for(int i = 0; i < 4998; i++) {
EXPECT_EQ(events.at(i).getType(), APIEvent::Type::OutputTruncated);
}
EXPECT_EQ(events.at(4999).getType(), APIEvent::Type::TooManyEvents);
}