Skip to content
Snippets Groups Projects
Commit f9a687d2 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Refactor directory structure and module names

parent 3f58c84b
No related branches found
No related tags found
No related merge requests found
Pipeline #9745 passed
Showing
with 5 additions and 15281 deletions
......@@ -114,8 +114,8 @@ endif()
SET(CMAKE_USE_RELATIVE_PATHS ON)
add_subdirectory(net)
add_subdirectory(cv-node)
add_subdirectory(rep-server)
add_subdirectory(vision)
add_subdirectory(reconstruct)
### Generate Build Configuration Files =========================================
......
......@@ -3,8 +3,9 @@
This monorepo contains all elements of the FTL software system.
* net : A p2p messaging library for C++ and JavaScript
* cv-node : Stereo vision node in p2p network
* renderer : Produce video or live image feeds from scene representation
* vision : Stereo vision node in p2p network
* reconstruct : Performs scene reconstruction from vision nodes
* renderer : Produce video or live feeds from scene representation
* front-end : Client side FTL code, both web and native
* web-service : A web backend service provider acting as a form of proxy
* www : FTL Website
......
File moved
File moved
cmake_minimum_required (VERSION 2.8.11)
include (CheckIncludeFile)
include (CheckIncludeFileCXX)
include (CheckFunctionExists)
project (ftlp2prm)
include(CTest)
enable_testing()
#find_package(PkgConfig)
#pkg_check_modules(GTKMM gtkmm-3.0)
# Need to include staged files and libs
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR})
set(ftl_VERSION_MAJOR "1")
set(ftl_VERSION_MINOR "0")
set(ftl_VERSION_PATCH "0")
set(CMAKE_CXX_FLAGS "-pthread -fopenmp -std=c++17 -Wall -Wno-deprecated -Werror -Wno-psabi")
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -pg -Wall -Werror")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
SET(CMAKE_USE_RELATIVE_PATHS ON)
set(FTLSOURCE
src/cluster.cpp
src/p2prm.cpp
)
add_library(ftl-p2prm ${FTLSOURCE})
check_include_file("uriparser/Uri.h" HAVE_URI_H)
if(NOT HAVE_URI_H)
message(FATAL_ERROR "Uriparser is required")
endif()
check_function_exists(uriParseSingleUriA HAVE_URIPARSESINGLE)
# Look for FTL Net
find_path(FTL_NET "ftl/net.hpp")
if (NOT FTL_NET)
message(STATUS "FTL Net is not installed")
find_path(FTL_NET_DEV "ftl/net.hpp" PATHS ../net/include)
if (NOT FTL_NET_DEV)
message(FATAL_ERROR "FTL Net is required")
endif()
#TODO Ensure this is built
message(STATUS ${FTL_NET_DEV})
include_directories(${FTL_NET_DEV})
link_directories(../net/build)
endif()
target_include_directories(ftl-p2prm PUBLIC ${PROJECT_SOURCE_DIR}/include)
#target_link_libraries(libftlp2pra pthread)
ADD_SUBDIRECTORY(test)
# Peer-2-Peer Remote Array Library
Provides a remote memory access abstraction to allocate, read and write to arrays stored
in different peers on the network.
Requires `libftl-net`
#ifndef _FTL_P2P_RM_HPP_
#define _FTL_P2P_RM_HPP_
#include <ftl/p2p-rm/cluster.hpp>
#include <memory>
namespace ftl {
namespace net {
class Listener;
};
namespace rm {
std::shared_ptr<Cluster> cluster(const char *uri, std::shared_ptr<ftl::net::Listener> l);
}
}
#endif // _FTL_P2P_RM_HPP_
#ifndef _FTL_P2P_RM_BLOB_HPP_
#define _FTL_P2P_RM_BLOB_HPP_
#include <mutex>
#include <shared_mutex>
#include <ftl/net.hpp>
#include <ftl/uuid.hpp>
#include <string>
#include <vector>
namespace ftl {
namespace rm {
class Cluster;
/* NOT TO BE USED DIRECTLY */
struct Blob {
//Blob();
//~Blob();
std::vector<ftl::net::Socket*> sockets_;
char *data_;
size_t size_;
std::string uri_;
ftl::UUID owner_;
uint32_t blobid_;
Cluster *cluster_;
void finished();
void becomeOwner();
//void write(size_t offset, const char *data, size_t size);
//void read(size_t offset, char *data, size_t size);
void sync(size_t offset, size_t size);
mutable std::shared_mutex mutex_;
};
void _sync(const Blob &blob, size_t offset, size_t size);
}
}
#endif // _FTL_P2P_RM_CACHE_HPP_
#ifndef _FTL_P2P_RM_CLUSTER_HPP_
#define _FTL_P2P_RM_CLUSTER_HPP_
#include "ftl/p2p-rm/mapped_ptr.hpp"
#include "ftl/p2p-rm/internal.hpp"
#include <ftl/p2p-rm/protocol.hpp>
#include <ftl/p2p-rm/p2p.hpp>
#include <ftl/uri.hpp>
#include <ftl/uuid.hpp>
#include <ftl/net/socket.hpp>
#include <ftl/net/protocol.hpp>
#include <type_traits>
#include <memory>
#include <vector>
#include <map>
#include <tuple>
#include <msgpack.hpp>
namespace ftl {
namespace net {
class Socket;
class Listener;
};
namespace rm {
class Blob;
class Cluster : public ftl::net::p2p {
public:
Cluster(const ftl::URI &uri, std::shared_ptr<ftl::net::Listener> l);
Cluster(const char *uri, std::shared_ptr<ftl::net::Listener> l);
~Cluster();
void reset();
inline void destroy() { reset(); }
const UUID &id() const { return id_; }
template <typename T>
static bool is_owner(const ftl::mapped_ptr<T> &p) {
return (p.blob) ? p.blob->cluster_->id() == p.blob->owner_ : false;
}
/**
* Obtain a remote pointer from a URI. A nullptr is returned if the URI is
* not valid. If the URI is actually local then a remote pointer is still
* returned and may be used normally, although it will possibly result in
* unwanted memory copies.
*/
template <typename T>
ftl::mapped_ptr<T> get(const char *uri) {
auto b = _lookup(uri);
// TODO Verify type and size
return ftl::mapped_ptr<T>{b,0};
}
/**
* Get a read-only memory reference from a URI.
*/
template <typename T>
ftl::read_ref<T> getReadable(const char *uri) {
return get<T>(uri).readable();
}
/**
* Get a read/writable memory reference from a URI.
*/
template <typename T>
ftl::write_ref<T> getWritable(const char *uri) {
return get<T>(uri).writable();
}
/**
* Register a memory area locally mapped to a given URI. The URI
* must not already exist within the peer group.
*/
template <typename T>
ftl::mapped_ptr<T> map(const char *uri, T *addr, size_t size=1) {
if (std::is_pointer<T>::value) return ftl::null_ptr<T>;
if (std::is_function<T>::value) return ftl::null_ptr<T>;
if (std::is_void<T>::value) return ftl::null_ptr<T>;
if (addr == NULL) return ftl::null_ptr<T>;
return ftl::mapped_ptr<T>{_create(uri, (char*)addr, sizeof(T), size,
static_cast<flags_t>(std::is_integral<T>::value * ftl::rm::FLAG_INTEGER |
std::is_signed<T>::value * ftl::rm::FLAG_SIGNED |
std::is_trivial<T>::value * ftl::rm::FLAG_TRIVIAL),
typeid(T).name()),0};
}
void unmap(const char *uri);
template <typename T>
void unmap(ftl::mapped_ptr<T> ptr) {}
/**
* Obtain a list or URI memory blocks in the current peer group that match
* the provided base URI.
*/
std::vector<std::string> search(const char *partial_uri);
/**
* Connect to a new peer node using the specified socket.
*/
void addPeer(std::shared_ptr<ftl::net::Socket> &s, bool incoming=false);
/**
* Connect to a new peer using a URL string.
*/
std::shared_ptr<ftl::net::Socket> addPeer(const char *url);
/**
* Allow member functions to be used for RPC calls by binding with 'this'.
*/
/*template <typename R, typename C, typename ...Args>
void bind_member(const std::string &name, R(C::*f)(Args...)) {
bind(name, [this,f](Args... args) -> R { return (this->*f)(std::forward<Args>(args)...); });
}*/
std::optional<ftl::UUID> getOwner(const std::string &uri);
private:
UUID id_;
std::string root_;
std::shared_ptr<ftl::net::Listener> listener_;
//std::vector<std::shared_ptr<ftl::net::Socket>> peers_;
std::map<std::string, ftl::rm::Blob*> blobs_;
std::map<int,std::vector<std::tuple<std::shared_ptr<ftl::net::Socket>,std::string>>> rpc_results_;
// Cache of seen requests.
//std::unordered_map<ftl::UUID,long int> requests_;
ftl::rm::Blob *_lookup(const char *uri);
Blob *_create(const char *uri, char *addr, size_t size, size_t count,
ftl::rm::flags_t flags, const std::string &tname);
void _registerRPC();
private:
//std::tuple<ftl::UUID,uint32_t> getOwner_RPC(const ftl::UUID &u, int ttl, const std::string &uri);
};
};
};
#endif // _FTL_P2P_RM_CLUSTER_HPP_
#ifndef _FTL_P2P_RM_INTERNAL_HPP_
#define _FTL_P2P_RM_INTERNAL_HPP_
namespace ftl {
namespace rm {
class Blob;
class Cluster;
enum flags_t : uint32_t {
FLAG_INTEGER = 1,
FLAG_SIGNED = 2,
FLAG_TRIVIAL = 4
};
ftl::rm::Blob *_lookup(const char *uri);
ftl::rm::Blob *_create(Cluster *c, const char *uri, char *addr, size_t size, size_t count, flags_t flags, const std::string &tname);
}; // namespace rm
}; // namespace ftl
#endif // _FTL_P2P_RM_INTERNAL_HPP_
#ifndef _FTL_P2P_RM_MAPPED_PTR_HPP_
#define _FTL_P2P_RM_MAPPED_PTR_HPP_
#include "ftl/p2p-rm/blob.hpp"
namespace ftl {
template <typename T> struct write_ref;
template <typename T> struct read_ref;
template <typename T> struct write_ptr;
template <typename T> struct read_ptr;
template <typename T>
struct mapped_ptr {
rm::Blob *blob;
size_t offset;
bool is_null() const { return blob == NULL; }
bool is_local() const { return blob->data_ != NULL; }
bool is_valid() const {
return !is_null() && offset+sizeof(T) <= blob->size_;
}
T *get() { return blob->data_; }
size_t size() const { return blob->size_; }
write_ref<T> operator*();
write_ref<T> operator[](ptrdiff_t idx);
write_ref<T> writable() { return ftl::write_ref<T>(*this); }
read_ref<T> operator*() const;
read_ref<T> operator[](ptrdiff_t idx) const;
read_ref<T> readable() { return ftl::read_ref<T>(*this); }
mapped_ptr<T> operator+(std::ptrdiff_t diff) const {
size_t new_offset = offset + sizeof(T)*diff;
return mapped_ptr<T>{blob, new_offset};
}
/** Allow pointer casting if a local blob */
template <typename U>
operator U*() {
if (is_local()) return (U*)blob->data_;
return NULL;
}
};
template <typename T>
static const mapped_ptr<T> null_ptr = mapped_ptr<T>{0,0};
template <typename T>
struct read_ref {
mapped_ptr<T> ptr_;
// Constructor
read_ref(mapped_ptr<T> ptr) : ptr_(ptr) {
if (ptr_.is_valid()) rlock_ = std::shared_lock<std::shared_mutex>(ptr.blob->mutex_);
}
bool is_valid() const { return !ptr_.is_null(); }
mapped_ptr<T> pointer() const { return ptr_; }
void reset() { rlock_.unlock(); }
void finish() { reset(); }
operator T() const {
//return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
//T t;
//ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
//return t;
}
read_ref &operator=(const T &value) {
// silent fail!
return *this;
}
std::shared_lock<std::shared_mutex> rlock_;
};
template <typename T>
struct write_ref {
mapped_ptr<T> ptr_;
// Constructor
write_ref(mapped_ptr<T> ptr) : ptr_(ptr), wlock_(ptr.blob->mutex_) {
// Ensure ownership
ptr.blob->becomeOwner();
}
~write_ref() { ptr_.blob->finished(); }
bool is_valid() const { return !ptr_.is_null(); }
mapped_ptr<T> pointer() const { return ptr_; }
void reset() { ptr_.blob->finished(); wlock_.unlock(); }
void end() { reset(); }
void begin() { wlock_.lock(); }
/** Cast to type reads the value */
operator T() const {
return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
//T t;
//ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
//return t;
}
write_ref &operator=(const T &value) {
//ptr_.blob->write(ptr_.offset, (char*)(&value), sizeof(T));
*((T*)&ptr_.blob->data_[ptr_.offset]) = value;
//ptr_.blob->sync(ptr_.offset, sizeof(T));
ftl::rm::_sync(*ptr_.blob, ptr_.offset, sizeof(T));
return *this;
}
std::unique_lock<std::shared_mutex> wlock_;
};
}
template <typename T>
ftl::read_ref<T> ftl::mapped_ptr<T>::operator*() const {
return ftl::read_ref<T>(*this);
}
template <typename T>
ftl::read_ref<T> ftl::mapped_ptr<T>::operator[](ptrdiff_t idx) const {
return ftl::read_ref<T>(*this + idx);
}
template <typename T>
ftl::write_ref<T> ftl::mapped_ptr<T>::operator*() {
return ftl::write_ref<T>(*this);
}
template <typename T>
ftl::write_ref<T> ftl::mapped_ptr<T>::operator[](ptrdiff_t idx) {
return ftl::write_ref<T>(*this + idx);
}
#endif // _FTL_P2P_RM_MAPPED_PTR_HPP_
#ifndef _FTL_P2P_RM_PROTOCOL_HPP_
#define _FTL_P2P_RM_PROTOCOL_HPP_
/* To get the service space for p2p */
#include <ftl/net/protocol.hpp>
#define P2P_SYNC (FTL_PROTOCOL_FREE + 1)
#define P2P_REQUESTOWNERSHIP (FTL_PROTOCOL_FREE + 2)
#define P2P_FINDOWNER (FTL_PROTOCOL_FREE + 3)
#define P2P_NOTIFYOWNERSHIP (FTL_PROTOCOL_FREE + 4)
#define P2P_URISEARCH (FTL_PROTOCOL_FREE + 5)
#define P2P_PEERSEARCH (FTL_PROTOCOL_FREE + 6)
#define P2P_RPC_CALL (FTL_PROTOCOL_FREE + 7)
namespace ftl {
namespace rm {
struct P2PQuery {
char guid[16];
uint8_t ttl;
};
struct MemOwner {
char peer[16];
uint64_t age;
};
};
};
#endif // _FTL_P2P_RM_PROTOCOL_HPP_
#include <glog/logging.h>
#include <ftl/p2p-rm/blob.hpp>
#include <ftl/net/socket.hpp>
#include <ftl/p2p-rm/protocol.hpp>
#include <ftl/p2p-rm/cluster.hpp>
#include <iostream>
using ftl::net::array;
struct SyncHeader {
uint32_t blobid;
uint32_t offset;
uint32_t size;
};
void ftl::rm::_sync(const Blob &blob, size_t offset, size_t size) {
// Sanity check
if (offset + size > blob.size_) {
LOG(ERROR) << "Memory overrun during sync";
return;
}
// TODO Delay send to collate many write operations?
LOG(INFO) << "Synchronise blob " << blob.blobid_;
if (blob.sockets_.size() > 0) {
SyncHeader header{blob.blobid_,static_cast<uint32_t>(offset),static_cast<uint32_t>(size)};
for (auto s : blob.sockets_) {
// Send over network
s->send(P2P_SYNC, std::string((const char*)&header,sizeof(header)),
array{&blob.data_[offset],size});
}
}
}
void ftl::rm::Blob::becomeOwner() {
if (cluster_->id() == owner_) return;
std::cout << "NOT OWNED BUT WRITING" << std::endl;
}
void ftl::rm::Blob::finished() {
}
#include <glog/logging.h>
#include "ftl/p2p-rm.hpp"
#include "ftl/p2p-rm/blob.hpp"
#include "ftl/p2p-rm/protocol.hpp"
#include <ftl/p2p-rm/cluster.hpp>
#include <ftl/net.hpp>
#include <ftl/net/listener.hpp>
#include <ftl/net/socket.hpp>
#include <map>
#include <string>
#include <iostream>
#include <vector>
#include <chrono>
using ftl::rm::Cluster;
using ftl::net::Listener;
using std::map;
using std::vector;
using std::tuple;
using std::shared_ptr;
using std::string;
using std::optional;
using ftl::URI;
using ftl::rm::Blob;
using ftl::net::Socket;
using ftl::UUID;
using ftl::net::p2p;
using namespace std::chrono;
Cluster::Cluster(const URI &uri, shared_ptr<Listener> l) : p2p(uri.getBaseURI()), listener_(l) {
//auto me = this;
root_ = uri.getHost();
_registerRPC();
if (l != nullptr) {
l->onConnection([&](shared_ptr<Socket> &s) {
addPeer(s, true);
});
}
LOG(INFO) << "Cluster UUID = " << id_.to_string();
}
Cluster::Cluster(const char *uri, shared_ptr<Listener> l) : p2p(uri), listener_(l) {
URI u(uri);
if (!u.isValid()) return;
if (u.getScheme() != ftl::URI::SCHEME_FTL) return;
if (u.getPath().size() > 0) return;
root_ = u.getHost();
_registerRPC();
if (l != nullptr) {
l->setProtocol(this);
l->onConnection([&](shared_ptr<Socket> &s) {
addPeer(s, true);
});
}
LOG(INFO) << "Cluster UUID = " << id_.to_string();
}
Cluster::~Cluster() {
reset();
}
void Cluster::reset() {
for (auto x : blobs_) {
delete x.second;
}
blobs_.clear();
}
void Cluster::_registerRPC() {
bind_find_one("getowner", &Cluster::getOwner);
bind(P2P_SYNC, [this](uint32_t msg, Socket &s) {
LOG(INFO) << "Receive blob sync";
});
}
void Cluster::addPeer(shared_ptr<Socket> &p, bool incoming) {
LOG(INFO) << ((incoming) ? "Incoming peer added: " : "Peer added: ") << p->getURI();
//p.setProtocol(this);
//peers_.push_back(p);
p2p::addPeer(p);
if (!incoming) {
p->onConnect([this](Socket &s) {
for (auto b : blobs_) {
auto o = find_one<UUID>("getowner", b.first);
if (o && *o != id()) {
b.second->owner_ = *o;
LOG(INFO) << "Lost ownership of " << b.first.c_str() << " to " << (*o).to_string();
}
}
});
}
}
shared_ptr<Socket> Cluster::addPeer(const char *url) {
auto sock = ftl::net::connect(url);
sock->setProtocol(this);
addPeer(sock);
return sock;
}
Blob *Cluster::_lookup(const char *uri) {
URI u(uri);
if (!u.isValid()) return NULL;
if (u.getScheme() != ftl::URI::SCHEME_FTL) return NULL;
//if (u.getPathSegment(0) != "memory") return NULL;
if (u.getHost() != root_) { LOG(ERROR) << "Non matching URI base : " << u.getHost() << " - " << root_ << std::endl; return NULL; }
auto b = blobs_[u.getBaseURI()];
std::cout << "Blob Found for " << u.getBaseURI() << " = " << (b != nullptr) << std::endl;
if (!b) {
LOG(WARNING) << "Unmapped memory requested: " << uri;
}
return b;
}
optional<UUID> Cluster::getOwner(const std::string &uri) {
if (blobs_.count(uri) > 0) {
return blobs_[uri]->owner_;
}
return {};
}
Blob *Cluster::_create(const char *uri, char *addr, size_t size, size_t count,
ftl::rm::flags_t flags, const std::string &tname) {
URI u(uri);
if (!u.isValid()) return NULL;
if (u.getScheme() != ftl::URI::SCHEME_FTL) return NULL;
if (u.getHost() != root_) { std::cerr << "Non matching host : " << u.getHost() << " - " << root_ << std::endl; return NULL; }
if (blobs_.count(u.getBaseURI()) > 0) {
LOG(WARNING) << "Mapping already exists for " << uri;
return blobs_[u.getBaseURI()];
}
Blob *b = new Blob;
b->cluster_ = this;
b->data_ = addr;
b->size_ = size;
b->uri_ = std::string(uri);
b->owner_ = id(); // I am initial owner by default...
auto o = find_one<UUID>("getowner", uri);
if ((o && *o == id()) || !o) {
} else {
b->owner_ = *o;
}
LOG(INFO) << "Mapping address to " << uri;
blobs_[u.getBaseURI()] = b;
//std::cout << owners << std::endl;
return b;
}
#include "ftl/p2p-rm.hpp"
#include "ftl/p2p-rm/blob.hpp"
#include "ftl/p2p-rm/protocol.hpp"
#include <ftl/uri.hpp>
#include <ftl/net.hpp>
#include <map>
#include <string>
using std::shared_ptr;
using ftl::rm::Cluster;
using ftl::URI;
using ftl::net::Listener;
shared_ptr<Cluster> ftl::rm::cluster(const char *uri, shared_ptr<Listener> l) {
URI u(uri);
if (!u.isValid()) return nullptr;
if (u.getScheme() != ftl::URI::SCHEME_FTL) return nullptr;
if (u.getPath().size() > 0) return nullptr;
shared_ptr<Cluster> c(new Cluster(u, l));
return c;
}
add_executable(mapped_ptr_unit
./tests.cpp
./mapped_ptr_unit.cpp
../src/blob.cpp
)
target_link_libraries(mapped_ptr_unit gflags glog uuid)
add_executable(cluster_unit
./tests.cpp
../src/cluster.cpp
./cluster_unit.cpp
)
target_link_libraries(cluster_unit uriparser ftlnet gflags glog uuid)
add_executable(p2p_unit
./tests.cpp
./p2p_unit.cpp
)
target_link_libraries(p2p_unit ftlnet uriparser gflags glog uuid)
add_executable(p2p_integration
./tests.cpp
../src/cluster.cpp
../src/p2prm.cpp
../src/blob.cpp
./p2p_integration.cpp
)
target_link_libraries(p2p_integration uriparser ftlnet gflags glog uuid)
add_executable(peer_test
./peer_cli.cpp
../src/p2prm.cpp
../src/cluster.cpp
../src/blob.cpp
)
target_link_libraries(peer_test uriparser ftlnet gflags glog uuid)
add_test(Mapped_ptrUnitTest mapped_ptr_unit)
add_test(ClusterUnitTest cluster_unit)
add_test(P2PUnitTest p2p_unit)
add_custom_target(tests)
add_dependencies(tests mapped_ptr_unit cluster_unit peer_test p2p_integration)
#include "catch.hpp"
#include <ftl/p2p-ra.hpp>
// ---- MOCK THE SOCKET --------------------------------------------------------
namespace ftl {
namespace net {
namespace raw {
class Socket {
public:
int close();
int send(uint32_t service, std::string &data);
//int send(uint32_t service, std::ostringstream &data);
//int send(uint32_t service, void *data, int length);
bool isConnected() { return true; };
void onMessage(sockdatahandler_t handler) { m_handler = handler; }
//void onError(sockerrorhandler_t handler) {}
//void onConnect(sockconnecthandler_t handler) {}
//void onDisconnect(sockdisconnecthandler_t handler) {}
};
}
}
}
// -----------------------------------------------------------------------------
SCENARIO( "Can get a remote array object", "[array]" ) {
GIVEN( "a valid uri" ) {
Array a = ftl::p2p::get("ftl://utu.fi/array/test1");
REQUIRE( a.isValid() );
}
}
This diff is collapsed.
#include "catch.hpp"
#include <ftl/p2p-rm/cluster.hpp>
#include <ftl/net/socket.hpp>
#include <ftl/net.hpp>
#include <vector>
#include <iostream>
using ftl::rm::Cluster;
// --- Mock Socket Send
/*static std::vector<uint32_t> msgs;
int ftl::net::Socket::send2(uint32_t service, const std::string &data1, const std::string &data2) {
msgs.push_back(service);
std::cout << "SEND2 (" << service << ")" << std::endl;
return 0;
}
ftl::net::Socket::Socket(int s) : disp_(this) {
}
ftl::net::Socket::~Socket() {
}
int ftl::net::Socket::rpcid__ = 0;
int ftl::net::Socket::send(uint32_t service, const std::string &data) {
msgs.push_back(service);
std::cout << "SEND (" << service << ")" << std::endl;
return 0;
}
bool ftl::net::wait() {
return true;
}
std::shared_ptr<ftl::net::Socket> ftl::net::connect(const char *url) {
return nullptr;
}*/
// --- End Mock Socket Send
SCENARIO( "Cluster::map()", "[map]" ) {
Cluster cluster("ftl://utu.fi", nullptr);
GIVEN( "a valid URI and array datatype" ) {
int data[10];
auto m = cluster.map<int[10]>("ftl://utu.fi/memory/test0", &data);
REQUIRE( m.is_valid() );
auto r = cluster.get<int[10]>("ftl://utu.fi/memory/test0");
REQUIRE( r.is_valid() );
REQUIRE( r.size() == 10*sizeof(int) );
REQUIRE( r.is_local() );
}
GIVEN( "a valid URI and invalid data" ) {
auto m = cluster.map<int>("ftl://utu.fi/memory/test0", NULL);
REQUIRE( !m.is_valid() );
}
GIVEN( "an empty URI" ) {
int data;
auto m = cluster.map<int>("", &data);
REQUIRE( !m.is_valid() );
}
GIVEN( "an invalid URI" ) {
int data;
auto m = cluster.map<int>("noschema/test", &data);
REQUIRE( !m.is_valid() );
}
GIVEN( "an invalid URI schema" ) {
int data;
auto m = cluster.map<int>("http://utu.fi/memory/test0", &data);
REQUIRE( !m.is_valid() );
}
GIVEN( "an invalid URI host" ) {
int data;
auto m = cluster.map<int>("ftl://yle.fi/wrong/test0", &data);
REQUIRE( !m.is_valid() );
}
GIVEN( "a duplicate URI" ) {
int data;
auto a = cluster.map<int>("ftl://utu.fi/memory/test0", &data);
auto b = cluster.map<int>("ftl://utu.fi/memory/test0", &data);
REQUIRE( !b.is_valid() );
REQUIRE( a.is_valid() );
}
}
SCENARIO( "Getting a read_ref", "[get]" ) {
Cluster cluster("ftl://utu.fi", nullptr);
// Add fake peer
auto p = std::make_shared<ftl::net::Socket>(0);
cluster.addPeer(p);
int data = 89;
int data2 = 99;
auto m = cluster.map<int>("ftl://utu.fi/memory/test1", &data);
cluster.map<int>("ftl://utu.fi/memory/remote0", &data2);
REQUIRE( m.is_valid() );
GIVEN( "a valid URI to local memory" ) {
const auto r = cluster.getReadable<int>("ftl://utu.fi/memory/test1");
REQUIRE( r.is_valid() );
REQUIRE( r.pointer().is_local() );
REQUIRE( r == 89 );
}
GIVEN( "a valid URI to remote memory" ) {
const auto r = cluster.getReadable<int>("ftl://utu.fi/memory/remote0");
REQUIRE( r.is_valid() );
//REQUIRE( !r.pointer().is_local() );
REQUIRE( r == 888 );
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment