From 4b0f9a2a7a0509f70da7e10dc46f8963eac930f5 Mon Sep 17 00:00:00 2001 From: Ludovic P Date: Sun, 29 Jan 2023 16:16:13 +0100 Subject: [PATCH 1/3] Test driver snooping blobs --- integs/DriverMock.cpp | 40 +++++++------- integs/DriverMock.h | 3 -- integs/IndiServerController.cpp | 49 +++++++++++++++++ integs/IndiServerController.h | 7 ++- integs/ProcessController.cpp | 9 +++- integs/ProcessController.h | 1 + integs/TestIndiserverSingleDriver.cpp | 77 +++++++++++++++++++++++++-- integs/utils.cpp | 4 ++ 8 files changed, 162 insertions(+), 28 deletions(-) diff --git a/integs/DriverMock.cpp b/integs/DriverMock.cpp index 358fb2c3ef..0c8410f486 100644 --- a/integs/DriverMock.cpp +++ b/integs/DriverMock.cpp @@ -21,18 +21,34 @@ #include "DriverMock.h" #include "utils.h" + +class FakeDriverListener { + std::string abstractPath; + bool ready = false; +public: + int serverConnection; + void setup() { + if (ready) return; + ready = true; + // Create a socket that will not have the clo on exec flag ? + abstractPath = "/tmp/fakedriver-test"; + setenv("FAKEDRIVER_ADDRESS", abstractPath.c_str(), 1); + + serverConnection = unixSocketListen(abstractPath); + } +}; + +static FakeDriverListener driverListener; + + void DriverMock::setup() { - // Create a socket that will not have the clo on exec flag ? - abstractPath = "/tmp/fakedriver-test"; - setenv("FAKEDRIVER_ADDRESS", abstractPath.c_str(), 1); - - serverConnection = unixSocketListen(abstractPath); + driverListener.setup(); } void DriverMock::waitEstablish() { - driverConnection = socketAccept(serverConnection); + driverConnection = socketAccept(driverListener.serverConnection); unixSocketRecvFds(driverConnection, 2, driverFds); cnx.setFds(driverFds[0], driverFds[1]); } @@ -55,19 +71,8 @@ void DriverMock::ping() cnx.expectXml(""); } - -void DriverMock::unsetup() -{ - if (serverConnection != -1) - { - close(serverConnection); - serverConnection = -1; - } -} - DriverMock::DriverMock() { - serverConnection = -1; driverConnection = -1; driverFds[0] = -1; driverFds[1] = -1; @@ -76,5 +81,4 @@ DriverMock::DriverMock() DriverMock::~DriverMock() { terminateDriver(); - unsetup(); } diff --git a/integs/DriverMock.h b/integs/DriverMock.h index 2496e0c9c7..40610d286b 100644 --- a/integs/DriverMock.h +++ b/integs/DriverMock.h @@ -31,8 +31,6 @@ */ class DriverMock { - std::string abstractPath; - int serverConnection; int driverConnection; int driverFds[2]; @@ -42,7 +40,6 @@ class DriverMock // Start the listening socket that will receive driver upon their starts void setup(); - void unsetup(); void waitEstablish(); diff --git a/integs/IndiServerController.cpp b/integs/IndiServerController.cpp index b7a3162a2f..d0dd39353d 100644 --- a/integs/IndiServerController.cpp +++ b/integs/IndiServerController.cpp @@ -18,6 +18,9 @@ #include #include +#include +#include +#include #include "utils.h" #include "IndiServerController.h" @@ -25,9 +28,25 @@ #define TEST_TCP_PORT 17624 #define TEST_UNIX_SOCKET "/tmp/indi-test-server" +#define TEST_INDI_FIFO "/tmp/indi-test-fifo" #define STRINGIFY_TOK(x) #x #define TO_STRING(x) STRINGIFY_TOK(x) +IndiServerController::IndiServerController() { + fifo = false; +} + +IndiServerController::~IndiServerController() { + // Abort any pending indi server + kill(); + join(); +} + + +void IndiServerController::setFifo(bool fifo) { + this->fifo = fifo; +} + void IndiServerController::start(const std::vector & args) { ProcessController::start("../indiserver/indiserver", args); } @@ -38,11 +57,41 @@ void IndiServerController::startDriver(const std::string & path) { args.push_back("-u"); args.push_back(TEST_UNIX_SOCKET); #endif + + if (fifo) { + unlink(TEST_INDI_FIFO); + if (mkfifo(TEST_INDI_FIFO, 0600) == -1) { + throw std::system_error(errno, std::generic_category(), "mkfifo"); + } + args.push_back("-f"); + args.push_back(TEST_INDI_FIFO); + } args.push_back(path); start(args); } +void IndiServerController::addDriver(const std::string & driver) { + if (!fifo) { + throw new std::runtime_error("Fifo is not enabled - cannot add driver"); + } + + int fifoFd = open(TEST_INDI_FIFO, O_WRONLY); + if (fifoFd == -1) { + throw std::system_error(errno, std::generic_category(), "opening fifo"); + } + + std::string cmd = "start " + driver +"\n"; + int wr = write(fifoFd, cmd.data(), cmd.length()); + if (wr == -1) { + auto e = errno; + close(fifoFd); + throw std::system_error(e, std::generic_category(), "write to fifo"); + } + + close(fifoFd); +} + std::string IndiServerController::getUnixSocketPath() const { return TEST_UNIX_SOCKET; } diff --git a/integs/IndiServerController.h b/integs/IndiServerController.h index 09364939aa..e71ae1a7a2 100644 --- a/integs/IndiServerController.h +++ b/integs/IndiServerController.h @@ -31,12 +31,17 @@ */ class IndiServerController : public ProcessController { - + bool fifo; public: + IndiServerController(); + ~IndiServerController(); + void setFifo(bool enable); void start(const std::vector & args); void startDriver(const std::string & driver); + void addDriver(const std::string & path); + std::string getUnixSocketPath() const; int getTcpPort() const; }; diff --git a/integs/ProcessController.cpp b/integs/ProcessController.cpp index 70fe6528b5..4f9f05eee7 100644 --- a/integs/ProcessController.cpp +++ b/integs/ProcessController.cpp @@ -89,7 +89,7 @@ void ProcessController::start(const std::string & path, const std::vector\n"); + fakeDriver.cnx.send("\n"); fakeDriver.cnx.send("\n"); fakeDriver.cnx.send("\n"); } +static void startFakeDev1(IndiServerController &indiServer, DriverMock &fakeDriver) +{ + fakeDriver.setup(); + startFakeDev(indiServer); + establishDriver(indiServer, fakeDriver, "fakeDev1"); +} + +static void addDriver(IndiServerController &indiServer, DriverMock &fakeDriver, const std::string & name) +{ + fakeDriver.setup(); + + std::string fakeDriverPath = getTestExePath("fakedriver"); + + indiServer.addDriver(fakeDriverPath); + + establishDriver(indiServer, fakeDriver, name); +} + + void connectFakeDev1Client(IndiServerController &, DriverMock &fakeDriver, IndiClientMock &indiClient) { fprintf(stderr, "Client asks properties\n"); @@ -363,7 +384,7 @@ TEST(IndiserverSingleDriver, ForwardBase64BlobToUnixClient) void driverSendAttachedBlob(DriverMock &fakeDriver, ssize_t size) { - fprintf(stderr, "Driver send new blob value - without actual attachment\n"); + fprintf(stderr, "Driver send new blob value as attachment\n"); // Allocate more memory than asked (simulate kernel BSD kernel rounding up) ssize_t physical_size=0x10000; @@ -482,4 +503,50 @@ TEST(IndiserverSingleDriver, ForwardAttachedBlobToIPClient) indiServer.waitProcessEnd(1); } + +TEST(IndiserverSingleDriver, ForwardAttachedBlobToDriver) +{ + // This tests attached blob pass through + DriverMock fakeDriver; + IndiServerController indiServer; + indiServer.setFifo(true); + startFakeDev1(indiServer, fakeDriver); + + + DriverMock snoopDriver; + addDriver(indiServer, snoopDriver, "snoopDriver"); + + // startFakeDev2(indiServer, fakeSnooper); + + fakeDriver.ping(); + snoopDriver.ping(); + + fprintf(stderr, "Snooper ask blobs\n"); + snoopDriver.cnx.send("\n"); + snoopDriver.cnx.send("Also\n"); + snoopDriver.ping(); + + ssize_t size = 32; + driverSendAttachedBlob(fakeDriver, size); + + snoopDriver.cnx.allowBufferReceive(true); + snoopDriver.cnx.expectXml(""); + snoopDriver.cnx.expectXml("\n"); + snoopDriver.cnx.expectXml(""); + + SharedBuffer receivedFd; + snoopDriver.cnx.expectBuffer(receivedFd); + snoopDriver.cnx.allowBufferReceive(false); + + EXPECT_GE( receivedFd.getSize(), 32); + + fakeDriver.terminateDriver(); + snoopDriver.terminateDriver(); + // fakeSnooper.terminateDriver(); + // Exit code 1 is expected when driver stopped + indiServer.kill(); + indiServer.join(); +} + + #endif diff --git a/integs/utils.cpp b/integs/utils.cpp index 469345ec8f..26d93ebacf 100644 --- a/integs/utils.cpp +++ b/integs/utils.cpp @@ -79,6 +79,10 @@ int unixSocketListen(const std::string &unixAddr) throw std::system_error(errno, std::generic_category(), "Socket"); } +#ifndef __linux__ + fcntl(sockfd, F_SETFD, FD_CLOEXEC); +#endif + int reuse = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { From 0b5ead99bcacd5135a0f72222113a08412d4e1f7 Mon Sep 17 00:00:00 2001 From: Ludovic P Date: Sun, 29 Jan 2023 16:27:07 +0100 Subject: [PATCH 2/3] Server forward blobs as base64 (workaround) --- indiserver/indiserver.cpp | 8 +++++++- integs/TestIndiserverSingleDriver.cpp | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/indiserver/indiserver.cpp b/indiserver/indiserver.cpp index eb75b9c02f..12420ee37d 100644 --- a/indiserver/indiserver.cpp +++ b/indiserver/indiserver.cpp @@ -587,7 +587,7 @@ class MsgQueue: public Collectable void setFds(int rFd, int wFd); - bool acceptSharedBuffers() const + virtual bool acceptSharedBuffers() const { return useSharedBuffer; } @@ -747,6 +747,12 @@ class DvrInfo: public MsgQueue /* Reference to all active drivers */ static ConcurrentSet drivers; + + // decoding of attached blobs from driver is not supported ATM. Be conservative here + virtual bool acceptSharedBuffers() const + { + return false; + } }; class LocalDvrInfo: public DvrInfo diff --git a/integs/TestIndiserverSingleDriver.cpp b/integs/TestIndiserverSingleDriver.cpp index 13bbd2531b..9e0479d72e 100644 --- a/integs/TestIndiserverSingleDriver.cpp +++ b/integs/TestIndiserverSingleDriver.cpp @@ -529,6 +529,8 @@ TEST(IndiserverSingleDriver, ForwardAttachedBlobToDriver) ssize_t size = 32; driverSendAttachedBlob(fakeDriver, size); +#if 0 + // Until proper support by drivers, indiserver converts to base64 for that path snoopDriver.cnx.allowBufferReceive(true); snoopDriver.cnx.expectXml(""); snoopDriver.cnx.expectXml("\n"); @@ -537,8 +539,14 @@ TEST(IndiserverSingleDriver, ForwardAttachedBlobToDriver) SharedBuffer receivedFd; snoopDriver.cnx.expectBuffer(receivedFd); snoopDriver.cnx.allowBufferReceive(false); - EXPECT_GE( receivedFd.getSize(), 32); +#else + snoopDriver.cnx.expectXml(""); + snoopDriver.cnx.expectXml("\n"); + snoopDriver.cnx.expect("\nMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDE="); + snoopDriver.cnx.expectXml("\n"); + snoopDriver.cnx.expectXml(""); +#endif fakeDriver.terminateDriver(); snoopDriver.terminateDriver(); From 36fc22f1907f2ae4af2d0bf4afc95c43c876462d Mon Sep 17 00:00:00 2001 From: Ludovic P Date: Sun, 29 Jan 2023 18:31:48 +0100 Subject: [PATCH 3/3] Tests non blob snooping --- integs/TestIndiserverSingleDriver.cpp | 41 ++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/integs/TestIndiserverSingleDriver.cpp b/integs/TestIndiserverSingleDriver.cpp index 9e0479d72e..e2cb82c0ac 100644 --- a/integs/TestIndiserverSingleDriver.cpp +++ b/integs/TestIndiserverSingleDriver.cpp @@ -335,6 +335,43 @@ TEST(IndiserverSingleDriver, ForwardBase64BlobToIPClient) } +TEST(IndiserverSingleDriver, SnoopDriverPropertie) +{ + // This tests snooping simple property from driver to driver + DriverMock fakeDriver; + IndiServerController indiServer; + indiServer.setFifo(true); + startFakeDev1(indiServer, fakeDriver); + + DriverMock snoopDriver; + addDriver(indiServer, snoopDriver, "snoopDriver"); + + fakeDriver.ping(); + snoopDriver.ping(); + + snoopDriver.cnx.send("\n"); + + snoopDriver.ping(); + fakeDriver.ping(); + + fakeDriver.cnx.send("\n"); + fakeDriver.cnx.send("50\n"); + fakeDriver.cnx.send("\n"); + + snoopDriver.cnx.expectXml(""); + snoopDriver.cnx.expectXml(""); + snoopDriver.cnx.expect("\n50"); + snoopDriver.cnx.expectXml(""); + snoopDriver.cnx.expectXml(""); + + fakeDriver.terminateDriver(); + snoopDriver.terminateDriver(); + + indiServer.kill(); + indiServer.join(); +} + + #define DUMMY_BLOB_SIZE 64 #ifdef ENABLE_INDI_SHARED_MEMORY @@ -512,16 +549,12 @@ TEST(IndiserverSingleDriver, ForwardAttachedBlobToDriver) indiServer.setFifo(true); startFakeDev1(indiServer, fakeDriver); - DriverMock snoopDriver; addDriver(indiServer, snoopDriver, "snoopDriver"); - // startFakeDev2(indiServer, fakeSnooper); - fakeDriver.ping(); snoopDriver.ping(); - fprintf(stderr, "Snooper ask blobs\n"); snoopDriver.cnx.send("\n"); snoopDriver.cnx.send("Also\n"); snoopDriver.ping();