From 69517e18f6ce1c3dbc6cf1c74bcec378a787936f Mon Sep 17 00:00:00 2001 From: Gasper Jansa Date: Mon, 27 Dec 2010 10:51:51 +0100 Subject: [PATCH] introspection registry test --- testApp/utils/introspectionRegistryTest.cpp | 467 ++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 testApp/utils/introspectionRegistryTest.cpp diff --git a/testApp/utils/introspectionRegistryTest.cpp b/testApp/utils/introspectionRegistryTest.cpp new file mode 100644 index 0000000..7851ad0 --- /dev/null +++ b/testApp/utils/introspectionRegistryTest.cpp @@ -0,0 +1,467 @@ +/* + * introspectionRegistryTest.cpp + * + * Created on: Dec 23, 2010 + * Author: Gasper Jansa + */ + +#include "introspectionRegistry.h" + +#include +#include +#include +#include +#include + +namespace epics { + namespace pvAccess { + + class SerializableControlImpl : public SerializableControl, + public NoDefaultMethods { + public: + virtual void flushSerializeBuffer() { + } + + virtual void ensureBuffer(int size) { + } + + SerializableControlImpl() { + } + + virtual ~SerializableControlImpl() { + } + }; + + class DeserializableControlImpl : public DeserializableControl, + public NoDefaultMethods { + public: + virtual void ensureData(int size) { + } + + DeserializableControlImpl() { + } + + virtual ~DeserializableControlImpl() { + } + }; + + } +} + +using namespace epics::pvAccess; +using namespace std; + +static SerializableControl* flusher; +static DeserializableControl* control; +static ByteBuffer* buffer; + +static PVDataCreate* pvDataCreate; +static StatusCreate* statusCreate; +static FieldCreate* fieldCreate; +static StandardField *standardField; + +static IntrospectionRegistry* registry; +static IntrospectionRegistry* clientRegistry; +static IntrospectionRegistry* serverRegistry; + +vector 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"); + FieldConstPtr powerSupply[3]; + powerSupply[0] = standardField->scalar( + String("voltage"),pvDouble,properties); + PVField *pvField = pvDataCreate->createPVField(0,powerSupply[0]); + pvFieldArray.push_back(pvField); + powerSupply[1] = standardField->scalar( + String("power"),pvDouble,properties); + pvField = pvDataCreate->createPVField(0,powerSupply[1]); + pvFieldArray.push_back(pvField); + powerSupply[2] = standardField->scalar( + String("current"),pvDouble,properties); + pvField = pvDataCreate->createPVField(0,powerSupply[2]); + pvFieldArray.push_back(pvField); + StructureConstPtr structure = standardField->structure(name,3,powerSupply); + pvField = pvDataCreate->createPVField(0,structure); + pvFieldArray.push_back(pvField); + return structure; +} + +StructureArrayConstPtr getStructureArray(string name1, string name2) +{ + String properties("alarm"); + FieldConstPtr powerSupply[3]; + powerSupply[0] = standardField->scalar( + String("voltage"),pvDouble,properties); + PVField *pvField = pvDataCreate->createPVField(0,powerSupply[0]); + pvFieldArray.push_back(pvField); + powerSupply[1] = standardField->scalar( + String("power"),pvDouble,properties); + pvField = pvDataCreate->createPVField(0,powerSupply[1]); + pvFieldArray.push_back(pvField); + powerSupply[2] = standardField->scalar( + String("current"),pvDouble,properties); + pvField = pvDataCreate->createPVField(0,powerSupply[2]); + pvFieldArray.push_back(pvField); + StructureConstPtr structure = standardField->structure(name1,3,powerSupply); + StructureArrayConstPtr structureArray = standardField->structureArray(name2,structure); + 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_cast(registry->getIntrospectionInterface(id)); + assert(scalarIn == scalarOut); + + id++; + ScalarArrayConstPtr scalarArrayOut = static_cast(registry->getIntrospectionInterface(id)); + assert(scalarArrayIn == scalarArrayOut); + + id++; + StructureConstPtr structureOut = static_cast(registry->getIntrospectionInterface(id)); + assert(structureIn == structureOut); + + id++; + StructureArrayConstPtr structureArrayOut = static_cast(registry->getIntrospectionInterface(id)); + assert(structureArrayIn == structureArrayOut); + + bool existing; + id = registry->registerIntrospectionInterface(static_cast(scalarIn),existing); + assert(existing == true); + assert(id == 0); + + id = registry->registerIntrospectionInterface(static_cast(scalarArrayIn),existing); + assert(existing == true); + assert(id == 1); + + id = registry->registerIntrospectionInterface(static_cast(structureIn),existing); + assert(existing == true); + assert(id == 2); + + id = registry->registerIntrospectionInterface(static_cast(structureArrayIn),existing); + assert(existing == true); + assert(id == 3); + + //should exist + ScalarConstPtr scalarInNew = getScalar("field1"); + id = registry->registerIntrospectionInterface(static_cast(scalarInNew),existing); + assert(existing == true); + assert(id == 0); + + scalarOut = static_cast(registry->getIntrospectionInterface(id)); + assert(scalarIn == scalarOut); +} + +void testRegistryReset() +{ + registry->reset(); + + short id = 0; + try //there is no elements so exception will be thrown + { + static_cast(registry->getIntrospectionInterface(id)); + } + catch(EpicsException& e) + { + return; + } + assert(false); +} + +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(); + 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 < 1 ; 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_cast(getScalar(name1)),static_cast(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_cast(getScalarArray(name1)),static_cast(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_cast(getStructure(name1)),static_cast(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_cast(getStructureArray(name1,name2)),static_cast(getStructureArray(name3,name4))); + } + + serverRegistry->printKeysAndValues("server"); + //clientRegistry->printKeysAndValues("client"); +} + +void testSerializeFull() +{ + buffer->clear(); + ScalarConstPtr scalarIn = getScalar("field1"); + IntrospectionRegistry::serializeFull(static_cast(scalarIn),buffer,flusher); + buffer->flip(); + ScalarConstPtr scalarOut = static_cast(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_cast(scalarArrayIn),buffer,flusher); + buffer->flip(); + ScalarArrayConstPtr scalarArrayOut = static_cast(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_cast(structureIn),buffer,flusher); + buffer->flip(); + StructureConstPtr structureOut = static_cast(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_cast(structureArrayIn),buffer,flusher); + buffer->flip(); + StructureArrayConstPtr structureArrayOut = static_cast(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 = statusCreate->getStatusOK(); + registry->serializeStatus(buffer,flusher,statusIn); + + buffer->flip(); + Status* statusOut= registry->deserializeStatus(buffer,control); + assert(statusIn->getType() == statusOut->getType()); + delete statusOut; + //TODO why are in and out on the same address? +} + +int main(int argc, char *argv[]) { + //TODO something is wrong with freeing structure and structure array, should be checked. + + pvDataCreate = getPVDataCreate(); + statusCreate = getStatusCreate(); + 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; + cout << "DONE" << endl; + return 0; +}