Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/basiliscos/cpp-empty_port
Finds empty port
https://github.com/basiliscos/cpp-empty_port
network testing
Last synced: 25 days ago
JSON representation
Finds empty port
- Host: GitHub
- URL: https://github.com/basiliscos/cpp-empty_port
- Owner: basiliscos
- License: mit
- Created: 2017-02-16T17:18:41.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2017-03-02T15:14:15.000Z (almost 8 years ago)
- Last Synced: 2024-11-17T09:41:00.658Z (3 months ago)
- Topics: network, testing
- Language: C++
- Size: 88.9 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cpp-empty_port
Finds empty port (C++, header-only)
linux [![Build Status](https://travis-ci.org/basiliscos/cpp-empty_port.png)](https://travis-ci.org/basiliscos/cpp-empty_port.png), windows [![Build status](https://ci.appveyor.com/api/projects/status/7lqgpi6kf8ajyd50?svg=true)](https://ci.appveyor.com/project/basiliscos/cpp-empty-port)
# synopsis
```cpp
#includenamespace ep = empty_port;
TEST_CASE("..." ) {
/* get first free port */
auto port = ep::get_random();
/* returns true or false */
ep::check_port(port);
/* waits until port will be occupied */
ep::wait_port(port);
}
```# API
```cpp
/* retrun true if port is ready for usage */
bool check_port(const port_t port, const char *host = "127.0.0.1");/* returns first available empty port or throws exception */
uint16_t get_random(const char *host = "127.0.0.1");/* waits until up to max_wait_ms before porta will be occupied.
Retruns true if it is, otherwise returns false */
<
T = Kind::TCP, typename D = std::chrono::milliseconds>
bool wait_port(const port_t port, const char *host = "127.0.0.1", D max_wait = D(500))
```# Description
This tiny library mimics Perl's [Net::EmptyPort](https://metacpan.org/pod/Net::EmptyPort). The idea is that it mihgt be rather easy to launch 3rd-party services, instead of mocking them, i.e. launch **redis**
```cpp
namespace ep = empty_port;
namespace ts = test_server;...;
uint16_t port = ep::get_random();
LOG_DEBUG("Using port :" << port);auto port_str = boost::lexical_cast(port);
auto server = ts::make_server({"redis-server", "--port", port_str});
ep::wait_port(port);
/* now it is possible to send requests for redis */```
or simple http-server, quickly written in scripting language:
```perl
# app.pgsi
my $app = sub {
my $env = shift;
return [
'200',
[ 'Content-Type' => 'text/plain' ],
[ "Hello World" ],
];
};```
and then use it in unit-tests:
```cpp
namespace ep = empty_port;
namespace ts = test_server;...;
uint16_t port = ep::get_random();
LOG_DEBUG("Using port :" << port);auto port_str = boost::lexical_cast(port);
auto server = ts::make_server({"plackup", "--port", port_str, "../t/app.psgi"} );
ep::wait_por(port);
LOG_DEBUG("app-server is ready on port " << port_str);```
The test-server RAII is unix-specific:
```cpp
#pragma once#include
#include
#include
#include
#include
#include#include
#include
#include
#include
#includenamespace test_server {
struct TestServer {
pid_t child_pid;
TestServer(std::initializer_list&& args) {
auto begin = args.begin();
auto end = args.end();auto program = (*begin).c_str();
auto args_count = args.size();
const char** c_args = (const char**) std::malloc(sizeof(char*) * (args_count + 1));
auto it = begin;
std::string stringized;
for (auto i = 0; i < args_count; i++, it++) {
const char* c_arg = (*it).c_str();
c_args[i] = c_arg;
stringized += " ";
stringized += c_arg;
}
c_args[args_count] = NULL;std::cout << "going to fork to start: " << stringized << "\n";
pid_t pid = fork();
if (pid == -1) {
throw std::runtime_error("cannot fork");
} else if (pid == 0) {
// child
std::cout << "executing in child" << "\n";
int result = execvp(program, (char* const*)c_args);
std::cout <<"failed to execute: " << strerror(errno) << "\n";
exit(-1);
} else {
// parent
child_pid = pid;
// sleep(5);
}
}
~TestServer() {
std::cout << "terminating child " << child_pid << "\n";
kill(child_pid, 9);
}
};using result_t = std::unique_ptr;
result_t make_server(std::initializer_list&& args) {
return std::make_unique(std::move(args));
}};
```