Testing FESA Device Software
Testing FESA device software, e.g. in a continuous integration (CI) process, can be performed using the FESA test generator.
Usage
On the asl74* or asl75* cluster:
asl7xx: fesa-test-generator FESAClassDUDirectory/src/FESAClass.deploy -f
asl7xx: fesa-test-generator -d0 <device_name> -s <FEC name>
The test sources are created in
<FESAClassDUDirectory>/src/Test<FESADU>/src/test
<FESAClassDUDirectory>/src/Test<FESADU>/src/test/include/IntegrationTestListener.h
<FESAClassDUDirectory>/src/Test<FESADU>/src/test/include/IntegrationTestRDAClient.h
<FESAClassDUDirectory>/src/Test<FESADU>/src/test/Test<FESADU>.h
<FESAClassDUDirectory>/src/Test<FESADU>/src/test/Test<FESADU>.cpp
The test cases to be adapted are in
<FESAClassDUDirectory>/src/Test<FESADU>/src/test/Test<FESADU>.cpp
The test run script is found in
<FESAClassDUDirectory>/src/Test<FESADU>/run_google_tests.sh
If the test is running against a remotely running FESA deploy-unit the appropriate CMW nameserver should be used, e.g.
export CMW_DIRECTORY_CLIENT_SERVERLIST=cmwint00a.acc.gsi.de:5021
Test Suggestions for the Status Property
Automatically notified Status Property
TEST_F(TestA_DU, A_Get_Status)
{
SetUpDevice(A_device_name);
//// Fill up as needed!
ASSERT_NO_THROW(
auto_ptr<Data> data = DataFactory::createData();
//executeSet(device_name,"Init", data); //This will fill the fields of the class with data
sleep(2);
std::auto_ptr<AcquiredData> value = executeGet(A_device_name, "Status");
std::cout << value->getData().toString() << endl; // Check the result manually
// // This example only show how GSI-Status-Property test can look like
int32_t status = value->getData().getInt("status");
size_t detailedStatus_size = 2;
const bool* detailedStatus = value->getData().getArrayBool("detailedStatus", detailedStatus_size);
const int* detailedStatus_severity = value->getData().getArrayInt("detailedStatus_severity", detailedStatus_size);
const char* const* detailedStatus_labels = value->getData().getArrayString("detailedStatus_labels", detailedStatus_size);
int32_t powerState = value->getData().getInt("powerState");
int32_t control = value->getData().getInt("control");
bool interlock = value->getData().getBool("interlock");
bool opReady = value->getData().getBool("opReady");
bool modulesReady = value->getData().getBool("modulesReady");
ASSERT_EQ(status, 0);
ASSERT_FALSE(detailedStatus[0]);
ASSERT_FALSE(detailedStatus[1]);
ASSERT_EQ(detailedStatus_severity[0], 0);
ASSERT_EQ(detailedStatus_severity[1], 0);
ASSERT_STREQ(detailedStatus_labels[0], "myStatusLabel1");
ASSERT_STREQ(detailedStatus_labels[1], "myStatusLabel2");
ASSERT_EQ(powerState, 2);
ASSERT_EQ(control, 1);
ASSERT_FALSE(opReady);
ASSERT_FALSE(modulesReady);
ASSERT_FALSE(interlock);
);
}
NOT automatically notified Status Property
TEST_F(TestA_DU, B_Get_Status)
{
SetUpDevice(B_device_name);
//// Fill up as needed!
EXPECT_THROW( {
std::string exception_text = "NO_DATA_AVAILABLE: Access point 'BLALA/Status' has no data: FESA_13021 The field 'status' has no data for the cycle selector 'ALL'";
//try {
auto_ptr<Data> data = DataFactory::createData();
sleep(2);
std::auto_ptr<AcquiredData> value = executeGet(B_device_name, "Status");
std::cout << value->getData().toString() << endl; // Check the result manually
int32_t status = value->getData().getInt("status");
size_t detailedStatus_size = 2;
const bool* detailedStatus = value->getData().getArrayBool("detailedStatus", detailedStatus_size);
const int* detailedStatus_severity = value->getData().getArrayInt("detailedStatus_severity", detailedStatus_size);
const char* const* detailedStatus_labels = value->getData().getArrayString("detailedStatus_labels", detailedStatus_size);
int32_t powerState = value->getData().getInt("powerState");
int32_t control = value->getData().getInt("control");
bool interlock = value->getData().getBool("interlock");
bool opReady = value->getData().getBool("opReady");
bool modulesReady = value->getData().getBool("modulesReady");
ASSERT_EQ(status, 0);
ASSERT_FALSE(detailedStatus[0]);
ASSERT_FALSE(detailedStatus[1]);
ASSERT_EQ(detailedStatus_severity[0], 0);
ASSERT_EQ(detailedStatus_severity[1], 0);
ASSERT_STREQ(detailedStatus_labels[0], "myStatusLabel1");
ASSERT_STREQ(detailedStatus_labels[1], "myStatusLabel2");
ASSERT_EQ(powerState, 2);
ASSERT_EQ(control, 1);
ASSERT_FALSE(opReady);
ASSERT_FALSE(modulesReady);
ASSERT_FALSE(interlock);
/*} catch (const cmw::rda3::common::RdaException& e) {
std::cout << "The exception: " << e.what() << std::endl;
if( std::string(e.what()).find(exception_text) != std::string::npos ) {
std::cout << "Text in exception" << std::endl;
} else {
std::cout << "Text NOT in exception" << std::endl;
}
}*//* catch (const std::exception& e) {
std::cout << "The exception: " << e.what() << " / " << typeid(e).name() << std::endl;
}*/
}, cmw::rda3::common::RdaException);
}
Testing Subscriptons
TEST_F(TestA_DU, A_RT_ACTION_StatusUpdateAction)
{
SetUpDevice(A_device_name);
auto_ptr<Data> data = DataFactory::createData();
ASSERT_NO_THROW(
TestListenerSharedPtr replyHandler(new IntegrationTestListener);
SubscriptionSharedPtr subscription = subscribe(A_device_name, "Status", replyHandler);
for(int i = 0 ; i < 5 ; i++)
{
sleep(1);
std::cout << "Data available: " << replyHandler->dataAvailable_ << std::endl;
if( replyHandler->dataAvailable_ ) {
std::cout << replyHandler->receivedData_->getData().getBool("opReady") << std::endl;
ASSERT_FALSE(replyHandler->receivedData_->getData().getBool("opReady"));
ASSERT_FALSE(replyHandler->receivedData_->getData().getBool("modulesReady"));
ASSERT_FALSE(replyHandler->receivedData_->getData().getBool("interlock"));
} else {
std::cout << "Subscription: no data received" << std::endl;
std::cout << "Please make sure the property is automatically notified." << std::endl;
}
}
unsubscribe(subscription);
);
}
Sources
https://git.gsi.de/t.madej/fesa-test-generator
https://google.github.io/googletest
http://google.github.io/googletest/reference/assertions.html
--
SolveighMatthies - 29 Sep 2022