mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-30 07:23:33 +08:00
Aggregate type signature computation + tests
This commit is contained in:
@@ -69,11 +69,8 @@ class DataTypeSignature
|
||||
|
||||
void mixin64(uint64_t x);
|
||||
|
||||
DataTypeSignature() : value_(0) { }
|
||||
|
||||
public:
|
||||
static DataTypeSignature zero() { return DataTypeSignature(); }
|
||||
|
||||
DataTypeSignature() : value_(0) { }
|
||||
explicit DataTypeSignature(uint64_t value) : value_(value) { }
|
||||
|
||||
void extend(DataTypeSignature dts);
|
||||
@@ -100,7 +97,6 @@ public:
|
||||
DataTypeDescriptor()
|
||||
: kind_(DataTypeKind(0))
|
||||
, id_(0)
|
||||
, signature_(DataTypeSignature::zero())
|
||||
, name_("")
|
||||
{ }
|
||||
|
||||
@@ -121,6 +117,7 @@ public:
|
||||
const char* getName() const { return name_; }
|
||||
|
||||
bool match(DataTypeKind kind, const char* name) const;
|
||||
bool match(DataTypeKind kind, uint16_t id) const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
|
||||
const DataTypeDescriptor* find(DataTypeKind kind, const char* name) const;
|
||||
|
||||
DataTypeSignature computeAggregateSignature(const DataTypeIDMask& msgs, const DataTypeIDMask& srvs) const;
|
||||
DataTypeSignature computeAggregateSignature(DataTypeKind kind, DataTypeIDMask& inout_id_mask) const;
|
||||
|
||||
void getDataTypeIDMask(DataTypeKind kind, DataTypeIDMask& mask) const;
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ bool DataTypeDescriptor::match(DataTypeKind kind, const char* name) const
|
||||
return (kind_ == kind) && !std::strcmp(name_, name);
|
||||
}
|
||||
|
||||
bool DataTypeDescriptor::match(DataTypeKind kind, uint16_t id) const
|
||||
{
|
||||
return (kind_ == kind) && (id_ == id);
|
||||
}
|
||||
|
||||
std::string DataTypeDescriptor::toString() const
|
||||
{
|
||||
char kindch = '?';
|
||||
|
||||
@@ -91,12 +91,55 @@ const DataTypeDescriptor* GlobalDataTypeRegistry::find(DataTypeKind kind, const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(const DataTypeIDMask& msgs,
|
||||
const DataTypeIDMask& srvs) const
|
||||
DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind kind,
|
||||
DataTypeIDMask& inout_id_mask) const
|
||||
{
|
||||
(void)msgs;
|
||||
(void)srvs;
|
||||
return DataTypeSignature::zero(); // TODO: implementation
|
||||
const List* list = selectList(kind);
|
||||
if (list == NULL)
|
||||
{
|
||||
assert(0);
|
||||
return DataTypeSignature();
|
||||
}
|
||||
|
||||
DataTypeSignature signature;
|
||||
bool signature_initialized = false;
|
||||
|
||||
for (int id = 0; id <= DataTypeDescriptor::MaxDataTypeID; id++)
|
||||
{
|
||||
if (!inout_id_mask[id])
|
||||
continue;
|
||||
|
||||
// TODO: do it faster - no need to traverse the list on each iteration
|
||||
const DataTypeDescriptor* desc = NULL;
|
||||
{
|
||||
Entry* p = list->get();
|
||||
while (p)
|
||||
{
|
||||
if (p->decriptor.match(kind, id))
|
||||
{
|
||||
desc = &p->decriptor;
|
||||
break;
|
||||
}
|
||||
p = p->getNextListNode();
|
||||
}
|
||||
}
|
||||
|
||||
if (desc)
|
||||
{
|
||||
if (signature_initialized)
|
||||
{
|
||||
signature.extend(desc->getSignature());
|
||||
}
|
||||
else
|
||||
{
|
||||
signature_initialized = true;
|
||||
signature = DataTypeSignature(desc->getSignature());
|
||||
}
|
||||
}
|
||||
else
|
||||
inout_id_mask[id] = false;
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
void GlobalDataTypeRegistry::getDataTypeIDMask(DataTypeKind kind, DataTypeIDMask& mask) const
|
||||
|
||||
@@ -42,7 +42,7 @@ TEST(DataTypeSignature, Correctness)
|
||||
using uavcan::DataTypeSignature;
|
||||
using uavcan::DataTypeSignatureCRC;
|
||||
|
||||
DataTypeSignature signature = DataTypeSignature::zero();
|
||||
DataTypeSignature signature;
|
||||
ASSERT_EQ(0, signature.get());
|
||||
|
||||
/*
|
||||
@@ -87,9 +87,9 @@ TEST(DataTypeSignature, Correctness)
|
||||
* Comparison
|
||||
*/
|
||||
ASSERT_TRUE(signature == DataTypeSignature(signature.get()));
|
||||
ASSERT_FALSE(signature == DataTypeSignature::zero());
|
||||
ASSERT_FALSE(signature == DataTypeSignature());
|
||||
ASSERT_FALSE(signature != DataTypeSignature(signature.get()));
|
||||
ASSERT_TRUE(signature != DataTypeSignature::zero());
|
||||
ASSERT_TRUE(signature != DataTypeSignature());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,22 @@ namespace
|
||||
static const char* getDataTypeName() { return "my_namespace.DataTypeB"; }
|
||||
};
|
||||
|
||||
struct DataTypeC
|
||||
{
|
||||
enum { DefaultDataTypeID = 43 };
|
||||
enum { DataTypeKind = uavcan::DataTypeKindMessage };
|
||||
static uavcan::DataTypeSignature getDataTypeSignature() { return uavcan::DataTypeSignature(654); }
|
||||
static const char* getDataTypeName() { return "foo.DataTypeC"; }
|
||||
};
|
||||
|
||||
struct DataTypeD
|
||||
{
|
||||
enum { DefaultDataTypeID = 43 };
|
||||
enum { DataTypeKind = uavcan::DataTypeKindService };
|
||||
static uavcan::DataTypeSignature getDataTypeSignature() { return uavcan::DataTypeSignature(987); }
|
||||
static const char* getDataTypeName() { return "foo.DataTypeD"; }
|
||||
};
|
||||
|
||||
|
||||
template <typename Type>
|
||||
uavcan::DataTypeDescriptor extractDescriptor(uint16_t dtid = Type::DefaultDataTypeID)
|
||||
@@ -44,13 +60,15 @@ namespace
|
||||
TEST(GlobalDataTypeRegistry, Basic)
|
||||
{
|
||||
using uavcan::GlobalDataTypeRegistry;
|
||||
using uavcan::DataTypeIDMask;
|
||||
using uavcan::DataTypeSignature;
|
||||
|
||||
GlobalDataTypeRegistry::instance().reset();
|
||||
ASSERT_FALSE(GlobalDataTypeRegistry::instance().isFrozen());
|
||||
ASSERT_EQ(0, GlobalDataTypeRegistry::instance().getNumMessageTypes());
|
||||
ASSERT_EQ(0, GlobalDataTypeRegistry::instance().getNumServiceTypes());
|
||||
|
||||
uavcan::DataTypeIDMask dtmask;
|
||||
DataTypeIDMask dtmask;
|
||||
dtmask.set();
|
||||
GlobalDataTypeRegistry::instance().getDataTypeIDMask(uavcan::DataTypeKindMessage, dtmask);
|
||||
ASSERT_FALSE(dtmask.any());
|
||||
@@ -106,6 +124,25 @@ TEST(GlobalDataTypeRegistry, Basic)
|
||||
dtmask[147] = false;
|
||||
ASSERT_FALSE(dtmask.any());
|
||||
|
||||
/*
|
||||
* These types will be necessary for the aggregate signature test
|
||||
*/
|
||||
ASSERT_TRUE(GlobalDataTypeRegistry::instance().assign<DataTypeC>(DataTypeC::DefaultDataTypeID));
|
||||
uavcan::DefaultDataTypeRegistrator<DataTypeD> reg_DataTypeD;
|
||||
|
||||
GlobalDataTypeRegistry::instance().getDataTypeIDMask(uavcan::DataTypeKindMessage, dtmask);
|
||||
ASSERT_TRUE(dtmask[0]);
|
||||
ASSERT_TRUE(dtmask[741]);
|
||||
ASSERT_TRUE(dtmask[43]);
|
||||
dtmask[0] = dtmask[43] = dtmask[741] = false;
|
||||
ASSERT_FALSE(dtmask.any());
|
||||
|
||||
GlobalDataTypeRegistry::instance().getDataTypeIDMask(uavcan::DataTypeKindService, dtmask);
|
||||
ASSERT_TRUE(dtmask[147]);
|
||||
ASSERT_TRUE(dtmask[43]);
|
||||
dtmask[43] = dtmask[147] = false;
|
||||
ASSERT_FALSE(dtmask.any());
|
||||
|
||||
/*
|
||||
* Frozen state
|
||||
*/
|
||||
@@ -131,14 +168,76 @@ TEST(GlobalDataTypeRegistry, Basic)
|
||||
|
||||
ASSERT_TRUE((pdtd = GlobalDataTypeRegistry::instance().find(uavcan::DataTypeKindService, "my_namespace.DataTypeA")));
|
||||
ASSERT_EQ(extractDescriptor<DataTypeAService>(147), *pdtd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Aggregate signature computation
|
||||
*/
|
||||
// TODO: test
|
||||
|
||||
TEST(GlobalDataTypeRegistry, AggregateSignature)
|
||||
{
|
||||
using uavcan::GlobalDataTypeRegistry;
|
||||
using uavcan::DataTypeIDMask;
|
||||
using uavcan::DataTypeSignature;
|
||||
|
||||
ASSERT_TRUE(GlobalDataTypeRegistry::instance().isFrozen());
|
||||
|
||||
DataTypeIDMask mask;
|
||||
DataTypeSignature sign;
|
||||
|
||||
// Zero - empty mask
|
||||
sign = GlobalDataTypeRegistry::instance().computeAggregateSignature(uavcan::DataTypeKindMessage, mask);
|
||||
|
||||
ASSERT_EQ(DataTypeSignature(), sign);
|
||||
ASSERT_FALSE(mask.any());
|
||||
|
||||
// All set
|
||||
mask.set();
|
||||
sign = GlobalDataTypeRegistry::instance().computeAggregateSignature(uavcan::DataTypeKindMessage, mask);
|
||||
ASSERT_TRUE(mask[0]); // DataTypeAMessage
|
||||
ASSERT_TRUE(mask[43]); // DataTypeC
|
||||
ASSERT_TRUE(mask[741]); // DataTypeB
|
||||
mask[0] = mask[43] = mask[741] = false;
|
||||
ASSERT_FALSE(mask.any());
|
||||
{
|
||||
DataTypeSignature check_signature(DataTypeAMessage::getDataTypeSignature()); // Order matters - low --> high
|
||||
check_signature.extend(DataTypeC::getDataTypeSignature());
|
||||
check_signature.extend(DataTypeB::getDataTypeSignature());
|
||||
ASSERT_EQ(check_signature, sign);
|
||||
}
|
||||
|
||||
mask.set();
|
||||
sign = GlobalDataTypeRegistry::instance().computeAggregateSignature(uavcan::DataTypeKindService, mask);
|
||||
ASSERT_TRUE(mask[43]); // DataTypeD
|
||||
ASSERT_TRUE(mask[147]); // DataTypeAService
|
||||
mask[43] = mask[147] = false;
|
||||
ASSERT_FALSE(mask.any());
|
||||
{
|
||||
DataTypeSignature check_signature(DataTypeD::getDataTypeSignature());
|
||||
check_signature.extend(DataTypeAService::getDataTypeSignature());
|
||||
ASSERT_EQ(check_signature, sign);
|
||||
}
|
||||
|
||||
// Random
|
||||
mask[0] = mask[99] = mask[147] = mask[741] = mask[999] = true;
|
||||
sign = GlobalDataTypeRegistry::instance().computeAggregateSignature(uavcan::DataTypeKindMessage, mask);
|
||||
ASSERT_TRUE(mask[0]); // DataTypeAMessage
|
||||
ASSERT_TRUE(mask[741]); // DataTypeB
|
||||
mask[0] = mask[741] = false;
|
||||
ASSERT_FALSE(mask.any());
|
||||
{
|
||||
DataTypeSignature check_signature(DataTypeAMessage::getDataTypeSignature()); // Order matters - low --> high
|
||||
check_signature.extend(DataTypeB::getDataTypeSignature());
|
||||
ASSERT_EQ(check_signature, sign);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(GlobalDataTypeRegistry, Reset)
|
||||
{
|
||||
using uavcan::GlobalDataTypeRegistry;
|
||||
|
||||
/*
|
||||
* Since we're dealing with singleton, we need to reset it for other tests to use
|
||||
*/
|
||||
ASSERT_TRUE(GlobalDataTypeRegistry::instance().isFrozen());
|
||||
GlobalDataTypeRegistry::instance().reset();
|
||||
ASSERT_FALSE(GlobalDataTypeRegistry::instance().isFrozen());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user