#include "TestCommon.h" #include "ANSCustomCodeWeaponDetection.h" // =========================================================================== // Unit Tests — no model files required // =========================================================================== class WeaponUnitTest : public ::testing::Test { protected: ANSCustomWD detector; }; TEST_F(WeaponUnitTest, EmptyFrameReturnsNoDetections) { cv::Mat empty; auto results = detector.RunInference(empty); EXPECT_TRUE(results.empty()); } TEST_F(WeaponUnitTest, TinyFrameReturnsNoDetections) { cv::Mat tiny = TestUtils::CreateTestFrame(5, 5); auto results = detector.RunInference(tiny); EXPECT_TRUE(results.empty()); } TEST_F(WeaponUnitTest, UninitializedDetectorReturnsNoDetections) { cv::Mat frame = TestUtils::CreateTestFrame(640, 480); auto results = detector.RunInference(frame); EXPECT_TRUE(results.empty()); } TEST_F(WeaponUnitTest, RunInferenceWithCameraId) { cv::Mat frame = TestUtils::CreateTestFrame(640, 480); auto results = detector.RunInference(frame, "test_cam_01"); EXPECT_TRUE(results.empty()); } TEST_F(WeaponUnitTest, ConfigureParametersReturnsValidConfig) { CustomParams params; bool result = detector.ConfigureParameters(params); EXPECT_TRUE(result); } TEST_F(WeaponUnitTest, DestroySucceeds) { EXPECT_TRUE(detector.Destroy()); } TEST_F(WeaponUnitTest, DestroyCanBeCalledMultipleTimes) { EXPECT_TRUE(detector.Destroy()); EXPECT_TRUE(detector.Destroy()); } TEST_F(WeaponUnitTest, InitializeWithInvalidDirectoryFails) { std::string labelMap; bool result = detector.Initialize("C:\\NonExistent\\Path\\Model", 0.5f, labelMap); EXPECT_FALSE(result); } TEST_F(WeaponUnitTest, OptimizeBeforeInitializeReturnsFalse) { EXPECT_FALSE(detector.OptimizeModel(true)); } // =========================================================================== // Integration Tests — require model files on disk // =========================================================================== class WeaponIntegrationTest : public ::testing::Test { protected: ANSCustomWD detector; std::string labelMap; std::vector classes; void SetUp() override { if (!TestConfig::ModelExists(TestConfig::WEAPON_MODEL_DIR)) { GTEST_SKIP() << "Weapon model not found at: " << TestConfig::WEAPON_MODEL_DIR; } bool ok = detector.Initialize(TestConfig::WEAPON_MODEL_DIR, 0.6f, labelMap); ASSERT_TRUE(ok) << "Failed to initialize Weapon detector"; classes = TestUtils::ParseLabelMap(labelMap); } void TearDown() override { detector.Destroy(); } }; TEST_F(WeaponIntegrationTest, InitializeProducesLabelMap) { EXPECT_FALSE(labelMap.empty()); EXPECT_FALSE(classes.empty()); } TEST_F(WeaponIntegrationTest, InferenceOnSolidFrameReturnsNoDetections) { cv::Mat frame = TestUtils::CreateTestFrame(1920, 1080); auto results = detector.RunInference(frame, "test_cam"); EXPECT_TRUE(results.empty()) << "Solid gray frame should not trigger weapon detection"; } TEST_F(WeaponIntegrationTest, InferenceOnSmallFrame) { cv::Mat frame = TestUtils::CreateTestFrame(320, 240); auto results = detector.RunInference(frame, "test_cam"); SUCCEED(); } TEST_F(WeaponIntegrationTest, InferenceOnLargeFrame) { cv::Mat frame = TestUtils::CreateTestFrame(3840, 2160); auto results = detector.RunInference(frame, "test_cam"); SUCCEED(); } TEST_F(WeaponIntegrationTest, DetectionResultFieldsAreValid) { if (!TestConfig::VideoExists(TestConfig::WEAPON_VIDEO)) { GTEST_SKIP() << "Weapon test video not found"; } cv::VideoCapture cap(TestConfig::WEAPON_VIDEO); ASSERT_TRUE(cap.isOpened()); bool detectionFound = false; for (int i = 0; i < 300 && !detectionFound; i++) { cv::Mat frame; if (!cap.read(frame)) break; auto results = detector.RunInference(frame, "test_cam"); for (const auto& obj : results) { detectionFound = true; EXPECT_GE(obj.confidence, 0.0f); EXPECT_LE(obj.confidence, 1.0f); EXPECT_GE(obj.box.width, 0); EXPECT_GE(obj.box.height, 0); EXPECT_GE(obj.classId, 0); } } cap.release(); } TEST_F(WeaponIntegrationTest, PerformanceBenchmark) { if (!TestConfig::VideoExists(TestConfig::WEAPON_VIDEO)) { GTEST_SKIP() << "Weapon test video not found"; } auto [totalDetections, avgMs] = TestUtils::RunVideoFrames(detector, TestConfig::WEAPON_VIDEO, 100); ASSERT_GE(totalDetections, 0) << "Video could not be opened"; std::cout << "[Weapon] 100 frames: avg=" << avgMs << "ms/frame, " << "detections=" << totalDetections << std::endl; EXPECT_LT(avgMs, 200.0) << "Average inference time exceeds 200ms"; } TEST_F(WeaponIntegrationTest, ThreadSafetyConcurrentInference) { cv::Mat frame1 = TestUtils::CreateTestFrame(640, 480, cv::Scalar(100, 100, 100)); cv::Mat frame2 = TestUtils::CreateTestFrame(640, 480, cv::Scalar(200, 200, 200)); std::vector results1, results2; std::thread t1([&]() { results1 = detector.RunInference(frame1, "cam_1"); }); std::thread t2([&]() { results2 = detector.RunInference(frame2, "cam_2"); }); t1.join(); t2.join(); SUCCEED(); }