Main Content

Incorrect use of test fixtures

Test fixture accessed in suite-test setup/teardown, suite-test fixture accessed in suite setup/teardown

Since R2023b

Description

This defect occurs when you incorrectly access a test or suite-test fixture pointer using macros from the Polyspace® Test™ xUnit API outside the scope where it is defined. For instance:

  • You invoke the test fixture accessor macro PST_TEST_FIXTURE_PTR from a suite-test setup or teardown function (that is, a function registered using PST_SUITE_TEST_SETUP or PST_SUITE_TEST_TEARDOWN).

  • You invoke the suite-test fixture accessor macro PST_SUITE_TEST_FIXTURE_PTR from a suite-level setup or teardown function (that is, a function registered using PST_SUITE_SETUP or PST_SUITE_TEARDOWN).

This checker is enabled if you specify the value pstunit for the option Libraries used (-library) or find defects in a test file from the Polyspace Platform (Polyspace Test) user interface. For more information, see Check for Bugs and Run-Time Errors in C/C++ Tests and Functions Under Test (Polyspace Test).

Risk

Accessing a test fixture outside the scope where it is defined leads to undefined behavior.

Fix

Invoke the correct fixture accessor macro in your setup and teardown functions.

Fixture Accessor MacroSetup and Teardown
PST_SUITE_TEST_FIXTURE_PTR
  • PST_SUITE_TEST_SETUP

  • PST_SUITE_TEST_TEARDOWN

PST_TEST_FIXTURE_PTR
  • PST_SETUP

  • PST_TEARDOWN

Examples

expand all

In this example, a fixture is used to reset the value of a global variable gSum to 0 after every test. Since the reset must happen after every test, the function resetGSum that performs the reset is registered using the suite-test macro PST_SUITE_TEST_TEARDOWN. However, the fixture is accessed using a test fixture accessor PST_TEST_FIXTURE_PTR and not a suite-test accessor PST_SUITE_TEST_FIXTURE_PTR.

  • Header with type definitions (named example.h):

    #include <limits.h>
    extern unsigned gSum;
    
    typedef enum {
        NOT_SATURATED = 0,
        SATURATED = 1
    } SUM_STATUS;
    
    SUM_STATUS globalSum(unsigned x);
  • Source:

    #include "example.h"
    
    unsigned gSum;
    
    SUM_STATUS globalSum(unsigned x) {
        if (x > UINT_MAX - gSum) {
            gSum = UINT_MAX;
            return SATURATED;
        }
        gSum += x;
        return NOT_SATURATED;
    }
  • Tests:

    #include <pstunit.h>
    #include "example.h"
    
    //Test utilities
    void setGSum (void) {
        PST_SET_FIXTURE_PTR(&gSum);
    }
    
    void resetGSum (void) {
        unsigned int* currentGSum = (unsigned int*)PST_TEST_FIXTURE_PTR();
        *currentGSum = 0;
    }
    
    
    PST_SUITE_CONFIG(gSumTests) {
        PST_SUITE_TEST_SETUP(setGSum);
        PST_SUITE_TEST_TEARDOWN(resetGSum);
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseOne){
    
    }
    PST_TEST_BODY(gSumTests, TestCaseOne) {
        unsigned test_data = 1;
        unsigned expected_gSum = 1;
        int  i;
        
        for(i = 1; i<= 1; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in nonsaturating sum.");
          
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseTwo){}
    PST_TEST_BODY(gSumTests, TestCaseTwo) {
        unsigned test_data = 1;
        unsigned expected_gSum = 2;
        int i;
        
        for(i = 1; i<= 2; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is just above limit.");
    
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseThree){}
    PST_TEST_BODY(gSumTests, TestCaseThree) {
        unsigned test_data = 1;
        unsigned expected_gSum = 3;
        int i;
            
        for(i = 1; i<= 3; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is well above limit.");
    }
    
    
    PST_REGFCN(myRegFcn) {
        PST_ADD_TEST(gSumTests, TestCaseOne);
        PST_ADD_TEST(gSumTests, TestCaseTwo);
        PST_ADD_TEST(gSumTests, TestCaseThree);
    }
    
    #ifndef PSTEST_BUILD
    int main(int argc, char *argv[]) {
        PST_REGFCN_CALL(myRegFcn);
        return PST_MAIN(argc, argv);
    }
    #endif
    
Correction — Use Suite-Test Fixture Accessor

Invoke the suite-test fixture accessor macro PST_SUITE_TEST_FIXTURE_PTR in a suite-test teardown function. The corrected test file is shown below.

  • Header with type definitions (named example.h):

    #include <limits.h>
    extern unsigned gSum;
    
    typedef enum {
        NOT_SATURATED = 0,
        SATURATED = 1
    } SUM_STATUS;
    
    SUM_STATUS globalSum(unsigned x);
  • Source:

    #include "example.h"
    
    unsigned gSum;
    
    SUM_STATUS globalSum(unsigned x) {
        if (x > UINT_MAX - gSum) {
            gSum = UINT_MAX;
            return SATURATED;
        }
        gSum += x;
        return NOT_SATURATED;
    }
  • Tests:

    #include <pstunit.h>
    #include "example.h"
    
    //Test utilities
    void setGSum (void) {
        PST_SET_FIXTURE_PTR(&gSum);
    }
    
    void resetGSum (void) {
        unsigned int* currentGSum = (unsigned int*)PST_SUITE_TEST_FIXTURE_PTR();
        *currentGSum = 0;
    }
    
    
    PST_SUITE_CONFIG(gSumTests) {
        PST_SUITE_TEST_SETUP(setGSum);
        PST_SUITE_TEST_TEARDOWN(resetGSum);
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseOne){
    
    }
    PST_TEST_BODY(gSumTests, TestCaseOne) {
        unsigned test_data = 1;
        unsigned expected_gSum = 1;
        int  i;
        
        for(i = 1; i<= 1; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in nonsaturating sum.");
          
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseTwo){}
    PST_TEST_BODY(gSumTests, TestCaseTwo) {
        unsigned test_data = 1;
        unsigned expected_gSum = 2;
        int i;
        
        for(i = 1; i<= 2; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is just above limit.");
    
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseThree){}
    PST_TEST_BODY(gSumTests, TestCaseThree) {
        unsigned test_data = 1;
        unsigned expected_gSum = 3;
        int i;
            
        for(i = 1; i<= 3; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is well above limit.");
    }
    
    
    PST_REGFCN(myRegFcn) {
        PST_ADD_TEST(gSumTests, TestCaseOne);
        PST_ADD_TEST(gSumTests, TestCaseTwo);
        PST_ADD_TEST(gSumTests, TestCaseThree);
    }
    
    #ifndef PSTEST_BUILD
    int main(int argc, char *argv[]) {
        PST_REGFCN_CALL(myRegFcn);
        return PST_MAIN(argc, argv);
    }
    #endif
    

Result Information

Group: Libraries Misuse
Language: C | C++
Default: Off
Command-Line Syntax: PSTUNIT_MISUSE_FIXTURES
Impact: Medium

Version History

Introduced in R2023b