summaryrefslogtreecommitdiff
path: root/test/persistence_common_object_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/persistence_common_object_test.c')
-rw-r--r--test/persistence_common_object_test.c2668
1 files changed, 2668 insertions, 0 deletions
diff --git a/test/persistence_common_object_test.c b/test/persistence_common_object_test.c
new file mode 100644
index 0000000..2815744
--- /dev/null
+++ b/test/persistence_common_object_test.c
@@ -0,0 +1,2668 @@
+/******************************************************************************
+ * Project persistence key value store
+ * (c) copyright 2014
+ * Company XS Embedded GmbH
+ *****************************************************************************/
+/******************************************************************************
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
+ * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+******************************************************************************/
+ /**
+ * @file persistence_common_object_test.c
+ * @ingroup persistency
+ * @author Simon Disch
+ * @brief test of persistence key value store
+ * @see
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h> /* exit */
+#include <time.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <dlt/dlt.h>
+#include <dlt/dlt_common.h>
+#include <../inc/protected/persComRct.h>
+#include <../inc/protected/persComDbAccess.h>
+#include <../test/pers_com_test_base.h>
+#include <../test/pers_com_check.h>
+#include <sys/wait.h>
+
+#define BUF_SIZE 64
+#define NUM_OF_FILES 3
+#define READ_SIZE 1024
+#define MaxAppNameLen 256
+
+/// application id
+char gTheAppId[MaxAppNameLen] = { 0 };
+
+// definition of weekday
+char* dayOfWeek[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+
+
+START_TEST(test_OpenLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpersistence_common_object_library");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of open localdb");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int k=0, handle =0;
+ int databases = 20;
+ char path[128];
+ int handles[100] = { 0 };
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/open-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/open-localdb.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/open-localdb.db");
+
+// if(remove("/tmp/open-uncached.db") == 0)
+// printf("File %s deleted.\n", "/tmp/open-uncached.db");
+// else
+// fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/open-uncached.db");
+
+
+ if(remove("/tmp/open-cached.db") == 0)
+ printf("File %s deleted.\n", "/tmp/open-cached.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/open-cached.db");
+
+
+ int ret = 0;
+ int ret2 = 0;
+ ret = persComDbOpen("/tmp/open-localdb.db", 0x0); //Do not create test.db / only open if present
+ x_fail_unless(ret < 0, "Open open-localdb.db works, but should fail: retval: [%d]", ret);
+
+ ret = persComDbOpen("/tmp/open-localdb.db", 0x1); //create test.db if not present
+ x_fail_unless(ret >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+ ret = persComDbClose(ret);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+ //test to use more than 16 static handles
+ for (k = 0; k < databases; k++)
+ {
+ snprintf(path, 128, "/tmp/handletest-%d.db", k);
+ //Cleaning up testdata folder
+ if (remove(path) == 0)
+ printf("File %s deleted.\n", path);
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", path);
+ }
+
+ for (k = 0; k < databases; k++)
+ {
+ snprintf(path, 128, "/tmp/handletest-%d.db", k);
+ handle = persComDbOpen(path, 0x1); //create test.db if not present
+ handles[k] = handle;
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+ }
+
+ //printf("closing! \n");
+ for (k = 0; k < databases; k++)
+ {
+ ret = persComDbClose(handles[k]);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database with number %d: retval: [%d]", k, ret);
+ }
+
+
+ //Test two consecutive open calls
+ ret = persComDbOpen("/tmp/open-consecutive.db", 0x1); //create test.db if not present
+ //printf("TEST handle first: %d \n", ret);
+ x_fail_unless(ret >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+ ret2 = persComDbOpen("/tmp/open-consecutive.db", 0x1); //create test.db if not present
+ //printf("TEST handle second: %d \n", ret2);
+ x_fail_unless(ret2 >= 0, "Failed at consecutive open: retval: [%d]", ret2);
+
+
+ ret = persComDbClose(ret);
+ if (ret != 0)
+ printf("persComDbClose() 1 failed: [%d] \n", ret);
+
+
+ ret = persComDbClose(ret2);
+ if (ret != 0)
+ printf("persComDbClose() 2 failed: [%d] \n", ret);
+
+
+
+ //Test chached uncached flag
+ ret = persComDbOpen("/tmp/open-uncached.db", 0x2); //cached and DO NOT create test.db -> no close needed
+ //printf("handle 1: %d \n", ret);
+ x_fail_unless(ret < 0, "Failed at uncached open: retval: [%d]", ret); //fail if open works, but should fail
+
+ ret2 = persComDbOpen("/tmp/open-cached.db", 0x3); //cached and create test.db if not present
+ //printf("handle 2: %d \n", ret2);
+ x_fail_unless(ret2 >= 0, "Failed at cached open: retval: [%d]", ret);
+
+
+// ret = persComDbClose(ret);
+// if (ret != 0)
+// printf("persComDbClose() uncached failed: [%d] \n", ret);
+
+
+ ret = persComDbClose(ret2);
+ if (ret != 0)
+ printf("persComDbClose() cached failed: [%d] \n", ret);
+
+
+}
+END_TEST
+
+
+
+START_TEST(test_OpenRCT)
+{
+
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpersistence_common_object_library");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of open rct");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/open-rct.db") == 0)
+ printf("File %s deleted.\n", "/tmp/open-rct.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/open-rct.db");
+
+ int ret = 0;
+ ret = persComRctOpen("/tmp/open-rct.db", 0x0); //Do not create rct.db / only open if present
+ x_fail_unless(ret < 0, "Open open-rct.db works, but should fail: retval: [%d]", ret);
+
+ ret = persComRctOpen("/tmp/open-rct.db", 0x1); //create test.db if not present
+ x_fail_unless(ret >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ ret = persComRctClose(ret);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close RCT database: retval: [%d]", ret);
+
+}
+END_TEST
+
+/*
+ * Write data to a key using the key interface in local DB.
+ * First write data to different keys and after
+ * read the data for verification.
+ */
+START_TEST(test_SetDataLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of set data local DB");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char write2[READ_SIZE] = { 0 };
+ char read[READ_SIZE] = { 0 };
+ char key[128] = { 0 };
+ char sysTimeBuffer[256];
+ struct tm *locTime;
+ int i =0;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/write-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/write-localdb.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/write-localdb.db");
+
+
+#if 1
+time_t t = time(0);
+locTime = localtime(&t);
+
+// write data
+snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+handle = persComDbOpen("/tmp/write-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+
+snprintf(write2, 128, "%s %s", "/key_70", sysTimeBuffer);
+
+//write to cache
+for(i=0; i< 300; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2) , "Wrong write size while inserting in cache");
+}
+
+//read from cache
+for(i=0; i< 300; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ ret = persComDbReadKey(handle, key, (char*) read, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong read size while reading from cache");
+}
+
+//printf("read from cache ok \n");
+
+//persist data in cache to file
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+
+handle = persComDbOpen("/tmp/write-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to reopen existing lDB: retval: [%d]", ret);
+
+
+//printf("open ok \n");
+
+//read from database file
+for(i=0; i< 300; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ ret = persComDbReadKey(handle, key, (char*) read, strlen(write2));
+ //printf("read: %d returns: %s \n", i, read);
+ x_fail_unless(ret == strlen(write2), "Wrong read size");
+}
+
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+}
+END_TEST
+
+
+
+
+/*
+ * Write data to a key using the key interface in local DB.
+ * First the data gets written to Cache. Then this data is read from the Cache.
+ * After that, the database gets closed in order to persist the cached data to the database file
+ * The database file is opened again and the keys are read from file for verification
+ */
+START_TEST(test_GetDataLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get data local DB");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ unsigned char readBuffer[READ_SIZE] = { 0 };
+ char write2[READ_SIZE] = { 0 };
+ char key[128] = { 0 };
+ int i = 0;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/get-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/get-localdb.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/get-localdb.db");
+
+
+#if 1
+
+handle = persComDbOpen("/tmp/get-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+
+//write keys to cache
+for(i=0; i< 50; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ memset(write2, 0, sizeof(write2));
+ snprintf(write2, 128, "DATA-%d-%d",i,i*i );
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong write size");
+}
+
+//Read keys from cache
+for(i=0; i< 50; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ memset(write2, 0, sizeof(write2));
+ snprintf(write2, sizeof(write2), "DATA-%d-%d",i,i*i );
+ memset(readBuffer, 0, sizeof(readBuffer));
+ ret = persComDbReadKey(handle, key, (char*) readBuffer, sizeof(readBuffer));
+ x_fail_unless(ret == strlen(write2), "Wrong read size");
+ x_fail_unless(memcmp(readBuffer, write2, sizeof(readBuffer)) == 0, "Reading Data from Cache failed: Buffer not correctly read");
+}
+
+//persist changed data for this lifecycle
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: Cached Data was not written back: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+//open database again
+handle = persComDbOpen("/tmp/get-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to reopen existing lDB: retval: [%d]", ret);
+
+
+//Read keys from database file
+for(i=0; i< 50; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ memset(write2, 0, sizeof(write2));
+ snprintf(write2, sizeof(write2), "DATA-%d-%d",i,i*i );
+ memset(readBuffer, 0, sizeof(readBuffer));
+ ret = persComDbReadKey(handle, key, (char*) readBuffer, sizeof(readBuffer));
+ x_fail_unless(ret == strlen(write2), "Wrong read size");
+ x_fail_unless(memcmp(readBuffer, write2, sizeof(readBuffer)) == 0, "Reading Data from File failed: Buffer not correctly read");
+}
+
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+}
+END_TEST
+
+
+
+
+/*
+ * Get the size from an existing local DB needed to store all already inserted key names in a list
+ * First insert 3 different keys then close the database to persist the data an reopen it.
+ * Then get the size of all keys separated with '\0'
+ * After that a duplicate key gets written to the cache and the size of the list is read again to test if duplicate keys are ignored correctly.
+ * Then a new key gets written to the cache and the list size is read again to test if keys in cache and also keys in the database file are counted.
+ */
+START_TEST(test_GetKeyListSizeLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get key list size local DB");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char write1[READ_SIZE] = { 0 };
+ char write2[READ_SIZE] = { 0 };
+ char sysTimeBuffer[256];
+ int listSize = 0;
+ char key[8] = { 0 };
+ struct tm *locTime;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/localdb-size-keylist.db") == 0)
+ printf("File %s deleted.\n", "/tmp/localdb-size-keylist.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/localdb-size-keylist.db");
+
+#if 1
+ time_t t = time(0);
+ locTime = localtime(&t);
+
+ // write data
+ snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+ handle = persComDbOpen("/tmp/localdb-size-keylist.db", 0x1); //create db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB for keylist test: retval: [%d]", ret);
+
+
+ snprintf(key, 8, "%s", "key_123");
+ ret = persComDbWriteKey(handle, key, (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+ x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+
+
+ snprintf(key, 8, "%s", "key_456");
+ snprintf(write1, 128, "%s %s", "k_456", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key, (char*) write1, strlen(write1));
+ x_fail_unless(ret == strlen(write1), "Wrong write size");
+
+ snprintf(key, 8, "%s", "key_789");
+ snprintf(write2, 128, "%s %s", "k_789", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong write size");
+
+
+ listSize = persComDbGetSizeKeysList(handle);
+ //printf("LISTSIZE: %d \n", listSize);
+ x_fail_unless(listSize == 3 * strlen(key) + 3, "Wrong list size read from cache");
+
+
+
+ //persist changes in order to read only keys that are in database file
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+ handle = persComDbOpen("/tmp/localdb-size-keylist.db", 0x1); //create db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB for keylist test: retval: [%d]", ret);
+
+
+ //write duplicated key to cache
+ snprintf(key, 8, "%s", "key_789");
+ snprintf(write2, 128, "%s %s", "k_789", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong write size");
+
+ //get needed listsize (looks for keys in cache and in database file) duplicate keys occuring in cache AND in database file are removed
+ // listsize here must be 24
+ listSize = persComDbGetSizeKeysList(handle);
+ //printf("LISTSIZE: %d \n", listSize);
+ x_fail_unless(listSize == 3 * strlen(key) + 3, "Wrong list size read from file");
+
+ //write new key to cache
+ snprintf(key, 8, "%s", "key_000");
+ snprintf(write2, 128, "%s %s", "k_000", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+
+ //read list size again (must be 32)
+ listSize = persComDbGetSizeKeysList(handle);
+ //printf("LISTSIZE: %d \n", listSize);
+ x_fail_unless(listSize == 4 * strlen(key) + 4, "Wrong list size read from combined cache / file");
+
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+
+}
+END_TEST
+
+
+
+
+/* Get the resource list from an existing local database with already inserted key names
+ * Insert some keys then get the list of all keys separated with '\0'
+ * Then check if the List returned contains all of the keys inserted before
+ */
+START_TEST(test_GetKeyListLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get key list local DB");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char write1[READ_SIZE] = { 0 };
+ char write2[READ_SIZE] = { 0 };
+ char sysTimeBuffer[256];
+ char origKeylist[256] = { 0 };
+ char key1[8] = { 0 };
+ char key2[8] = { 0 };
+ char key3[8] = { 0 };
+ char key4[8] = { 0 };
+ struct tm *locTime;
+ char* keyList = NULL;
+ int listSize = 0;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/localdb-keylist.db") == 0)
+ printf("File %s deleted.\n", "/tmp/localdb-keylist.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/localdb-keylist.db");
+
+#if 1
+ time_t t = time(0);
+ locTime = localtime(&t);
+
+ // write data
+ snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+ handle = persComDbOpen("/tmp/localdb-keylist.db", 0x1); //create db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB for keylist test: retval: [%d]", ret);
+
+ /**
+ * Logical DB
+ */
+ snprintf(key1, 8, "%s", "key_123");
+ ret = persComDbWriteKey(handle, key1, (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+ x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+
+ /**
+ * Logical DB
+ */
+ snprintf(key2, 8, "%s", "key_456");
+ snprintf(write1, 128, "%s %s", "k_456", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key2, (char*) write1, strlen(write1));
+ x_fail_unless(ret == strlen(write1), "Wrong write size");
+
+ /**
+ * Logical DB
+ */
+ snprintf(key3, 8, "%s", "key_789");
+ snprintf(write2, 128, "%s %s", "k_789", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key3, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong write size");
+
+
+
+ //close database in order to persist the cached keys.
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+ handle = persComDbOpen("/tmp/localdb-keylist.db", 0x1); //create db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB for keylist test: retval: [%d]", ret);
+
+
+ //write to cache
+ snprintf(key4, 8, "%s", "key_456");
+ snprintf(write1, 128, "%s %s", "k_456", sysTimeBuffer);
+ ret = persComDbWriteKey(handle, key4, (char*) write1, strlen(write1));
+
+ //read keys from file and from cache
+ listSize = persComDbGetSizeKeysList(handle);
+ x_fail_unless(listSize == 3 * strlen(key1) + 3, "Wrong list size");
+
+ keyList = (char*) malloc(listSize);
+ ret = persComDbGetKeysList(handle, keyList, listSize);
+ int cmp_result = 0;
+
+ //try all possible key orders in the list
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key1, '\0', key2, '\0', key3);
+ if( memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key1, '\0', key3, '\0', key2);
+ if(memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key2, '\0', key3, '\0', key1);
+ if(memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key2, '\0', key1, '\0', key3);
+ if(memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key3, '\0', key1, '\0', key2);
+ if(memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key3, '\0', key2, '\0', key1);
+ if(memcmp(keyList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+
+// printf("original keylist: [%s] \n", origKeylist);
+// printf("keylist: [%s] \n", keyList);
+ free(keyList);
+ x_fail_unless(cmp_result == 0, "List not correctly read");
+
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+
+}
+END_TEST
+
+/*
+ * Get the size from an existing RCT database needed to store all already inserted key names in a list
+ * Insert some keys then get the size of all keys separated with '\0'. Then close the database and reopen it to read the size again (from file).
+ * After that, close and reopen the database, to insert a duplicate key and a new key into cache. Then verify the listsize again.
+ */
+START_TEST(test_GetResourceListSizeRct)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get resource size RCT");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char sysTimeBuffer[256];
+ char key1[8] = { 0 };
+ char key2[8] = { 0 };
+ char key3[8] = { 0 };
+ char key4[8] = { 0 };
+ int listSize = 0;
+ struct tm *locTime;
+
+ PersistenceConfigurationKey_s psConfig;
+ psConfig.policy = PersistencePolicy_wt;
+ psConfig.storage = PersistenceStorage_local;
+ psConfig.type = PersistenceResourceType_key;
+ psConfig.permission = PersistencePermission_ReadWrite;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/rct-size-resource-list.db") == 0)
+ printf("File %s deleted.\n", "/tmp/rct-size-resource-list.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/rct-size-resource-list.db");
+
+#if 1
+ time_t t = time(0);
+ locTime = localtime(&t);
+
+ // write data
+ snprintf(sysTimeBuffer, 64, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+ handle = persComRctOpen("/tmp/rct-size-resource-list.db", 0x1); //create rct.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ memset(psConfig.custom_name, 0, sizeof(psConfig.custom_name));
+ memset(psConfig.customID, 0, sizeof(psConfig.customID));
+ memset(psConfig.reponsible, 0, sizeof(psConfig.reponsible));
+
+ psConfig.max_size = 12345;
+ char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME] = "this is the custom name";
+ char custom_ID[PERS_RCT_MAX_LENGTH_CUSTOM_ID] = "this is the custom ID";
+ char responsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE] = "this is the responsible";
+
+ strncpy(psConfig.custom_name, custom_name, strlen(custom_name));
+ strncpy(psConfig.customID, custom_ID, strlen(custom_ID));
+ strncpy(psConfig.reponsible, responsible, strlen(responsible));
+
+ snprintf(key1, 8, "%s", "key_123");
+ ret = persComRctWrite(handle, key1, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ snprintf(key2, 8, "%s", "key_45");
+ ret = persComRctWrite(handle, key2, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ snprintf(key3, 8, "%s", "key_7");
+ ret = persComRctWrite(handle, key3, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ //get listsize from cache
+ listSize = persComRctGetSizeResourcesList(handle);
+ x_fail_unless(listSize == 3 * strlen(key1), "Read Wrong list size from file and cache");
+
+ //persist cached data
+ ret = persComRctClose(handle);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+ handle = persComRctOpen("/tmp/rct-size-resource-list.db", 0x1); //create rct.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ //get listsize from file
+ listSize = persComRctGetSizeResourcesList(handle);
+ x_fail_unless(listSize == 3 * strlen(key1), "Read Wrong list size from file and cache");
+
+ ret = persComRctClose(handle);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+ handle = persComRctOpen("/tmp/rct-size-resource-list.db", 0x1); //create rct.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ //insert duplicate key
+ snprintf(key3, 8, "%s", "key_7");
+ ret = persComRctWrite(handle, key3, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ //insert new key
+ snprintf(key4, 8, "%s", "key_new");
+ ret = persComRctWrite(handle, key4, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ //get listsize if keys are in cache and in file
+ listSize = persComRctGetSizeResourcesList(handle);
+ x_fail_unless(listSize == strlen(key1)+ strlen(key2) + strlen(key3) + strlen(key4) + 4, "Read Wrong list size from file and cache");
+
+ ret = persComRctClose(handle);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+
+}
+END_TEST
+
+/*
+ * Get the resource list from an existing RCT database with already inserted key names
+ * Insert some keys then get the list of all keys separated with '\0'
+ * Then check if the List returned contains all of the keys inserted before
+ */
+START_TEST(test_GetResourceListRct)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get resource list RCT");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char sysTimeBuffer[256];
+ char origKeylist[256] = { 0 };
+ char* resourceList = NULL;
+ int listSize = 0;
+ char key1[8] = { 0 };
+ char key2[8] = { 0 };
+ char key3[8] = { 0 };
+ char key4[8] = { 0 };
+ struct tm *locTime;
+
+ PersistenceConfigurationKey_s psConfig;
+ psConfig.policy = PersistencePolicy_wt;
+ psConfig.storage = PersistenceStorage_local;
+ psConfig.type = PersistenceResourceType_key;
+ psConfig.permission = PersistencePermission_ReadWrite;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/rct-resource-list.db") == 0)
+ printf("File %s deleted.\n", "/tmp/rct-resource-list.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/rct-resource-list.db");
+
+#if 1
+ time_t t = time(0);
+ locTime = localtime(&t);
+
+ // write data
+ snprintf(sysTimeBuffer, 64, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+ handle = persComRctOpen("/tmp/rct-resource-list.db", 0x1); //create rct.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ memset(psConfig.custom_name, 0, sizeof(psConfig.custom_name));
+ memset(psConfig.customID, 0, sizeof(psConfig.customID));
+ memset(psConfig.reponsible, 0, sizeof(psConfig.reponsible));
+
+ psConfig.max_size = 12345;
+ char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME] = "this is the custom name";
+ char custom_ID[PERS_RCT_MAX_LENGTH_CUSTOM_ID] = "this is the custom ID";
+ char responsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE] = "this is the responsible";
+
+ strncpy(psConfig.custom_name, custom_name, strlen(custom_name));
+ strncpy(psConfig.customID, custom_ID, strlen(custom_ID));
+ strncpy(psConfig.reponsible, responsible, strlen(responsible));
+
+ snprintf(key1, 8, "%s", "key_123");
+ ret = persComRctWrite(handle, key1, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ snprintf(key2, 8, "%s", "key_456");
+ ret = persComRctWrite(handle, key2, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ snprintf(key3, 8, "%s", "key_789");
+ ret = persComRctWrite(handle, key3, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key1, '\0', key3, '\0', key2);
+
+ //persist keys to file
+ ret = persComRctClose(handle);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+ handle = persComRctOpen("/tmp/rct-resource-list.db", 0x1); //create rct.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent rct: retval: [%d]", ret);
+
+ //write duplicate key to cache
+ snprintf(key4, 8, "%s", "key_456");
+ ret = persComRctWrite(handle, key4, &psConfig);
+ x_fail_unless(ret == sizeof(psConfig), "Wrong write size");
+
+ //read keys from file and from cache
+ listSize = persComRctGetSizeResourcesList(handle);
+ x_fail_unless(listSize == 3 * strlen(key1) + 3, "Wrong list size");
+
+ resourceList = (char*) malloc(listSize);
+ ret = persComRctGetResourcesList(handle, resourceList, listSize);
+
+ //compare returned list (unsorted) with original list
+ int cmp_result = 0;
+
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key1, '\0', key2, '\0', key3);
+ if( memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key1, '\0', key3, '\0', key2);
+ if(memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key2, '\0', key3, '\0', key1);
+ if(memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key2, '\0', key1, '\0', key3);
+ if(memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key3, '\0', key1, '\0', key2);
+ if(memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ snprintf(origKeylist, 24, "%s%c%s%c%s", key3, '\0', key2, '\0', key1);
+ if(memcmp(resourceList, origKeylist, listSize) != 0)
+ {
+ cmp_result = 1;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+ }
+ else
+ cmp_result = 0;
+
+ //printf("original resourceList: [%s] \n", origKeylist);
+ //printf("resourceList: [%s]\n", resourceList);
+ free(resourceList);
+ x_fail_unless(cmp_result == 0, "List not correctly read");
+
+ ret = persComRctClose(handle);
+ if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+#endif
+
+}
+END_TEST
+
+/*
+ * Write data to a key using the key interface for RCT databases
+ * First write data to different keys and after that
+ * read the data for verification.
+ */
+START_TEST(test_SetDataRCT)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of set data in RCT");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char sysTimeBuffer[256];
+ struct tm *locTime;
+
+ PersistenceConfigurationKey_s psConfig, psConfig_out;
+ psConfig.policy = PersistencePolicy_wt;
+ psConfig.storage = PersistenceStorage_local;
+ psConfig.type = PersistenceResourceType_key;
+ psConfig.permission = PersistencePermission_ReadWrite;
+
+#if 1
+time_t t = time(0);
+locTime = localtime(&t);
+
+// write data
+snprintf(sysTimeBuffer, 64, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+//Cleaning up testdata folder
+if (remove("/tmp/write-rct.db") == 0)
+ printf("File %s deleted.\n", "/tmp/write-rct.db");
+else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/write-rct.db");
+
+handle = persComRctOpen("/tmp/write-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+memset(psConfig.custom_name, 0, sizeof(psConfig.custom_name));
+memset(psConfig.customID, 0, sizeof(psConfig.customID));
+memset(psConfig.reponsible, 0, sizeof(psConfig.reponsible));
+
+psConfig.max_size = 12345;
+char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME] = "this is the custom name";
+char custom_ID[PERS_RCT_MAX_LENGTH_CUSTOM_ID] = "this is the custom ID";
+char responsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE] = "this is the responsible";
+
+strncpy(psConfig.custom_name, custom_name, strlen(custom_name));
+strncpy(psConfig.customID, custom_ID, strlen(custom_ID));
+strncpy(psConfig.reponsible, responsible, strlen(responsible));
+
+
+//printf("Custom ID : %s\n", psConfig.customID );
+//printf("Custom Name : %s\n", psConfig.custom_name );
+//printf("reponsible : %s\n", psConfig.reponsible );
+//printf("max_size : %d\n", psConfig.max_size );
+//printf("permission : %d\n", psConfig.permission );
+//printf("type : %d\n", psConfig.type );
+//printf("storage : %d\n", psConfig.storage );
+//printf("policy : %d\n", psConfig.policy );
+
+
+ret = persComRctWrite(handle, "69", &psConfig);
+x_fail_unless(ret == sizeof(psConfig), "wrong write size \n");
+#if 1
+
+memset(psConfig_out.custom_name, 0, sizeof(psConfig_out.custom_name));
+memset(psConfig_out.customID, 0, sizeof(psConfig_out.customID));
+memset(psConfig_out.reponsible, 0, sizeof(psConfig_out.reponsible));
+
+//read from cache
+ret = persComRctRead(handle, "69", &psConfig_out);
+x_fail_unless(ret == sizeof(psConfig), "Wrong read size from cache");
+
+
+//persist data in cache to database file
+ret = persComRctClose(handle);
+if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+//reopen database
+handle = persComRctOpen("/tmp/write-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+/*
+ * now read the data written in the previous steps to the keys in RCT
+ * and verify data has been written correctly.
+ */
+memset(psConfig_out.custom_name, 0, sizeof(psConfig_out.custom_name));
+memset(psConfig_out.customID, 0, sizeof(psConfig_out.customID));
+memset(psConfig_out.reponsible, 0, sizeof(psConfig_out.reponsible));
+
+//read from file
+ret = persComRctRead(handle, "69", &psConfig_out);
+x_fail_unless(ret == sizeof(psConfig), "Wrong read size from file");
+
+//printf("Custom ID : %s\n", psConfig_out.customID );
+//printf("Custom Name : %s\n", psConfig_out.custom_name );
+//printf("reponsible : %s\n", psConfig_out.reponsible );
+//printf("max_size : %d\n", psConfig_out.max_size );
+//printf("permission : %d\n", psConfig_out.permission );
+//printf("type : %d\n", psConfig_out.type );
+//printf("storage : %d\n", psConfig_out.storage );
+//printf("policy : %d\n", psConfig_out.policy );
+
+x_fail_unless(strncmp(psConfig.customID, psConfig_out.customID, strlen(psConfig_out.customID)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.custom_name, psConfig_out.custom_name, strlen(psConfig_out.custom_name)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.reponsible, psConfig_out.reponsible, strlen(psConfig_out.reponsible)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(psConfig.max_size == psConfig_out.max_size, "Buffer not correctly read");
+x_fail_unless(psConfig.permission == psConfig_out.permission, "Buffer not correctly read");
+x_fail_unless(psConfig.policy == psConfig_out.policy, "Buffer not correctly read");
+x_fail_unless(psConfig.storage == psConfig_out.storage, "Buffer not correctly read");
+x_fail_unless(psConfig.type == psConfig_out.type, "Buffer not correctly read");
+
+//persist to database file
+ret = persComRctClose(handle);
+if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+#endif
+#endif
+
+}
+END_TEST
+
+
+
+/*
+ * Test reading of data to a key using the key interface for RCT
+ * First write data to cache, then read from cache.
+ * Then the database gets closed and reopened.
+ * The next read for verification is done from file.
+ */
+START_TEST(test_GetDataRCT)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get data in RCT");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char sysTimeBuffer[256];
+ struct tm *locTime;
+
+ PersistenceConfigurationKey_s psConfig, psConfig_out;
+ psConfig.policy = PersistencePolicy_wt;
+ psConfig.storage = PersistenceStorage_local;
+ psConfig.type = PersistenceResourceType_key;
+ psConfig.permission = PersistencePermission_ReadWrite;
+
+#if 1
+time_t t = time(0);
+locTime = localtime(&t);
+
+// write data
+snprintf(sysTimeBuffer, 64, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+//Cleaning up testdata folder
+if (remove("/tmp/get-rct.db") == 0)
+ printf("File %s deleted.\n", "/tmp/get-rct.db");
+else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/get-rct.db");
+
+
+handle = persComRctOpen("/tmp/get-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+memset(psConfig.custom_name, 0, sizeof(psConfig.custom_name));
+memset(psConfig.customID, 0, sizeof(psConfig.customID));
+memset(psConfig.reponsible, 0, sizeof(psConfig.reponsible));
+psConfig.max_size = 12345;
+
+char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME] = "this is the custom name";
+char custom_ID[PERS_RCT_MAX_LENGTH_CUSTOM_ID] = "this is the custom ID";
+char responsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE] = "this is the responsible";
+
+strncpy(psConfig.custom_name, custom_name, strlen(custom_name));
+strncpy(psConfig.customID, custom_ID, strlen(custom_ID));
+strncpy(psConfig.reponsible, responsible, strlen(responsible));
+
+
+ret = persComRctWrite(handle, "69", &psConfig);
+x_fail_unless(ret == sizeof(psConfig), "write size wrong");
+#if 1
+
+
+/*
+ * now read the data written in the previous steps to the keys in RCT
+ * and verify data has been written correctly.
+ */
+memset(psConfig_out.custom_name, 0, sizeof(psConfig_out.custom_name));
+memset(psConfig_out.customID, 0, sizeof(psConfig_out.customID));
+memset(psConfig_out.reponsible, 0, sizeof(psConfig_out.reponsible));
+
+//read from cache
+ret = persComRctRead(handle, "69", &psConfig_out);
+x_fail_unless(ret == sizeof(psConfig_out), "Wrong read size from cache");
+
+//printf("Custom ID : %s\n", psConfig_out.customID );
+//printf("Custom Name : %s\n", psConfig_out.custom_name );
+//printf("reponsible : %s\n", psConfig_out.reponsible );
+//printf("max_size : %d\n", psConfig_out.max_size );
+//printf("permission : %d\n", psConfig_out.permission );
+//printf("type : %d\n", psConfig_out.type );
+//printf("storage : %d\n", psConfig_out.storage );
+//printf("policy : %d\n", psConfig_out.policy );
+
+
+
+x_fail_unless(strncmp(psConfig.customID, psConfig_out.customID, strlen(psConfig_out.customID)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.custom_name, psConfig_out.custom_name, strlen(psConfig_out.custom_name)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.reponsible, psConfig_out.reponsible, strlen(psConfig_out.reponsible)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(psConfig.max_size == psConfig_out.max_size, "Buffer not correctly read");
+x_fail_unless(psConfig.permission == psConfig_out.permission, "Buffer not correctly read");
+x_fail_unless(psConfig.policy == psConfig_out.policy, "Buffer not correctly read");
+x_fail_unless(psConfig.storage == psConfig_out.storage, "Buffer not correctly read");
+x_fail_unless(psConfig.type == psConfig_out.type, "Buffer not correctly read");
+
+
+//persist to database file
+ret = persComRctClose(handle);
+if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+#endif
+#endif
+
+
+handle = persComRctOpen("/tmp/get-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+
+memset(psConfig_out.custom_name, 0, sizeof(psConfig_out.custom_name));
+memset(psConfig_out.customID, 0, sizeof(psConfig_out.customID));
+memset(psConfig_out.reponsible, 0, sizeof(psConfig_out.reponsible));
+
+
+//read from file
+ret = persComRctRead(handle, "69", &psConfig_out);
+x_fail_unless(ret == sizeof(psConfig_out), "Wrong read size from file");
+
+//printf("Custom ID : %s\n", psConfig_out.customID );
+//printf("Custom Name : %s\n", psConfig_out.custom_name );
+//printf("reponsible : %s\n", psConfig_out.reponsible );
+//printf("max_size : %d\n", psConfig_out.max_size );
+//printf("permission : %d\n", psConfig_out.permission );
+//printf("type : %d\n", psConfig_out.type );
+//printf("storage : %d\n", psConfig_out.storage );
+//printf("policy : %d\n", psConfig_out.policy );
+
+x_fail_unless(strncmp(psConfig.customID, psConfig_out.customID, strlen(psConfig_out.customID)) == 0,
+ "Buffer not correctly read from file");
+x_fail_unless(strncmp(psConfig.custom_name, psConfig_out.custom_name, strlen(psConfig_out.custom_name)) == 0,
+ "Buffer not correctly read from file");
+x_fail_unless(strncmp(psConfig.reponsible, psConfig_out.reponsible, strlen(psConfig_out.reponsible)) == 0,
+ "Buffer not correctly read from file");
+x_fail_unless(psConfig.max_size == psConfig_out.max_size, "Buffer not correctly read from file");
+x_fail_unless(psConfig.permission == psConfig_out.permission, "Buffer not correctly read from file");
+x_fail_unless(psConfig.policy == psConfig_out.policy, "Buffer not correctly read from file");
+x_fail_unless(psConfig.storage == psConfig_out.storage, "Buffer not correctly read from file");
+x_fail_unless(psConfig.type == psConfig_out.type, "Buffer not correctly read from file");
+
+
+ret = persComRctClose(handle);
+if (ret != 0)
+ printf("persComRctClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+
+}
+END_TEST
+
+
+
+/*
+ * Test to get the datasize for a key
+ * write a key to cache, then the size of the data to that key from cache
+ * Close and reopens the database to read the size to a key from file again.
+ */
+START_TEST(test_GetDataSize)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of get data size");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ char sysTimeBuffer[256];
+ int size = 0, ret = 0;
+ int handle = 0;
+ struct tm *locTime;
+
+ time_t t = time(0);
+ locTime = localtime(&t);
+
+ // write data
+ snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/size-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/size-localdb.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/size-localdb.db");
+
+
+ handle = persComDbOpen("/tmp/size-localdb.db", 0x1); //create localdb.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+ //write key to cache
+ ret = persComDbWriteKey(handle, "status/open_document", (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+ x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+
+#if 1
+ //get keysize from cache
+ size = persComDbGetKeySize(handle, "status/open_document");
+ //printf("=>=>=>=> soll: %d | ist: %d\n", strlen(sysTimeBuffer), size);
+ x_fail_unless(size == strlen(sysTimeBuffer), "Invalid size read from cache");
+
+ //persist cached data
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+ handle = persComDbOpen("/tmp/size-localdb.db", 0x1); //create localdb.db if not present
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+ //get keysize from file
+ size = persComDbGetKeySize(handle, "status/open_document");
+ //printf("=>=>=>=> soll: %d | ist: %d\n", strlen(sysTimeBuffer), size);
+ x_fail_unless(size == strlen(sysTimeBuffer), "Invalid size read from cache");
+
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database: retval: [%d]", ret);
+
+#endif
+}
+END_TEST
+
+/*
+ * Delete a key from local DB using the key value interface.
+ * First write some keys, then read the keys. After that the keys get deleted.
+ * A further read is performed and must fail.
+ * The keys are inserted again and get persisted to file. the database gets reopened and the keys are deleted again.
+ * The next read must fail again.
+ */
+START_TEST(test_DeleteDataLocalDB)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of delete data local DB");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int rval = 0;
+ int handle = 0;
+ unsigned char buffer[READ_SIZE] = { 0 };
+ char write1[READ_SIZE] = { 0 };
+ char sysTimeBuffer[256];
+ struct tm *locTime;
+
+#if 1
+
+time_t t = time(0);
+locTime = localtime(&t);
+
+// write data
+snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+
+////Cleaning up testdata folder
+if (remove("/tmp/delete-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/delete-localdb.db");
+else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/delete-localdb.db");
+
+
+handle = persComDbOpen("/tmp/delete-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", handle);
+
+snprintf(write1, 128, "%s %s", "/70", sysTimeBuffer);
+
+
+//write data to cache
+rval = persComDbWriteKey(handle, "key1", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key2", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key3", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key4", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key5", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key6", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+
+
+// read data from cache
+rval = persComDbReadKey(handle, "key1", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key2", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key3", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key4", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key5", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key6", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+
+
+
+// mark data in cache as deleted
+rval = persComDbDeleteKey(handle, "key1");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key2");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key3");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key4");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key5");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key6");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+
+// after deleting the keys in cache, reading from key must fail now!
+rval = persComDbReadKey(handle, "key1", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key1] works, but should fail");
+
+rval = persComDbReadKey(handle, "key2", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key2] works, but should fail");
+
+rval = persComDbReadKey(handle, "key3", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key3] works, but should fail");
+
+rval = persComDbReadKey(handle, "key4", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key4] works, but should fail");
+
+rval = persComDbReadKey(handle, "key5", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key5] works, but should fail");
+
+rval = persComDbReadKey(handle, "key6", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key6] works, but should fail");
+
+
+
+
+
+//write data again which gets persisted to file afterwards
+//write data to cache
+rval = persComDbWriteKey(handle, "key1", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key2", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key3", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key4", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key5", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+rval = persComDbWriteKey(handle, "key6", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+
+
+// read data from cache
+rval = persComDbReadKey(handle, "key1", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key2", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key3", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key4", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key5", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+rval = persComDbReadKey(handle, "key6", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size");
+
+
+
+//persist data to file
+rval = persComDbClose(handle);
+if (rval != 0)
+ printf("persComDbClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close cached database: retval: [%d]", rval);
+
+//reopen database
+handle = persComDbOpen("/tmp/delete-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to open lDB: retval: [%d]", handle);
+
+
+//delete keys
+rval = persComDbDeleteKey(handle, "key1");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key2");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key3");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key4");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key5");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+rval = persComDbDeleteKey(handle, "key6");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+
+
+// after deleting the keys, reading from key must fail now!
+rval = persComDbReadKey(handle, "key1", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key1] in file works, but should fail");
+
+
+rval = persComDbReadKey(handle, "key2", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key2] in file works, but should fail");
+
+rval = persComDbReadKey(handle, "key3", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key3] in file works, but should fail");
+
+rval = persComDbReadKey(handle, "key4", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key4] in file works, but should fail");
+
+rval = persComDbReadKey(handle, "key5", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key5] in file works, but should fail");
+
+rval = persComDbReadKey(handle, "key6", (char*) buffer, READ_SIZE);
+x_fail_unless(rval < 0, "Read form key [key6] in file works, but should fail");
+
+
+rval = persComDbClose(handle);
+if (rval != 0)
+ printf("persComDbClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close database: retval: [%d]", rval);
+
+//reopen the database to write a key again into cache that must reuse the already deleted slot in the file when closing the database
+handle = persComDbOpen("/tmp/delete-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", handle);
+
+// write a key again to test if slot in file is reused (CONTENT OF offset == 4 in kissdb.c)
+rval = persComDbWriteKey(handle, "key1", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+
+
+// write a key again to test if slot in file is reused (CONTENT OF offset == 4 in kissdb.c)
+rval = persComDbWriteKey(handle, "key1", (char*) write1, strlen(write1));
+x_fail_unless(rval == strlen(write1), "Wrong write size");
+
+
+rval = persComDbClose(handle);
+if (rval != 0)
+ printf("persComDbClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close database: retval: [%d]", rval);
+
+
+
+//reopen the database to read key1
+handle = persComDbOpen("/tmp/delete-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", handle);
+
+rval = persComDbReadKey(handle, "key1", (char*) buffer, READ_SIZE);
+x_fail_unless(rval == strlen(write1), "Wrong read size for key1");
+
+
+
+
+
+
+
+
+rval = persComDbClose(handle);
+if (rval != 0)
+ printf("persComDbClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close last database: retval: [%d]", rval);
+
+
+
+
+
+
+#endif
+}
+END_TEST
+
+
+/*
+ * Delete a key from local DB using the key value interface.
+ * First read a from a key, the delte the key
+ * and then try to read again. The Last read must fail.
+ */
+START_TEST(test_DeleteDataRct)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of delete data RCT");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int rval = 0;
+ int handle = 0;
+ char sysTimeBuffer[256];
+ struct tm *locTime;
+ PersistenceConfigurationKey_s psConfig, psConfig_out;
+ psConfig.policy = PersistencePolicy_wt;
+ psConfig.storage = PersistenceStorage_local;
+ psConfig.type = PersistenceResourceType_key;
+ psConfig.permission = PersistencePermission_ReadWrite;
+
+#if 1
+
+time_t t = time(0);
+locTime = localtime(&t);
+
+// write data
+snprintf(sysTimeBuffer, 128, "\"%s %d.%d.%d - %d:%.2d:%.2d Uhr\"", dayOfWeek[locTime->tm_wday], locTime->tm_mday,
+ locTime->tm_mon, (locTime->tm_year + 1900), locTime->tm_hour, locTime->tm_min, locTime->tm_sec);
+
+//Cleaning up testdata folder
+if (remove("/tmp/delete-rct.db") == 0)
+ printf("File %s deleted.\n", "/tmp/delete-rct.db");
+else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/delete-rct.db");
+
+handle = persComRctOpen("/tmp/delete-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent RCT: retval: [%d]", handle);
+
+memset(psConfig.custom_name, 0, sizeof(psConfig.custom_name));
+memset(psConfig.customID, 0, sizeof(psConfig.customID));
+memset(psConfig.reponsible, 0, sizeof(psConfig.reponsible));
+
+psConfig.max_size = 12345;
+char custom_name[PERS_RCT_MAX_LENGTH_CUSTOM_NAME] = "this is the custom name";
+char custom_ID[PERS_RCT_MAX_LENGTH_CUSTOM_ID] = "this is the custom ID";
+char responsible[PERS_RCT_MAX_LENGTH_RESPONSIBLE] = "this is the responsible";
+
+strncpy(psConfig.custom_name, custom_name, strlen(custom_name));
+strncpy(psConfig.customID, custom_ID, strlen(custom_ID));
+strncpy(psConfig.reponsible, responsible, strlen(responsible));
+
+//write key to cache
+rval = persComRctWrite(handle, "key_to_delete", &psConfig);
+x_fail_unless(rval == sizeof(psConfig), "Wrong write size in cache");
+
+memset(psConfig_out.custom_name, 0, sizeof(psConfig_out.custom_name));
+memset(psConfig_out.customID, 0, sizeof(psConfig_out.customID));
+memset(psConfig_out.reponsible, 0, sizeof(psConfig_out.reponsible));
+
+//read from cache
+rval = persComRctRead(handle, "key_to_delete", &psConfig_out);
+x_fail_unless(rval == sizeof(psConfig), "Wrong read size from cache");
+
+
+// printf("Custom ID : %s\n", psConfig_out.customID );
+// printf("Custom Name : %s\n", psConfig_out.custom_name );
+// printf("reponsible : %s\n", psConfig_out.reponsible );
+// printf("max_size : %d\n", psConfig_out.max_size );
+// printf("permission : %d\n", psConfig_out.permission );
+// printf("type : %d\n", psConfig_out.type );
+// printf("storage : %d\n", psConfig_out.storage );
+// printf("policy : %d\n", psConfig_out.policy );
+
+
+x_fail_unless(strncmp(psConfig.customID, psConfig_out.customID, strlen(psConfig_out.customID)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.custom_name, psConfig_out.custom_name, strlen(psConfig_out.custom_name)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(strncmp(psConfig.reponsible, psConfig_out.reponsible, strlen(psConfig_out.reponsible)) == 0,
+ "Buffer not correctly read");
+x_fail_unless(psConfig.max_size == psConfig_out.max_size, "Buffer not correctly read");
+x_fail_unless(psConfig.permission == psConfig_out.permission, "Buffer not correctly read");
+x_fail_unless(psConfig.policy == psConfig_out.policy, "Buffer not correctly read");
+x_fail_unless(psConfig.storage == psConfig_out.storage, "Buffer not correctly read");
+x_fail_unless(psConfig.type == psConfig_out.type, "Buffer not correctly read");
+
+// mark key in cache as deleted
+rval = persComRctDelete(handle, "key_to_delete");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+
+// after deleting the key, reading from key must fail now!
+rval = persComRctRead(handle, "key_to_delete", &psConfig_out);
+x_fail_unless(rval < 0, "Read form key [key_to_delete] works, but should fail");
+
+
+//write data again to cache
+//write key to cache which already exists in database file
+rval = persComRctWrite(handle, "key_to_delete", &psConfig);
+x_fail_unless(rval == sizeof(psConfig), "Wrong write size in cache");
+
+//read from cache
+rval = persComRctRead(handle, "key_to_delete", &psConfig_out);
+x_fail_unless(rval == sizeof(psConfig), "Wrong read size from cache");
+
+
+rval = persComRctClose(handle);
+if (rval != 0)
+ printf("persComRctClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close database: retval: [%d]", rval);
+
+handle = persComRctOpen("/tmp/delete-rct.db", 0x1); //create db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent RCT: retval: [%d]", handle);
+
+
+// mark key in cache as deleted
+rval = persComRctDelete(handle, "key_to_delete");
+x_fail_unless(rval >= 0, "Failed to delete key");
+
+// after deleting the key, reading from key must fail now!
+rval = persComRctRead(handle, "key_to_delete", &psConfig_out);
+x_fail_unless(rval < 0, "Read form key [key_to_delete] works, but should fail");
+
+
+rval = persComRctClose(handle);
+if (rval != 0)
+ printf("persComRctClose() failed: [%d] \n", rval);
+x_fail_unless(rval == 0, "Failed to close database: retval: [%d]", rval);
+
+
+#endif
+}
+END_TEST
+
+
+
+
+START_TEST(test_CachedConcurrentAccess)
+{
+ int pid;
+
+ //Cleaning up testdata folder
+ if (remove("/tmp/cached-concurrent.db") == 0)
+ printf("File %s deleted.\n", "/tmp/cached-concurrent.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/cached-concurrent.db");
+
+ pid = fork();
+ if (pid == 0)
+ { /*child*/
+ printf("Started child process with PID: [%d] \n", pid);
+ int handle = 0;
+ int ret = 0;
+ char childSysTimeBuffer[256] = { 0 };
+ char key[128] = { 0 };
+ char write2[READ_SIZE] = { 0 };
+ int i =0;
+
+ snprintf(childSysTimeBuffer, 256, "%s", "1");
+
+ //wait so that father has already opened the db
+ sleep(3);
+
+ //open db after father (in order to use the hashtable in shared memory)
+ handle = persComDbOpen("/tmp/cached-concurrent.db", 0x0); //create test.db if not present
+ x_fail_unless(handle >= 0, "Child failed to create non existent lDB: retval: [%d]", ret);
+
+ //read the new key written by the father from cache
+ for(i=0; i< 200; i++)
+ {
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ snprintf(write2, 128, "DATA-%d",i );
+ ret = persComDbReadKey(handle, key, (char*) childSysTimeBuffer, 256);
+ //printf("Child Key Read from Cache: %s ------: %s -------------- returnvalue: %d\n",key, childSysTimeBuffer, ret);
+ x_fail_unless(ret == strlen(write2), "Child: Wrong read size");
+ }
+
+ //close database for child instance
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Child failed to close database: retval: [%d]", ret);
+
+
+ _exit(EXIT_SUCCESS);
+ }
+ else if (pid > 0)
+ { /*parent*/
+ printf("Started father process with PID: [%d] \n", pid);
+ int handle = 0;
+ int ret = 0;
+ char write2[READ_SIZE] = { 0 };
+ char key[128] = { 0 };
+ char sysTimeBuffer[256] = { 0 };
+ int i =0;
+
+ handle = persComDbOpen("/tmp/cached-concurrent.db", 0x1); //create test.db if not present
+ x_fail_unless(handle >= 0, "Father failed to create non existent lDB: retval: [%d]", ret);
+
+ //Write data to cache
+ for(i=0; i< 200; i++)
+ {
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ snprintf(write2, 128, "DATA-%d",i);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ //printf("Father persComDbWriteKey: %s -- returnvalue: %d \n", key, ret);
+ x_fail_unless(ret == strlen(write2), "Father: Wrong write size");
+ }
+
+ //read data from cache
+ for(i=0; i< 200; i++)
+ {
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ snprintf(write2, 128, "DATA-%d",i );
+ ret = persComDbReadKey(handle, key, (char*) sysTimeBuffer, 256);
+ //printf("Father Key Read from key: %s ------: %s -------------- returnvalue: %d\n",key, sysTimeBuffer, ret);
+ x_fail_unless(ret == strlen(write2), "Father: Wrong read size");
+ }
+
+ printf("INFO: Waiting for child process to exit ... \n");
+
+ //wait for child exiting
+ int status;
+ (void) waitpid(pid, &status, 0);
+
+ //close database for father instance (closes the cache)
+ ret = persComDbClose(handle);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Father failed to close database: retval: [%d]", ret);
+
+ _exit(EXIT_SUCCESS);
+ }
+}
+END_TEST
+
+
+
+
+
+/*
+ * tests the remapping of the shared hashtable. An application A has opened the shared hashtable that holds for example 100 entires.
+ * If application B has also access to the database and iserts further keys, a second hashtable gets added.
+ * Now application A must remap the shared memory used to hold the hashtable to its process space with the new size.lll
+ */
+//START_TEST(test_RemapHashtableHeader)
+//{
+// int pid;
+//
+// //Cleaning up testdata folder
+// if (remove("/tmp/cached-remap1.db") == 0)
+// printf("File %s deleted.\n", "/tmp/cached-remap1.db");
+// else
+// fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/cached-remap1.db");
+//
+// pid = fork();
+// if (pid == 0)
+// { /*child*/
+// printf("Started child process with PID: [%d] \n", pid);
+// int handle = 0;
+// int ret = 0;
+// char childSysTimeBuffer[256] = { 0 };
+// char key[128] = { 0 };
+// char write2[READ_SIZE] = { 0 };
+// int i =0;
+// snprintf(childSysTimeBuffer, 256, "%s", "1");
+//
+// //wait so that father has already opened the db
+// sleep(2);
+//
+// //open db after father (in order to use the hashtable in shared memory)
+// handle = persComDbOpen("/tmp/cached-remap1.db", 0x0); //create test.db if not present
+// x_fail_unless(handle >= 0, "Child failed to create non existent lDB: retval: [%d]", ret);
+//
+// //read the new key written by the father from cache
+// for(i=0; i< 300; i++)
+// {
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "DATA-%d",i );
+// ret = persComDbReadKey(handle, key, (char*) childSysTimeBuffer, 256);
+// //printf("Child Key Read from Cache: %s ------: %s -------------- returnvalue: %d\n",key, childSysTimeBuffer, ret);
+// x_fail_unless(ret == strlen(write2), "Child: Wrong read size");
+// }
+//
+// //try to read a key which is not in cache in order to force a read from file and provoke a remap of the hashtable
+// snprintf(key, 128, "Not-in-Cache-Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "DATA-%d",i );
+// ret = persComDbReadKey(handle, key, (char*) childSysTimeBuffer, 256);
+//
+//
+//
+//
+// //write more keys
+// for(i=0; i< 500; i++)
+// {
+// memset(key, 0, 128);
+// snprintf(key, 128, "CHILD_Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "Child-DATA-%d",i);
+// ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+// //printf("Father persComDbWriteKey: %s -- returnvalue: %d \n", key, ret);
+// x_fail_unless(ret == strlen(write2), "Father: Wrong write size");
+// }
+//
+// //sleep(1);
+//
+// //close database for child instance
+// ret = persComDbClose(handle);
+// if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+// x_fail_unless(ret == 0, "Child failed to close database: retval: [%d]", ret);
+//
+//
+// _exit(EXIT_SUCCESS);
+// }
+// else if (pid > 0)
+// { /*parent*/
+// printf("Started father process with PID: [%d] \n", pid);
+// int handle = 0;
+// int ret = 0;
+// char write2[READ_SIZE] = { 0 };
+// char key[128] = { 0 };
+// char sysTimeBuffer[256] = { 0 };
+// int i =0;
+//
+// handle = persComDbOpen("/tmp/cached-remap1.db", 0x1); //create test.db if not present
+// x_fail_unless(handle >= 0, "Father failed to create non existent lDB: retval: [%d]", ret);
+//
+// //Write data to cache
+// for(i=0; i< 300; i++)
+// {
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "DATA-%d",i);
+// ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+// //printf("Father persComDbWriteKey: %s -- returnvalue: %d \n", key, ret);
+// x_fail_unless(ret == strlen(write2), "Father: Wrong write size");
+// }
+//
+// //read data from cache
+// for(i=0; i< 300; i++)
+// {
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "DATA-%d",i );
+// ret = persComDbReadKey(handle, key, (char*) sysTimeBuffer, 256);
+// //printf("Father Key Read from key: %s ------: %s -------------- returnvalue: %d\n",key, sysTimeBuffer, ret);
+// x_fail_unless(ret == strlen(write2), "Father: Wrong read size");
+// }
+//
+// //wait so that child has written new hashtables
+// sleep(3);
+//
+// //Now read the keys written by the child
+// for(i=0; i< 500; i++)
+// {
+// memset(key, 0, 128);
+// snprintf(key, 128, "CHILD_Key_in_loop_%d_%d",i,i*i);
+// snprintf(write2, 128, "Child-DATA-%d",i);
+// ret = persComDbReadKey(handle, key, (char*) sysTimeBuffer, 256);
+// //printf("Father Key Read from Cache 2: %s ------: %s -------------- returnvalue: %d\n",key, sysTimeBuffer, ret);
+// //x_fail_unless(ret == strlen(write2), "Father 2: Wrong read size");
+// }
+//
+// printf("INFO: Waiting for child process to exit ... \n");
+// int status;
+// (void) waitpid(pid, &status, 0);
+//
+// //close database for father instance (closes the cache)
+// ret = persComDbClose(handle);
+// if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+// x_fail_unless(ret == 0, "Father failed to close database: retval: [%d]", ret);
+//
+// _exit(EXIT_SUCCESS);
+// }
+//}
+//END_TEST
+//
+//
+
+
+
+
+
+
+
+/*
+ * check if shared memory is correctly resized if new hastable is appended
+ */
+//START_TEST(test_SharedHeaderResize)
+//{
+//
+// int pid;
+//
+// //Cleaning up testdata folder
+// if (remove("/tmp/resize-localdb.db") == 0)
+// printf("File %s deleted.\n", "/tmp/resize-localdb.db");
+// else
+// fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/resize-localdb.db");
+//
+// pid = fork();
+//
+// if (pid == 0)
+// { /*child*/
+// unsigned char buffer[READ_SIZE] = { 0 };
+// int handle = 0;
+// int ret = 0;
+// char childSysTimeBuffer[256];
+// char childWrite[256];
+// snprintf(childSysTimeBuffer, 128, "%s", "CONCURRENT_TEST_DATA"), snprintf(childWrite, 128, "%s",
+// "CHILD_DATA_WRITTEN"),
+//
+// //wait so that father has already opened the db
+// sleep(1);
+//
+// //open db after father
+// handle = persComDbOpen("/tmp/resize-localdb.db", 0x0); //create test.db if not present
+// printf("child persComDbOpen returnvalue: %d \n", handle);
+// x_fail_unless(handle >= 0, "Child failed to create non existent lDB: retval: [%d]", ret);
+//
+// //wait until father has written a new key
+// sleep(5);
+//
+//
+// //read the new key written by the father
+// ret = persComDbReadKey(handle, "69", buffer, READ_SIZE);
+// printf("child persComDbReadKey returnvalue: %d \n", ret);
+// x_fail_unless(strncmp((char* )buffer, childSysTimeBuffer, strlen(childSysTimeBuffer)) == 0,
+// "Buffer not correctly read");
+// x_fail_unless(ret == strlen(childSysTimeBuffer), "Wrong read size");
+//
+//
+// ret = persComDbReadKey(handle, "70", buffer, READ_SIZE);
+// printf("child persComDbReadKey returnvalue: %d \n", ret);
+// x_fail_unless(strncmp((char* )buffer, childSysTimeBuffer, strlen(childSysTimeBuffer)) == 0,
+// "Buffer not correctly read");
+// x_fail_unless(ret == strlen(childSysTimeBuffer), "Wrong read size");
+//
+//
+//
+// ret = persComDbReadKey(handle, "71", buffer, READ_SIZE);
+// printf("child persComDbReadKey returnvalue: %d \n", ret);
+// x_fail_unless(strncmp((char* )buffer, childSysTimeBuffer, strlen(childSysTimeBuffer)) == 0,
+// "Buffer not correctly read");
+// x_fail_unless(ret == strlen(childSysTimeBuffer), "Wrong read size");
+//
+//
+//
+// ret = persComDbClose(handle);
+// if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+//
+//
+// printf("############################## Child: TEST OK ##########################\n");
+//
+// _exit(EXIT_SUCCESS);
+// }
+// else if (pid > 0)
+// { /*parent*/
+// int handle = 0;
+// int ret = 0;
+// unsigned char buffer[READ_SIZE] = { 0 };
+// char write1[READ_SIZE] = { 0 };
+// char write2[READ_SIZE] = { 0 };
+// char sysTimeBuffer[256];
+// char fatherRead[256];
+//
+// snprintf(sysTimeBuffer, 128, "%s", "CONCURRENT_TEST_DATA"),
+//
+// handle = persComDbOpen("/tmp/resize-localdb.db", 0x1); //create test.db if not present
+// printf("father persComDbOpen returnvalue: %d \n", handle);
+// x_fail_unless(handle >= 0, "Father failed to create non existent lDB: retval: [%d]", ret);
+//
+// /**
+// * delay writing so that the child opens the db which does not already
+// * contain the new keys written by the father (testing if shared header works)
+// **/
+// sleep(3);
+//
+// // write data
+// ret = persComDbWriteKey(handle, "69", (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+// printf("father persComDbWriteKey returnvalue: %d \n", ret);
+// x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+//
+// ret = persComDbWriteKey(handle, "70", (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+// printf("father persComDbWriteKey returnvalue: %d \n", ret);
+// x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+//
+// ret = persComDbWriteKey(handle, "71", (char*) sysTimeBuffer, strlen(sysTimeBuffer));
+// printf("father persComDbWriteKey returnvalue: %d \n", ret);
+// x_fail_unless(ret == strlen(sysTimeBuffer), "Wrong write size");
+//
+//
+// int status;
+// (void) waitpid(pid, &status, 0); //wait for child exiting
+//
+// ret = persComDbClose(handle);
+// if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+//
+//
+// printf("############################## Father: TEST OK ##########################\n");
+// _exit(EXIT_SUCCESS);
+// }
+//}
+//END_TEST
+
+
+
+START_TEST(test_CacheSize)
+ {
+
+ unsigned char buffer2[PERS_DB_MAX_SIZE_KEY_DATA] = { 1 };
+ int handle = 0;
+ int i, k, ret = 0;
+ char dataBufer[PERS_DB_MAX_SIZE_KEY_DATA] = { 1 };
+ char key[128] = { 0 };
+ char path[128] = { 0 };
+ int handles[100] = { 0 };
+ int writings = 300;
+ int databases = 1;
+
+ for (k = 0; k < databases; k++)
+ {
+ snprintf(path, 128, "/tmp/cacheSize-%d.db", k);
+ //Cleaning up testdata folder
+ if (remove(path) == 0)
+ printf("File %s deleted.\n", path);
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", path);
+ }
+
+ //use maximum allowed data size
+ for (i = 0; i < PERS_DB_MAX_SIZE_KEY_DATA; i++)
+ {
+ dataBufer[i] = 'x';
+ }
+ dataBufer[PERS_DB_MAX_SIZE_KEY_DATA-1] = '\0';
+
+ //fill k databases with i key /value pairs
+ for (k = 0; k < databases; k++)
+ {
+ snprintf(path, 128, "/tmp/cacheSize-%d.db", k);
+ handle = persComDbOpen(path, 0x1); //create test.db if not present
+ handles[k] = handle;
+ x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+
+ //write data to cache
+ for (i = 0; i < writings; i++)
+ {
+ snprintf(key, 128, "Key_in_loop_%d_%d", i, i * i);
+ ret = persComDbWriteKey(handle, key, (char*) dataBufer, strlen(dataBufer));
+ //printf("Writing Key: %s | Retval: %d \n", key, ret);
+ x_fail_unless(ret == strlen(dataBufer) , "Wrong write size while inserting in cache");
+ }
+ //read data from cache
+ for (i = 0; i < writings; i++)
+ {
+ snprintf(key, 128, "Key_in_loop_%d_%d", i, i * i);
+ ret = persComDbReadKey(handle, key, (char*) buffer2, PERS_DB_MAX_SIZE_KEY_DATA);
+ //printf("read from key: %s | Retval: %d \n", key, ret);
+ x_fail_unless(ret == strlen(dataBufer), "Wrong read size while reading from cache");
+ }
+ }
+
+ //sleep to look for memory consumption of cache
+ //sleep(20);
+ //Close k databases in order to persist the data
+ for (k = 0; k < databases; k++)
+ {
+ ret = persComDbClose(handles[k]);
+ if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+ x_fail_unless(ret == 0, "Failed to close database with number %d: retval: [%d]", k, ret);
+ }
+}
+END_TEST
+
+
+
+
+
+///*
+// *
+// * Write data to a key using the key interface in local DB.
+// * First write data to different keys and after
+// * read the data for verification.
+// */
+//START_TEST(test_SupportedChars)
+//{
+// X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+// X_TEST_REPORT_COMP_NAME("libpers_common");
+// X_TEST_REPORT_REFERENCE("NONE");
+// X_TEST_REPORT_DESCRIPTION("Test of supported characters in local DB");
+// X_TEST_REPORT_TYPE(GOOD);
+//
+// int ret = 0;
+// int handle = 0;
+// char write2[READ_SIZE] = { 0 };
+// char read[READ_SIZE] = { 0 };
+// char key[128] = { 0 };
+// char value[128] = { 0 };
+// char sysTimeBuffer[256];
+// struct tm *locTime;
+// unsigned int i =0;
+//
+//
+// //Cleaning up testdata folder
+// if (remove("/tmp/chars-localdb2.db") == 0)
+// printf("File %s deleted.\n", "/tmp/chars-localdb2.db");
+// else
+// fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/chars-localdb2.db");
+//
+//
+//#if 1
+//time_t t = time(0);
+//locTime = localtime(&t);
+//
+//unsigned char c;
+//
+//unsigned char values[256];
+//for (i=0; i<256; i++){
+// unsigned char temp = i;
+// values[i] = temp;
+// //printf("VALUE: %d = %c \n", values[i], values[i]);
+//}
+//
+//
+//handle = persComDbOpen("/tmp/chars-localdb2.db", 0x1); //create test.db if not present
+//x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+//
+//
+////write to cache
+//for(i=0; i< 256; i++)
+//{
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// ret = persComDbWriteKey(handle, key, &values[i], 1);
+// x_fail_unless(ret == 1, "Wrong write size while inserting in cache");
+//}
+//
+////read from cache
+//for(i=0; i< 256; i++)
+//{
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// ret = persComDbReadKey(handle, key, (char*) read, 1);
+// x_fail_unless(ret == 1 , "Wrong read size while reading from cache: %d", ret);
+// x_fail_unless( memcmp(read, &values[i], 1) == 0, "Reading Data from Cache failed: Buffer not correctly read");
+//}
+//
+//
+//
+//ret = persComDbWriteKey(handle, "DEGREE", "°", 1);
+//ret = persComDbReadKey(handle, "DEGREE", (char*) read, 1);
+//printf("degree: %s\n",read);
+//
+//
+////persist data in cache to file
+//ret = persComDbClose(handle);
+//if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+//x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+//
+//
+//handle = persComDbOpen("/tmp/chars-localdb2.db", 0x1); //create test.db if not present
+//x_fail_unless(handle >= 0, "Failed to reopen existing lDB: retval: [%d]", ret);
+//
+//
+////read from database file
+//for(i=0; i< 256; i++)
+//{
+// snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+// ret = persComDbReadKey(handle, key, (char*) write2, 1);
+// x_fail_unless(ret == 1, "Wrong read size: %d",ret);
+// //printf("READ from file: %d = %c \n", write2[0], write2[0]);
+// x_fail_unless( memcmp(write2, &values[i], 1) == 0, "Reading Data from File failed: Buffer not correctly read");
+//}
+//
+//
+//
+//ret = persComDbWriteKey(handle, "DEGREE", "qwertz°abcd", 11);
+//ret = persComDbReadKey(handle, "DEGREE", (char*) write2, 1);
+//printf("degree: %s\n",write2);
+//
+//ret = persComDbClose(handle);
+//if (ret != 0)
+// printf("persComDbClose() failed: [%d] \n", ret);
+//x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+//
+//#endif
+//}
+//END_TEST
+
+
+
+
+START_TEST(test_BadParameters)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpersistence_common_object_library");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of bad parameters behavior");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ //perscomdbopen
+ char* path = NULL;
+ int ret = 0;
+
+ //percomDBwrite test
+ char buffer[16384] = { 0 };
+ char* Badbuffer = NULL;
+ char* key = NULL;
+ char* data = NULL;
+
+ //rct write
+ PersistenceConfigurationKey_s* BadPsConfig = NULL;
+ PersistenceConfigurationKey_s psConfig;
+
+ ret = persComDbOpen("6l3HrKvT9TmXdTbqF4mc3N38llpbKkn2qMhdiLOlwXnY7H09ZewvQG80uyLr8sg0by0oD9UXNOm9OHvXl8zf7vKosu0M90Aau6WFqELDJl6OYr3xPYPH59o7AvixDMQXlNrPUUTdluU24TEFEiTVhcRcWJDoxlL6LHg1u9p3pNURI9GKmAsXDHovXXrvwP3qSjDYB0gMhvEvfpDI5oy8vb3Frz81zZmKuHsx9GQi0xWTB5n6grRH9TvcJW7F1yu7", 0x0); //Pathname exceeds 255 chars
+ x_fail_unless(ret < 0, "Open local db with too long path length works, but should fail: retval: [%d]", ret);
+
+ ret = persComDbOpen(path, 0x1); //create test.db if not present
+ x_fail_unless(ret < 0, "Open local db with bad pathname works, but should fail: retval: [%d]", ret);
+
+ ret = persComDbClose(-1);
+ x_fail_unless(ret < 0, "Closing the local database with negative handle works, but should fail: retval: [%d]", ret);
+
+ ret = persComRctOpen("6l3HrKvT9TmXdTbqF4mc3N38llpbKkn2qMhdiLOlwXnY7H09ZewvQG80uyLr8sg0by0oD9UXNOm9OHvXl8zf7vKosu0M90Aau6WFqELDJl6OYr3xPYPH59o7AvixDMQXlNrPUUTdluU24TEFEiTVhcRcWJDoxlL6LHg1u9p3pNURI9GKmAsXDHovXXrvwP3qSjDYB0gMhvEvfpDI5oy8vb3Frz81zZmKuHsx9GQi0xWTB5n6grRH9TvcJW7F1yu7", 0x0); //Pathname exceeds 255 chars
+ x_fail_unless(ret < 0, "Open RCT db with too long path length works, but should fail: retval: [%d]", ret);
+
+ ret = persComRctOpen(path, 0x1); //create test.db if not present
+ x_fail_unless(ret < 0, "Open RCT db with bad pathname works, but should fail: retval: [%d]", ret);
+
+ ret = persComRctClose(-1);
+ x_fail_unless(ret < 0, "Closing the RCT database with negative handle works, but should fail: retval: [%d]", ret);
+
+
+
+ ret = persComDbWriteKey(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV", "data", 4); //key too long
+ x_fail_unless(ret < 0 , "Writing with wrong keylength works, but should fail");
+
+ ret = persComDbWriteKey(-1, "key", "data", 4); //negative handle
+ x_fail_unless(ret < 0 , "Writing with negative handle works, but should fail");
+
+ ret = persComDbWriteKey(1, key, "data", 4); //key is NULL
+ x_fail_unless(ret < 0 , "Writing key that is NULL works, but should fail");
+
+ ret = persComDbWriteKey(1, "key", data, 4); //data is NULL
+ x_fail_unless(ret < 0 , "Writing data that is NULL works, but should fail");
+
+ ret = persComDbWriteKey(1, "key", "data", -1254); //datasize is negative
+ x_fail_unless(ret < 0 , "Writing with negative datasize works, but should fail");
+
+ ret = persComDbWriteKey(1, "key", "data", 0); //datasize is zero
+ x_fail_unless(ret < 0 , "Writing with zero datasize works, but should fail");
+
+ ret = persComDbWriteKey(1, "key", "data", 16385); //datasize too big
+ x_fail_unless(ret < 0 , "Writing with too big datasize works, but should fail");
+
+
+
+ ret = persComRctWrite(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV", &psConfig); //key too long
+ x_fail_unless(ret < 0 , "Writing RCT with wrong keylength works, but should fail");
+
+ ret = persComRctWrite(-1, "key", &psConfig); //negative handle
+ x_fail_unless(ret < 0 , "Writing RCT with negative handle works, but should fail");
+
+ ret = persComRctWrite(1, key, &psConfig); //key is NULL
+ x_fail_unless(ret < 0 , "Writing RCT key that is NULL works, but should fail");
+
+ ret = persComRctWrite(1, "key", BadPsConfig); //data is NULL
+ x_fail_unless(ret < 0 , "Writing RCT data that is NULL works, but should fail");
+
+
+
+ ret = persComDbReadKey(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV", "data", 4); //key too long
+ x_fail_unless(ret < 0 , "Reading with wrong keylength works, but should fail");
+
+ ret = persComDbReadKey(-1, "key", buffer, 4); //negative handle
+ x_fail_unless(ret < 0 , "Reading with negative handle works, but should fail");
+
+ ret = persComDbReadKey(1, key, buffer, 4); //key is NULL
+ x_fail_unless(ret < 0 , "Reading key that is NULL works, but should fail");
+
+ ret = persComDbReadKey(1, "key", Badbuffer, 4); //data is NULL
+ x_fail_unless(ret < 0 , "Reading data to buffer that is NULL works, but should fail");
+
+ ret = persComDbReadKey(1, "key", buffer, -1254); //data buffer size is negative
+ x_fail_unless(ret < 0 , "Reading with negative data buffer size works, but should fail");
+
+ ret = persComDbReadKey(1, "key", buffer, 0); //data buffer size is zero
+ x_fail_unless(ret < 0 , "Reading with zero data buffer size works, but should fail");
+
+
+
+ ret = persComRctRead(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV", &psConfig); //key too long
+ x_fail_unless(ret < 0 , "Reading RCT with wrong keylength works, but should fail");
+
+ ret = persComRctRead(-1, "key", &psConfig); //negative handle
+ x_fail_unless(ret < 0 , "Reading RCT with negative handle works, but should fail");
+
+ ret = persComRctRead(1, key, &psConfig); //key is NULL
+ x_fail_unless(ret < 0 , "Reading RCT key that is NULL works, but should fail");
+
+ ret = persComRctRead(1, "key", BadPsConfig); //data is NULL
+ x_fail_unless(ret < 0 , "Reading RCT data to buffer that is NULL works, but should fail");
+
+
+
+ ret = persComDbGetSizeKeysList(-1);
+ x_fail_unless(ret < 0 , "Reading keylist size with negative handle works, but should fail");
+
+ ret = persComRctGetSizeResourcesList(-1);
+ x_fail_unless(ret < 0 , "Reading RCT resourcelist size with negative handle works, but should fail");
+
+
+
+ ret = persComDbGetKeySize(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV"); //key too long
+ x_fail_unless(ret < 0 , "Reading Size with wrong keylength works, but should fail");
+
+ ret = persComDbGetKeySize(-1, "key"); //negative handle
+ x_fail_unless(ret < 0 , "Reading Size with negative handle works, but should fail");
+
+ ret = persComDbGetKeySize(1, key); //key is NULL
+ x_fail_unless(ret < 0 , "Reading Size from key that is NULL works, but should fail");
+
+
+
+
+ ret = persComDbGetKeysList(-1, buffer, 10); //
+ x_fail_unless(ret < 0 , "Reading key list with negative handle works, but should fail");
+
+ ret = persComDbGetKeysList(1, Badbuffer, 10); //
+ x_fail_unless(ret < 0 , "Reading key list with readbuffer that is NULL works, but should fail");
+
+ ret = persComDbGetKeysList(1, buffer, -1); //
+ x_fail_unless(ret < 0 , "Reading key list with negative buffer size works, but should fail");
+
+ ret = persComDbGetKeysList(1, buffer, 0); //
+ x_fail_unless(ret < 0 , "Reading key list with zero buffer size works, but should fail");
+
+
+
+
+
+ ret = persComRctGetResourcesList(-1, buffer, 10); //
+ x_fail_unless(ret < 0 , "Reading RCT key list with negative handle works, but should fail");
+
+ ret = persComRctGetResourcesList(1, Badbuffer, 10); //
+ x_fail_unless(ret < 0 , "Reading RCT key list with readbuffer that is NULL works, but should fail");
+
+ ret = persComRctGetResourcesList(1, buffer, -1); //
+ x_fail_unless(ret < 0 , "Reading RCT key list with negative buffer size works, but should fail");
+
+ ret = persComRctGetResourcesList(1, buffer, 0); //
+ x_fail_unless(ret < 0 , "Reading RCT key list with zero buffer size works, but should fail");
+
+
+ ret = persComDbDeleteKey(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV");
+ x_fail_unless(ret < 0 , "Deleting key with wrong keylength works, but should fail");
+
+ ret = persComDbDeleteKey(1, key);
+ x_fail_unless(ret < 0 , "Deleting key with key that is NULL works, but should fail");
+
+ ret = persComDbDeleteKey(-1, "key");
+ x_fail_unless(ret < 0 , "Deleting with negative handle works, but should fail");
+
+
+ ret = persComRctDelete(1, "CteKh3FTonalS4AlOaEruzUbgAP9fryYJLCykq5tTPQkPrHEcV9p6akxa6TuF9gqnJu5iCEyxMUu17QhTP7sYgFwFKU1qqNMcCmps8WcpWDR2oCnjqdaBtATL2A36q6QV");
+ x_fail_unless(ret < 0 , "Deleting RCT key with wrong keylength works, but should fail");
+
+ ret = persComRctDelete(1, key);
+ x_fail_unless(ret < 0 , "Deleting RCT key with key that is NULL works, but should fail");
+
+ ret = persComRctDelete(-1, "key");
+ x_fail_unless(ret < 0 , "Deleting RCT key with negative handle works, but should fail");
+
+
+}
+END_TEST
+
+
+
+
+
+START_TEST(test_Backups)
+{
+ X_TEST_REPORT_TEST_NAME("persistence_common_object_test");
+ X_TEST_REPORT_COMP_NAME("libpers_common");
+ X_TEST_REPORT_REFERENCE("NONE");
+ X_TEST_REPORT_DESCRIPTION("Test of backup functionality");
+ X_TEST_REPORT_TYPE(GOOD);
+
+ int ret = 0;
+ int handle = 0;
+ char write2[READ_SIZE] = { 0 };
+ char read[READ_SIZE] = { 0 };
+ char key[128] = { 0 };
+ int i =0;
+
+// //Cleaning up testdata folder
+ if (remove("/tmp/backups-localdb.db") == 0)
+ printf("File %s deleted.\n", "/tmp/backups-localdb.db");
+ else
+ fprintf(stderr, "Warning: Could not delete file [%s].\n", "/tmp/backups-localdb.db");
+
+
+#if 1
+snprintf(write2, 176 , "%s", "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/");
+
+
+handle = persComDbOpen("/tmp/backups-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to create non existent lDB: retval: [%d]", ret);
+//write to cache
+for(i=0; i< 2; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ ret = persComDbWriteKey(handle, key, (char*) write2, strlen(write2));
+ x_fail_unless(ret == strlen(write2) , "Wrong write size while inserting in cache");
+}
+
+//read from cache
+for(i=0; i< 1; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i);
+ ret = persComDbReadKey(handle, key, (char*) read, strlen(write2));
+ x_fail_unless(ret == strlen(write2), "Wrong read size while reading from cache");
+ x_fail_unless(memcmp(read, write2, sizeof(write2)) == 0, "Reading Data from Cache failed: Buffer not correctly read");
+}
+
+//persist data in cache to file
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close cached database: retval: [%d]", ret);
+
+
+// IF DATABASE HEADER STRUCTURES OR KEY VALUE PAIR STORAGE CHANGES, the seek to offset part must be updated
+//open database and make data corrupt
+int fd;
+FILE* f;
+fd = open("/tmp/backups-localdb.db", O_RDWR , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); //gets closed when f is closed
+f = fdopen(fd, "w+b");
+
+//seek to data of offsetA for Key_in_loop_0_0
+fseeko(f,7357, SEEK_SET);
+fputc('b',f); //make data corrupt
+
+//seek to data of offsetA for Key_in_loop_1_1
+fseeko(f,40389, SEEK_SET);
+fputc('b',f); //make data corrupt
+
+//seek to backupdata of offsetB for Key_in_loop_1_1
+fseeko(f,56905, SEEK_SET);
+fputc('b',f); //make backup data corrupt
+fclose(f);
+
+handle = persComDbOpen("/tmp/backups-localdb.db", 0x1); //create test.db if not present
+x_fail_unless(handle >= 0, "Failed to reopen existing lDB: retval: [%d]", ret);
+memset(read, 0 , sizeof(read));
+//read from database file must return backup data
+for(i=0; i< 1; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i); //Key_in_loop_0_0
+ ret = persComDbReadKey(handle, key, (char*) read, strlen(write2));
+ //printf("read returnval: %d Data: %s \n", ret, read);
+ memset(read, 0 , sizeof(read));
+ x_fail_unless(ret == strlen(write2), "Wrong read size");
+}
+
+//test when backupdata is also corrupted -> no data should be returned
+for(i=1; i< 2; i++)
+{
+ snprintf(key, 128, "Key_in_loop_%d_%d",i,i*i); //Key_in_loop_1_1
+ ret = persComDbReadKey(handle, key, (char*) read, strlen(write2));
+ //printf("read returnval: %d Data: %s \n", ret, read);
+ memset(read, 0 , sizeof(read));
+ x_fail_unless(ret < 0 , "Reading for key with corrupt data and corrupt backup worked, but should fail");
+}
+
+ret = persComDbClose(handle);
+if (ret != 0)
+ printf("persComDbClose() failed: [%d] \n", ret);
+x_fail_unless(ret == 0, "Failed to close database file: retval: [%d]", ret);
+
+#endif
+}
+END_TEST
+
+
+
+
+
+
+static Suite * persistenceCommonLib_suite()
+{
+ Suite * s = suite_create("Persistence common object");
+
+ TCase * tc_persOpenLocalDB = tcase_create("OpenlocalDB");
+ tcase_add_test(tc_persOpenLocalDB, test_OpenLocalDB);
+
+ TCase * tc_persOpenRCT = tcase_create("OpenRCT");
+ tcase_add_test(tc_persOpenRCT, test_OpenRCT);
+
+ TCase * tc_persSetDataLocalDB = tcase_create("SetDataLocalDB");
+ tcase_add_test(tc_persSetDataLocalDB, test_SetDataLocalDB);
+ tcase_set_timeout(tc_persSetDataLocalDB, 20);
+
+ TCase * tc_persGetDataLocalDB = tcase_create("GetDataLocalDB");
+ tcase_add_test(tc_persGetDataLocalDB, test_GetDataLocalDB);
+ tcase_set_timeout(tc_persGetDataLocalDB, 20);
+
+ TCase * tc_persSetDataRCT = tcase_create("SetDataRCT");
+ tcase_add_test(tc_persSetDataRCT, test_SetDataRCT);
+
+ TCase * tc_persGetDataRCT = tcase_create("GetDataRCT");
+ tcase_add_test(tc_persGetDataRCT, test_GetDataRCT);
+
+ TCase * tc_persGetDataSize = tcase_create("GetDataSize");
+ tcase_add_test(tc_persGetDataSize, test_GetDataSize);
+
+ TCase * tc_persDeleteDataLocalDB = tcase_create("DeleteDataLocalDB");
+ tcase_add_test(tc_persDeleteDataLocalDB, test_DeleteDataLocalDB);
+
+ TCase * tc_persDeleteDataRct = tcase_create("DeleteDataRct");
+ tcase_add_test(tc_persDeleteDataRct, test_DeleteDataRct);
+
+ TCase * tc_persGetKeyListSizeLocalDB = tcase_create("GetKeyListSizeLocalDb");
+ tcase_add_test(tc_persGetKeyListSizeLocalDB, test_GetKeyListSizeLocalDB);
+
+ TCase * tc_persGetKeyListLocalDB = tcase_create("GetKeyListLocalDb");
+ tcase_add_test(tc_persGetKeyListLocalDB, test_GetKeyListLocalDB);
+
+ TCase * tc_persGetResourceListSizeRct = tcase_create("GetResourceListSizeRct");
+ tcase_add_test(tc_persGetResourceListSizeRct, test_GetResourceListSizeRct);
+
+ TCase * tc_persGetResourceListRct = tcase_create("GetResourceListRct");
+ tcase_add_test(tc_persGetResourceListRct, test_GetResourceListRct);
+
+ TCase * tc_persCacheSize = tcase_create("CacheSize");
+ tcase_add_test(tc_persCacheSize, test_CacheSize);
+ tcase_set_timeout(tc_persCacheSize, 20);
+
+ TCase * tc_persCachedConcurrentAccess = tcase_create("CachedConcurrentAccess");
+ tcase_add_test(tc_persCachedConcurrentAccess, test_CachedConcurrentAccess);
+ tcase_set_timeout(tc_persCachedConcurrentAccess, 20);
+
+ //TCase * tc_persSharedHeaderResize = tcase_create("SharedHeaderResize");
+ //tcase_add_test(tc_persSharedHeaderResize, test_SharedHeaderResize);
+ //tcase_set_timeout(tc_persSharedHeaderResize, 20);
+
+
+ //TCase * tc_RemapHashtableHeader = tcase_create("RemapHashtableHeader");
+ //tcase_add_test(tc_RemapHashtableHeader, test_RemapHashtableHeader);
+ //tcase_set_timeout(tc_RemapHashtableHeader, 20);
+
+// TCase * tc_SupportedChars = tcase_create("SupportedChars");
+// tcase_add_test(tc_SupportedChars, test_SupportedChars);
+// tcase_set_timeout(tc_SupportedChars, 20);
+
+ TCase * tc_BadParameters = tcase_create("BadParameters");
+ tcase_add_test(tc_BadParameters, test_BadParameters);
+ tcase_set_timeout(tc_BadParameters, 5);
+
+ TCase * tc_Backups = tcase_create("Backups");
+ tcase_add_test(tc_Backups, test_Backups);
+ tcase_set_timeout(tc_Backups, 5);
+
+
+
+ suite_add_tcase(s, tc_persOpenLocalDB);
+ suite_add_tcase(s, tc_persOpenRCT);
+ suite_add_tcase(s, tc_persSetDataLocalDB);
+ suite_add_tcase(s, tc_persGetDataLocalDB);
+ suite_add_tcase(s, tc_persSetDataRCT);
+ suite_add_tcase(s, tc_persGetDataRCT);
+ suite_add_tcase(s, tc_persGetDataSize);
+ suite_add_tcase(s, tc_persDeleteDataLocalDB);
+ suite_add_tcase(s, tc_persDeleteDataRct);
+ suite_add_tcase(s, tc_persGetKeyListSizeLocalDB);
+ suite_add_tcase(s, tc_persGetKeyListLocalDB);
+ suite_add_tcase(s, tc_persGetResourceListSizeRct);
+ suite_add_tcase(s, tc_persGetResourceListRct);
+ suite_add_tcase(s, tc_persCacheSize);
+ suite_add_tcase(s, tc_persCachedConcurrentAccess);
+ //suite_add_tcase(s, tc_RemapHashtableHeader);
+ //suite_add_tcase(s, tc_SupportedChars);
+ suite_add_tcase(s, tc_BadParameters);
+ //suite_add_tcase(s, tc_Backups);
+
+ return s;
+}
+
+int main(int argc, char *argv[])
+{
+ int nr_failed = 0, nr_run = 0, i = 0;
+ TestResult** tResult;
+
+ // assign application name
+ strncpy(gTheAppId, "lt-persistence_common_object_test", MaxAppNameLen);
+ gTheAppId[MaxAppNameLen - 1] = '\0';
+
+ /// debug log and trace (DLT) setup
+ DLT_REGISTER_APP("PCOt", "tests the persistence common object library");
+
+#if 1
+ Suite * s = persistenceCommonLib_suite();
+ SRunner * sr = srunner_create(s);
+ srunner_set_xml(sr, "/tmp/persistenceCommonObjectTest.xml");
+ srunner_set_log(sr, "/tmp/persistenceCommonObjectTest.log");
+ srunner_run_all(sr, /*CK_NORMAL*/CK_VERBOSE);
+
+ nr_failed = srunner_ntests_failed(sr);
+ nr_run = srunner_ntests_run(sr);
+
+ tResult = srunner_results(sr);
+ for (i = 0; i < nr_run; i++)
+ {
+ (void) tr_rtype(tResult[i]); // get status of each test
+ }
+
+ srunner_free(sr);
+#endif
+
+ // unregister debug log and trace
+ DLT_UNREGISTER_APP()
+ ;
+
+ dlt_free();
+ return (0 == nr_failed) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+