Matter SDK Coverage Report
Current view: top level - lib/support - PersistentStorageAudit.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 0.0 % 179 0
Test Date: 2025-01-17 19:00:11 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2022 Project CHIP Authors
       3              :  *    All rights reserved.
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #include <cstring>
      19              : 
      20              : #include <lib/core/CHIPError.h>
      21              : #include <lib/core/CHIPPersistentStorageDelegate.h>
      22              : #include <lib/support/logging/CHIPLogging.h>
      23              : 
      24              : #include "PersistentStorageAudit.h"
      25              : 
      26              : #ifdef NL_TEST_ASSERT
      27              : #undef NL_TEST_ASSERT
      28              : #endif
      29              : 
      30              : #define NL_TEST_ASSERT(inSuite, inCondition)                                                                                       \
      31              :     do                                                                                                                             \
      32              :     {                                                                                                                              \
      33              :         (inSuite)->performedAssertions += 1;                                                                                       \
      34              :                                                                                                                                    \
      35              :         if (!(inCondition))                                                                                                        \
      36              :         {                                                                                                                          \
      37              :             ChipLogError(Automation, "%s:%u: assertion failed: \"%s\"", __FILE__, __LINE__, #inCondition);                         \
      38              :             (inSuite)->failedAssertions += 1;                                                                                      \
      39              :             (inSuite)->flagError = true;                                                                                           \
      40              :         }                                                                                                                          \
      41              :     } while (0)
      42              : 
      43              : namespace chip {
      44              : namespace audit {
      45              : 
      46              : // The following test is a copy of `src/lib/support/tests/TestTestPersistentStorageDelegate.cpp` 's
      47              : // `TestBasicApi()` test. It has to be copied since we currently are not setup to
      48              : // run on-device unit tests at large on all embedded platforms part of the SDK.
      49            0 : bool ExecutePersistentStorageApiAudit(PersistentStorageDelegate & storage)
      50              : {
      51              :     struct fakeTestSuite
      52              :     {
      53              :         int performedAssertions = 0;
      54              :         int failedAssertions    = 0;
      55              :         bool flagError          = false;
      56            0 :     } theSuite;
      57            0 :     auto * inSuite = &theSuite;
      58              : 
      59              :     static const char kLongKeyString[] = "aKeyThatIsExactlyMaxKeyLengthhhh";
      60              :     // Start fresh.
      61            0 :     (void) storage.SyncDeleteKeyValue("roboto");
      62            0 :     (void) storage.SyncDeleteKeyValue("key2");
      63            0 :     (void) storage.SyncDeleteKeyValue("key3");
      64            0 :     (void) storage.SyncDeleteKeyValue("key4");
      65            0 :     (void) storage.SyncDeleteKeyValue("keyDOES_NOT_EXIST");
      66            0 :     (void) storage.SyncDeleteKeyValue(kLongKeyString);
      67              : 
      68              :     // ========== Start of actual audit from TestTestPersistentStorageDelegate.cpp =========
      69              : 
      70              :     uint8_t buf[16];
      71            0 :     const uint16_t actualSizeOfBuf = static_cast<uint16_t>(sizeof(buf));
      72            0 :     uint16_t size                  = actualSizeOfBuf;
      73              : 
      74              :     // Key not there
      75              :     CHIP_ERROR err;
      76            0 :     memset(&buf[0], 0, sizeof(buf));
      77            0 :     size = actualSizeOfBuf;
      78            0 :     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
      79            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
      80            0 :     NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
      81              : 
      82            0 :     err = storage.SyncDeleteKeyValue("roboto");
      83            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
      84              : 
      85              :     // Add basic key, read it back, erase it
      86              :     static const char kStringValue1[] = "abcd";
      87            0 :     err = storage.SyncSetKeyValue("roboto", kStringValue1, static_cast<uint16_t>(strlen(kStringValue1)));
      88            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
      89              : 
      90            0 :     memset(&buf[0], 0, sizeof(buf));
      91            0 :     size = actualSizeOfBuf;
      92            0 :     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
      93            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
      94            0 :     NL_TEST_ASSERT(inSuite, size == strlen(kStringValue1));
      95            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));
      96              : 
      97            0 :     err = storage.SyncDeleteKeyValue("roboto");
      98            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
      99              : 
     100            0 :     memset(&buf[0], 0, sizeof(buf));
     101            0 :     size = actualSizeOfBuf;
     102            0 :     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
     103            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
     104            0 :     NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
     105              : 
     106              :     // Validate adding 2 different keys
     107              :     static const char kStringValue2[] = "0123abcd";
     108              :     static const char kStringValue3[] = "cdef89";
     109            0 :     err = storage.SyncSetKeyValue("key2", kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
     110            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     111              : 
     112            0 :     err = storage.SyncSetKeyValue("key3", kStringValue3, static_cast<uint16_t>(strlen(kStringValue3)));
     113            0 :     NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key3"));
     114            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     115              : 
     116              :     // Read them back
     117              : 
     118              :     uint8_t all_zeroes[sizeof(buf)];
     119            0 :     memset(&all_zeroes[0], 0, sizeof(all_zeroes));
     120              : 
     121            0 :     memset(&buf[0], 0, sizeof(buf));
     122            0 :     size = actualSizeOfBuf;
     123            0 :     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
     124            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     125            0 :     NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
     126            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
     127              :     // Make sure that there was no buffer overflow during SyncGetKeyValue
     128            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
     129              : 
     130            0 :     memset(&buf[0], 0, sizeof(buf));
     131            0 :     size = actualSizeOfBuf;
     132            0 :     err  = storage.SyncGetKeyValue("key3", &buf[0], size);
     133            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     134            0 :     NL_TEST_ASSERT(inSuite, size == strlen(kStringValue3));
     135            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue3, strlen(kStringValue3)));
     136              :     // Make sure that there was no buffer overflow during SyncGetKeyValue
     137            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
     138              : 
     139              :     // Read providing too small a buffer. Data read up to `size` and nothing more.
     140            0 :     memset(&buf[0], 0, sizeof(buf));
     141            0 :     size                               = static_cast<uint16_t>(strlen(kStringValue2) - 1);
     142            0 :     uint16_t sizeBeforeGetKeyValueCall = size;
     143            0 :     err                                = storage.SyncGetKeyValue("key2", &buf[0], size);
     144            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
     145            0 :     NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
     146            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, size));
     147              :     // Make sure that there was no buffer overflow during SyncGetKeyValue
     148            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
     149              : 
     150              :     // Read in too small a buffer, which is nullptr and size == 0: check CHIP_ERROR_BUFFER_TOO_SMALL is given.
     151            0 :     memset(&buf[0], 0, sizeof(buf));
     152            0 :     size                      = 0;
     153            0 :     sizeBeforeGetKeyValueCall = size;
     154            0 :     err                       = storage.SyncGetKeyValue("key2", nullptr, size);
     155            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
     156            0 :     NL_TEST_ASSERT(inSuite, size != strlen(kStringValue2));
     157            0 :     NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
     158              :     // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
     159              :     // nullptr is provided.
     160            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
     161              : 
     162              :     // Read in too small a buffer, which is nullptr and size != 0: error
     163            0 :     size                      = static_cast<uint16_t>(strlen(kStringValue2) - 1);
     164            0 :     sizeBeforeGetKeyValueCall = size;
     165            0 :     err                       = storage.SyncGetKeyValue("key2", nullptr, size);
     166            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
     167            0 :     NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
     168              :     // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
     169              :     // nullptr is provided.
     170            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
     171              : 
     172              :     // When key not found, size is not touched.
     173            0 :     size = actualSizeOfBuf;
     174            0 :     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", &buf[0], size);
     175            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
     176            0 :     NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
     177            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
     178              : 
     179            0 :     size = 0;
     180            0 :     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
     181            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
     182            0 :     NL_TEST_ASSERT(inSuite, 0 == size);
     183            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
     184              : 
     185              :     // Even when key not found, cannot pass nullptr with size != 0.
     186            0 :     size = actualSizeOfBuf;
     187            0 :     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
     188            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
     189            0 :     NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
     190            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));
     191              : 
     192              :     // Attempt an empty key write with either nullptr or zero size works
     193            0 :     err = storage.SyncSetKeyValue("key2", kStringValue2, 0);
     194            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     195            0 :     NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));
     196              : 
     197            0 :     size = 0;
     198            0 :     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
     199            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     200            0 :     NL_TEST_ASSERT(inSuite, size == 0);
     201              : 
     202            0 :     size = 0;
     203            0 :     err  = storage.SyncGetKeyValue("key2", nullptr, size);
     204            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     205            0 :     NL_TEST_ASSERT(inSuite, size == 0);
     206              : 
     207            0 :     size = actualSizeOfBuf;
     208            0 :     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
     209            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     210            0 :     NL_TEST_ASSERT(inSuite, size == 0);
     211              : 
     212            0 :     err = storage.SyncSetKeyValue("key2", nullptr, 0);
     213            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     214            0 :     NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));
     215              : 
     216            0 :     size = 0;
     217            0 :     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
     218            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     219            0 :     NL_TEST_ASSERT(inSuite, size == 0);
     220              : 
     221              :     // Failure to set key if buffer is nullptr and size != 0
     222            0 :     size = 10;
     223            0 :     err  = storage.SyncSetKeyValue("key4", nullptr, size);
     224            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
     225            0 :     NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key4"));
     226              : 
     227              :     // Can delete empty key
     228            0 :     err = storage.SyncDeleteKeyValue("key2");
     229            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     230              : 
     231            0 :     NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key2"));
     232              : 
     233            0 :     size = actualSizeOfBuf;
     234            0 :     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
     235            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
     236            0 :     NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
     237            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));
     238              : 
     239              :     // Using key and value with base64 symbols
     240              :     static const char kBase64SymbolsKey[]   = "key+/=";
     241              :     static const char kBase64SymbolValues[] = "value+/=";
     242            0 :     err = storage.SyncSetKeyValue(kBase64SymbolsKey, kBase64SymbolValues, static_cast<uint16_t>(strlen(kBase64SymbolValues)));
     243            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     244              : 
     245            0 :     memset(&buf[0], 0, sizeof(buf));
     246            0 :     size = actualSizeOfBuf;
     247            0 :     err  = storage.SyncGetKeyValue(kBase64SymbolsKey, &buf[0], size);
     248            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     249            0 :     NL_TEST_ASSERT(inSuite, size == strlen(kBase64SymbolValues));
     250            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kBase64SymbolValues, strlen(kBase64SymbolValues)));
     251              :     // Make sure that there was no buffer overflow during SyncGetKeyValue
     252            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
     253              : 
     254            0 :     err = storage.SyncDeleteKeyValue(kBase64SymbolsKey);
     255            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     256            0 :     NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(kBase64SymbolsKey));
     257              : 
     258              :     // Try using key that is a size that equals PersistentStorageDelegate::kKeyLengthMax
     259              :     char longKeyString[PersistentStorageDelegate::kKeyLengthMax + 1];
     260            0 :     memset(&longKeyString, 'X', PersistentStorageDelegate::kKeyLengthMax);
     261            0 :     longKeyString[sizeof(longKeyString) - 1] = '\0';
     262              :     // strlen() is not compile time so we just have this runtime assert that should aways pass as a sanity check.
     263            0 :     NL_TEST_ASSERT(inSuite, strlen(longKeyString) == PersistentStorageDelegate::kKeyLengthMax);
     264              : 
     265            0 :     err = storage.SyncSetKeyValue(longKeyString, kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
     266            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     267              : 
     268            0 :     memset(&buf[0], 0, sizeof(buf));
     269            0 :     size = actualSizeOfBuf;
     270            0 :     err  = storage.SyncGetKeyValue(longKeyString, &buf[0], size);
     271            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     272            0 :     NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
     273            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
     274              :     // Make sure that there was no buffer overflow during SyncGetKeyValue
     275            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
     276              : 
     277            0 :     NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist(longKeyString));
     278              : 
     279            0 :     err = storage.SyncDeleteKeyValue(longKeyString);
     280            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     281            0 :     NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(longKeyString));
     282              : 
     283            0 :     constexpr size_t kMaxCHIPCertLength = 400; // From credentials/CHIPCert.h and spec
     284              :     uint8_t largeBuffer[kMaxCHIPCertLength];
     285            0 :     memset(&largeBuffer, 'X', sizeof(largeBuffer));
     286              :     uint8_t largeBufferForCheck[sizeof(largeBuffer)];
     287            0 :     memcpy(largeBufferForCheck, largeBuffer, sizeof(largeBuffer));
     288              : 
     289            0 :     err = storage.SyncSetKeyValue(longKeyString, largeBuffer, static_cast<uint16_t>(sizeof(largeBuffer)));
     290            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     291              : 
     292            0 :     memset(&largeBuffer, 0, sizeof(largeBuffer));
     293            0 :     size = static_cast<uint16_t>(sizeof(largeBuffer));
     294            0 :     err  = storage.SyncGetKeyValue(longKeyString, &largeBuffer[0], size);
     295            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     296            0 :     NL_TEST_ASSERT(inSuite, size == static_cast<uint16_t>(sizeof(largeBuffer)));
     297            0 :     NL_TEST_ASSERT(inSuite, 0 == memcmp(&largeBuffer, largeBufferForCheck, sizeof(largeBuffer)));
     298              : 
     299            0 :     err = storage.SyncDeleteKeyValue(longKeyString);
     300            0 :     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
     301              : 
     302              :     // Cleaning up
     303            0 :     (void) storage.SyncDeleteKeyValue("roboto");
     304            0 :     (void) storage.SyncDeleteKeyValue("key2");
     305            0 :     (void) storage.SyncDeleteKeyValue("key3");
     306            0 :     (void) storage.SyncDeleteKeyValue("key4");
     307            0 :     (void) storage.SyncDeleteKeyValue(kBase64SymbolsKey);
     308            0 :     (void) storage.SyncDeleteKeyValue(kLongKeyString);
     309              : 
     310              :     // ========== End of code from TestTestPersistentStorageDelegate.cpp =========
     311            0 :     if (inSuite->flagError)
     312              :     {
     313            0 :         ChipLogError(Automation,
     314              :                      "==== PersistentStorageDelegate API audit: FAILED: %d/%d failed assertions ====", inSuite->failedAssertions,
     315              :                      inSuite->performedAssertions);
     316            0 :         return false;
     317              :     }
     318              : 
     319            0 :     ChipLogError(Automation, "==== PersistentStorageDelegate API audit: SUCCESS ====");
     320            0 :     return true;
     321              : }
     322              : 
     323            0 : bool ExecutePersistentStorageLoadTestAudit(PersistentStorageDelegate & storage)
     324              : {
     325              :     (void) storage;
     326            0 :     ChipLogError(Automation, "==== PersistentStorageDelegate load test audit: SUCCESS ====");
     327            0 :     return true;
     328              : }
     329              : 
     330              : } // namespace audit
     331              : } // namespace chip
        

Generated by: LCOV version 2.0-1