diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index e04040d821..83008f194c 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -154,7 +154,7 @@ jobs: if-no-files-found: error - name: Push image - if: github.ref == 'refs/heads/${{ env.DEFAULT_BRANCH }}' + if: ${{ github.ref == format('refs/heads/{0}', env.DEFAULT_BRANCH) }} run: | echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin docker push "${{ needs.strings.outputs.docker-image-tag }}" diff --git a/nel/include/nel/net/callback_net_base.h b/nel/include/nel/net/callback_net_base.h index 3efb068a4e..ce616454e9 100644 --- a/nel/include/nel/net/callback_net_base.h +++ b/nel/include/nel/net/callback_net_base.h @@ -31,6 +31,7 @@ #include #endif +#include #include @@ -43,7 +44,7 @@ class CCallbackNetBase; * msgin contains parameters of the message * from is the SockId of the connection, for a client, from is always the same value */ -typedef void (*TMsgCallback) (CMessage &msgin, TSockId from, CCallbackNetBase &netbase); +typedef std::function TMsgCallback; /// Callback items. See CMsgSocket::update() for an explanation on how the callbacks are called. diff --git a/nel/src/net/callback_net_base.cpp b/nel/src/net/callback_net_base.cpp index 7a117f6403..70f260e0d8 100644 --- a/nel/src/net/callback_net_base.cpp +++ b/nel/src/net/callback_net_base.cpp @@ -206,7 +206,7 @@ void CCallbackNetBase::processOneMessage () } else { - LNETL3_DEBUG ("LNETL3NB_CB: Calling callback (%s)%s", msgin.getName().c_str(), (cb==_DefaultCallback)?" DEFAULT_CB":""); + LNETL3_DEBUG ("LNETL3NB_CB: Calling callback (%s)", msgin.getName().c_str()); if (_PreDispatchCallback != NULL) { diff --git a/nelns/naming_service/nelns/naming_service/functions.cpp b/nelns/naming_service/nelns/naming_service/functions.cpp index 32d533070a..37f819cc11 100644 --- a/nelns/naming_service/nelns/naming_service/functions.cpp +++ b/nelns/naming_service/nelns/naming_service/functions.cpp @@ -420,28 +420,6 @@ void cbResendRegisteration(CMessage &msgin, TSockId from, CCallbackNetBase &netb doRegister(name, addr, sid, from, netbase, true); } -/** - * Callback for service registration. - * - * Message expected : RG - * - Name of service to register (string) - * - Address of service (CInetAddress) - * - * Message emitted : RG - * - Allocated service identifier (TServiceId) or 0 if failed - */ -void cbRegister(CMessage &msgin, TSockId from, CCallbackNetBase &netbase) -{ - string name; - vector addr; - TServiceId sid; - msgin.serial(name); - msgin.serialCont(addr); - msgin.serial(sid); - - doRegister(name, addr, sid, from, netbase); -} - /** * Callback for service unregistration. * diff --git a/nelns/naming_service/nelns/naming_service/functions.h b/nelns/naming_service/nelns/naming_service/functions.h index 9959349a9e..41b33b5fb4 100644 --- a/nelns/naming_service/nelns/naming_service/functions.h +++ b/nelns/naming_service/nelns/naming_service/functions.h @@ -50,18 +50,6 @@ void cbACKUnregistration(NLNET::CMessage &msgin, NLNET::TSockId from, NLNET::CCa */ void cbResendRegisteration(NLNET::CMessage &msgin, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase); -/** - * Callback for service registration. - * - * Message expected : RG - * - Name of service to register (string) - * - Address of service (CInetAddress) - * - * Message emitted : RG - * - Allocated service identifier (TServiceId) or 0 if failed - */ -void cbRegister(NLNET::CMessage &msgin, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase); - /** * Callback for service unregistration. * diff --git a/nelns/naming_service/nelns/naming_service/naming_service.cpp b/nelns/naming_service/nelns/naming_service/naming_service.cpp index 757d2ad959..efcce08190 100644 --- a/nelns/naming_service/nelns/naming_service/naming_service.cpp +++ b/nelns/naming_service/nelns/naming_service/naming_service.cpp @@ -18,26 +18,15 @@ using std::vector; using NLMISC::CConfigFile; using NLMISC::Exception; using NLMISC::toString; +using NLNET::CCallbackNetBase; using NLNET::CCallbackServer; using NLNET::CInetAddress; +using NLNET::CMessage; using NLNET::CUnifiedNetwork; using NLNET::TCallbackItem; using NLNET::TServiceId; using NLNET::TSockId; -// -// Callback array -// - -TCallbackItem CallbackArray[] = { - { "RG", cbRegister }, - { "RRG", cbResendRegisteration }, - { "QP", cbQueryPort }, - { "UNI", cbUnregisterSId }, - { "ACK_UNI", cbACKUnregistration }, - // { "RS", cbRegisteredServices }, -}; - /** * Init */ @@ -105,6 +94,14 @@ void CNamingService::init() nsport = var->asInt(); } + TCallbackItem CallbackArray[] = { + { "RG", [=](auto &msgin, auto from, auto &netbase) { cbRegister(msgin, from); } }, + { "RRG", cbResendRegisteration }, + { "QP", cbQueryPort }, + { "UNI", cbUnregisterSId }, + { "ACK_UNI", cbACKUnregistration }, + // { "RS", cbRegisteredServices }, + }; CallbackServer = new CCallbackServer; CallbackServer->init(nsport); CallbackServer->addCallbackArray(CallbackArray, sizeof(CallbackArray) / sizeof(CallbackArray[0])); @@ -130,3 +127,15 @@ void CNamingService::release() delete CallbackServer; CallbackServer = NULL; } + +void CNamingService::cbRegister(CMessage &msgin, TSockId from) +{ + string name; + vector addr; + TServiceId sid; + msgin.serial(name); + msgin.serialCont(addr); + msgin.serial(sid); + + doRegister(name, addr, sid, from, *CallbackServer); +} diff --git a/nelns/naming_service/nelns/naming_service/naming_service.h b/nelns/naming_service/nelns/naming_service/naming_service.h index c4c41babe3..6e43836cc3 100644 --- a/nelns/naming_service/nelns/naming_service/naming_service.h +++ b/nelns/naming_service/nelns/naming_service/naming_service.h @@ -2,6 +2,8 @@ #define NELNS_NAMING_SERVICE_SERVICE_NAMING_SERVICE_H #include +#include +#include #include #include @@ -26,6 +28,18 @@ class CNamingService : public NLNET::IService void release(); private: + /** + * Callback for service registration. + * + * Message expected : RG + * - Name of service to register (string) + * - Address of service (CInetAddress) + * + * Message emitted : RG + * - Allocated service identifier (TServiceId) or 0 if failed + */ + void cbRegister(NLNET::CMessage &msgin, NLNET::TSockId from); + /// Service instance manager singleton CServiceInstanceManager _ServiceInstances; }; diff --git a/nelns/naming_service/tests/CMakeLists.txt b/nelns/naming_service/tests/CMakeLists.txt index b28a912800..1e7050e586 100644 --- a/nelns/naming_service/tests/CMakeLists.txt +++ b/nelns/naming_service/tests/CMakeLists.txt @@ -1,22 +1,29 @@ -add_test_executable(do_allocate_port_test +add_test_executable(nelns_do_allocate_port_test do_allocate_port.test.cpp ) -target_link_libraries(do_allocate_port_test +target_link_libraries(nelns_do_allocate_port_test nelns::ns ) -add_test_executable(naming_service_test +add_test_executable(nelns_naming_service_test naming_service.test.cpp ) -target_link_libraries(naming_service_test +target_link_libraries(nelns_naming_service_test nelns::ns ) -add_test_executable(service_instance_manager_test +add_test_executable(nelns_service_instance_manager_test service_instance_manager.test.cpp ) -target_link_libraries(service_instance_manager_test +target_link_libraries(nelns_service_instance_manager_test + nelns::ns +) + +add_test_executable(nelns_naming_service_it + naming_service.it.cpp +) +target_link_libraries(nelns_naming_service_it nelns::ns ) diff --git a/nelns/naming_service/tests/naming_service.it.cpp b/nelns/naming_service/tests/naming_service.it.cpp new file mode 100644 index 0000000000..a93fea964b --- /dev/null +++ b/nelns/naming_service/tests/naming_service.it.cpp @@ -0,0 +1,198 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using ::std::nullopt; +using ::std::optional; +using ::std::string; +using ::std::vector; +using ::testing::AllOf; +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Field; +using ::testing::FieldsAre; +using ::testing::IsFalse; +using ::testing::IsNull; +using ::testing::IsTrue; +using ::testing::Not; +using ::testing::NotNull; +using ::testing::Optional; +using ::testing::Property; +using ::testing::SizeIs; +using ::testing::StrEq; + +using CVar = ::NLMISC::CConfigFile::CVar; +using ::NLMISC::IStream; +using ::NLNET::CCallbackClient; +using ::NLNET::CCallbackNetBase; +using ::NLNET::CInetAddress; +using ::NLNET::CInetHost; +using ::NLNET::CMessage; +using ::NLNET::TCallbackItem; +using ::NLNET::TServiceId; +using ::NLNET::TSockId; + +struct RGBResponseEntry +{ + string name; + TServiceId sid; + vector addr; + void serial(IStream &stream) + { + stream.serial(name); + stream.serial(sid); + stream.serialCont(addr); + } +}; + +struct RGBResponse +{ + vector items; + void serial(IStream &stream) + { + TServiceId::size_type size; + stream.serial(size); + for (TServiceId::size_type i = 0; i < size; ++i) + { + RGBResponseEntry entry; + + stream.serial(entry); + items.push_back(entry); + } + } +}; + +struct RGResponse +{ + bool success; + optional sid; + optional content; + optional reason; + void serial(IStream &stream) + { + stream.serial(success); + + if (success) + { + TServiceId sidIn; + stream.serial(sidIn); + sid = sidIn; + RGBResponse contentIn; + stream.serial(contentIn); + content = contentIn; + } + else + { + string reasonIn; + stream.serial(reasonIn); + reason = reasonIn; + } + } +}; + +struct RGRequest +{ + TServiceId serviceId; + string name; + vector addresses; + + void serial(IStream &stream) + { + stream.serial(name); + stream.serialCont(addresses); + stream.serial(serviceId); + } +}; + +class CNamingServiceIT : public testing::Test +{ +protected: + CCallbackClient client; + CNamingService instance; + int port = 50000; + + void SetUp() override + { + CVar basePort; + basePort.Type = NLMISC::CConfigFile::CVar::T_INT; + basePort.setAsInt(51000); + instance.ConfigFile.insertVar("BasePort", basePort); + + CVar uniqueOnShardServices; + uniqueOnShardServices.Type = NLMISC::CConfigFile::CVar::T_STRING; + uniqueOnShardServices.setAsString((vector) {}); + instance.ConfigFile.insertVar("UniqueOnShardServices", uniqueOnShardServices); + + CVar uniqueByMachineServices; + uniqueByMachineServices.Type = NLMISC::CConfigFile::CVar::T_STRING; + uniqueByMachineServices.setAsString((vector) {}); + instance.ConfigFile.insertVar("UniqueByMachineServices", uniqueByMachineServices); + + CVar nsPort; + nsPort.Type = NLMISC::CConfigFile::CVar::T_INT; + nsPort.setAsInt(port); + instance.ConfigFile.insertVar("NSPort", nsPort); + instance.init(); + + CInetHost host("localhost"); + host.setPort(port); + client.connect(host); + ASSERT_THAT(client.connected(), IsTrue()); + } + + void TearDown() override + { + client.disconnect(); + } +}; + +TEST_F(CNamingServiceIT, shouldAnswerToRegistration) +{ + RGRequest request{ + .serviceId = TServiceId(123), + .name = "test-service", + .addresses = {"localhost:12345"} + }; + CMessage msgout("RG"); + msgout.serial(request); + + RGResponse response; + TCallbackItem callbackArray[] = { + { "RG", [&response](CMessage &msgin, TSockId from, CCallbackNetBase &netbase) { + msgin.serial(response); + } } + }; + client.addCallbackArray(callbackArray, sizeof(callbackArray) / sizeof(callbackArray[0])); + + client.send(msgout); + client.flush(); + instance.update(); + client.update2(-1, 100); + + EXPECT_THAT(response.success, IsTrue()); + EXPECT_THAT(response.sid, Optional(Eq(request.serviceId))); + EXPECT_THAT( + response.content, + Optional(Field(&RGBResponse::items, + ElementsAre( + AllOf( + Field(&RGBResponseEntry::name, "test-service"), + Field(&RGBResponseEntry::sid, Eq(request.serviceId)), + Field(&RGBResponseEntry::addr, ElementsAre(Property(&CInetAddress::asString, "[::1]:12345")))))))); +}