140 lines
3.5 KiB
C++
140 lines
3.5 KiB
C++
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
|
|
// the main distribution directory for license terms and copyright or visit
|
|
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
|
|
|
|
#define CAF_SUITE net.doorman
|
|
|
|
#include "caf/net/doorman.hpp"
|
|
|
|
#include "caf/binary_serializer.hpp"
|
|
#include "caf/error.hpp"
|
|
#include "caf/net/endpoint_manager.hpp"
|
|
#include "caf/net/ip.hpp"
|
|
#include "caf/net/make_endpoint_manager.hpp"
|
|
#include "caf/net/multiplexer.hpp"
|
|
#include "caf/net/socket_guard.hpp"
|
|
#include "caf/net/tcp_accept_socket.hpp"
|
|
#include "caf/uri.hpp"
|
|
|
|
#include "caf/test/dsl.hpp"
|
|
|
|
#include "caf/net/test/host_fixture.hpp"
|
|
|
|
using namespace caf;
|
|
using namespace caf::net;
|
|
using namespace std::literals::string_literals;
|
|
|
|
namespace {
|
|
|
|
struct fixture : test_coordinator_fixture<>, host_fixture {
|
|
fixture() {
|
|
mpx = std::make_shared<multiplexer>();
|
|
if (auto err = mpx->init())
|
|
CAF_FAIL("mpx->init failed: " << err);
|
|
mpx->set_thread_id();
|
|
CAF_CHECK_EQUAL(mpx->num_socket_managers(), 1u);
|
|
auth.port = 0;
|
|
auth.host = "0.0.0.0"s;
|
|
}
|
|
|
|
bool handle_io_event() override {
|
|
return mpx->poll_once(false);
|
|
}
|
|
|
|
multiplexer_ptr mpx;
|
|
uri::authority_type auth;
|
|
};
|
|
|
|
class dummy_application {
|
|
public:
|
|
template <class Parent>
|
|
error init(Parent&) {
|
|
return none;
|
|
}
|
|
|
|
template <class Parent>
|
|
error write_message(Parent& parent,
|
|
std::unique_ptr<endpoint_manager_queue::message> msg) {
|
|
auto payload_buf = parent.next_payload_buffer();
|
|
binary_serializer sink{parent.system(), payload_buf};
|
|
if (auto err = sink(msg->msg->payload))
|
|
CAF_FAIL("serializing failed: " << err);
|
|
parent.write_packet(payload_buf);
|
|
return none;
|
|
}
|
|
|
|
template <class Parent>
|
|
error handle_data(Parent&, span<const byte>) {
|
|
return none;
|
|
}
|
|
|
|
template <class Parent>
|
|
void resolve(Parent&, string_view path, const actor& listener) {
|
|
anon_send(listener, resolve_atom_v,
|
|
"the resolved path is still "
|
|
+ std::string(path.begin(), path.end()));
|
|
}
|
|
|
|
template <class Parent>
|
|
void timeout(Parent&, const std::string&, uint64_t) {
|
|
// nop
|
|
}
|
|
|
|
template <class Parent>
|
|
void new_proxy(Parent&, actor_id) {
|
|
// nop
|
|
}
|
|
|
|
template <class Parent>
|
|
void local_actor_down(Parent&, actor_id, error) {
|
|
// nop
|
|
}
|
|
|
|
void handle_error(sec) {
|
|
// nop
|
|
}
|
|
};
|
|
|
|
class dummy_application_factory {
|
|
public:
|
|
using application_type = dummy_application;
|
|
|
|
template <class Parent>
|
|
error init(Parent&) {
|
|
return none;
|
|
}
|
|
|
|
application_type make() const {
|
|
return dummy_application{};
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
CAF_TEST_FIXTURE_SCOPE(doorman_tests, fixture)
|
|
|
|
CAF_TEST(doorman accept) {
|
|
auto acceptor = unbox(make_tcp_accept_socket(auth, false));
|
|
auto port = unbox(local_port(socket_cast<network_socket>(acceptor)));
|
|
auto acceptor_guard = make_socket_guard(acceptor);
|
|
CAF_MESSAGE("opened acceptor on port " << port);
|
|
auto mgr = make_endpoint_manager(
|
|
mpx, sys,
|
|
doorman<dummy_application_factory>{acceptor_guard.release(),
|
|
dummy_application_factory{}});
|
|
CAF_CHECK_EQUAL(mgr->init(), none);
|
|
auto before = mpx->num_socket_managers();
|
|
CAF_CHECK_EQUAL(before, 2u);
|
|
uri::authority_type dst;
|
|
dst.port = port;
|
|
dst.host = "localhost"s;
|
|
CAF_MESSAGE("connecting to doorman on: " << dst);
|
|
auto conn = make_socket_guard(unbox(make_connected_tcp_stream_socket(dst)));
|
|
CAF_MESSAGE("waiting for connection");
|
|
while (mpx->num_socket_managers() != before + 1)
|
|
run();
|
|
CAF_MESSAGE("connected");
|
|
}
|
|
|
|
CAF_TEST_FIXTURE_SCOPE_END()
|