Skip to content

Commit 3829045

Browse files
authored
Merge pull request #27 from SimonCahill/feat/fix-multiple-reports
Bug fixes: Adds cache so reports aren't reported multiple times. Finally fixed #23
2 parents 447c346 + 0bf01e9 commit 3829045

File tree

16 files changed

+987
-69
lines changed

16 files changed

+987
-69
lines changed

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
build
2+
.git
3+
.gitmodules
4+
submodules/fmt/.git
5+
submodules/date/.git
6+
*.tar.gz
7+
*.zip
8+
bin
9+
__pycache__

.github/workflows/coverage.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Coverage CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
coverage:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v4
13+
14+
- name: Install dependencies
15+
run: |
16+
sudo apt-get update
17+
sudo apt-get install -y build-essential cmake lcov git
18+
19+
- name: Configure & Build
20+
run: |
21+
cmake -S . -B build -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug
22+
cmake --build build -j
23+
24+
- name: Run tests and generate coverage
25+
run: ./scripts/coverage.sh
26+
27+
- name: Upload coverage report
28+
if: always()
29+
uses: actions/upload-artifact@v4
30+
with:
31+
name: coverage-report
32+
path: build/coverage-report

CMakeLists.txt

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
cmake_minimum_required(VERSION 3.10)
22

3-
project(endlessh-report VERSION 1.2.3 LANGUAGES CXX DESCRIPTION "A simple report generator for endlessh tarpits.")
3+
project(endlessh-report VERSION 1.3.0 LANGUAGES CXX DESCRIPTION "A simple report generator for endlessh tarpits.")
44
set(PROJECT_LONG_NAME "Endlessh Report Generator")
55
set(CMAKE_CXX_STANDARD 17)
66
set(CMAKE_CXX_STANDARD_REQUIRED True)
77

8+
option(ENABLE_COVERAGE "Enable compilation flags for gcov coverage" ON)
9+
10+
include(CTest)
11+
812
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/version.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/version.hpp)
913

1014
add_compile_options(
1115
-Wpedantic
1216
-Werror
1317
-Wall
18+
-Wno-unused-function
1419
)
1520

1621
include_directories(
@@ -26,10 +31,16 @@ if (DEFINED endlesshreport_DEBUG OR CMAKE_BUILD_TYPE STREQUAL "Debug")
2631
else()
2732
add_compile_options(
2833
-O2
29-
-s
3034
)
3135
endif()
3236

37+
if (ENABLE_COVERAGE)
38+
message(STATUS "Building with coverage support (--coverage)")
39+
add_compile_options(--coverage -O0 -g)
40+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
41+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
42+
endif()
43+
3344
###
3445
# Make sure submodules are updated
3546
###
@@ -42,21 +53,24 @@ execute_process(
4253
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/submodules/date)
4354
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt)
4455

45-
file(GLOB_RECURSE FILES FOLLOW_SYMLINKS ${CMAKE_CURRENT_SOURCE_DIR} src/*.cpp)
56+
add_library(endlessh_core STATIC src/core.cpp)
4657

47-
add_executable(
48-
${PROJECT_NAME}
49-
50-
${FILES}
51-
)
58+
add_executable(${PROJECT_NAME} src/main.cpp)
5259

5360
target_link_libraries(
5461
${PROJECT_NAME}
55-
56-
date
57-
fmt
62+
PRIVATE
63+
endlessh_core
64+
date
65+
fmt
5866
)
5967

68+
target_link_libraries(endlessh_core PRIVATE fmt date)
69+
70+
if (BUILD_TESTING)
71+
add_subdirectory(tests)
72+
endif()
73+
6074
###
6175
# Docs target
6276
###
@@ -92,3 +106,10 @@ set(CPACK_PACKAGE_CONTACT "Simon Cahill <simon@simonc.eu>")
92106
set(CPACK_PACKAGE_VENDOR "Simon Cahill")
93107
set(CPACK_GENERATOR DEB)
94108
include(CPack)
109+
110+
# Coverage target that runs the coverage helper script
111+
add_custom_target(coverage
112+
COMMAND ${CMAKE_SOURCE_DIR}/scripts/coverage.sh
113+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
114+
COMMENT "Run tests and generate coverage report (requires lcov/genhtml)"
115+
)

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM ubuntu:22.04
2+
ENV DEBIAN_FRONTEND=noninteractive
3+
4+
RUN apt-get update && apt-get install -y \
5+
build-essential \
6+
cmake \
7+
lcov \
8+
git \
9+
ca-certificates \
10+
pkg-config \
11+
wget \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
WORKDIR /src
15+
16+
# Copy project into image
17+
COPY . /src
18+
19+
# Prepare build (do not run coverage at build time)
20+
RUN cmake -S . -B build -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug \
21+
&& cmake --build build -j
22+
23+
ENTRYPOINT ["/src/scripts/coverage.sh"]

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,13 @@ Switches:
7777
--detailed, -d Provide detailed information
7878
--help, -h Show this text and exit
7979
--version, -v Display version information and exit
80+
--sort, -x Sort IP statistics
81+
--dns-lookup, -D Perform DNS lookups on IP addresses
82+
--strict, -t Skip IPs whose cached stats haven't changed
8083
8184
Arguments:
8285
--syslog [f], -S[f] Override syslog/endlessh log location
86+
--cache-file[f],-C[f] Override persistent cache file location
8387
```
8488

8589
## Output

include/extensions.hpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ using std::chrono::seconds;
3131
using std::chrono::system_clock;
3232
using std::function;
3333
using std::string;
34+
using std::string_view;
3435
using std::vector;
3536

3637
/**
@@ -179,12 +180,8 @@ inline string getSpacerString(const uint32_t totalWidth, const uint32_t strLengt
179180
*
180181
* @return The trimmed string.
181182
*/
182-
inline string trimStart(string nonTrimmed, const string& trimChar) {
183-
//nonTrimmed.erase(nonTrimmed.begin(), find_if(nonTrimmed.begin(), nonTrimmed.end(), not1(ptr_fun<int32_t, int32_t>(isspace))));
184-
185-
function<bool(char)> shouldTrimChar = [=](char c) -> bool { return trimChar.size() == 0 ? isspace(c) : trimChar.find(c) != string::npos; };
186-
187-
nonTrimmed.erase(nonTrimmed.begin(), find_if(nonTrimmed.begin(), nonTrimmed.end(), not1(shouldTrimChar)));
183+
inline string& trimStart(string& nonTrimmed, const string_view trimChars) {
184+
nonTrimmed.erase(nonTrimmed.begin(), std::find_if(nonTrimmed.begin(), nonTrimmed.end(), [&trimChars](int ch) { return trimChars.find(static_cast<char>(ch)) == string_view::npos; }));
188185

189186
return nonTrimmed;
190187
}
@@ -196,11 +193,8 @@ inline string trimStart(string nonTrimmed, const string& trimChar) {
196193
*
197194
* @return The trimmed string.
198195
*/
199-
inline string trimEnd(string nonTrimmed, const string& trimChar) {
200-
// nonTrimmed.erase(find_if(nonTrimmed.rbegin(), nonTrimmed.rend(), not1(ptr_fun<int32_t, int32_t>(isspace))).base(), nonTrimmed.end());
201-
202-
function<bool(char)> shouldTrimChar = [=](char c) -> bool { return trimChar.size() == 0 ? isspace(c) : trimChar.find(c) != string::npos; };
203-
nonTrimmed.erase(find_if(nonTrimmed.rbegin(), nonTrimmed.rend(), not1(shouldTrimChar)).base(), nonTrimmed.end());
196+
inline string& trimEnd(string& nonTrimmed, const string_view trimChars) {
197+
nonTrimmed.erase(std::find_if(nonTrimmed.rbegin(), nonTrimmed.rend(), [&trimChars](int ch) { return trimChars.find(static_cast<char>(ch)) == string_view::npos; }).base(), nonTrimmed.end());
204198

205199
return nonTrimmed;
206200
}
@@ -213,7 +207,7 @@ inline string trimEnd(string nonTrimmed, const string& trimChar) {
213207
*
214208
* @return The trimmed string.
215209
*/
216-
inline string trim(const string& nonTrimmed, const string& trimChar) { return trimStart(trimEnd(nonTrimmed, trimChar), trimChar); }
210+
inline string& trim(string& nonTrimmed, const string_view trimChars) { return trimStart(trimEnd(nonTrimmed, trimChars), trimChars); }
217211

218212

219213
#endif // ENDLESSH_REPORT_INCLUDE_EXTENSIONS_HPP

include/options.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ using std::string_view;
3030
*
3131
* @return constexpr string_view The arg string as required for @see getopt_long
3232
*/
33-
constexpr string_view getAppArgs() { return R"(icsandhvS:)"; }
33+
constexpr string_view getAppArgs() { return R"(icsandhtvS:xDC:)"; }
3434

3535
/**
3636
* @brief Gets the application's command-line options for @see getopt_long.
@@ -44,9 +44,14 @@ const option* getAppOptions() {
4444
{ "stdin", no_argument, nullptr, 's' },
4545
{ "abuse-ipdb", no_argument, nullptr, 'a' },
4646
{ "detailed", no_argument, nullptr, 'd' },
47+
{ "strict", no_argument, nullptr, 't' },
48+
{ "cache-file", required_argument, nullptr, 'C' },
4749
{ "help", no_argument, nullptr, 'h' },
4850
{ "syslog", required_argument, nullptr, 'S' },
4951
{ "version", no_argument, nullptr, 'v' },
52+
{ "sort", no_argument, nullptr, 'x' },
53+
{ "no-ad", no_argument, nullptr, 'n' },
54+
{ "dns-lookup", no_argument, nullptr, 'D' },
5055
{ nullptr, no_argument, nullptr, 0 }
5156
};
5257

@@ -77,14 +82,18 @@ inline string getAppHelpText(const string_view& binName = getProjectNa
7782
--abuse-ipdb, -a Enable AbuseIPDB-compatible CSV output
7883
--no-ad, -n No advertising please!
7984
--detailed, -d Provide detailed information
85+
--strict, -t Skip IPs whose cached stats haven't changed
8086
--help, -h Show this text and exit
8187
--version, -v Display version information and exit
88+
--sort, -x Sort IP statistics
89+
--dns-lookup, -D Perform DNS lookups on IP addresses
8290
8391
Arguments:
8492
--syslog [f], -S[f] Override syslog/endlessh log location
93+
--cache-file[f],-C[f] Override persistent cache file location
8594
)";
8695

87-
return fmt::format(HELP_TEXT_FMT, binName, getApplicationVersion(), getProjectDescription());
96+
return fmt::format(fmt::runtime(HELP_TEXT_FMT), binName, getApplicationVersion(), getProjectDescription());
8897
}
8998

9099
/**

include/public_api.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @file public_api.hpp
3+
* @brief Public API wrappers for functions that are implemented in `main.cpp`.
4+
*/
5+
#ifndef ENDLESSH_REPORT_PUBLIC_API_HPP
6+
#define ENDLESSH_REPORT_PUBLIC_API_HPP
7+
8+
#include <string>
9+
10+
using std::string;
11+
12+
// Expose utility functions for unit testing.
13+
string normalizeIp(string ip);
14+
string getHostFromIp(const string& ip);
15+
// Global configuration flags used by the application. Tests may rely on defaults.
16+
extern bool g_performDnsLookup;
17+
18+
#endif // ENDLESSH_REPORT_PUBLIC_API_HPP

0 commit comments

Comments
 (0)