Skip to content

Commit

Permalink
Downgrade to base64 for snooped blobs (indilib#1828)
Browse files Browse the repository at this point in the history
  • Loading branch information
pludov authored Jan 30, 2023
1 parent 0c6f52a commit 431869f
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 29 deletions.
8 changes: 7 additions & 1 deletion indiserver/indiserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ class MsgQueue: public Collectable

void setFds(int rFd, int wFd);

bool acceptSharedBuffers() const
virtual bool acceptSharedBuffers() const
{
return useSharedBuffer;
}
Expand Down Expand Up @@ -747,6 +747,12 @@ class DvrInfo: public MsgQueue

/* Reference to all active drivers */
static ConcurrentSet<DvrInfo> drivers;

// decoding of attached blobs from driver is not supported ATM. Be conservative here
virtual bool acceptSharedBuffers() const
{
return false;
}
};

class LocalDvrInfo: public DvrInfo
Expand Down
40 changes: 22 additions & 18 deletions integs/DriverMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
Expand All @@ -55,19 +71,8 @@ void DriverMock::ping()
cnx.expectXml("<pingReply uid=\"flush\"/>");
}


void DriverMock::unsetup()
{
if (serverConnection != -1)
{
close(serverConnection);
serverConnection = -1;
}
}

DriverMock::DriverMock()
{
serverConnection = -1;
driverConnection = -1;
driverFds[0] = -1;
driverFds[1] = -1;
Expand All @@ -76,5 +81,4 @@ DriverMock::DriverMock()
DriverMock::~DriverMock()
{
terminateDriver();
unsetup();
}
3 changes: 0 additions & 3 deletions integs/DriverMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
*/
class DriverMock
{
std::string abstractPath;
int serverConnection;
int driverConnection;

int driverFds[2];
Expand All @@ -42,7 +40,6 @@ class DriverMock

// Start the listening socket that will receive driver upon their starts
void setup();
void unsetup();

void waitEstablish();

Expand Down
49 changes: 49 additions & 0 deletions integs/IndiServerController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,35 @@

#include <system_error>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "utils.h"
#include "IndiServerController.h"


#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<std::string> & args) {
ProcessController::start("../indiserver/indiserver", args);
}
Expand All @@ -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;
}
Expand Down
7 changes: 6 additions & 1 deletion integs/IndiServerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@
*/
class IndiServerController : public ProcessController
{

bool fifo;
public:
IndiServerController();
~IndiServerController();
void setFifo(bool enable);
void start(const std::vector<std::string> & args);

void startDriver(const std::string & driver);

void addDriver(const std::string & path);

std::string getUnixSocketPath() const;
int getTcpPort() const;
};
Expand Down
9 changes: 8 additions & 1 deletion integs/ProcessController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void ProcessController::start(const std::string & path, const std::vector<std::s
}
if (pid == 0) {
std::string error = "exec " + path;

// TODO : Close all file descriptor
execv(fullArgs[0], (char * const *) fullArgs);

// Child goes here....
Expand All @@ -103,6 +103,13 @@ void ProcessController::waitProcessEnd(int exitCode) {
expectExitCode(exitCode);
}

void ProcessController::kill() {
if (pid == -1) {
return;
}
::kill(pid, SIGKILL);
}

void ProcessController::join() {
if (pid == -1) {
return;
Expand Down
1 change: 1 addition & 0 deletions integs/ProcessController.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class ProcessController {
void expectAlive();
void expectExitCode(int e);
void join();
void kill();

void waitProcessEnd(int expectedExitCode);

Expand Down
118 changes: 113 additions & 5 deletions integs/TestIndiserverSingleDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,30 +96,51 @@ TEST(IndiserverSingleDriver, ReplyToPing)
}


void startFakeDev1(IndiServerController &indiServer, DriverMock &fakeDriver)
static void startFakeDev(IndiServerController &indiServer)
{
setupSigPipe();

fakeDriver.setup();

std::string fakeDriverPath = getTestExePath("fakedriver");

// Start indiserver with one instance, repeat 0
indiServer.startDriver(fakeDriverPath);
fprintf(stderr, "indiserver started\n");
}


static void establishDriver(IndiServerController &indiServer, DriverMock &fakeDriver, const std::string & name) {
(void)indiServer;
fakeDriver.waitEstablish();
fprintf(stderr, "fake driver started\n");

fakeDriver.cnx.expectXml("<getProperties version='1.7'/>");
fprintf(stderr, "getProperties received\n");

// Give one props to the driver
fakeDriver.cnx.send("<defBLOBVector device='fakedev1' name='testblob' label='test label' group='test_group' state='Idle' perm='ro' timeout='100' timestamp='2018-01-01T00:00:00'>\n");
fakeDriver.cnx.send("<defBLOBVector device='" + name + "' name='testblob' label='test label' group='test_group' state='Idle' perm='ro' timeout='100' timestamp='2018-01-01T00:00:00'>\n");
fakeDriver.cnx.send("<defBLOB name='content' label='content'/>\n");
fakeDriver.cnx.send("</defBLOBVector>\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");
Expand Down Expand Up @@ -314,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("<getProperties version='1.7' device='fakedev1' name='testnumber1'/>\n");

snoopDriver.ping();
fakeDriver.ping();

fakeDriver.cnx.send("<defNumberVector device='fakedev1' name='testnumber1' label='test label' group='test_group' state='Idle' perm='rw' timeout='100' timestamp='2018-01-01T00:00:00'>\n");
fakeDriver.cnx.send("<defNumber name='content' label='content' min='0' max='100' step='1'>50</defNumber>\n");
fakeDriver.cnx.send("</defNumberVector>\n");

snoopDriver.cnx.expectXml("<defNumberVector device='fakedev1' name='testnumber1' label='test label' group='test_group' state='Idle' perm='rw' timeout='100' timestamp='2018-01-01T00:00:00'>");
snoopDriver.cnx.expectXml("<defNumber name='content' label='content' min='0' max='100' step='1'>");
snoopDriver.cnx.expect("\n50");
snoopDriver.cnx.expectXml("</defNumber>");
snoopDriver.cnx.expectXml("</defNumberVector>");

fakeDriver.terminateDriver();
snoopDriver.terminateDriver();

indiServer.kill();
indiServer.join();
}


#define DUMMY_BLOB_SIZE 64

#ifdef ENABLE_INDI_SHARED_MEMORY
Expand Down Expand Up @@ -363,7 +421,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;
Expand Down Expand Up @@ -482,4 +540,54 @@ 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");

fakeDriver.ping();
snoopDriver.ping();

snoopDriver.cnx.send("<getProperties version='1.7' device='fakedev1' name='testblob'/>\n");
snoopDriver.cnx.send("<enableBLOB device='fakedev1' name='testblob'>Also</enableBLOB>\n");
snoopDriver.ping();

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("<setBLOBVector device='fakedev1' name='testblob' timestamp='2018-01-01T00:01:00'>");
snoopDriver.cnx.expectXml("<oneBLOB name='content' size='32' format='.fits' attached='true'/>\n");
snoopDriver.cnx.expectXml("</setBLOBVector>");

SharedBuffer receivedFd;
snoopDriver.cnx.expectBuffer(receivedFd);
snoopDriver.cnx.allowBufferReceive(false);
EXPECT_GE( receivedFd.getSize(), 32);
#else
snoopDriver.cnx.expectXml("<setBLOBVector device='fakedev1' name='testblob' timestamp='2018-01-01T00:01:00'>");
snoopDriver.cnx.expectXml("<oneBLOB name='content' size='32' format='.fits'>\n");
snoopDriver.cnx.expect("\nMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDE=");
snoopDriver.cnx.expectXml("</oneBLOB>\n");
snoopDriver.cnx.expectXml("</setBLOBVector>");
#endif

fakeDriver.terminateDriver();
snoopDriver.terminateDriver();
// fakeSnooper.terminateDriver();
// Exit code 1 is expected when driver stopped
indiServer.kill();
indiServer.join();
}


#endif
Loading

0 comments on commit 431869f

Please sign in to comment.