Aggregate type signature computation + tests

This commit is contained in:
Pavel Kirienko
2014-02-28 11:19:16 +04:00
parent 3b67b15ff5
commit c6518d22f5
6 changed files with 163 additions and 19 deletions
+2 -5
View File
@@ -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;
+5
View File
@@ -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 = '?';
+48 -5
View File
@@ -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
+3 -3
View File
@@ -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());
}
+104 -5
View File
@@ -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());
}