462 lines
14 KiB
C++
462 lines
14 KiB
C++
/*
|
|
* introspectionRegistryTest.cpp
|
|
*
|
|
* Created on: Dec 23, 2010
|
|
* Author: Gasper Jansa
|
|
*/
|
|
|
|
#include <pv/introspectionRegistry.h>
|
|
|
|
#include <epicsAssert.h>
|
|
#include <epicsExit.h>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <pv/CDRMonitor.h>
|
|
#include <pv/convert.h>
|
|
|
|
using std::tr1::static_pointer_cast;
|
|
using namespace epics::pvData;
|
|
|
|
namespace epics {
|
|
namespace pvAccess {
|
|
|
|
class SerializableControlImpl : public SerializableControl,
|
|
public NoDefaultMethods {
|
|
public:
|
|
virtual void flushSerializeBuffer() {
|
|
}
|
|
|
|
virtual void ensureBuffer(int size) {
|
|
}
|
|
|
|
virtual void alignBuffer(int alignment) {
|
|
}
|
|
|
|
SerializableControlImpl() {
|
|
}
|
|
|
|
virtual ~SerializableControlImpl() {
|
|
}
|
|
};
|
|
|
|
class DeserializableControlImpl : public DeserializableControl,
|
|
public NoDefaultMethods {
|
|
public:
|
|
virtual void ensureData(int size) {
|
|
}
|
|
|
|
virtual void alignData(int alignment) {
|
|
}
|
|
|
|
DeserializableControlImpl() {
|
|
}
|
|
|
|
virtual ~DeserializableControlImpl() {
|
|
}
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
using namespace epics::pvAccess;
|
|
using namespace std;
|
|
|
|
static SerializableControl* flusher;
|
|
static DeserializableControl* control;
|
|
static ByteBuffer* buffer;
|
|
|
|
static PVDataCreate* pvDataCreate;
|
|
static FieldCreate* fieldCreate;
|
|
static StandardField *standardField;
|
|
|
|
static IntrospectionRegistry* registry;
|
|
static IntrospectionRegistry* clientRegistry;
|
|
static IntrospectionRegistry* serverRegistry;
|
|
|
|
vector<PVField*> pvFieldArray;
|
|
|
|
static string builder;
|
|
|
|
//helper methods
|
|
ScalarConstPtr getScalar(string name)
|
|
{
|
|
ScalarConstPtr scalar = standardField->scalar(name,pvFloat);
|
|
PVField *pvField = pvDataCreate->createPVField(0,scalar);
|
|
pvFieldArray.push_back(pvField);
|
|
return scalar;
|
|
}
|
|
|
|
ScalarArrayConstPtr getScalarArray(string name)
|
|
{
|
|
ScalarArrayConstPtr scalarArray = standardField->scalarArray(name,pvFloat);
|
|
PVField *pvField = pvDataCreate->createPVField(0,scalarArray);
|
|
pvFieldArray.push_back(pvField);
|
|
return scalarArray;
|
|
}
|
|
|
|
StructureConstPtr getStructure(string name)
|
|
{
|
|
String properties("alarm");
|
|
FieldConstPtrArray powerSupply = new FieldConstPtr[3];
|
|
powerSupply[0] = standardField->scalar(
|
|
String("voltage"),pvDouble,properties);
|
|
powerSupply[1] = standardField->scalar(
|
|
String("power"),pvDouble,properties);
|
|
powerSupply[2] = standardField->scalar(
|
|
String("current"),pvDouble,properties);
|
|
StructureConstPtr structure = standardField->structure(name,3,powerSupply);
|
|
PVField *pvField = pvDataCreate->createPVField(0,structure);
|
|
pvFieldArray.push_back(pvField);
|
|
return structure;
|
|
}
|
|
|
|
StructureArrayConstPtr getStructureArray(string name1, string name2)
|
|
{
|
|
String properties("alarm");
|
|
FieldConstPtrArray powerSupply = new FieldConstPtr[3];
|
|
powerSupply[0] = standardField->scalar(
|
|
String("voltage"),pvDouble,properties);
|
|
powerSupply[1] = standardField->scalar(
|
|
String("power"),pvDouble,properties);
|
|
powerSupply[2] = standardField->scalar(
|
|
String("current"),pvDouble,properties);
|
|
StructureConstPtr structure = standardField->structure(name1,3,powerSupply);
|
|
StructureArrayConstPtr structureArray = standardField->structureArray(name2,structure);
|
|
PVField *pvField = pvDataCreate->createPVField(0,structureArray);
|
|
pvFieldArray.push_back(pvField);
|
|
return structureArray;
|
|
}
|
|
|
|
//test methods
|
|
void testRegistryPutGet()
|
|
{
|
|
short id = 0;
|
|
ScalarConstPtr scalarIn = getScalar("field1");
|
|
registry->registerIntrospectionInterface(id,scalarIn);
|
|
|
|
id++;
|
|
ScalarArrayConstPtr scalarArrayIn = getScalarArray("fieldArray1");
|
|
registry->registerIntrospectionInterface(id,scalarArrayIn);
|
|
|
|
id++;
|
|
StructureConstPtr structureIn = getStructure("struct1");
|
|
registry->registerIntrospectionInterface(id,structureIn);
|
|
|
|
id++;
|
|
StructureArrayConstPtr structureArrayIn = getStructureArray("struct1","structArray1");
|
|
registry->registerIntrospectionInterface(id,structureArrayIn);
|
|
|
|
id = 0;
|
|
ScalarConstPtr scalarOut = static_pointer_cast<const Scalar>(registry->getIntrospectionInterface(id));
|
|
assert(scalarIn == scalarOut);
|
|
|
|
id++;
|
|
ScalarArrayConstPtr scalarArrayOut = static_pointer_cast<const ScalarArray>(registry->getIntrospectionInterface(id));
|
|
assert(scalarArrayIn == scalarArrayOut);
|
|
|
|
id++;
|
|
StructureConstPtr structureOut = static_pointer_cast<const Structure>(registry->getIntrospectionInterface(id));
|
|
assert(structureIn == structureOut);
|
|
|
|
id++;
|
|
StructureArrayConstPtr structureArrayOut = static_pointer_cast<const StructureArray>(registry->getIntrospectionInterface(id));
|
|
assert(structureArrayIn == structureArrayOut);
|
|
|
|
bool existing;
|
|
id = registry->registerIntrospectionInterface(static_pointer_cast<const Field>(scalarIn),existing);
|
|
assert(existing == true);
|
|
assert(id == 0);
|
|
|
|
id = registry->registerIntrospectionInterface(static_pointer_cast<const Field>(scalarArrayIn),existing);
|
|
assert(existing == true);
|
|
assert(id == 1);
|
|
|
|
id = registry->registerIntrospectionInterface(static_pointer_cast<const Field>(structureIn),existing);
|
|
assert(existing == true);
|
|
assert(id == 2);
|
|
|
|
id = registry->registerIntrospectionInterface(static_pointer_cast<const Field>(structureArrayIn),existing);
|
|
assert(existing == true);
|
|
assert(id == 3);
|
|
|
|
//should exist
|
|
ScalarConstPtr scalarInNew = getScalar("field1");
|
|
id = registry->registerIntrospectionInterface(static_pointer_cast<const Field>(scalarInNew),existing);
|
|
assert(existing == true);
|
|
assert(id == 0);
|
|
|
|
scalarOut = static_pointer_cast<const Scalar>(registry->getIntrospectionInterface(id));
|
|
assert(scalarIn == scalarOut);
|
|
}
|
|
|
|
void testRegistryReset()
|
|
{
|
|
registry->reset();
|
|
|
|
short id = 0;
|
|
assert(static_pointer_cast<const Scalar>(registry->getIntrospectionInterface(id)) == 0);
|
|
}
|
|
|
|
void serialize(FieldConstPtr field, IntrospectionRegistry* registry)
|
|
{
|
|
buffer->clear();
|
|
registry->serialize(field,buffer,flusher);
|
|
//should be in registry
|
|
bool existing;
|
|
registry->registerIntrospectionInterface(field,existing);
|
|
assert(existing == true);
|
|
}
|
|
|
|
FieldConstPtr deserialize(IntrospectionRegistry* registry)
|
|
{
|
|
FieldConstPtr field = registry->deserialize(buffer,control);
|
|
PVField *pvField = pvDataCreate->createPVField(0,field);
|
|
pvFieldArray.push_back(pvField);
|
|
//should be in registry
|
|
bool existing;
|
|
registry->registerIntrospectionInterface(field,existing);
|
|
assert(existing == true);
|
|
return field;
|
|
}
|
|
|
|
void checkTypeCode(int8 typeCodeIn)
|
|
{
|
|
int8 typeCode = buffer->getByte();
|
|
//printf("%d == %d\n", typeCode, typeCodeIn);
|
|
assert(typeCode == typeCodeIn);
|
|
buffer->rewind();
|
|
}
|
|
|
|
void testSerializeCommon(FieldConstPtr serverField1, FieldConstPtr clientField2)
|
|
{
|
|
//server serializes field 1
|
|
serialize(serverField1,serverRegistry);
|
|
|
|
//full should be serialized
|
|
buffer->flip();
|
|
checkTypeCode(IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE);
|
|
|
|
//client deserializes 1
|
|
FieldConstPtr clientField1 = deserialize(clientRegistry);
|
|
assert(serverField1->getFieldName() == clientField1->getFieldName());
|
|
assert(serverField1->getType() == clientField1->getType());
|
|
|
|
//client serializes the same field
|
|
serialize(serverField1,clientRegistry);
|
|
|
|
//only id should be serialized
|
|
buffer->flip();
|
|
checkTypeCode(IntrospectionRegistry::ONLY_ID_TYPE_CODE);
|
|
|
|
//server deserializes the same field
|
|
serverField1 = deserialize(serverRegistry);
|
|
assert(serverField1->getFieldName() == clientField1->getFieldName());
|
|
assert(serverField1->getType() == clientField1->getType());
|
|
|
|
//client requests new field
|
|
serialize(clientField2,clientRegistry);
|
|
|
|
//full should be serialized
|
|
buffer->flip();
|
|
checkTypeCode(IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE);
|
|
|
|
//server deserializes new field
|
|
FieldConstPtr serverField2 = deserialize(serverRegistry);
|
|
assert(serverField2->getFieldName() == clientField2->getFieldName());
|
|
assert(serverField2->getType() == clientField2->getType());
|
|
}
|
|
|
|
void testSerialize()
|
|
{
|
|
clientRegistry->reset();
|
|
serverRegistry->reset();
|
|
stringstream ss;
|
|
string name1,name2,name3,name4;
|
|
|
|
for(int i = 0, j = 0; i < 10 ; i++, j++)
|
|
{
|
|
name1.clear();
|
|
name2.clear();
|
|
ss.str("");
|
|
ss << j;
|
|
name1 = "field" + ss.str();
|
|
ss.str("");
|
|
j++;
|
|
ss << j;
|
|
name2 = "field" + ss.str();
|
|
testSerializeCommon(static_pointer_cast<const Field>(getScalar(name1)),static_pointer_cast<const Field>(getScalar(name2)));
|
|
|
|
name1.clear();
|
|
name2.clear();
|
|
ss.str("");
|
|
ss << j;
|
|
name1 = "fieldArray" + ss.str();
|
|
ss.str("");
|
|
j++;
|
|
ss << j;
|
|
name2 = "fieldArray" + ss.str();
|
|
testSerializeCommon(static_pointer_cast<const Field>(getScalarArray(name1)),static_pointer_cast<const Field>(getScalarArray(name2)));
|
|
|
|
name1.clear();
|
|
name2.clear();
|
|
ss.str("");
|
|
ss << j;
|
|
name1 = "structure" + ss.str();
|
|
ss.str("");
|
|
j++;
|
|
ss << j;
|
|
name2 = "structure" + ss.str();
|
|
testSerializeCommon(static_pointer_cast<const Field>(getStructure(name1)),static_pointer_cast<const Field>(getStructure(name2)));
|
|
|
|
name1.clear();
|
|
name2.clear();
|
|
name3.clear();
|
|
name4.clear();
|
|
ss.str("");
|
|
ss << j;
|
|
name1 = "structure" + ss.str();
|
|
name2 = "structureArray" + ss.str();
|
|
ss.str("");
|
|
j++;
|
|
ss << j;
|
|
name3 = "structure" + ss.str();
|
|
name4 = "structureArray" + ss.str();
|
|
testSerializeCommon(static_pointer_cast<const Field>(getStructureArray(name1,name2)),static_pointer_cast<const Field>(getStructureArray(name3,name4)));
|
|
}
|
|
|
|
//serverRegistry->printKeysAndValues("server");
|
|
//clientRegistry->printKeysAndValues("client");
|
|
}
|
|
|
|
void testSerializeFull()
|
|
{
|
|
buffer->clear();
|
|
ScalarConstPtr scalarIn = getScalar("field1");
|
|
IntrospectionRegistry::serializeFull(static_pointer_cast<const Field>(scalarIn),buffer,flusher);
|
|
buffer->flip();
|
|
ScalarConstPtr scalarOut = static_pointer_cast<const Scalar>(IntrospectionRegistry::deserializeFull(buffer,control));
|
|
PVField *pvField = pvDataCreate->createPVField(0,scalarOut);
|
|
pvFieldArray.push_back(pvField);
|
|
assert(scalarIn->getFieldName() == scalarOut->getFieldName());
|
|
assert(scalarIn->getType() == scalarOut->getType());
|
|
|
|
buffer->clear();
|
|
ScalarArrayConstPtr scalarArrayIn = getScalarArray("fieldArray1");
|
|
IntrospectionRegistry::serializeFull(static_pointer_cast<const Field>(scalarArrayIn),buffer,flusher);
|
|
buffer->flip();
|
|
ScalarArrayConstPtr scalarArrayOut = static_pointer_cast<const ScalarArray>(IntrospectionRegistry::deserializeFull(buffer,control));
|
|
pvField = pvDataCreate->createPVField(0,scalarArrayOut);
|
|
pvFieldArray.push_back(pvField);
|
|
assert(scalarArrayIn->getFieldName() == scalarArrayOut->getFieldName());
|
|
assert(scalarArrayIn->getType() == scalarArrayOut->getType());
|
|
|
|
buffer->clear();
|
|
StructureConstPtr structureIn = getStructure("struct1");
|
|
IntrospectionRegistry::serializeFull(static_pointer_cast<const Field>(structureIn),buffer,flusher);
|
|
buffer->flip();
|
|
StructureConstPtr structureOut = static_pointer_cast<const Structure>(IntrospectionRegistry::deserializeFull(buffer,control));
|
|
pvField = pvDataCreate->createPVField(0,structureOut);
|
|
pvFieldArray.push_back(pvField);
|
|
assert(structureIn->getFieldName() == structureOut->getFieldName());
|
|
assert(structureIn->getType() == structureOut->getType());
|
|
|
|
buffer->clear();
|
|
StructureArrayConstPtr structureArrayIn = getStructureArray("struct1","structArray1");
|
|
IntrospectionRegistry::serializeFull(static_pointer_cast<const Field>(structureArrayIn),buffer,flusher);
|
|
buffer->flip();
|
|
StructureArrayConstPtr structureArrayOut = static_pointer_cast<const StructureArray>(IntrospectionRegistry::deserializeFull(buffer,control));
|
|
pvField = pvDataCreate->createPVField(0,structureArrayOut);
|
|
pvFieldArray.push_back(pvField);
|
|
assert(structureArrayIn->getFieldName() == structureArrayOut->getFieldName());
|
|
assert(structureArrayIn->getType() == structureArrayOut->getType());
|
|
}
|
|
|
|
void testSerializePVRequest()
|
|
{
|
|
buffer->clear();
|
|
registry->reset();
|
|
PVStructurePtr pvStructureIn = pvDataCreate->createPVStructure(NULL,getStructure("structure1"));
|
|
registry->serializePVRequest(buffer,flusher,pvStructureIn);
|
|
|
|
buffer->flip();
|
|
PVStructurePtr pvStructureOut = registry->deserializePVRequest(buffer,control);
|
|
assert(*pvStructureIn == *pvStructureOut);
|
|
delete pvStructureIn;
|
|
delete pvStructureOut;
|
|
}
|
|
|
|
void testDeserializeStructureAndCreatePVStructure()
|
|
{
|
|
buffer->clear();
|
|
registry->reset();
|
|
StructureConstPtr structureIn = getStructure("structure1");
|
|
serialize(structureIn,registry);
|
|
|
|
buffer->flip();
|
|
PVStructurePtr pvStructureOut = registry->deserializeStructureAndCreatePVStructure(buffer,control);
|
|
StructureConstPtr structureOut = pvStructureOut->getStructure();
|
|
assert(structureIn->getFieldName() == structureOut->getFieldName());
|
|
assert(structureIn->getType() == structureOut->getType());
|
|
delete pvStructureOut;
|
|
}
|
|
|
|
void testSerializeStatus()
|
|
{
|
|
buffer->clear();
|
|
registry->reset();
|
|
Status statusIn(Status::STATUSTYPE_WARNING, "msg", "dumpy");
|
|
registry->serializeStatus(buffer,flusher,statusIn);
|
|
|
|
buffer->flip();
|
|
Status statusOut;
|
|
registry->deserializeStatus(statusOut, buffer,control);
|
|
assert(statusIn.getType() == statusOut.getType());
|
|
assert(statusIn.getMessage() == statusOut.getMessage());
|
|
assert(statusIn.getStackDump() == statusOut.getStackDump());
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
pvDataCreate = getPVDataCreate();
|
|
fieldCreate = getFieldCreate();
|
|
standardField = getStandardField();
|
|
|
|
|
|
flusher = new SerializableControlImpl();
|
|
control = new DeserializableControlImpl();
|
|
buffer = new ByteBuffer(1<<16);
|
|
registry = new IntrospectionRegistry(true);
|
|
clientRegistry = new IntrospectionRegistry(false);
|
|
serverRegistry = new IntrospectionRegistry(true);
|
|
|
|
testRegistryPutGet();
|
|
testRegistryReset();
|
|
testSerialize();
|
|
testSerializeFull();
|
|
testDeserializeStructureAndCreatePVStructure();
|
|
testSerializeStatus();
|
|
|
|
registry->reset();
|
|
clientRegistry->reset();
|
|
serverRegistry->reset();
|
|
for (unsigned int i=0; i < pvFieldArray.size(); i++)
|
|
{
|
|
delete pvFieldArray[i];
|
|
}
|
|
pvFieldArray.clear();
|
|
|
|
if(flusher) delete flusher;
|
|
if(control) delete control;
|
|
if(buffer) delete buffer;
|
|
if(registry) delete registry;
|
|
if(clientRegistry) delete clientRegistry;
|
|
if(serverRegistry) delete serverRegistry;
|
|
|
|
epicsExitCallAtExits();
|
|
CDRMonitor::get().show(stdout, true);
|
|
cout << "DONE" << endl;
|
|
return 0;
|
|
}
|