@@ -51,6 +51,7 @@ using namespace utest::v1;
51
51
#else
52
52
#define CFSTORE_CREATE_GREENTEA_TIMEOUT_S 60
53
53
#endif
54
+ #define CFSTORE_CREATE_MALLOC_SIZE 1024
54
55
55
56
static char cfstore_create_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
56
57
@@ -272,15 +273,14 @@ static control_t cfstore_create_test_00(const size_t call_count)
272
273
}
273
274
274
275
275
- /* * @brief
276
+ /* * @brief Test case to change the value blob size of pre-existing key.
276
277
*
277
- * Test case to change the value blob size of pre-existing key.
278
278
* The test does the following:
279
279
* - creates a cfstore with ~10 entries.
280
- * - for a mid-cfstore entry, grow the value blob size
280
+ * - for a mid-cfstore entry, double the value blob size.
281
281
* - check all the cfstore entries can be read correctly and their
282
282
* data agrees with the data supplied upon creation.
283
- * - grow the mid-entry value blob size to be ~double the initial size.
283
+ * - shrink the mid-entry value blob size to be ~half the initial size.
284
284
* - check all the cfstore entries can be read correctly and their
285
285
* data agrees with the data supplied upon creation.
286
286
*
@@ -501,14 +501,13 @@ control_t cfstore_create_test_04_end(const size_t call_count)
501
501
return CaseNext;
502
502
}
503
503
504
- /* *@brief
505
- *
506
- * Test to create ~500 kvs. The amount of data store in the cfstore is as follows:
507
- * - total = (220*500)+(256/64)*500*501/2 500*8 = 8236000 = 8.236M
504
+
505
+ /* *
506
+ * @brief Support function for test cases 05
508
507
*
509
- * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
508
+ * Create enough KV's to consume the whole of available memory
510
509
*/
511
- control_t cfstore_create_test_05_end (const size_t call_count)
510
+ int32_t cfstore_create_test_05_core (const size_t call_count, uint32_t * bytes_stored_ex )
512
511
{
513
512
int32_t ret = ARM_DRIVER_ERROR;
514
513
uint32_t i = 0 ;
@@ -523,7 +522,10 @@ control_t cfstore_create_test_05_end(const size_t call_count)
523
522
ARM_CFSTORE_DRIVER* drv = &cfstore_driver;
524
523
525
524
CFSTORE_FENTRYLOG (" %s:entered\n " , __func__);
526
- (void ) call_count;
525
+
526
+ /* Initialize() */
527
+ cfstore_utest_default_start (call_count);
528
+
527
529
value_buf = (char *) malloc (max_value_buf_size);
528
530
CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: out of memory.\n " , __func__);
529
531
TEST_ASSERT_MESSAGE (value_buf != NULL , cfstore_create_utest_msg_g);
@@ -549,6 +551,48 @@ control_t cfstore_create_test_05_end(const size_t call_count)
549
551
free (value_buf);
550
552
CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: Uninitialize() call failed.\n " , __func__);
551
553
TEST_ASSERT_MESSAGE (drv->Uninitialize () >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
554
+ if (bytes_stored_ex){
555
+ *bytes_stored_ex = bytes_stored;
556
+ }
557
+ return ret;
558
+ }
559
+
560
+
561
+ /* *
562
+ * @brief Test case to check cfstore recovers from out of memory
563
+ * errors without leaking memory
564
+ *
565
+ * This test case does the following:
566
+ * 1. Start loop.
567
+ * 2. Initializes CFSTORE.
568
+ * 3. Creates as many KVs as required to run out of memory. The number of bytes B
569
+ * allocated before running out of memory is recorded.
570
+ * 4. For loop i, check that B_i = B_i-1 for i>0 i.e. that no memory has been leaked
571
+ * 5. Uninitialize(), which should clean up any cfstore internal state including
572
+ * freeing the internal memeory area.
573
+ * 6. Repeat from step 1 N times.
574
+ */
575
+ control_t cfstore_create_test_05 (const size_t call_count)
576
+ {
577
+ uint32_t i = 0 ;
578
+ int32_t ret = ARM_DRIVER_ERROR;
579
+ uint32_t bytes_stored = 0 ;
580
+ uint32_t bytes_stored_prev = 0 ;
581
+ const uint32_t max_loops = 50 ;
582
+
583
+ CFSTORE_FENTRYLOG (" %s:entered\n " , __func__);
584
+ for (i = 0 ; i < max_loops; i++) {
585
+ ret = cfstore_create_test_05_core (call_count, &bytes_stored);
586
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: cfstore_create_test_05_core() failed (ret = %d.\n " , __func__, (int ) ret);
587
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
588
+
589
+ if (i > 1 ) {
590
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: memory leak: stored %d bytes on loop %d, but %d bytes on loop %d .\n " , __func__, (int ) bytes_stored, (int ) i, (int ) bytes_stored_prev, (int ) i-1 );
591
+ TEST_ASSERT_MESSAGE (bytes_stored == bytes_stored_prev, cfstore_create_utest_msg_g);
592
+
593
+ }
594
+ bytes_stored_prev = bytes_stored;
595
+ }
552
596
return CaseNext;
553
597
}
554
598
@@ -580,9 +624,8 @@ cfstore_create_key_name_validate_t cfstore_create_test_06_data[] = {
580
624
// / @endcond
581
625
582
626
583
- /* *@brief
584
- *
585
- * Test whether a key name can be created or not.
627
+ /* *
628
+ * @brief Test whether a key name can be created or not.
586
629
*
587
630
* @param key_name
588
631
* name of the key to create in the store
@@ -663,6 +706,109 @@ control_t cfstore_create_test_06_end(const size_t call_count)
663
706
return CaseNext;
664
707
}
665
708
709
+
710
+ /* * @brief Test case to change the value blob size of pre-existing
711
+ * key in a way that causes the memory area to realloc-ed,
712
+ *
713
+ * The test is a modified version of cfstore_create_test_01_end which
714
+ * - creates KVs,
715
+ * - mallocs a memory object on the heap
716
+ * - increases the size of one of the existing KVs, causing the
717
+ * internal memory area to be realloc-ed.
718
+ *
719
+ * In detail, the test does the following:
720
+ * 1. creates a cfstore with ~10 entries. This causes the configuration
721
+ * store to realloc() heap memory for KV storage.
722
+ * 2. mallocs a memory object on heap.
723
+ * 3. for a mid-cfstore entry, double the value blob size. This will cause the
724
+ * cfstore memory area to be realloced.
725
+ * 4. check all the cfstore entries can be read correctly and their
726
+ * data agrees with the data supplied upon creation.
727
+ * 5. shrink the mid-entry value blob size to be ~half the initial size.
728
+ * check all the cfstore entries can be read correctly and their
729
+ * data agrees with the data supplied upon creation.
730
+ *
731
+ * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors.
732
+ */
733
+ control_t cfstore_create_test_07_end (const size_t call_count)
734
+ {
735
+ int32_t ret = ARM_DRIVER_ERROR;
736
+ void *test_buf1 = NULL ;
737
+ ARM_CFSTORE_FMODE flags;
738
+ cfstore_kv_data_t * node = NULL ;
739
+ ARM_CFSTORE_DRIVER* drv = &cfstore_driver;
740
+
741
+ CFSTORE_FENTRYLOG (" %s:entered\n " , __func__);
742
+ (void ) call_count;
743
+ memset (&flags, 0 , sizeof (flags));
744
+
745
+ /* step 1 */
746
+ ret = cfstore_test_create_table (cfstore_create_test_01_data_step_01);
747
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Failed to add cfstore_create_test_01_data_head (ret=%d).\n " , __func__, (int ) ret);
748
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
749
+
750
+ /* step 2 */
751
+ test_buf1 = malloc (CFSTORE_CREATE_MALLOC_SIZE);
752
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: failed to allocate memory (test_buf1=%p)\n " , __func__, test_buf1);
753
+ TEST_ASSERT_MESSAGE (test_buf1 != NULL , cfstore_create_utest_msg_g);
754
+
755
+ /* step 3. find cfstore_create_test_01_data[0] and grow the KV MID_ENTRY_01 to MID_ENTRY_02 */
756
+ ret = cfstore_create_test_KV_change (&cfstore_create_test_01_data[0 ], &cfstore_create_test_01_data[1 ]);
757
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Failed to increase size of KV (ret=%d).\n " , __func__, (int ) ret);
758
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
759
+
760
+ /* step 4. Now check that the KVs are all present and correct */
761
+ node = cfstore_create_test_01_data_step_02;
762
+ while (node->key_name != NULL )
763
+ {
764
+ ret = cfstore_test_check_node_correct (node);
765
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:node (key_name=\" %s\" , value=\" %s\" ) not correct in cfstore\n " , __func__, node->key_name , node->value );
766
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
767
+ node++;
768
+ }
769
+ /* revert CFSTORE_LOG for more trace */
770
+ CFSTORE_DBGLOG (" KV successfully increased in size and other KVs remained unchanged.%s" , " \n " );
771
+
772
+ /* Shrink the KV from KV MID_ENTRY_02 to MID_ENTRY_03 */
773
+ ret = cfstore_create_test_KV_change (&cfstore_create_test_01_data[1 ], &cfstore_create_test_01_data[2 ]);
774
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Failed to decrease size of KV (ret=%d).\n " , __func__, (int ) ret);
775
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
776
+
777
+ /* Step 5. Now check that the KVs are all present and correct */
778
+ node = cfstore_create_test_01_data_step_03;
779
+ while (node->key_name != NULL )
780
+ {
781
+ ret = cfstore_test_check_node_correct (node);
782
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:node (key_name=\" %s\" , value=\" %s\" ) not correct in cfstore\n " , __func__, node->key_name , node->value );
783
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
784
+ node++;
785
+ }
786
+ /* revert CFSTORE_LOG for more trace */
787
+ CFSTORE_DBGLOG (" KV successfully decreased in size and other KVs remained unchanged.%s" , " \n " );
788
+
789
+ /* Delete the KV */
790
+ ret = cfstore_test_delete (cfstore_create_test_01_data[2 ].key_name );
791
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:failed to delete node(key_name=\" %s\" )\n " , __func__, node->key_name );
792
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
793
+
794
+ /* Now check that the KVs are all present and correct */
795
+ node = cfstore_create_test_01_data_step_04;
796
+ while (node->key_name != NULL )
797
+ {
798
+ ret = cfstore_test_check_node_correct (node);
799
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:node (key_name=\" %s\" , value=\" %s\" ) not correct in cfstore\n " , __func__, node->key_name , node->value );
800
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
801
+ node++;
802
+ }
803
+
804
+ free (test_buf1);
805
+ ret = drv->Uninitialize ();
806
+ CFSTORE_TEST_UTEST_MESSAGE (cfstore_create_utest_msg_g, CFSTORE_UTEST_MSG_BUF_SIZE, " %s:Error: Uninitialize() call failed.\n " , __func__);
807
+ TEST_ASSERT_MESSAGE (ret >= ARM_DRIVER_OK, cfstore_create_utest_msg_g);
808
+ return CaseNext;
809
+ }
810
+
811
+
666
812
// / @cond CFSTORE_DOXYGEN_DISABLE
667
813
utest::v1::status_t greentea_setup (const size_t number_of_cases)
668
814
{
@@ -682,10 +828,11 @@ Case cases[] = {
682
828
Case (" CREATE_test_03_end" , cfstore_create_test_03_end),
683
829
Case (" CREATE_test_04_start" , cfstore_utest_default_start),
684
830
Case (" CREATE_test_04_end" , cfstore_create_test_04_end),
685
- Case (" CREATE_test_05_start" , cfstore_utest_default_start),
686
- Case (" CREATE_test_05_end" , cfstore_create_test_05_end),
831
+ Case (" CREATE_test_05" , cfstore_create_test_05),
687
832
Case (" CREATE_test_06_start" , cfstore_utest_default_start),
688
833
Case (" CREATE_test_06_end" , cfstore_create_test_06_end),
834
+ Case (" CREATE_test_07_start" , cfstore_utest_default_start),
835
+ Case (" CREATE_test_07_end" , cfstore_create_test_07_end),
689
836
};
690
837
691
838
0 commit comments