leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_main.c Source File

test_main.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2019 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "test_runners.h"
00020 
00021 #include "mbed_trace.h"
00022 
00023 #include "mcc_common_setup.h"
00024 
00025 #include "unity.h"
00026 #include "unity_fixture.h"
00027 
00028 #include <stdio.h>
00029 
00030 #define TRACE_GROUP "PAL"
00031 
00032 extern struct _Unity Unity;
00033 
00034 #define PAL_TEST_STATUS_FILE_LOCATION "/tstSts"
00035 #define PAL_TEST_STATUS_FILE_DATA_MAX_SIZE 128
00036 
00037 void * g_palTestNetworkInterface = NULL;
00038 void * g_palTestTLSInterfaceCTX = NULL;
00039 
00040 static volatile main_t main_test_function;
00041 static volatile int main_init_flags;
00042 
00043 static int palTestMainRunner(void);
00044 
00045 
00046 pal_args_t g_args; // defiend as global so it could persist 
00047                    // during task execution on FreeRTOS
00048 
00049 #ifdef DEBUG
00050 #define PAL_TESTS_LOG_LEVEL ((uint8_t)((TRACE_MASK_LEVEL & TRACE_ACTIVE_LEVEL_ALL) | (TRACE_MASK_CONFIG & TRACE_CARRIAGE_RETURN)))
00051 #else
00052 #define PAL_TESTS_LOG_LEVEL ((uint8_t)((TRACE_MASK_LEVEL & TRACE_ACTIVE_LEVEL_ERROR) | (TRACE_MASK_CONFIG & TRACE_CARRIAGE_RETURN)))
00053 #endif
00054 
00055 
00056 palTestsStatusData_t palTestStatus = {-1,-1,-1,0,0,0};
00057 
00058 
00059 palStatus_t getPalTestStatus(void)
00060 {
00061     palStatus_t status = PAL_SUCCESS, status2 = PAL_SUCCESS;
00062     char filePath[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0};
00063     palFileDescriptor_t fd = 0;
00064     size_t dataSizeWritten = 0;
00065     char data[128] = {0};
00066   
00067 
00068     status = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, filePath);
00069     if (PAL_SUCCESS == status) 
00070     {
00071         strncat(filePath,PAL_TEST_STATUS_FILE_LOCATION,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath));
00072         status = pal_fsFopen(filePath, PAL_FS_FLAG_READONLY, &fd);
00073          if (PAL_SUCCESS == status)
00074          {
00075 
00076              status =  pal_fsFread(&fd, (void *)data, PAL_TEST_STATUS_FILE_DATA_MAX_SIZE, &dataSizeWritten);
00077              if ((PAL_SUCCESS == status) && (dataSizeWritten > 0))
00078              {
00079                  printf("reading DATA into test\r\n");
00080                  sscanf(data,"%i %i %i %llu %llu %llu", &palTestStatus.module, &palTestStatus.test, &palTestStatus.inner, &palTestStatus.numOfTestsFailures, &palTestStatus.numberOfTests, &palTestStatus.numberOfIgnoredTests);
00081              }
00082              status2 = pal_fsFclose(&fd);
00083              if (PAL_SUCCESS != status2) 
00084              {
00085                  PAL_LOG_ERR("Failed to close data file of test status after read");
00086              }
00087              status2 = pal_fsUnlink(filePath);
00088              if (PAL_SUCCESS != status2) 
00089              {
00090                  PAL_LOG_ERR("Failed to delete data file of test status after read");
00091              }
00092          }
00093         else if (PAL_ERR_FS_NO_FILE == status) {
00094             //this is not an error... in most times there will be no file
00095             status = PAL_SUCCESS;
00096         }
00097     }
00098 
00099     PAL_LOG_DBG("*********************************\n"
00100             "** Test status:                **\n"
00101             "** Module %d                   **\n"
00102             "** Test %d                     **\n"
00103             "** Inner %d                    **\n"
00104             "** num of tests failures %llu  **\n"
00105             "** num of tests %llu           **\n"
00106             "** num of ignored tests %llu   **\n"
00107             "*********************************\n",
00108             palTestStatus.module, palTestStatus.test, palTestStatus.inner,
00109             palTestStatus.numOfTestsFailures, palTestStatus.numberOfTests,
00110             palTestStatus.numberOfIgnoredTests);
00111 
00112     return status;
00113 }
00114 
00115 void updatePalTestStatusAfterReboot(void)
00116 {
00117     if (palTestStatus.numberOfTests > 0)
00118     {
00119         Unity.TestFailures = palTestStatus.numOfTestsFailures;
00120         Unity.NumberOfTests = palTestStatus.numberOfTests;
00121         Unity.CurrentTestIgnored =palTestStatus.numberOfIgnoredTests;
00122         PAL_LOG_DBG("Unity number of tests was updated\r\n");
00123     }
00124 
00125     palTestStatus.inner = -1;
00126 }
00127 
00128 
00129 palStatus_t setPalTestStatus(palTestsStatusData_t palRebootTestStatus)
00130 {
00131     palStatus_t status = PAL_SUCCESS, status2 = PAL_SUCCESS;;
00132     char filePath[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0};
00133     palFileDescriptor_t fd = 0;
00134     size_t dataSizeWritten = 0;
00135     char data[PAL_TEST_STATUS_FILE_DATA_MAX_SIZE] = {0};
00136     
00137 
00138     status = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, filePath);
00139     if (PAL_SUCCESS == status) 
00140     {
00141         strncat(filePath,PAL_TEST_STATUS_FILE_LOCATION,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath));
00142         status = pal_fsFopen(filePath, PAL_FS_FLAG_READWRITETRUNC, &fd);
00143          if (PAL_SUCCESS == status)
00144          {
00145              snprintf((char *)data,PAL_TEST_STATUS_FILE_DATA_MAX_SIZE, "%d %d %d %llu %llu %llu ", palRebootTestStatus.module, palRebootTestStatus.test, palRebootTestStatus.inner, palRebootTestStatus.numOfTestsFailures, palRebootTestStatus.numberOfTests, palRebootTestStatus.numberOfIgnoredTests);
00146              status =  pal_fsFwrite(&fd, (void *)data, PAL_TEST_STATUS_FILE_DATA_MAX_SIZE, &dataSizeWritten);
00147              pal_fsFclose(&fd);
00148              if (PAL_SUCCESS != status2) 
00149              {
00150                  PAL_LOG_ERR("Failed to close data file of test status after write");
00151              }
00152          }
00153     }
00154     return status;
00155 }
00156 
00157 
00158 palStatus_t palTestReboot(palTestModules_t module ,palTestSOTPTests_t test )
00159 {
00160     palStatus_t status = PAL_SUCCESS;
00161     palTestsStatusData_t palRebootTestStatus;
00162     palRebootTestStatus.module = module;
00163     palRebootTestStatus.test = test;
00164     palRebootTestStatus.inner = 1;
00165     palRebootTestStatus.numberOfTests = Unity.NumberOfTests;
00166     palRebootTestStatus.numOfTestsFailures = Unity.TestFailures;
00167     palRebootTestStatus.numberOfIgnoredTests = Unity.CurrentTestIgnored;
00168 
00169     status = setPalTestStatus(palRebootTestStatus);
00170     if (PAL_SUCCESS != status)
00171     {
00172         PAL_LOG_ERR("Failed to set test status before reboot");
00173     }
00174     else
00175     {
00176         pal_osReboot();
00177     }
00178     return status;
00179 }
00180 
00181 
00182 void TEST_pal_all_GROUPS_RUNNER(void)
00183 {
00184     PRINT_MEMORY_STATS;
00185     switch (palTestStatus.module) // fall through is in design
00186     {
00187         case -1:
00188             //TEST_pal_sanity_GROUP_RUNNER(); // always run this at least once
00189         case PAL_TEST_MODULE_SOTP:
00190             PRINT_MEMORY_STATS;
00191             /**
00192              *  CAUTION:THIS TEST MUDOLE REBOOTS THE SYSTEM
00193              *  THIS TEST MUST BE 1ST!!!!!
00194              *  DO NOT MOVE THIS TEST!!!!!
00195             */
00196             #ifndef PAL_SKIP_TEST_MODULE_SOTP
00197                 TEST_pal_SOTP_GROUP_RUNNER();
00198             #endif
00199         case PAL_TEST_MODULE_RTOS:
00200             PRINT_MEMORY_STATS;
00201             #ifndef PAL_SKIP_TEST_MODULE_RTOS
00202                 TEST_pal_rtos_GROUP_RUNNER();
00203             #endif
00204         case PAL_TEST_MODULE_SOCKET:
00205             PRINT_MEMORY_STATS;
00206             #ifndef PAL_SKIP_TEST_MODULE_NETWORK
00207                 TEST_pal_socket_GROUP_RUNNER();
00208             #endif
00209         case PAL_TEST_MODULE_TIME:
00210             PRINT_MEMORY_STATS;
00211             #ifndef PAL_SKIP_TEST_MODULE_TIME
00212                 TEST_pal_time_GROUP_RUNNER();
00213             #endif
00214         case PAL_TEST_MODULE_CRYPTO:
00215             PRINT_MEMORY_STATS;
00216             #ifndef PAL_SKIP_TEST_MODULE_CRYPTO
00217                 TEST_pal_crypto_GROUP_RUNNER();
00218             #endif
00219         case PAL_TEST_MODULE_DRBG:
00220             PRINT_MEMORY_STATS;
00221             #ifndef PAL_SKIP_TEST_MODULE_DRBG
00222                 TEST_pal_drbg_GROUP_RUNNER();
00223             #endif
00224         case PAL_TEST_MODULE_FILESYSTEM:
00225             PRINT_MEMORY_STATS;
00226             #ifndef PAL_SKIP_TEST_MODULE_FILESYSTEM
00227                 TEST_pal_fileSystem_GROUP_RUNNER();
00228             #endif
00229         case PAL_TEST_MODULE_SST:
00230             PRINT_MEMORY_STATS;
00231             #ifndef PAL_SKIP_TEST_MODULE_SST
00232                 TEST_pal_sst_GROUP_RUNNER();
00233             #endif
00234         case PAL_TEST_MODULE_ROT:
00235             // if the implementation is using SOTP, it may be better to test storage and SOTP before it
00236             PRINT_MEMORY_STATS;
00237             #ifndef PAL_SKIP_TEST_MODULE_ROT
00238                 TEST_pal_rot_GROUP_RUNNER();
00239             #endif
00240         case PAL_TEST_MODULE_UPDATE:
00241             PRINT_MEMORY_STATS;
00242             #ifndef PAL_SKIP_TEST_MODULE_UPDATE
00243                 TEST_pal_update_GROUP_RUNNER();
00244             #endif
00245         case PAL_TEST_MODULE_INTERNALFLASH:
00246             PRINT_MEMORY_STATS;
00247             #ifndef PAL_SKIP_TEST_MODULE_INTERNALFLASH
00248                 TEST_pal_internalFlash_GROUP_RUNNER();
00249             #endif
00250         case PAL_TEST_MODULE_TLS:
00251             PRINT_MEMORY_STATS;
00252             #ifndef PAL_SKIP_TEST_MODULE_TLS
00253                 TEST_pal_tls_GROUP_RUNNER();
00254             #endif
00255             PRINT_MEMORY_STATS;
00256             break;
00257         default:
00258             PAL_PRINTF("this should not happen!!! Error Error Error");
00259     }
00260 }
00261 
00262 // Wrapper for running the palTestMainRunner in platform specific way.
00263 int palTestMain(void (*runAllTests)(void), int init_flags)
00264 {
00265     // As the mcc_platform_run_program() misses a way to pass data, the arguments
00266     // for palTestMainRunner() need to be stored into static variables.
00267     main_test_function = runAllTests;
00268     main_init_flags = init_flags;
00269 
00270     // On FreeRTOS the test needs to be started via the platform API, which will
00271     // create a task out of it and run the scheduler. Without this, the many of
00272     // the FreeRTOS API's are not usable.
00273     return mcc_platform_run_program((main_t)palTestMainRunner);
00274 }
00275 
00276 // XXX: when this is ran by mcc_platform_run_program(), the return value is not
00277 // actually passed on out of main(). This needs to be fixed in mcc_platform_run_program().
00278 static int palTestMainRunner(void)
00279 {
00280     const char * myargv[] = {"app","-v"};
00281 
00282     int status = 0;
00283 
00284     // copy back the arguments given to palTestMain.
00285     int init_flags = main_init_flags;
00286     void (*runAllTests)(void) = main_test_function;
00287 
00288     // this might be even a default as most tests need some kind of platform. But the
00289     // platfrom tests themselves might do some special stuff, so let's make mcc_platfrom_init()
00290     // call optional too.
00291     if (init_flags & PAL_TEST_PLATFORM_INIT_BASE) {
00292         status = mcc_platform_init();
00293 
00294         // The TEST_ASSERT can not be used yet, as it will cause a segfault on Unity, as
00295         // it has not yet performed its own setup for Unity.AbortFrame.
00296         // In any case, we will stop the test run as there is no point to continue tests
00297         // with half initialized platform.
00298         if (status) {
00299             PAL_LOG_ERR("failed to initialize platform: %d", status);
00300             return EXIT_FAILURE;
00301         }
00302     }
00303 
00304     // initialize the tracing as soon as possible so it can be used to debug the
00305     // more complex and fragile parts, such as storage and network driver initializations.
00306     mbed_trace_init();
00307     mbed_trace_config_set(PAL_TESTS_LOG_LEVEL);
00308 
00309     if (init_flags & PAL_TEST_PLATFORM_INIT_CONNECTION) {
00310         status = mcc_platform_init_connection();
00311 
00312         if (status) {
00313             PAL_LOG_ERR("failed to initialize connection: %d", status);
00314             return EXIT_FAILURE;
00315         }
00316 
00317         void* network;
00318 
00319 #if defined(PAL_LINUX_ETH)
00320         // On Linux side there is CMake magic to find out a interface name, which will fill
00321         // the PAL_LINUX_ETH macro.
00322         network = (char*)PAL_LINUX_ETH;
00323 #else
00324         network = mcc_platform_get_network_interface();
00325 #endif
00326 
00327         g_palTestNetworkInterface = network;
00328         g_palTestTLSInterfaceCTX = network;
00329     }
00330 
00331     if (init_flags & PAL_TEST_PLATFORM_INIT_STORAGE) {
00332         status = mcc_platform_storage_init();
00333 
00334         if (status) {
00335             PAL_LOG_ERR("failed to initialize storage: %d", status);
00336             return EXIT_FAILURE;
00337         }
00338     }
00339 
00340 // Format call is not needed with SST implementation
00341 #ifndef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00342     if (init_flags & PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE) {
00343         status = mcc_platform_reformat_storage();
00344 
00345         if (status) {
00346             PAL_LOG_ERR("failed to reformat storage: %d", status);
00347             return EXIT_FAILURE;
00348         }
00349     }
00350 #endif
00351 
00352     // XXX: this function uses the filesystem and it will typically fail if the storage is not initialized.
00353     palStatus_t getTestStatusReturnValue = getPalTestStatus();
00354     if (PAL_SUCCESS != getTestStatusReturnValue) 
00355     {
00356         PAL_LOG_ERR("%s: Failed to get current status of tests 0x%" PRIX32 "\r\n",__FUNCTION__,getTestStatusReturnValue);
00357     }
00358 
00359     UnityPrint("*****PAL_TEST_START*****");
00360     UNITY_PRINT_EOL();
00361 
00362     UnityMain(sizeof(myargv) / sizeof(myargv[0]), myargv, runAllTests);
00363 
00364     UnityPrint("*****PAL_TEST_END*****");
00365     UNITY_PRINT_EOL();
00366 
00367     mbed_trace_free();
00368 
00369     // TODO: should this actually return exit_failure if some of the tests failed?!
00370     return EXIT_SUCCESS;
00371 }
00372 
00373 int palAllTestMain(void)
00374 {
00375     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_CONNECTION|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00376     return palTestMain(TEST_pal_all_GROUPS_RUNNER, init_flags);
00377 }
00378 
00379 int palFileSystemTestMain(void)
00380 {
00381     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00382     return palTestMain(TEST_pal_fileSystem_GROUP_RUNNER, init_flags);
00383 }
00384 
00385 int palNetworkTestMain(void)
00386 {
00387     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_CONNECTION;
00388     return palTestMain(TEST_pal_socket_GROUP_RUNNER, init_flags);
00389 }
00390 
00391 int palCryptoTestMain(void)
00392 {
00393     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00394     return palTestMain(TEST_pal_crypto_GROUP_RUNNER, init_flags);
00395 }
00396 
00397 int palDRBGTestMain(void)
00398 {
00399     int init_flags = PAL_TEST_PLATFORM_INIT_BASE;
00400     return palTestMain(TEST_pal_drbg_GROUP_RUNNER, init_flags);
00401 }
00402 
00403 int palRTOSTestMain(void)
00404 {
00405     int init_flags = PAL_TEST_PLATFORM_INIT_BASE;
00406     return palTestMain(TEST_pal_rtos_GROUP_RUNNER, init_flags);
00407 }
00408 
00409 int palROTTestMain(void)
00410 {
00411     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE;
00412     return palTestMain(TEST_pal_rot_GROUP_RUNNER, init_flags);
00413 }
00414 
00415 int palEntropyTestMain(void)
00416 {
00417     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE;
00418     return palTestMain(TEST_pal_entropy_GROUP_RUNNER, init_flags);
00419 }
00420 
00421 int palStorageTestMain(void)
00422 {
00423     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE;
00424     return palTestMain(TEST_pal_internalFlash_GROUP_RUNNER, init_flags);
00425 }
00426 
00427 int palSSTTestMain(void)
00428 {
00429     int init_flags = PAL_TEST_PLATFORM_INIT_BASE | PAL_TEST_PLATFORM_INIT_STORAGE;
00430     return palTestMain(TEST_pal_sst_GROUP_RUNNER, init_flags);
00431 }
00432 
00433 int palTimeTestMain(void)
00434 {
00435     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00436     return palTestMain(TEST_pal_time_GROUP_RUNNER, init_flags);
00437 }
00438 
00439 int palTLSTestMain(void)
00440 {
00441     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_CONNECTION|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00442     return palTestMain(TEST_pal_tls_GROUP_RUNNER, init_flags);
00443 }
00444 
00445 int palUpdateTestMain(void)
00446 {
00447     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00448     return palTestMain(TEST_pal_update_GROUP_RUNNER, init_flags);
00449 }
00450 
00451 int palSOTPTestMain(void)
00452 {
00453     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00454     return palTestMain(TEST_pal_SOTP_GROUP_RUNNER, init_flags);
00455 }
00456 
00457 int palSanityTestMain(void)
00458 {
00459     int init_flags = PAL_TEST_PLATFORM_INIT_BASE;
00460     return palTestMain(TEST_pal_sanity_GROUP_RUNNER, init_flags);
00461 }
00462 
00463 int palReformatTestMain(void)
00464 {
00465     int init_flags = PAL_TEST_PLATFORM_INIT_BASE|PAL_TEST_PLATFORM_INIT_STORAGE|PAL_TEST_PLATFORM_INIT_REFORMAT_STORAGE;
00466     return palTestMain(TEST_pal_sanity_GROUP_RUNNER, init_flags);
00467 }
00468 
00469