Skip to content

Commit

Permalink
Merge pull request #5 from CESNET/tests
Browse files Browse the repository at this point in the history
Introduce unit tests for Telemetry library
  • Loading branch information
SiskaPavel authored May 3, 2024
2 parents 87f22a1 + 48a77c4 commit f41537e
Show file tree
Hide file tree
Showing 26 changed files with 1,768 additions and 2 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
build-os-matrix:
needs: check
runs-on: ubuntu-latest
outputs:
outputs:
os: ${{ steps.os.outputs.os }}
steps:
- name: Build OS Array
Expand Down Expand Up @@ -38,3 +38,11 @@ jobs:
uses: ./.github/workflows/rpm-test.yml
with:
os: ${{ matrix.os }}
make-test:
needs: [build-os-matrix, build]
strategy:
matrix:
os: ${{ fromJSON(needs.build-os-matrix.outputs.os) }}
uses: ./.github/workflows/make-test.yml
with:
os: ${{ matrix.os }}
2 changes: 1 addition & 1 deletion .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
inline_suppression: enable
output_file: 'cppcheck_report.txt'
enable: warning,performance,portability,style,information
other_options: --error-exitcode=1
other_options: --error-exitcode=1 --library=googletest
- name: Print cppcheck_report.txt
if: failure()
run: cat cppcheck_report.txt
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/make-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: make-test

on:
workflow_call:
inputs:
os:
required: true
type: string

jobs:
make-test:
runs-on: ubuntu-latest
container: ${{ inputs.os }}
steps:
- name: Install dependencies
run: |
dnf install -y make gcc-c++ cmake3 git rpm-build fuse3-devel
- name: Check out repository code
uses: actions/checkout@v4
- name: Mark github workspace as safe
run: git config --system --add safe.directory $PWD
- name: make test
run: make test
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include(cmake/installation.cmake)
option(TELEMETRY_BUILD_SHARED "Build shared library" ON)
option(TELEMETRY_PACKAGE_BUILDER "Enable RPM package builder (make rpm)" ON)
option(TELEMETRY_INSTALL_TARGETS "Generate the install target" ON)
option(TELEMETRY_ENABLE_TESTS "Build Unit tests (make test)" OFF)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -32,8 +33,16 @@ endif()

include(cmake/dependencies.cmake)

if (TELEMETRY_ENABLE_TESTS)
include(cmake/googletest.cmake)
include(GoogleTest)
enable_testing()
endif()

add_subdirectory(src)

if (TELEMETRY_PACKAGE_BUILDER)
add_subdirectory(pkg)
endif()


6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ tidy: all
tidy-fix: all
$(RUN_CLANG_TIDY) -p build -quiet -fix -j $(shell nproc) $(SOURCE_DIR)

.PHONY: test
test: build
@cd build && $(CMAKE) $(CMAKE_ARGS) -DTELEMETRY_ENABLE_TESTS=ON ..
@$(MAKE) --no-print-directory -C build
@$(MAKE) test --no-print-directory -C build

15 changes: 15 additions & 0 deletions cmake/googletest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Google Test library
#
# Google Test is a testing framework for C++ developed by Google.
#
# This CMake script integrates Google Test into the project, allowing easy usage.
# Usage example: target_link_libraries(my_target PRIVATE GTest::gtest_main)

include(FetchContent)

FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
8 changes: 8 additions & 0 deletions src/telemetry/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ if (TELEMETRY_INSTALL_TARGETS)
install(TARGETS telemetry LIBRARY DESTINATION ${INSTALL_DIR_LIB})
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION ${INSTALL_DIR_INCLUDE})
endif()

if (TELEMETRY_ENABLE_TESTS)
add_executable(testTelemetry ${TELEMETRY_SOURCE_FILES})
target_compile_definitions(testTelemetry PRIVATE TELEMETRY_ENABLE_TESTS)
target_include_directories(testTelemetry PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(testTelemetry GTest::gtest_main)
gtest_discover_tests(testTelemetry)
endif()
4 changes: 4 additions & 0 deletions src/telemetry/aggFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,7 @@ AggregatedFile::AggregatedFile(
}

} // namespace telemetry

#ifdef TELEMETRY_ENABLE_TESTS
#include "tests/testAggFile.cpp"
#endif
4 changes: 4 additions & 0 deletions src/telemetry/aggregator/aggAvg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ Content AggMethodAvg::aggregate(const std::vector<Content>& contents)
}

} // namespace telemetry

#ifdef TELEMETRY_ENABLE_TESTS
#include "tests/testAggAvg.cpp"
#endif
4 changes: 4 additions & 0 deletions src/telemetry/aggregator/aggJoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ Content AggMethodJoin::aggregate(const std::vector<Content>& contents)
}

} // namespace telemetry

#ifdef TELEMETRY_ENABLE_TESTS
#include "tests/testAggJoin.cpp"
#endif
4 changes: 4 additions & 0 deletions src/telemetry/aggregator/aggSum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,7 @@ Content AggMethodSum::aggregate(const std::vector<Content>& contents)
}

} // namespace telemetry

#ifdef TELEMETRY_ENABLE_TESTS
#include "tests/testAggSum.cpp"
#endif
152 changes: 152 additions & 0 deletions src/telemetry/aggregator/tests/testAggAvg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/**
* @file
* @author Pavel Siska <siska@cesnet.cz>
* @brief Unit tests of Telemetry::AggMethodAvg
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <telemetry/directory.hpp>

#include <gtest/gtest.h>

namespace telemetry {

/**
* @test Test making average from a result and count
*/
TEST(AggAvgTest, TestMakeAverage)
{
// Test making average from uint64_t
{
Scalar result = uint64_t(100);
makeAverage(result, 10);
EXPECT_EQ(10.0, std::get<double>(result));
}

// Test making average from int64_t
{
Scalar result = int64_t(100);
makeAverage(result, 20);
EXPECT_EQ(5.0, std::get<double>(result));
}

// Test making average from double
{
Scalar result = 100.0;
makeAverage(result, 50);
EXPECT_EQ(2.0, std::get<double>(result));
}

// Test making average from unsupported type (expect failure)
{
Scalar result = true;
EXPECT_THROW(makeAverage(result, 10), TelemetryException);
}
}

/**
* @test Test converting aggregated content to an average value
*/
TEST(AggAvgTest, convertToAverage)
{
// Test converting Scalar to average
{
AggContent aggContent = Scalar {5.0};
ResultType result = convertToAverage(aggContent, 10);
EXPECT_TRUE(std::holds_alternative<Scalar>(result));
const auto& scalar = std::get<Scalar>(result);
EXPECT_EQ(0.5, std::get<double>(scalar));
}

// Test converting ScalarWithUnit to average
{
AggContent aggContent = ScalarWithUnit {5.0, "unit"};
ResultType result = convertToAverage(aggContent, 2);
EXPECT_TRUE(std::holds_alternative<ScalarWithUnit>(result));
const auto& [scalar, unit] = std::get<ScalarWithUnit>(result);
EXPECT_EQ(2.5, std::get<double>(scalar));
EXPECT_EQ("unit", unit);
}

// Test converting unsupported type to average (expect failure)
{
AggContent aggContent = std::monostate();
EXPECT_THROW(convertToAverage(aggContent, 2), TelemetryException);
}
}

/**
* @test Test aggregation method for averaging values
*/
TEST(AggAvgTest, TestAggregate)
{
// Test aggregation of scalar values
{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {Scalar {5.0}, Scalar {10.0}, Scalar {15.0}};
Content content = aggMethodAvg.aggregate(contents);
EXPECT_TRUE(std::holds_alternative<Scalar>(content));
Scalar& scalar = std::get<Scalar>(content);
EXPECT_TRUE(std::holds_alternative<double>(scalar));
double result = std::get<double>(scalar);
EXPECT_EQ(10.0, result);
}

// Test aggregation of ScalarWithUnit values
{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {ScalarWithUnit {5.0, "unit"}};
Content content = aggMethodAvg.aggregate(contents);
EXPECT_TRUE(std::holds_alternative<ScalarWithUnit>(content));
const auto& [scalar, unit] = std::get<ScalarWithUnit>(content);
EXPECT_EQ(5.0, std::get<double>(scalar));
EXPECT_EQ("unit", unit);
}

{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {ScalarWithUnit {5.0, "unit"}, Scalar {5.0}};
EXPECT_THROW(aggMethodAvg.aggregate(contents), TelemetryException);
}

{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {Scalar {true}, Scalar {5.0}};
EXPECT_THROW(aggMethodAvg.aggregate(contents), TelemetryException);
}

{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {Scalar {uint64_t(20)}, Scalar {5.0}};
EXPECT_THROW(aggMethodAvg.aggregate(contents), TelemetryException);
}

{
AggMethodAvg aggMethodAvg;
std::vector<Content> contents = {Scalar {uint64_t(20)}, uint64_t {5}};
Content content = aggMethodAvg.aggregate(contents);
EXPECT_TRUE(std::holds_alternative<Scalar>(content));
const auto& scalar = std::get<Scalar>(content);
EXPECT_EQ(12.5, std::get<double>(scalar));
}

// Test aggregation of dictionaries
{
AggMethodAvg aggMethodAvg;
aggMethodAvg.setDictField("packets", "packetsSum");
std::vector<Content> contents
= {Dict({{"packets", Scalar {uint64_t(1)}}}),
Dict({{"packets", Scalar {uint64_t(5)}}})};
Content content = aggMethodAvg.aggregate(contents);
EXPECT_TRUE(std::holds_alternative<Dict>(content));

const Dict& dict = std::get<Dict>(content);
EXPECT_EQ(1, dict.size());

const Scalar& scalarValueAvg = std::get<Scalar>(dict.at("packetsSum"));
EXPECT_EQ(3.0, std::get<double>(scalarValueAvg));
}
}

} // namespace telemetry
Loading

0 comments on commit f41537e

Please sign in to comment.