mirror of
https://github.com/Zxilly/UA2F.git
synced 2025-12-16 16:21:58 +00:00
test: add more test
This commit is contained in:
parent
51bcf099f4
commit
9d94b7957c
@ -213,8 +213,12 @@ if (UA2F_BUILD_TESTS)
|
||||
ua2f_test
|
||||
test/util_test.cc
|
||||
test/cache_test.cc
|
||||
test/statistics_test.cc
|
||||
test/cli_test.cc
|
||||
src/util.c
|
||||
src/cache.c
|
||||
src/statistics.c
|
||||
src/cli.c
|
||||
)
|
||||
target_link_libraries(
|
||||
ua2f_test
|
||||
|
||||
@ -46,4 +46,73 @@ TEST_F(CacheTest, CacheDoesNotContainNonexistentEntry) {
|
||||
addr_port nonexistent_addr{};
|
||||
nonexistent_addr.addr.ip4 = 54321;
|
||||
EXPECT_FALSE(cache_contains(nonexistent_addr));
|
||||
}
|
||||
|
||||
TEST_F(CacheTest, MultipleDifferentAddresses) {
|
||||
addr_port addr1{}, addr2{}, addr3{};
|
||||
addr1.addr.ip4 = 1001;
|
||||
addr1.port = 80;
|
||||
addr2.addr.ip4 = 1002;
|
||||
addr2.port = 443;
|
||||
addr3.addr.ip4 = 1003;
|
||||
addr3.port = 8080;
|
||||
|
||||
// Initially none should be in cache
|
||||
EXPECT_FALSE(cache_contains(addr1));
|
||||
EXPECT_FALSE(cache_contains(addr2));
|
||||
EXPECT_FALSE(cache_contains(addr3));
|
||||
|
||||
// Add all to cache
|
||||
cache_add(addr1);
|
||||
cache_add(addr2);
|
||||
cache_add(addr3);
|
||||
|
||||
// All should now be in cache
|
||||
EXPECT_TRUE(cache_contains(addr1));
|
||||
EXPECT_TRUE(cache_contains(addr2));
|
||||
EXPECT_TRUE(cache_contains(addr3));
|
||||
}
|
||||
|
||||
TEST_F(CacheTest, SameAddressDifferentPorts) {
|
||||
addr_port addr1{}, addr2{};
|
||||
addr1.addr.ip4 = 2000;
|
||||
addr1.port = 80;
|
||||
addr2.addr.ip4 = 2000; // Same IP
|
||||
addr2.port = 443; // Different port
|
||||
|
||||
cache_add(addr1);
|
||||
|
||||
EXPECT_TRUE(cache_contains(addr1));
|
||||
EXPECT_FALSE(cache_contains(addr2)); // Different port should not match
|
||||
}
|
||||
|
||||
TEST_F(CacheTest, CacheRefreshOnAccess) {
|
||||
addr_port addr{};
|
||||
addr.addr.ip4 = 3000;
|
||||
addr.port = 80;
|
||||
|
||||
cache_add(addr);
|
||||
EXPECT_TRUE(cache_contains(addr));
|
||||
|
||||
// Access the cache multiple times - this should refresh the last_time
|
||||
for (int i = 0; i < 5; i++) {
|
||||
EXPECT_TRUE(cache_contains(addr));
|
||||
sleep(1); // Small delay
|
||||
}
|
||||
|
||||
// Should still be in cache after multiple accesses
|
||||
EXPECT_TRUE(cache_contains(addr));
|
||||
}
|
||||
|
||||
TEST_F(CacheTest, DuplicateAddDoesNotCrash) {
|
||||
addr_port addr{};
|
||||
addr.addr.ip4 = 4000;
|
||||
addr.port = 80;
|
||||
|
||||
// Add the same address multiple times
|
||||
cache_add(addr);
|
||||
cache_add(addr);
|
||||
cache_add(addr);
|
||||
|
||||
EXPECT_TRUE(cache_contains(addr));
|
||||
}
|
||||
64
test/cli_test.cc
Normal file
64
test/cli_test.cc
Normal file
@ -0,0 +1,64 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
#include <cli.h>
|
||||
}
|
||||
|
||||
class CLITest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Capture original uid for cleanup
|
||||
original_uid = geteuid();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Reset to original state if needed
|
||||
}
|
||||
|
||||
uid_t original_uid;
|
||||
};
|
||||
|
||||
TEST_F(CLITest, TryPrintInfoNoArgs) {
|
||||
char *argv[] = {(char*)"ua2f"};
|
||||
int argc = 1;
|
||||
|
||||
// Should not crash with no arguments
|
||||
EXPECT_NO_THROW(try_print_info(argc, argv));
|
||||
}
|
||||
|
||||
TEST_F(CLITest, TryPrintInfoVersion) {
|
||||
char *argv[] = {(char*)"ua2f", (char*)"--version"};
|
||||
int argc = 2;
|
||||
|
||||
// --version should exit, but we can't easily test exit behavior in unit tests
|
||||
// Just make sure the function exists and can be called without segfault
|
||||
EXPECT_EXIT(try_print_info(argc, argv), ::testing::ExitedWithCode(EXIT_SUCCESS), ".*");
|
||||
}
|
||||
|
||||
TEST_F(CLITest, TryPrintInfoHelp) {
|
||||
char *argv[] = {(char*)"ua2f", (char*)"--help"};
|
||||
int argc = 2;
|
||||
|
||||
// --help should exit with success
|
||||
EXPECT_EXIT(try_print_info(argc, argv), ::testing::ExitedWithCode(EXIT_SUCCESS), ".*");
|
||||
}
|
||||
|
||||
TEST_F(CLITest, TryPrintInfoUnknownOption) {
|
||||
char *argv[] = {(char*)"ua2f", (char*)"--unknown"};
|
||||
int argc = 2;
|
||||
|
||||
// Unknown option should exit with failure
|
||||
EXPECT_EXIT(try_print_info(argc, argv), ::testing::ExitedWithCode(EXIT_FAILURE), ".*");
|
||||
}
|
||||
|
||||
TEST_F(CLITest, RequireRootWhenRoot) {
|
||||
if (geteuid() == 0) {
|
||||
// If we're actually root, this should not exit
|
||||
EXPECT_NO_THROW(require_root());
|
||||
} else {
|
||||
// If we're not root, this should exit with failure
|
||||
EXPECT_EXIT(require_root(), ::testing::ExitedWithCode(EXIT_FAILURE), ".*");
|
||||
}
|
||||
}
|
||||
101
test/statistics_test.cc
Normal file
101
test/statistics_test.cc
Normal file
@ -0,0 +1,101 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstring>
|
||||
|
||||
extern "C" {
|
||||
#include <statistics.h>
|
||||
}
|
||||
|
||||
class StatisticsTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
init_statistics();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(StatisticsTest, InitializeStatistics) {
|
||||
// Statistics should be initialized without error
|
||||
EXPECT_NO_THROW(init_statistics());
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, CountUserAgentPacket) {
|
||||
EXPECT_NO_THROW(count_user_agent_packet());
|
||||
// Call multiple times to test counting
|
||||
for (int i = 0; i < 5; i++) {
|
||||
count_user_agent_packet();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, CountTcpPacket) {
|
||||
EXPECT_NO_THROW(count_tcp_packet());
|
||||
// Call multiple times to test counting
|
||||
for (int i = 0; i < 10; i++) {
|
||||
count_tcp_packet();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, CountHttpPacket) {
|
||||
EXPECT_NO_THROW(count_http_packet());
|
||||
// Call multiple times to test counting
|
||||
for (int i = 0; i < 3; i++) {
|
||||
count_http_packet();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, CountIpv4Packet) {
|
||||
EXPECT_NO_THROW(count_ipv4_packet());
|
||||
// Call multiple times to test counting
|
||||
for (int i = 0; i < 7; i++) {
|
||||
count_ipv4_packet();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, CountIpv6Packet) {
|
||||
EXPECT_NO_THROW(count_ipv6_packet());
|
||||
// Call multiple times to test counting
|
||||
for (int i = 0; i < 4; i++) {
|
||||
count_ipv6_packet();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StatisticsTest, TryPrintStatistics) {
|
||||
// Should not crash when called
|
||||
EXPECT_NO_THROW(try_print_statistics());
|
||||
|
||||
// Generate some statistics and try printing
|
||||
for (int i = 0; i < 100; i++) {
|
||||
count_user_agent_packet();
|
||||
count_tcp_packet();
|
||||
count_http_packet();
|
||||
count_ipv4_packet();
|
||||
}
|
||||
EXPECT_NO_THROW(try_print_statistics());
|
||||
}
|
||||
|
||||
// Test time string formatting function if accessible
|
||||
extern "C" char *fill_time_string(const double sec);
|
||||
|
||||
TEST_F(StatisticsTest, TimeStringFormatting) {
|
||||
char *result;
|
||||
|
||||
// Test seconds
|
||||
result = fill_time_string(30.0);
|
||||
EXPECT_TRUE(strstr(result, "seconds") != nullptr);
|
||||
|
||||
// Test minutes
|
||||
result = fill_time_string(150.0);
|
||||
EXPECT_TRUE(strstr(result, "minutes") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "seconds") != nullptr);
|
||||
|
||||
// Test hours
|
||||
result = fill_time_string(3700.0);
|
||||
EXPECT_TRUE(strstr(result, "hours") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "minutes") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "seconds") != nullptr);
|
||||
|
||||
// Test days
|
||||
result = fill_time_string(90000.0);
|
||||
EXPECT_TRUE(strstr(result, "days") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "hours") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "minutes") != nullptr);
|
||||
EXPECT_TRUE(strstr(result, "seconds") != nullptr);
|
||||
}
|
||||
@ -84,4 +84,74 @@ TEST(HttpProtocolTest, RealWorldRequests) {
|
||||
|
||||
// Check that these cases return false
|
||||
EXPECT_FALSE(is_http_protocol(invalidPayload, strlen(invalidPayload))) << "Invalid method passed";
|
||||
}
|
||||
|
||||
TEST(HttpProtocolTest, AllHttpMethods) {
|
||||
// Test all supported HTTP methods
|
||||
EXPECT_TRUE(is_http_protocol("GET /", 5));
|
||||
EXPECT_TRUE(is_http_protocol("POST /", 6));
|
||||
EXPECT_TRUE(is_http_protocol("OPTIONS /", 9));
|
||||
EXPECT_TRUE(is_http_protocol("HEAD /", 6));
|
||||
EXPECT_TRUE(is_http_protocol("PUT /", 5));
|
||||
EXPECT_TRUE(is_http_protocol("DELETE /", 8));
|
||||
EXPECT_TRUE(is_http_protocol("TRACE /", 7));
|
||||
EXPECT_TRUE(is_http_protocol("CONNECT /", 9));
|
||||
}
|
||||
|
||||
TEST(HttpProtocolTest, EdgeCases) {
|
||||
// Empty payload
|
||||
EXPECT_FALSE(is_http_protocol("", 0));
|
||||
|
||||
// Too short for any method
|
||||
EXPECT_FALSE(is_http_protocol("G", 1));
|
||||
EXPECT_FALSE(is_http_protocol("GE", 2));
|
||||
|
||||
// Incomplete methods
|
||||
EXPECT_FALSE(is_http_protocol("GE", 2));
|
||||
EXPECT_FALSE(is_http_protocol("POS", 3));
|
||||
|
||||
// Case sensitivity
|
||||
EXPECT_FALSE(is_http_protocol("get /", 5));
|
||||
EXPECT_FALSE(is_http_protocol("Post /", 6));
|
||||
|
||||
// Non-HTTP protocols
|
||||
EXPECT_FALSE(is_http_protocol("FTP /", 5));
|
||||
EXPECT_FALSE(is_http_protocol("SSH /", 5));
|
||||
EXPECT_FALSE(is_http_protocol("HTTPS /", 7));
|
||||
}
|
||||
|
||||
TEST(MemNCaseMemTest, CaseInsensitiveSearch) {
|
||||
const char *l = "HELLO WORLD";
|
||||
size_t l_len = 11;
|
||||
|
||||
// Test case insensitive matching
|
||||
EXPECT_EQ(memncasemem(l, l_len, "hello", 5), (void *)l);
|
||||
EXPECT_EQ(memncasemem(l, l_len, "HELLO", 5), (void *)l);
|
||||
EXPECT_EQ(memncasemem(l, l_len, "HeLLo", 5), (void *)l);
|
||||
EXPECT_EQ(memncasemem(l, l_len, "world", 5), (void *)(l + 6));
|
||||
EXPECT_EQ(memncasemem(l, l_len, "WORLD", 5), (void *)(l + 6));
|
||||
EXPECT_EQ(memncasemem(l, l_len, "WoRLd", 5), (void *)(l + 6));
|
||||
}
|
||||
|
||||
TEST(MemNCaseMemTest, NotFoundCases) {
|
||||
const char *l = "Hello World";
|
||||
size_t l_len = 11;
|
||||
|
||||
// Search for non-existent strings
|
||||
EXPECT_EQ(memncasemem(l, l_len, "xyz", 3), nullptr);
|
||||
EXPECT_EQ(memncasemem(l, l_len, "foo", 3), nullptr);
|
||||
EXPECT_EQ(memncasemem(l, l_len, "hello world!", 12), nullptr); // Longer than haystack
|
||||
}
|
||||
|
||||
TEST(MemNCaseMemTest, MultipleOccurrences) {
|
||||
const char *l = "hello hello hello";
|
||||
size_t l_len = 17;
|
||||
|
||||
// Should find the first occurrence
|
||||
void *result = memncasemem(l, l_len, "hello", 5);
|
||||
EXPECT_EQ(result, (void *)l);
|
||||
|
||||
// Search from different starting positions
|
||||
void *result2 = memncasemem(l + 6, l_len - 6, "hello", 5);
|
||||
EXPECT_EQ(result2, (void *)(l + 6));
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user