allow override of sendBE and test all combinations

Cross-testing client/server with all byte order combinations.
This commit is contained in:
Michael Davidsaver
2022-05-18 12:08:40 -07:00
parent cce797263d
commit ec8d0df1b3
8 changed files with 105 additions and 5 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ namespace client {
DEFINE_LOGGER(io, "pvxs.client.io");
Connection::Connection(const std::shared_ptr<ContextImpl>& context, const SockAddr& peerAddr)
:ConnBase (true,
:ConnBase (true, context->effective.sendBE(),
bufferevent_socket_new(context->tcp_loop.base, -1, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS),
peerAddr)
,context(context)
+2 -2
View File
@@ -17,12 +17,12 @@ DEFINE_LOGGER(connio, "pvxs.tcp.io");
namespace pvxs {
namespace impl {
ConnBase::ConnBase(bool isClient, bufferevent* bev, const SockAddr& peerAddr)
ConnBase::ConnBase(bool isClient, bool sendBE, bufferevent* bev, const SockAddr& peerAddr)
:peerAddr(peerAddr)
,peerName(peerAddr.tostring())
,bev(bev)
,isClient(isClient)
,sendBE(EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG)
,sendBE(sendBE)
,peerBE(true) // arbitrary choice, default should be overwritten before use
,expectSeg(false)
,segCmd(0xff)
+1 -1
View File
@@ -36,7 +36,7 @@ struct ConnBase
size_t statTx{}, statRx{};
ConnBase(bool isClient, bufferevent* bev, const SockAddr& peerAddr);
ConnBase(bool isClient, bool sendBE, bufferevent* bev, const SockAddr& peerAddr);
ConnBase(const ConnBase&) = delete;
ConnBase& operator=(const ConnBase&) = delete;
virtual ~ConnBase();
+11
View File
@@ -16,6 +16,7 @@
#include <typeinfo>
#include <epicsTime.h>
#include <epicsEndian.h>
#include <pvxs/version.h>
#include <pvxs/data.h>
@@ -971,6 +972,10 @@ struct PVXS_API Config {
//! @since 0.2.0
double tcpTimeout = 40.0;
private:
bool BE = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG;
public:
// compat
static inline Config from_env() { return Config{}.applyEnv(); }
@@ -1004,6 +1009,12 @@ struct PVXS_API Config {
Context build() const {
return Context(*this);
}
#ifdef PVXS_EXPERT_API_ENABLED
// for protocol compatibility testing
inline Config& overrideSendBE(bool be) { BE = be; return *this; }
inline bool sendBE() const { return BE; }
#endif
};
PVXS_API
+12
View File
@@ -18,6 +18,8 @@
#include <memory>
#include <array>
#include <epicsEndian.h>
#include <pvxs/version.h>
#include <pvxs/util.h>
#include <pvxs/data.h>
@@ -172,6 +174,10 @@ struct PVXS_API Config {
//! Server unique ID. Only meaningful in readback via Server::config()
ServerGUID guid{};
private:
bool BE = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG;
public:
// compat
static inline Config from_env() { return Config{}.applyEnv(); }
@@ -209,6 +215,12 @@ struct PVXS_API Config {
inline Server build() const {
return Server(*this);
}
#ifdef PVXS_EXPERT_API_ENABLED
// for protocol compatibility testing
inline Config& overrideSendBE(bool be) { BE = be; return *this; }
inline bool sendBE() const { return BE; }
#endif
};
PVXS_API
+1 -1
View File
@@ -44,7 +44,7 @@ DEFINE_LOGGER(connio, "pvxs.tcp.io");
DEFINE_LOGGER(remote, "pvxs.remote.log");
ServerConn::ServerConn(ServIface* iface, evutil_socket_t sock, struct sockaddr *peer, int socklen)
:ConnBase(false,
:ConnBase(false, iface->server->effective.sendBE(),
bufferevent_socket_new(iface->server->acceptor_loop.base, sock, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS),
SockAddr(peer))
,iface(iface)
+4
View File
@@ -94,6 +94,10 @@ TESTPROD_HOST += test1000
test1000_SRCS += test1000.cpp
TESTS += test1000
TESTPROD_HOST += testendian
testendian_SRCS += testendian.cpp
TESTS += testendian
ifdef BASE_7_0
TESTPROD_HOST += benchdata
+73
View File
@@ -0,0 +1,73 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvxs is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#define PVXS_ENABLE_EXPERT_API
#include <testMain.h>
#include <epicsUnitTest.h>
#include <epicsEvent.h>
#include <pvxs/unittest.h>
#include <pvxs/log.h>
#include <pvxs/client.h>
#include <pvxs/server.h>
#include <pvxs/sharedpv.h>
#include <pvxs/source.h>
#include <pvxs/nt.h>
namespace {
using namespace pvxs;
void testEndian(bool srvBE, bool cliBE)
{
testDiag("%s(%c, %c)", __func__,
srvBE ? 'B' : 'L',
cliBE ? 'B' : 'L');
const auto proto = nt::NTScalar{TypeCode::UInt32}
.create()
.update("value", 42);
auto mbox(server::SharedPV::buildMailbox());
mbox.open(proto);
auto srv = server::Config::isolated()
.overrideSendBE(srvBE)
.build()
.addPV("dut", mbox)
.start();
auto cli = srv.clientConfig()
.overrideSendBE(cliBE)
.build();
try {
auto val = cli.get("dut")
.exec()
->wait(5.0);
testEq(val["value"].as<uint32_t>(), 42u);
}catch(std::exception& e){
testFail("Unexpected exception: %s\n", e.what());
}
}
} // namespace
MAIN(testendian)
{
testPlan(4);
testSetup();
logger_config_env();
testEndian(false, false);
testEndian(false, true);
testEndian(true, false);
testEndian(true, true);
cleanup_for_valgrind();
return testDone();
}