1
0
Fork 0
mirror of https://bitbucket.org/King_DuckZ/keepupnpup.git synced 2024-11-07 21:29:00 +00:00

Introduce rapidcheck and a basic test.

This commit is contained in:
King_DuckZ 2016-09-13 00:38:40 +02:00
parent ca316fffbb
commit 5659177217
8 changed files with 258 additions and 9 deletions

6
.gitmodules vendored
View file

@ -4,3 +4,9 @@
[submodule "lib/better-enums"] [submodule "lib/better-enums"]
path = lib/better-enums path = lib/better-enums
url = https://github.com/aantron/better-enums url = https://github.com/aantron/better-enums
[submodule "lib/gtest"]
path = lib/gtest
url = https://github.com/google/googletest.git
[submodule "lib/rapidcheck"]
path = lib/rapidcheck
url = https://github.com/emil-e/rapidcheck.git

View file

@ -2,8 +2,14 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
project(keepupnpup CXX) project(keepupnpup CXX)
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules) list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
set(CXX_STANDARD_REQUIRED ON)
option (USE_SYSTEM_MINIUPNP "Try to locate miniupnpc on the system and build against that" ON) option (USE_SYSTEM_MINIUPNP "Try to locate miniupnpc on the system and build against that" ON)
include(CTest)
find_package(Boost 1.55.0 REQUIRED)
if (USE_SYSTEM_MINIUPNP) if (USE_SYSTEM_MINIUPNP)
find_package(Miniupnpc 2.0 REQUIRED) find_package(Miniupnpc 2.0 REQUIRED)
else() else()
@ -17,35 +23,56 @@ else()
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "" FORCE) set(UPNPC_BUILD_SHARED OFF CACHE BOOL "" FORCE)
endif() endif()
set(UPNPC_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(UPNPC_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(CXX_STANDARD_REQUIRED ON)
add_subdirectory(lib/miniupnp/miniupnpc) add_subdirectory(lib/miniupnp/miniupnpc)
endif() endif()
add_executable(${PROJECT_NAME} add_executable(${PROJECT_NAME}
src/main.cpp src/main.cpp
)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
add_library(${PROJECT_NAME}_implem STATIC
src/upnp.cpp src/upnp.cpp
src/upnpexceptions.cpp src/upnpexceptions.cpp
src/find_redirections.cpp
) )
set_property(TARGET ${PROJECT_NAME}_implem PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET ${PROJECT_NAME}_implem PROPERTY CXX_STANDARD 14)
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}_implem
PRIVATE lib/better-enums PUBLIC lib/better-enums
)
target_include_directories(${PROJECT_NAME}_implem SYSTEM
PUBLIC ${Boost_INCLUDE_DIRS}
) )
if (USE_SYSTEM_MINIUPNP) if (USE_SYSTEM_MINIUPNP)
target_include_directories(${PROJECT_NAME} SYSTEM target_include_directories(${PROJECT_NAME}_implem SYSTEM
PRIVATE ${MINIUPNP_INCLUDE_DIR} PRIVATE ${MINIUPNP_INCLUDE_DIR}
) )
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}_implem
PRIVATE ${MINIUPNP_LIBRARY} PRIVATE ${MINIUPNP_LIBRARY}
) )
else() else()
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}_implem
PRIVATE lib/miniupnp/miniupnpc PRIVATE lib/miniupnp/miniupnpc
) )
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}_implem
libminiupnpc-${upnp_lib_type} PRIVATE libminiupnpc-${upnp_lib_type}
) )
endif() endif()
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) target_link_libraries(${PROJECT_NAME}
PRIVATE ${PROJECT_NAME}_implem
)
if (BUILD_TESTING)
set(BUILD_GTEST ON CACHE BOOL "" FORCE)
set(BUILD_GMOCK OFF CACHE BOOL "" FORCE)
set(RC_ENABLE_GTEST ON CACHE BOOL "" FORCE)
add_subdirectory(lib/gtest)
add_subdirectory(lib/rapidcheck)
add_subdirectory(test/unit)
endif()

1
lib/gtest Submodule

@ -0,0 +1 @@
Subproject commit 48ee8e98abc950abd8541e15550b18f8f6cfb3a9

1
lib/rapidcheck Submodule

@ -0,0 +1 @@
Subproject commit f5d3afa4f387ecf147faf98d96710a6edfa420f1

49
src/find_redirections.cpp Normal file
View file

@ -0,0 +1,49 @@
/* Copyright 2016, Michele Santullo
* This file is part of "keepupnpup".
*
* "keepupnpup" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "keepupnpup" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "keepupnpup". If not, see <http://www.gnu.org/licenses/>.
*/
#include "find_redirections.hpp"
#include <ciso646>
namespace kuu {
auto redirections_for_localaddr (
const RedirectionsList& parRedirs,
const std::string& parAddr,
uint16_t parPort,
Protocol parProto
) {
return parRedirs | boost::adaptors::filtered([=](const Redirection& parRedir) {
return parRedir.internal_port == parPort and
parRedir.protocol == parProto and
parRedir.internal_client == parAddr
;
});
}
auto redirections_not_for_localaddr (
const RedirectionsList& parRedirs,
const std::string& parAddr,
uint16_t parPort,
Protocol parProto
) {
return parRedirs | boost::adaptors::filtered([=](const Redirection& parRedir) {
return parRedir.internal_port == parPort and
parRedir.protocol == parProto and
parRedir.internal_client != parAddr
;
});
}
} //namespace kuu

41
src/find_redirections.hpp Normal file
View file

@ -0,0 +1,41 @@
/* Copyright 2016, Michele Santullo
* This file is part of "keepupnpup".
*
* "keepupnpup" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "keepupnpup" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "keepupnpup". If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "redirection.hpp"
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#include <cstdint>
namespace kuu {
using RedirectionsList = std::vector<Redirection>;
auto redirections_for_localaddr (
const RedirectionsList& parRedirs,
const std::string& parAddr,
uint16_t parPort,
Protocol parProto
);
auto redirections_not_for_localaddr (
const RedirectionsList& parRedirs,
const std::string& parAddr,
uint16_t parPort,
Protocol parProto
);
} //namespace kuu

23
test/unit/CMakeLists.txt Normal file
View file

@ -0,0 +1,23 @@
project(test_kuu CXX)
add_executable(${PROJECT_NAME}
test_upnp.cpp
)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
add_test(
NAME kuu
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${PROJECT_NAME}
)
target_link_libraries(${PROJECT_NAME}
PRIVATE keepupnpup_implem
PRIVATE gtest
PRIVATE gtest_main
PRIVATE rapidcheck_gtest
)
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_SOURCE_DIR}/src
)

101
test/unit/test_upnp.cpp Normal file
View file

@ -0,0 +1,101 @@
/* Copyright 2016, Michele Santullo
* This file is part of "keepupnpup".
*
* "keepupnpup" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "keepupnpup" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "keepupnpup". If not, see <http://www.gnu.org/licenses/>.
*/
#include "gtest/gtest.h"
#include "rapidcheck/gtest.h"
#include "redirection.hpp"
#include "find_redirections.hpp"
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
namespace {
std::string make_ip(uint8_t parA, uint8_t parB, uint8_t parC, uint8_t parD) {
std::ostringstream oss;
oss <<
static_cast<int>(parA) << '.' <<
static_cast<int>(parB) << '.' <<
static_cast<int>(parC) << '.' <<
static_cast<int>(parD)
;
return oss.str();
}
rc::Gen<std::string> generate_lan_ip() {
using namespace rc;
auto ip_any = gen::arbitrary<uint8_t>();
auto ip_pos = gen::positive<uint8_t>();
std::vector<Gen<std::string>> gens;
gens.push_back(gen::apply([](uint8_t c, uint8_t d) { return make_ip(192, 168, c, d); }, ip_any, ip_pos));
gens.push_back(gen::apply([](uint8_t b, uint8_t c, uint8_t d) { return make_ip(10, b, c, d); }, ip_any, ip_any, ip_pos));
gens.push_back(gen::apply([](uint8_t b, uint8_t c, uint8_t d) { return make_ip(172, b, c, d); }, gen::inRange<uint8_t>(16, 31), ip_any, ip_pos));
return gen::join(gen::elementOf(gens));
}
rc::Gen<std::string> generate_external_ip() {
using namespace rc;
auto ip_a = gen::suchThat(gen::inRange<uint8_t>(1, 254), [](uint8_t v) { return 192 != v and 10 != v and 172 != v; });
auto ip_b = gen::arbitrary<uint8_t>();
auto ip_c = gen::arbitrary<uint8_t>();
auto ip_d = gen::positive<uint8_t>();
return gen::apply(&make_ip, ip_a, ip_b, ip_c, ip_d);
}
rc::Gen<std::string> generate_description() {
using namespace rc;
return gen::nonEmpty(gen::resize(80, gen::container<std::string>(gen::inRange<char>('a', 'z'))));
}
} //unnamed namespace
namespace rc {
template <>
struct Arbitrary<kuu::Redirection> {
static Gen<kuu::Redirection> arbitrary() {
using kuu::Redirection;
return gen::build<Redirection>(
gen::set(&Redirection::internal_client, generate_lan_ip()),
gen::set(&Redirection::remote_host, generate_external_ip()),
gen::set(&Redirection::desc, generate_description()),
gen::set(&Redirection::protocol, gen::element<kuu::Protocol>(kuu::Protocol::TCP, kuu::Protocol::UDP)),
gen::set(&Redirection::duration, gen::just<uint32_t>(0)),
gen::set(&Redirection::internal_port),
gen::set(&Redirection::external_port),
gen::set(&Redirection::enabled, gen::just<bool>(true))
);
}
};
} //namespace rc
RC_GTEST_PROP(kuu, upnp, (const std::vector<kuu::Redirection>& parRedirections)) {
//for (auto& red : parRedirections) {
// std::cout << "internal_client: " << red.internal_client << '\n';
// std::cout << "remote_host: " << red.remote_host << '\n';
// std::cout << "desc: \"" << red.desc << "\" (" << red.desc.size() << ")\n";
// std::cout << "protocol: " << red.protocol << '\n';
// std::cout << "duration: " << red.duration << '\n';
// std::cout << "internal_port: " << red.internal_port << '\n';
// std::cout << "external_port: " << red.external_port << '\n';
// std::cout << "enabled: " << red.enabled << '\n';
// std::cout << "---------------------------------------------------------\n";
//}
}