# See the License for the specific language governing permissions and
# limitations under the License
-ADD_VIST_COMMON_LIBRARY(vist_rmi client.cpp
- server.cpp
- exposer.cpp
+ADD_VIST_COMMON_LIBRARY(vist_rmi exposer.cpp
remote.cpp)
FILE(GLOB RMI_TESTS "tests/*.cpp")
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file client.cpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Implementation of client application.
- */
-
-#include "client.hpp"
-
-namespace vist {
-namespace rmi {
-
-Client::Client(const std::string& remotePath) : connection(remotePath)
-{
-}
-
-} // namespace rmi
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file client.hpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Client application for invoking remote function(method).
- */
-
-#pragma once
-
-#include <vist/transport/connection.hpp>
-#include <vist/transport/message.hpp>
-
-#include <string>
-#include <mutex>
-
-using namespace vist::transport;
-
-namespace vist {
-namespace rmi {
-
-class Client {
-public:
- explicit Client(const std::string& remotePath);
- virtual ~Client() = default;
-
- Client(const Client&) = delete;
- Client& operator=(const Client&) = delete;
-
- Client(Client&&) = delete;
- Client& operator=(Client&&) = delete;
-
- template<typename R, typename... Args>
- R invoke(const std::string& name, Args&&... args);
-
-private:
- Connection connection;
- std::mutex mutex;
-};
-
-template<typename R, typename... Args>
-R Client::invoke(const std::string& name, Args&&... args)
-{
- Message msg(Message::Type::MethodCall, name);
- msg.enclose(std::forward<Args>(args)...);
-
- std::lock_guard<std::mutex> lock(this->mutex);
-
- Message reply = this->connection.request(msg);
- R ret;
- reply.disclose(ret);
-
- return ret;
-}
-
-} // namespace rmi
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file server.cpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Implementation of server application.
- */
-
-#include "server.hpp"
-
-#include <vist/exception.hpp>
-#include <vist/logger.hpp>
-#include <vist/transport/message.hpp>
-
-namespace vist {
-namespace rmi {
-
-void Server::start(void)
-{
- for (const auto& path : this->socketPaths) {
- auto socket = std::make_shared<Socket>(path);
- auto accept = [this, socket]() {
- this->onAccept(std::make_shared<Connection>(socket->accept()));
- };
-
- this->mainloop.addHandler(socket->getFd(), std::move(accept));
- }
-
- this->mainloop.run();
-}
-
-void Server::stop(void)
-{
- {
- std::lock_guard<std::mutex> lock(this->connectionMutex);
-
- for (auto iter : this->connectionMap)
- this->mainloop.removeHandler(iter.first);
- }
-
- this->mainloop.stop();
-}
-
-void Server::listen(const std::string& socketPath)
-{
- this->socketPaths.insert(socketPath);
-}
-
-void Server::onAccept(std::shared_ptr<Connection>&& connection)
-{
- if (connection == nullptr)
- THROW(ErrCode::LogicError) << "Wrong connection.";
-
- auto onRead = [this, connection]() {
- std::shared_ptr<Connection> conn;
-
- std::lock_guard<std::mutex> lock(this->connectionMutex);
-
- auto iter = this->connectionMap.find(connection->getFd());
- if (iter == this->connectionMap.end())
- THROW(ErrCode::RuntimeError) << "Faild to find connection.";
-
- conn = iter->second;
-
- this->dispatch(conn);
- };
-
- auto onError = [this, connection]() {
- ERROR(VIST) << "Connection error occured. fd: " << connection->getFd();
- this->onClose(connection);
- };
-
- int clientFd = connection->getFd();
- this->mainloop.addHandler(clientFd, std::move(onRead), std::move(onError));
- INFO(VIST) << "Connection is accepted. fd: " << clientFd;
-
- {
- std::lock_guard<std::mutex> lock(this->connectionMutex);
-
- this->dispatch(connection);
- this->connectionMap[clientFd] = std::move(connection);
- }
-}
-
-void Server::onClose(const std::shared_ptr<Connection>& connection)
-{
- if (connection == nullptr)
- THROW(ErrCode::LogicError) << "Wrong connection.";
-
- {
- std::lock_guard<std::mutex> lock(this->connectionMutex);
-
- auto iter = this->connectionMap.find(connection->getFd());
- if (iter == this->connectionMap.end())
- THROW(ErrCode::RuntimeError) << "Faild to find connection.";
-
- this->mainloop.removeHandler(iter->first);
- INFO(VIST) << "Connection is closed. fd: " << iter->first;
- this->connectionMap.erase(iter);
- }
-}
-
-void Server::dispatch(const std::shared_ptr<Connection>& connection)
-{
- Message request = connection->recv();
- std::string funcName = request.signature;
-
- {
- std::lock_guard<std::mutex> lock(this->functorMutex);
-
- auto iter = this->functorMap.find(funcName);
- if (iter == this->functorMap.end())
- THROW(ErrCode::RuntimeError) << "Faild to find function.";
-
- DEBUG(VIST) << "Remote method invokation: " << funcName;
-
- auto functor = iter->second;
- auto result = functor->invoke(request.buffer);
-
- Message reply(Message::Type::Reply, funcName);
- reply.enclose(result);
-
- connection->send(reply);
- }
-}
-
-} // namespace rmi
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file server.hpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Server application for exposing function(method).
- */
-
-#pragma once
-
-#include <vist/event/mainloop.hpp>
-#include <vist/klass/functor.hpp>
-#include <vist/transport/connection.hpp>
-#include <vist/transport/socket.hpp>
-
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <mutex>
-#include <memory>
-
-using namespace vist::klass;
-using namespace vist::transport;
-using namespace vist::event;
-
-namespace vist {
-namespace rmi {
-
-class Server {
-public:
- explicit Server() = default;
- virtual ~Server() = default;
-
- Server(const Server&) = delete;
- Server& operator=(const Server&) = delete;
-
- Server(Server&&) = delete;
- Server& operator=(Server&&) = delete;
-
- void start(void);
- void stop(void);
-
- void listen(const std::string& socketPath);
-
- template<typename O, typename F>
- void expose(O&& object, const std::string& name, F&& func);
-
-private:
- using ConnectionMap = std::unordered_map<int, std::shared_ptr<Connection>>;
-
- void onAccept(std::shared_ptr<Connection>&& connection);
- void onClose(const std::shared_ptr<Connection>& connection);
-
- void dispatch(const std::shared_ptr<Connection>& connection);
-
- Mainloop mainloop;
-
- std::set<std::string> socketPaths;
-
- ConnectionMap connectionMap;
- std::mutex connectionMutex;
-
- FunctorMap functorMap;
- std::mutex functorMutex;
-};
-
-template<typename O, typename F>
-void Server::expose(O&& object, const std::string& name, F&& func)
-{
- auto functor = klass::make_functor_ptr(std::forward<O>(object), std::forward<F>(func));
- this->functorMap[name] = functor;
-}
-
-} // namespace rmi
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#include <vist/rmi/server.hpp>
-#include <vist/rmi/client.hpp>
-
-#include <chrono>
-#include <iostream>
-#include <memory>
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-
-using namespace vist::rmi;
-using namespace vist::transport;
-
-// Server side methods
-struct Foo {
- bool setName(const std::string& name)
- {
- this->name = name;
- return false;
- }
-
- std::string getName(void)
- {
- return this->name;
- }
-
- std::string name;
-};
-
-TEST(RmiTests, server_client)
-{
- std::string sockPath = ("/tmp/test-server");
-
- // server-side
- Server server;
- server.listen(sockPath);
-
- auto foo = std::make_shared<Foo>();
- server.expose(foo, "Foo::setName", &Foo::setName);
- server.expose(foo, "Foo::getName", &Foo::getName);
-
- auto client = std::thread([&]() {
- std::this_thread::sleep_for(std::chrono::seconds(1));
-
- // client-side
- Client client(sockPath);
-
- std::string param = "RMI-TEST";
- bool ret = client.invoke<bool>("Foo::setName", param);
- EXPECT_EQ(ret, false);
-
- std::string name = client.invoke<std::string>("Foo::getName");
- EXPECT_EQ(name, param);
-
- server.stop();
- });
-
- server.start();
-
- if (client.joinable())
- client.join();
-}
# See the License for the specific language governing permissions and
# limitations under the License
-ADD_VIST_COMMON_LIBRARY(vist_transport connection.cpp
- socket.cpp
- message.cpp
+ADD_VIST_COMMON_LIBRARY(vist_transport message.cpp
protocol.cpp)
FILE(GLOB TRANSPORT_TESTS "tests/*.cpp")
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file connection.cpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Implementation of the socket communication session.
- */
-
-#include "connection.hpp"
-
-#include <utility>
-
-namespace vist {
-namespace transport {
-
-Connection::Connection(transport::Socket&& socket) noexcept : socket(std::move(socket))
-{
-}
-
-Connection::Connection(const std::string& path) :
- socket(transport::Socket::connect(path))
-{
-}
-
-void Connection::send(Message& message)
-{
- std::lock_guard<std::mutex> lock(this->sendMutex);
-
- message.header.id = this->sequence++;
- this->socket.send(&message.header);
-
- this->socket.send(message.buffer.get(), message.header.length);
-}
-
-Message Connection::recv(void) const
-{
- std::lock_guard<std::mutex> lock(this->recvMutex);
- Message::Header header;
- this->socket.recv(&header);
-
- Message message(header);
- this->socket.recv(message.buffer.get(), message.size());
- message.disclose(message.signature);
-
- return message;
-}
-
-Message Connection::request(Message& message)
-{
- this->send(message);
- return this->recv();
-}
-
-int Connection::getFd(void) const noexcept
-{
- return this->socket.getFd();
-}
-
-} // namespace transport
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file connection.hpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Define the socket communication session.
- */
-
-#pragma once
-
-#include <vist/transport/message.hpp>
-#include <vist/transport/socket.hpp>
-
-#include <mutex>
-#include <utility>
-
-namespace vist {
-namespace transport {
-
-class Connection {
-public:
- explicit Connection(transport::Socket&& socket) noexcept;
- explicit Connection(const std::string& path);
- virtual ~Connection() = default;
-
- Connection(const Connection&) = delete;
- Connection& operator=(const Connection&) = delete;
-
- Connection(Connection&&) = default;
- Connection& operator=(Connection&&) = default;
-
- // server-side
- void send(Message& message);
- Message recv(void) const;
-
- // client-side
- Message request(Message& message);
-
- int getFd(void) const noexcept;
-
-private:
- transport::Socket socket;
-
- // SOCK_STREAM are full-duplex byte streams
- mutable std::mutex sendMutex;
- mutable std::mutex recvMutex;
-
- unsigned int sequence = 0;
-};
-
-} // namespace transport
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file socket.cpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Implementation of Unix Domain Socket.
- */
-
-#include "socket.hpp"
-
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-
-#include <fstream>
-#include <iostream>
-
-namespace vist {
-namespace transport {
-
-namespace {
-
-void set_cloexec(int fd)
-{
- if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- THROW(ErrCode::RuntimeError) << "Failed to set CLOSEXEC.";
-}
-
-} // anonymous namespace
-
-Socket::Socket(int fd) noexcept : fd(fd)
-{
-}
-
-Socket::Socket(const std::string& path)
-{
- if (path.size() >= sizeof(::sockaddr_un::sun_path))
- THROW(ErrCode::LogicError) << "Socket path size is wrong.";
-
- int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd == -1)
- THROW(ErrCode::RuntimeError) << "Failed to create socket.";
-
- set_cloexec(fd);
-
- ::sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- ::strncpy(addr.sun_path, path.c_str(), sizeof(sockaddr_un::sun_path));
-
- if (addr.sun_path[0] == '@')
- addr.sun_path[0] = '\0';
-
- struct stat buf;
- if (::stat(path.c_str(), &buf) == 0)
- if (::unlink(path.c_str()) == -1)
- THROW(ErrCode::RuntimeError) << "Failed to remove exist socket.";
-
- if (::bind(fd, reinterpret_cast<::sockaddr*>(&addr), sizeof(::sockaddr_un)) == -1) {
- ::close(fd);
- THROW(ErrCode::RuntimeError) << "Failed to bind.";
- }
-
- if (::listen(fd, MAX_BACKLOG_SIZE) == -1) {
- ::close(fd);
- THROW(ErrCode::RuntimeError) << "Failed to listen.";
- }
-
- this->fd = fd;
-}
-
-Socket::Socket(Socket&& that) : fd(that.fd)
-{
- that.fd = -1;
-}
-
-Socket& Socket::operator=(Socket&& that)
-{
- if (this == &that)
- return *this;
-
- this->fd = that.fd;
- that.fd = -1;
-
- return *this;
-}
-
-Socket::~Socket(void)
-{
- if (fd != -1)
- ::close(fd);
-}
-
-Socket Socket::accept(void) const
-{
- int fd = ::accept(this->fd, nullptr, nullptr);
- if (fd == -1)
- THROW(ErrCode::RuntimeError) << "Failed to accept.";
-
- set_cloexec(fd);
-
- return Socket(fd);
-}
-
-Socket Socket::connect(const std::string& path)
-{
- if (path.size() >= sizeof(::sockaddr_un::sun_path))
- THROW(ErrCode::LogicError) << "Socket path size is wrong.";
-
- int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd == -1)
- THROW(ErrCode::RuntimeError) << "Failed to create socket.";
-
- set_cloexec(fd);
-
- ::sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- ::strncpy(addr.sun_path, path.c_str(), sizeof(::sockaddr_un::sun_path));
-
- if (addr.sun_path[0] == '@')
- addr.sun_path[0] = '\0';
-
- if (::connect(fd, reinterpret_cast<::sockaddr*>(&addr), sizeof(sockaddr_un)) == -1) {
- ::close(fd);
- THROW(ErrCode::RuntimeError) << "Failed to connect.";
- }
-
- return Socket(fd);
-}
-
-int Socket::getFd(void) const noexcept
-{
- return this->fd;
-}
-
-} // namespace transport
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file socket.hpp
- * @author Jaemin Ryu (jm77.ryu@samsung.com)
- * @author Sangwan Kwon (sangwan.kwon@samsung.com)
- * @brief Define Unix Domain Socket.
- */
-
-#pragma once
-
-#include <vist/exception.hpp>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <cstddef>
-#include <string>
-
-namespace vist {
-namespace transport {
-
-class Socket {
-public:
- explicit Socket(int fd) noexcept;
- explicit Socket(const std::string& path);
- virtual ~Socket(void);
-
- Socket(const Socket&) = delete;
- Socket& operator=(const Socket&) = delete;
-
- Socket(Socket&&);
- Socket& operator=(Socket&&);
-
- Socket accept(void) const;
- static Socket connect(const std::string& path);
-
- template<typename T>
- void send(const T* buffer, const std::size_t size = sizeof(T)) const;
-
- template<typename T>
- void recv(T* buffer, const std::size_t size = sizeof(T)) const;
-
- int getFd(void) const noexcept;
-
-private:
- const int MAX_BACKLOG_SIZE = 100;
-
- int fd = -1;
-};
-
-template<typename T>
-void Socket::send(const T *buffer, const std::size_t size) const
-{
- std::size_t written = 0;
- while (written < size) {
- auto rest = reinterpret_cast<const unsigned char*>(buffer) + written;
- auto bytes = ::write(this->fd, rest, size - written);
- if (bytes >= 0)
- written += bytes;
- else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
- continue;
- else
- THROW(ErrCode::RuntimeError) << "Failed to write to socket.";
- }
-}
-
-template<typename T>
-void Socket::recv(T *buffer, const std::size_t size) const
-{
- std::size_t readen = 0;
- while (readen < size) {
- auto rest = reinterpret_cast<unsigned char*>(buffer) + readen;
- auto bytes = ::read(this->fd, rest, size - readen);
- if (bytes >= 0)
- readen += bytes;
- else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
- continue;
- else
- std::runtime_error("Failed to read.");
- }
-}
-
-} // namespace transport
-} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#include <vist/transport/connection.hpp>
-#include <vist/transport/socket.hpp>
-#include <vist/event/mainloop.hpp>
-#include <vist/event/eventfd.hpp>
-
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-
-using namespace vist::transport;
-using namespace vist::event;
-
-TEST(TransportTests, socket_communication)
-{
- std::string sockPath = ("/tmp/vist-test.sock");
-
- // server-side
- Mainloop mainloop;
- Socket socket(sockPath);
-
- std::string requestSignature = "request signature";
- int request1 = 100;
- bool request2 = true;
- std::string request3 = "request argument";
-
- std::string responseSignature = "response signature";
- int response1 = 300;
- bool response2 = false;
- std::string response3 = "response argument";
-
- auto onAccept = [&]() {
- Connection conn(socket.accept());
- Message request = conn.recv();
- EXPECT_EQ(requestSignature, request.signature);
-
- int recv1;
- bool recv2;
- std::string recv3;
- request.disclose(recv1, recv2, recv3);
- EXPECT_EQ(request1, recv1);
- EXPECT_EQ(request2, recv2);
- EXPECT_EQ(request3, recv3);
-
- Message reply(Message::Type::Reply, responseSignature);
- reply.enclose(response1, response2, response3);
- conn.send(reply);
-
- mainloop.removeHandler(socket.getFd());
- mainloop.stop();
- };
-
- mainloop.addHandler(socket.getFd(), std::move(onAccept));
- auto serverThread = std::thread([&]() { mainloop.run(); });
-
- // client-side
- Connection conn(sockPath);
- Message msg(Message::Type::Signal, requestSignature);
- msg.enclose(request1, request2, request3);
-
- Message reply = conn.request(msg);
- EXPECT_EQ(reply.signature, responseSignature);
-
- int recv1;
- bool recv2;
- std::string recv3;
- reply.disclose(recv1, recv2, recv3);
- EXPECT_EQ(response1, recv1);
- EXPECT_EQ(response2, recv2);
- EXPECT_EQ(response3, recv3);
-
- if (serverThread.joinable())
- serverThread.join();
-}
+++ /dev/null
-/*
- * Copyright (c) 2018-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#include <vist/transport/socket.hpp>
-
-#include <chrono>
-#include <cstring>
-#include <limits>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-using namespace vist::transport;
-
-TEST(TransportTests, socket_read_write)
-{
- std::string sockPath = "/tmp/vist-test.sock";
- Socket socket(sockPath);
-
- int input = std::numeric_limits<int>::max();
- bool input2 = true;
-
- int output = 0;
- bool output2 = false;
-
- auto client = std::thread([&]() {
- std::this_thread::sleep_for(std::chrono::seconds(1));
-
- // Send input to server.
- Socket connected = Socket::connect(sockPath);
- connected.send(&input);
-
- // Recv input2 from server.
- connected.recv(&output2);
-
- EXPECT_EQ(input2, output2);
- });
-
- Socket accepted = socket.accept();
-
- // Recv input from client.
- accepted.recv(&output);
- EXPECT_EQ(input, output);
-
- // Send input2 to client.
- accepted.send(&input2);
-
- if (client.joinable())
- client.join();
-}
-
-TEST(TransportTests, socket_abstract)
-{
- std::string sockPath = "@vist-sock";
- Socket socket(sockPath);
-
- int input = std::numeric_limits<int>::max();
- bool input2 = true;
-
- int output = 0;
- bool output2 = false;
-
- auto client = std::thread([&]() {
- std::this_thread::sleep_for(std::chrono::seconds(1));
-
- // Send input to server.
- Socket connected = Socket::connect(sockPath);
- connected.send(&input);
-
- // Recv input2 from server.
- connected.recv(&output2);
-
- EXPECT_EQ(input2, output2);
- });
-
- Socket accepted = socket.accept();
-
- // Recv input from client.
- accepted.recv(&output);
- EXPECT_EQ(input, output);
-
- // Send input2 to client.
- accepted.send(&input2);
-
- if (client.joinable())
- client.join();
-}