From 21931ab402f5d15c2b7a3862397579deaa102462 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Fri, 12 Apr 2019 10:33:42 +0300
Subject: [PATCH] Fix for memcpy order and added tests for rpc calls

---
 net/cpp/test/peer_unit.cpp | 72 ++++++++++++++++++++++++++++++++++++++
 reconstruct/src/main.cpp   |  3 +-
 vision/src/main.cpp        |  3 +-
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/net/cpp/test/peer_unit.cpp b/net/cpp/test/peer_unit.cpp
index 61c47ff41..b7bebbcb1 100644
--- a/net/cpp/test/peer_unit.cpp
+++ b/net/cpp/test/peer_unit.cpp
@@ -2,6 +2,7 @@
 #include <iostream>
 #include <memory>
 //#include <map>
+#include <vector>
 #include <tuple>
 #include <thread>
 #include <chrono>
@@ -20,6 +21,7 @@
 
 using std::tuple;
 using std::get;
+using std::vector;
 using ftl::net::Peer;
 using std::this_thread::sleep_for;
 using std::chrono::milliseconds;
@@ -128,6 +130,14 @@ tuple<uint32_t, T> readRPC(int s) {
 	return std::make_tuple(get<1>(req), get<3>(req));
 }
 
+template <typename T>
+T readRPCReturn(int s) {
+	msgpack::object_handle msg = msgpack::unpack(fakedata[s].data(), fakedata[s].size());
+	tuple<uint8_t, uint32_t, std::string, T> req;
+	msg.get().convert(req);
+	return get<3>(req);
+}
+
 // --- Files to test -----------------------------------------------------------
 
 #include "../src/peer.cpp"
@@ -242,6 +252,33 @@ TEST_CASE("Peer::call()", "[rpc]") {
 		
 		REQUIRE( (res == 77) );
 	}
+
+	SECTION("vector return from call") {
+		REQUIRE( s.isConnected() );
+		
+		fakedata[0] = "";
+		
+		// Thread to provide response to otherwise blocking call
+		std::thread thr([&s]() {
+			while (fakedata[0].size() == 0) std::this_thread::sleep_for(std::chrono::milliseconds(20));
+			
+			auto [id,value] = readRPC<tuple<>>(0);
+			vector<int> data = {44,55,66};
+			auto res_obj = std::make_tuple(1,id,"__return__",data);
+			std::stringstream buf;
+			msgpack::pack(buf, res_obj);
+			fakedata[0] = buf.str();
+			s.mock_data();
+			sleep_for(milliseconds(50));
+		});
+		
+		vector<int> res = s.call<vector<int>>("test1");
+		
+		thr.join();
+		
+		REQUIRE( (res[0] == 44) );
+		REQUIRE( (res[2] == 66) );
+	}
 }
 
 TEST_CASE("Peer::bind()", "[rpc]") {
@@ -291,6 +328,41 @@ TEST_CASE("Peer::bind()", "[rpc]") {
 		
 		REQUIRE( (done == "world") );
 	}
+
+	SECTION("int return value") {		
+		int done = 0;
+		
+		s.bind("hello", [&](int a) -> int {
+			done = a;
+			return a;
+		});
+		
+		s.asyncCall<int>("hello", [](int a){}, 55);
+		s.mock_data(); // Force it to read the fake send...
+		sleep_for(milliseconds(50));
+		
+		REQUIRE( (done == 55) );
+		REQUIRE( readRPCReturn<int>(0) == 55 );
+	}
+
+	SECTION("vector return value") {		
+		int done = 0;
+		
+		s.bind("hello", [&](int a) -> vector<int> {
+			done = a;
+			vector<int> b = {a,45};
+			return b;
+		});
+		
+		s.asyncCall<int>("hello", [](int a){}, 55);
+		s.mock_data(); // Force it to read the fake send...
+		sleep_for(milliseconds(50));
+		
+		REQUIRE( (done == 55) );
+
+		auto res = readRPCReturn<vector<int>>(0);
+		REQUIRE( res[1] == 45 );
+	}
 }
 
 TEST_CASE("Socket::send()", "[io]") {
diff --git a/reconstruct/src/main.cpp b/reconstruct/src/main.cpp
index 0ec511f87..719dcdc9f 100644
--- a/reconstruct/src/main.cpp
+++ b/reconstruct/src/main.cpp
@@ -157,8 +157,7 @@ static void run(const string &file) {
 				auto buf = net.findOne<vector<unsigned char>>((string)config["source"]+"/calibration");
 				if (buf) {
 					Q = Mat(cv::Size(4,4), CV_32F);
-					memcpy((*buf).data(), Q.data, (*buf).size());
-					LOG(INFO) << "Have calibration";
+					memcpy(Q.data, (*buf).data(), (*buf).size());
 					if (Q.step*Q.rows != (*buf).size()) LOG(ERROR) << "Corrupted calibration";
 					disp.setCalibration(Q);
 				}
diff --git a/vision/src/main.cpp b/vision/src/main.cpp
index 1b0c709c0..a22ebc25e 100644
--- a/vision/src/main.cpp
+++ b/vision/src/main.cpp
@@ -147,7 +147,8 @@ static void run(const string &file) {
 	net.bind(string("ftl://utu.fi/")+(string)config["stream"]["name"]+string("/rgb-d/calibration"), [&calibrate,Q_32F]() -> vector<unsigned char> {
 		vector<unsigned char> buf;
 		buf.resize(Q_32F.step*Q_32F.rows);
-		memcpy(Q_32F.data, buf.data(), buf.size());
+		LOG(INFO) << "Calib buf size = " << buf.size();
+		memcpy(buf.data(), Q_32F.data, buf.size());
 		return buf;
 	});
 
-- 
GitLab