Mining/miner/proxy/README_TESTS.md

7.9 KiB

Testing Guide for Miner Proxy

This document provides comprehensive guidance on testing the miner-proxy project.

Quick Start

# Build and run all tests
mkdir build && cd build
cmake ..
make -j$(nproc)
cd tests
make -j$(nproc)
./unit_tests
./integration_tests

Test Framework

We use Google Test (gtest) version 1.14.0, automatically fetched via CMake's FetchContent.

Test Organization

Unit Tests (tests/unit/)

Test individual components in isolation:

Test File Component Status
test_counters.cpp Share counters, miner count Complete
test_custom_diff.cpp Per-user difficulty Complete
test_error.cpp Error code mapping Complete
test_worker.cpp Worker tracking Complete
test_login.cpp Login validation 🚧 Needs mocks
test_nonce_mapper.cpp Nonce transformation 🚧 Needs mocks

Integration Tests (tests/integration/)

Test component interactions:

Test File Purpose Status
test_splitter_nicehash.cpp NiceHash splitter flow 🚧 Needs mocks
test_splitter_simple.cpp Simple splitter mode 🚧 Needs mocks
test_event_system.cpp Event dispatching 🚧 Needs setup

Test Utilities (tests/utils/)

  • test_helpers.h/cpp - Base test fixtures, mock objects, test data generators
  • ProxyTestBase - Common test fixture with temp file management
  • TestDataGenerator - Generate valid stratum JSON (login, job, submit)
  • MockController - Placeholder for Controller mocking

Running Tests

All Tests

cd build
ctest --output-on-failure

Specific Test Suite

./tests/unit_tests --gtest_filter=CountersTest.*
./tests/unit_tests --gtest_filter=CustomDiffTest.*

Single Test

./tests/unit_tests --gtest_filter=CountersTest.InitialStateIsZero

List Available Tests

./tests/unit_tests --gtest_list_tests

Verbose Output

./tests/unit_tests --gtest_verbose

Repeat Tests

./tests/unit_tests --gtest_repeat=100

Shuffle Test Order

./tests/unit_tests --gtest_shuffle

Code Coverage

Generate Coverage Report

# Configure with coverage flags
mkdir build-coverage && cd build-coverage
cmake .. -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_CXX_FLAGS="--coverage" \
  -DCMAKE_C_FLAGS="--coverage"

# Build and run tests
make -j$(nproc)
cd tests && make -j$(nproc)
./unit_tests
./integration_tests

# Generate HTML report
gcovr --root ../.. --exclude ../../tests \
  --html --html-details -o coverage.html

# Open in browser
xdg-open coverage.html

Coverage Tools

  • gcovr - Recommended, included in most Linux distros
  • lcov - Alternative tool with HTML output
  • Codecov - CI integration (automatic via GitHub Actions)

CI/CD Integration

Tests run automatically on:

  • Every push to main or develop
  • All pull requests
  • Manual workflow dispatch

Platforms tested:

  • Linux (Ubuntu latest) - Primary platform
  • macOS (latest) - Secondary platform
  • Windows (latest) - Compatibility check

See .github/workflows/test.yml for configuration.

Writing New Tests

Unit Test Template

#include <gtest/gtest.h>
#include "proxy/YourComponent.h"
#include "../utils/test_helpers.h"

using namespace xmrig;
using namespace xmrig::test;

class YourComponentTest : public ProxyTestBase {
protected:
    void SetUp() override {
        ProxyTestBase::SetUp();
        component = new YourComponent();
    }

    void TearDown() override {
        delete component;
        ProxyTestBase::TearDown();
    }

    YourComponent* component = nullptr;
};

TEST_F(YourComponentTest, DescriptiveTestName) {
    // Arrange
    int input = 42;

    // Act
    int result = component->process(input);

    // Assert
    EXPECT_EQ(result, 84);
    ASSERT_NE(component, nullptr);
}

Integration Test Template

#include <gtest/gtest.h>
#include "../utils/test_helpers.h"

using namespace xmrig;
using namespace xmrig::test;

class SystemIntegrationTest : public ProxyTestBase {
protected:
    void SetUp() override {
        ProxyTestBase::SetUp();
        // Setup multiple components
    }
};

TEST_F(SystemIntegrationTest, EndToEndFlow) {
    // Test complete workflow through multiple components
    SUCCEED();
}

Test Best Practices

Naming Conventions

  • Test files: test_<component>.cpp
  • Test fixtures: <Component>Test
  • Test cases: <DescriptiveAction><ExpectedResult>

Examples:

  • TEST_F(CountersTest, IncrementMinerCount)
  • TEST_F(CustomDiffTest, OverwriteExistingDifficulty)

Assertions

Use appropriate assertions:

  • EXPECT_* - Continues test on failure (preferred for multiple checks)
  • ASSERT_* - Stops test on failure (use for critical checks)

Common assertions:

EXPECT_EQ(a, b)         // a == b
EXPECT_NE(a, b)         // a != b
EXPECT_LT(a, b)         // a < b
EXPECT_LE(a, b)         // a <= b
EXPECT_GT(a, b)         // a > b
EXPECT_GE(a, b)         // a >= b
EXPECT_TRUE(condition)
EXPECT_FALSE(condition)
EXPECT_STREQ(s1, s2)    // C strings

Test Organization

  1. Arrange - Set up test data and conditions
  2. Act - Execute the code under test
  3. Assert - Verify the results

Test Independence

  • Each test should be independent
  • Use SetUp() and TearDown() for initialization/cleanup
  • Don't rely on test execution order

Debugging Tests

Run with GDB

gdb --args ./tests/unit_tests --gtest_filter=CountersTest.InitialStateIsZero
(gdb) break CountersTest_InitialStateIsZero_Test::TestBody
(gdb) run

Valgrind Memory Check

valgrind --leak-check=full --show-leak-kinds=all \
  ./tests/unit_tests --gtest_filter=CountersTest.*

Address Sanitizer

# Configure with ASAN
cmake .. -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer"

# Build and run
make -j$(nproc)
./tests/unit_tests

Future Enhancements

Priority 1 - Mocking Infrastructure

  • Create mock implementations for Controller, IClient, IStrategy
  • Complete NonceMapper and Login integration tests
  • Mock libuv networking for full E2E tests

Priority 2 - Protocol Testing

  • Stratum protocol request/response validation
  • Invalid input handling (fuzzing)
  • Protocol extension tests (NiceHash, algorithm negotiation)

Priority 3 - Performance Testing

  • Load tests with 100K+ simulated miners
  • Nonce mapping throughput benchmarks
  • Memory usage profiling under load
  • Connection handling stress tests

Priority 4 - Additional Coverage

  • TLS/SSL connection tests
  • Configuration loading/validation
  • HTTP API endpoint tests
  • Log output validation
  • Platform-specific code (Windows/macOS/Linux)

Troubleshooting

Tests Won't Build

# Clean build
rm -rf build
mkdir build && cd build
cmake .. -DBUILD_TESTS=ON
make clean
make -j$(nproc)

Google Test Not Found

Google Test is automatically downloaded via CMake FetchContent. If you have network issues:

# Download manually
git clone https://github.com/google/googletest.git
cd googletest && mkdir build && cd build
cmake .. && make && sudo make install

Ensure all dependencies are installed:

# Ubuntu/Debian
sudo apt-get install libuv1-dev libssl-dev

# macOS
brew install libuv openssl

# Check CMake finds them
cmake .. -DWITH_TLS=ON -DWITH_HTTP=ON

Contributing

When adding new features:

  1. Write tests first (TDD approach recommended)
  2. Ensure all existing tests pass
  3. Add integration tests for new subsystems
  4. Update this documentation
  5. Verify CI passes on all platforms

Resources