/// @brief Destructor
~AlarmStore() = default;
+ /// @brief Checks a sample against an alarm.
+ ///
+ /// If the alarm exists in the store for the duration key, then Alarm::checkSample()
+ /// is invoked on the in-store alarm. If this returns true, indicating an alarm
+ /// state change, then a copy of the in-store alarm is returned, otherwise an empty
+ /// pointer is returned.
+ ///
+ /// If no alarm exists in the store, then it simply returns an empty pointer.
+ ///
+ /// This function does not/must not modify any index keys.
+ ///
+ /// @param key key value of the alarm to check.
+ /// @param sample duration value to check.
+ /// @param report_interval amount of time that must elapse between high
+ /// water reports.
+ ///
+ /// @return A copy of the updated alarm if it should be reported, an empty
+ /// pointer otherwise.
+ AlarmPtr checkDurationSample(DurationKeyPtr key, const Duration& sample,
+ const Duration& report_interval);
+
/// @brief Creates a new Alarm and adds it to the store
///
/// @param key key value of the Alarm to create.
" - family mismatch, key is v4, store is v6");
}
-
/// @brief Verify that alarms in the store can be updated.
///
/// @param family protocol family to test, AF_INET or AF_INET6
// Add the duration to the store.
AlarmPtr alarm;
- ASSERT_NO_THROW(alarm.reset(new Alarm(*makeKey(family), milliseconds(10),
+ ASSERT_NO_THROW_LOG(alarm.reset(new Alarm(*makeKey(family), milliseconds(10),
milliseconds(250))));
- ASSERT_NO_THROW(store.addAlarm(alarm));
+ ASSERT_NO_THROW_LOG(store.addAlarm(alarm));
// Fetch it.
AlarmPtr found;
// Now change the thresholds and update it.
alarm->setLowWater(milliseconds(125));
alarm->setHighWater(milliseconds(500));
- ASSERT_NO_THROW(store.updateAlarm(alarm));
+ ASSERT_NO_THROW_LOG(store.updateAlarm(alarm));
// Fetch it again.
ASSERT_NO_THROW_LOG(found = store.getAlarm(alarm));
"AlarmStore::updateAlarm"
" - family mismatch, key is v4, store is v6");
}
+
+ /// @brief Verify checkDurationSample() valid behavior.
+ ///
+ /// @param family protocol family to test, AF_INET or AF_INET6
+ void checkDurationSampleTest(uint16_t family) {
+ AlarmStore store(family);
+
+ Duration under_low_water(milliseconds(50));
+ Duration low_water(milliseconds(100));
+ Duration mid_range(milliseconds(175));
+ Duration high_water(milliseconds(250));
+ Duration over_high_water(milliseconds(300));
+ Duration report_interval(milliseconds(10));
+
+ DurationKeyPtr key(makeKey(family));
+ AlarmPtr reportable;
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, over_high_water,
+ report_interval));
+ ASSERT_FALSE(reportable);
+
+ // Add an alarm for the key to the store.
+ AlarmPtr alarm;
+ ASSERT_NO_THROW_LOG(alarm.reset(new Alarm(*key, low_water, high_water)));
+ ASSERT_NO_THROW_LOG(store.addAlarm(alarm));
+
+ // Fetch it.
+ AlarmPtr found;
+ ASSERT_NO_THROW_LOG(found = store.getAlarm(alarm));
+ ASSERT_TRUE(found);
+
+ // Check a sample at mid range. Should not return the alarm.
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, mid_range,
+ report_interval));
+ ASSERT_FALSE(reportable);
+
+ // Check a sample over high water. Should return the alarm.
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, over_high_water,
+ report_interval));
+ ASSERT_TRUE(reportable);
+ EXPECT_EQ(reportable->getState(), Alarm::TRIGGERED);
+
+ // Check a sample over high water but before report interval elapses.
+ // Should not return the alarm.
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, over_high_water,
+ report_interval));
+ ASSERT_FALSE(reportable);
+
+ // Sleep beyond the report interval.
+ usleep(15 * 1000);
+
+ // Check a sample over high water after report interval elapses.
+ // Should return the alarm.
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, over_high_water,
+ report_interval));
+ ASSERT_TRUE(reportable);
+ EXPECT_EQ(reportable->getState(), Alarm::TRIGGERED);
+
+ // Check a sample below low water.
+ // Should return the alarm.
+ ASSERT_NO_THROW_LOG(reportable = store.checkDurationSample(key, under_low_water,
+ report_interval));
+ ASSERT_TRUE(reportable);
+ EXPECT_EQ(reportable->getState(), Alarm::CLEAR);
+ }
};
TEST_F(AlarmStoreTest, addAlarm) {
updateAlarmInvalidTest();
}
+TEST_F(AlarmStoreTest, checkDurationSample) {
+ checkDurationSampleTest(AF_INET);
+}
+
+TEST_F(AlarmStoreTest, checkDurationSampleMultiThreading) {
+ MultiThreadingTest mt;
+ checkDurationSampleTest(AF_INET);
+}
+
+TEST_F(AlarmStoreTest, checkDurationSample6) {
+ checkDurationSampleTest(AF_INET6);
+}
+
+TEST_F(AlarmStoreTest, checkDurationSample6MultiThreading) {
+ MultiThreadingTest mt;
+ checkDurationSampleTest(AF_INET6);
+}
} // end of anonymous namespace
EXPECT_EQ(previous_interval->getTotalDuration(), (five_ms) * 2);
}
+ /// @todo TAKE THIS OUT
/// @brief Test tool for gauging speed.
///
/// This test is really just a development tool for gauging performance.
for (int s = 0; s < num_subnets; ++s) {
keys.push_back(makeKey(family, s));
}
+
+ auto start_time = PktEvent::now();
+
+ for (auto k : keys) {
+ store.addDuration(k);
+ }
+
+ auto add_keys_time = PktEvent::now();
+
size_t num_passes = 100;
size_t report_count = 0;
Duration two_us(microseconds(2));
}
}
- std::cout << "report count: " << report_count << std::endl;
+ auto add_samples_time = PktEvent::now();
+
+ EXPECT_GT(report_count, 0);
auto durations = store.getAll();
- EXPECT_EQ(durations->size(), 100);
+ EXPECT_EQ(durations->size(), num_subnets);
+ std::cout << "add keys time : " << (add_keys_time - start_time) << std::endl
+ << "add samples time: " << (add_samples_time - add_keys_time) << std::endl
+ << "time per sample: "
+ << (add_samples_time - add_keys_time) / (num_subnets * num_passes) << std::endl;
}
};
addDurationSampleTest(AF_INET6);
}
+/// @todo TAKE THESE OUT
TEST_F(MonitoredDurationStoreTest, speedCheck) {
speedCheckTest(AF_INET);
}
speedCheckTest(AF_INET6);
}
-
} // end of anonymous namespace