allow override of sendBE and test all combinations
Cross-testing client/server with all byte order combinations.
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user