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
Topic revision: r3 - 06 Dec 2022, SolveighMatthies
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback