Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
build/
build-*/
.git/
node_modules/
*.o
*.so
*.dylib
*.dll
CMakeCache.txt
CMakeFiles/
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build directories
build/
build-*/

# CMake files
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
CTestTestfile.cmake
Makefile
*.cmake

# Compiled binaries
*.exe
*.out
*.app
*.so
*.dylib
*.dll

# Test outputs
Testing/

# IDE files
.vscode/
.idea/
*.swp
*.swo
*~

# macOS
.DS_Store

# Node modules (from pre-commit prettier)
node_modules/
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ auto addrs_all = gmlc::netif::getInterfaceAddressesAll(); // Get all addresses (
| macOS | ARM64 | [![CI](https://github.com/GMLC-TDC/netif/actions/workflows/build.yml/badge.svg)](https://github.com/GMLC-TDC/netif/actions/workflows/build.yml) |
| Windows 10 | x86_64 | [![CI](https://github.com/GMLC-TDC/netif/actions/workflows/build.yml/badge.svg)](https://github.com/GMLC-TDC/netif/actions/workflows/build.yml) |

## Testing

NetIF includes a comprehensive test environment that supports testing with virtual network interfaces. This allows testing of corner cases, including IPv6 addresses and multiple addresses per interface.

For more information about the test environment, see [tests/README.md](tests/README.md).

### Quick Test

```bash
mkdir -p build && cd build
cmake -DENABLE_NETIF_TESTS=ON ..
cmake --build .
ctest --verbose
```

### Testing with Virtual Interfaces (Linux)

```bash
# Setup virtual test interfaces
cd tests
sudo ./setup_virtual_interfaces.sh setup

# Export current configuration
./setup_virtual_interfaces.sh export expected_interfaces.txt

# Run tests with validation
cd ../build
export NETIF_EXPECTED_INTERFACES=../tests/expected_interfaces.txt
ctest --verbose

# Cleanup
cd ../tests
sudo ./setup_virtual_interfaces.sh teardown
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. See [Contributing](CONTRIBUTING) for more details and [Contributors](CONTRIBUTORS) for a list of the current and past contributors to this project.
Expand Down
1 change: 1 addition & 0 deletions _codeql_detected_source_root
31 changes: 31 additions & 0 deletions tests/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Dockerfile for testing NetIF with custom network configurations
# This provides an environment where we can create virtual network interfaces

FROM ubuntu:22.04

# Install required dependencies
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
iproute2 \
iputils-ping \
net-tools \
&& rm -rf /var/lib/apt/lists/*

# Create a working directory
WORKDIR /netif

# Copy the project files
COPY . /netif/

# Build the project
RUN mkdir -p build && cd build && \
cmake -DENABLE_NETIF_TESTS=ON .. && \
cmake --build .

# Entry point script
COPY tests/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["test"]
72 changes: 72 additions & 0 deletions tests/GetAddressTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ SPDX-License-Identifier: BSD-3-Clause
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>

#include "gmlc/netif/NetIF.hpp"
#include "InterfaceParser.hpp"

void printStringVector(std::string header, std::vector<std::string> vec)
{
Expand All @@ -27,10 +29,80 @@ TEST_CASE("Get IPv4 Addresses")
{
auto addrs = gmlc::netif::getInterfaceAddressesV4();
printStringVector("IPv4 Addresses", addrs);

// Optional validation if expected interfaces file is provided
const char* expected_file = std::getenv("NETIF_EXPECTED_INTERFACES");
if (expected_file != nullptr) {
auto expected = gmlc::netif::test::parseInterfaceFile(expected_file);
std::vector<std::string> missing_v4, missing_v6;
std::vector<std::string> empty_v6;

bool valid =
gmlc::netif::test::validateAddresses(addrs, empty_v6, expected, missing_v4, missing_v6);

if (!missing_v4.empty()) {
std::cout << "Missing expected IPv4 addresses:\n";
printStringVector("Missing IPv4", missing_v4);
}

REQUIRE(missing_v4.empty());
}
}

TEST_CASE("Get IPv6 Addresses")
{
auto addrs = gmlc::netif::getInterfaceAddressesV6();
printStringVector("IPv6 Addresses", addrs);

// Optional validation if expected interfaces file is provided
const char* expected_file = std::getenv("NETIF_EXPECTED_INTERFACES");
if (expected_file != nullptr) {
auto expected = gmlc::netif::test::parseInterfaceFile(expected_file);
std::vector<std::string> missing_v4, missing_v6;
std::vector<std::string> empty_v4;

bool valid =
gmlc::netif::test::validateAddresses(empty_v4, addrs, expected, missing_v4, missing_v6);

if (!missing_v6.empty()) {
std::cout << "Missing expected IPv6 addresses:\n";
printStringVector("Missing IPv6", missing_v6);
}

REQUIRE(missing_v6.empty());
}
}

TEST_CASE("Get All Addresses")
{
auto addrs = gmlc::netif::getInterfaceAddressesAll();
printStringVector("All Addresses", addrs);

// Verify the "All" function returns both IPv4 and IPv6
auto v4_addrs = gmlc::netif::getInterfaceAddressesV4();
auto v6_addrs = gmlc::netif::getInterfaceAddressesV6();

// All IPv4 addresses should be in the combined list
for (const auto& v4 : v4_addrs) {
bool found = false;
for (const auto& addr : addrs) {
if (addr == v4) {
found = true;
break;
}
}
REQUIRE(found);
}

// All IPv6 addresses should be in the combined list
for (const auto& v6 : v6_addrs) {
bool found = false;
for (const auto& addr : addrs) {
if (addr == v6) {
found = true;
break;
}
}
REQUIRE(found);
}
}
Loading