static void test_stSortedSetIterator_getIteratorFrom(CuTest* testCase) { sonLibSortedSetTestSetup(); int32_t i; for(i=0; i<size; i++) { stSortedSet_insert(sortedSet, stIntTuple_construct(1, input[i])); } stSortedSetIterator *iterator = stSortedSet_getIterator(sortedSet); CuAssertTrue(testCase, iterator != NULL); for(i=0; i<sortedSize; i++) { stSortedSetIterator *it = stSortedSet_getIteratorFrom(sortedSet, stIntTuple_construct(1, sortedInput[i])); stIntTuple *intTuple = stSortedSet_getNext(it); CuAssertTrue(testCase, intTuple != NULL); CuAssertIntEquals(testCase, sortedInput[i], stIntTuple_getPosition(intTuple, 0)); stSortedSet_destructIterator(it); } stTry { stSortedSet_getIteratorFrom(sortedSet, stIntTuple_construct(1, 7)); //This number if not in the input. CuAssertTrue(testCase, 0); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SORTED_SET_EXCEPTION_ID); } stTryEnd sonLibSortedSetTestTeardown(); }
static void test_st_randomInt(CuTest *testCase) { /* * Exercises the random int function. */ int32_t min = INT32_MIN; int32_t max = INT32_MAX; int32_t v; for (int32_t i = -9; i < 10; ++i) { CuAssertTrue(testCase, st_randomInt(i, i + 1) == i); } for(int64_t i = 0; i < 100000; i++) { v = st_randomInt(min, max); CuAssertTrue(testCase, v >= min); CuAssertTrue(testCase, v < max); } min = -1; max = 10; for(int64_t i = 0; i < 100000; i++) { v = st_randomInt(min, max); CuAssertTrue(testCase, v >= min); CuAssertTrue(testCase, v < max); } stTry { st_randomInt(1, 1); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == RANDOM_EXCEPTION_ID); } stTryEnd }
static void test_stSet_getUnion(CuTest* testCase) { testSetup(); // Check union of empty sets is empty stSet *set2 = stSet_construct(); stSet *set3 = stSet_construct(); stSet *set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 0); stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check union of non empty set and empty set is non-empty set2 = stSet_construct(); set3 = stSet_getUnion(set0, set2); CuAssertTrue(testCase, stSet_size(set3) == 6); stSet_destruct(set2); stSet_destruct(set3); // Check union of two non-empty overlapping sets is correct set2 = stSet_construct(); set3 = stSet_construct(); stIntTuple **uniqs = (stIntTuple **) st_malloc(sizeof(*uniqs) * 4); uniqs[0] = stIntTuple_construct2(9, 0); uniqs[1] = stIntTuple_construct2(9, 1); uniqs[2] = stIntTuple_construct2(9, 2); uniqs[3] = stIntTuple_construct2(9, 3); stIntTuple **common = (stIntTuple **) st_malloc(sizeof(*uniqs) * 5); common[0] = stIntTuple_construct2(5, 0); common[1] = stIntTuple_construct2(5, 1); common[2] = stIntTuple_construct2(5, 2); common[3] = stIntTuple_construct2(5, 3); common[4] = stIntTuple_construct2(5, 4); for (int i = 0; i < 5; ++i) { stSet_insert(set2, common[i]); stSet_insert(set3, common[i]); } stSet_insert(set2, uniqs[0]); stSet_insert(set2, uniqs[1]); stSet_insert(set3, uniqs[2]); stSet_insert(set3, uniqs[3]); set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 9); for (int i = 0; i < 4; ++i) { CuAssertTrue(testCase, stSet_search(set4, uniqs[i]) != NULL); } for (int i = 0; i < 5; ++i) { CuAssertTrue(testCase, stSet_search(set4, common[i]) != NULL); } stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check we get an exception with sets with different functions. stTry { stSet_getUnion(set0, set1); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SET_EXCEPTION_ID); } stTryEnd testTeardown(); }
static void readWriteAndRemoveRecords(CuTest *testCase) { setup(); CuAssertIntEquals(testCase, 0, stKVDatabase_getNumberOfRecords(database)); //Write some records CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, -10000)); stKVDatabase_insertRecord(database, -10000, "Red", sizeof(char) * 4); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, -10000)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, 4297559944418269136)); stKVDatabase_insertRecord(database, 4297559944418269136, "Green", sizeof(char) * 6); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, 4297559944418269136)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, 0)); stKVDatabase_insertRecord(database, 0, "Black", sizeof(char) * 6); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, 0)); //Now read and check the records exist CuAssertIntEquals(testCase, 3, stKVDatabase_getNumberOfRecords(database)); CuAssertStrEquals(testCase, "Red", stKVDatabase_getRecord(database, -10000)); CuAssertStrEquals(testCase, "Green", stKVDatabase_getRecord(database, 4297559944418269136)); CuAssertStrEquals(testCase, "Black", stKVDatabase_getRecord(database, 0)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, -10000)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, 4297559944418269136)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, 0)); //Now check we can retrieve records partially CuAssertStrEquals(testCase, "d", stKVDatabase_getPartialRecord(database, -10000, 2, 2, sizeof(char) * 4)); CuAssertStrEquals(testCase, "ed", stKVDatabase_getPartialRecord(database, -10000, 1, 3, sizeof(char) * 4)); CuAssertStrEquals(testCase, "Red", stKVDatabase_getPartialRecord(database, -10000, 0, 4, sizeof(char) * 4)); char *record = stKVDatabase_getPartialRecord(database, 0, 2, 3, sizeof(char) * 6); record[2] = '\0'; CuAssertStrEquals(testCase, "ac", record); //Now try removing the records stKVDatabase_removeRecord(database, 0); CuAssertIntEquals(testCase, 2, stKVDatabase_getNumberOfRecords(database)); CuAssertPtrEquals(testCase, NULL, stKVDatabase_getRecord(database, 0)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, 0)); //Test we get exception if we remove twice. stTry { stKVDatabase_removeRecord(database, 0); CuAssertTrue(testCase, false); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; teardown(); }
static void test_stSortedSetDifference(CuTest* testCase) { sonLibSortedSetTestSetup(); //Check difference of empty sets is okay.. stSortedSet *sortedSet3 = stSortedSet_getDifference(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_size(sortedSet3) == 0); stSortedSet_destruct(sortedSet3); int32_t i; for(i=0; i<size; i++) { stSortedSet_insert(sortedSet, stIntTuple_construct(1, input[i])); } //Check difference of non-empty set / empty set is the non-empty. sortedSet3 = stSortedSet_getDifference(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_equals(sortedSet, sortedSet3)); stSortedSet_destruct(sortedSet3); //Check difference of two non-empty, overlapping sets in correct. stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 0)); stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 1)); stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 5)); sortedSet3 = stSortedSet_getDifference(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_size(sortedSet3) == stSortedSet_size(sortedSet) - 2); CuAssertTrue(testCase, !stSortedSet_equals(sortedSet, sortedSet3)); stSortedSet_insert(sortedSet3, stIntTuple_construct(1, 1)); stSortedSet_insert(sortedSet3, stIntTuple_construct(1, 5)); CuAssertTrue(testCase, stSortedSet_equals(sortedSet, sortedSet3)); stSortedSet_destruct(sortedSet3); //Check we get an exception when merging sorted sets with different comparators. stSortedSet *sortedSet4 = stSortedSet_construct(); stTry { stSortedSet_getDifference(sortedSet, sortedSet4); CuAssertTrue(testCase, 0); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SORTED_SET_EXCEPTION_ID); } stTryEnd stSortedSet_destruct(sortedSet4); sonLibSortedSetTestTeardown(); }
static void test_stSortedSetIntersection(CuTest* testCase) { sonLibSortedSetTestSetup(); //Check intersection of empty sets is okay.. stSortedSet *sortedSet3 = stSortedSet_getIntersection(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_size(sortedSet3) == 0); stSortedSet_destruct(sortedSet3); int32_t i; for(i=0; i<size; i++) { stSortedSet_insert(sortedSet, stIntTuple_construct(1, input[i])); } //Check intersection of empty and non-empty set is empty. sortedSet3 = stSortedSet_getIntersection(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_size(sortedSet3) == 0); stSortedSet_destruct(sortedSet3); //Check intersection of two non-empty, overlapping sets in correct. stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 0)); stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 1)); stSortedSet_insert(sortedSet2, stIntTuple_construct(1, 5)); sortedSet3 = stSortedSet_getIntersection(sortedSet, sortedSet2); CuAssertTrue(testCase, stSortedSet_size(sortedSet3) == 2); stIntTuple *intTuple = stIntTuple_construct(1, 1); CuAssertTrue(testCase, stSortedSet_search(sortedSet3, intTuple) != NULL); stIntTuple_destruct(intTuple); intTuple = stIntTuple_construct(1, 5); CuAssertTrue(testCase, stSortedSet_search(sortedSet3, intTuple) != NULL); stIntTuple_destruct(intTuple); stSortedSet_destruct(sortedSet3); //Check we get an exception with sorted sets with different comparators. stSortedSet *sortedSet4 = stSortedSet_construct(); stTry { stSortedSet_getIntersection(sortedSet, sortedSet4); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SORTED_SET_EXCEPTION_ID); } stTryEnd stSortedSet_destruct(sortedSet4); sonLibSortedSetTestTeardown(); }
static void test_st_randomChoice(CuTest *testCase) { /* * Excercies the random int function. */ stList *list = stList_construct3(0, (void (*)(void *))stIntTuple_destruct); stTry { st_randomChoice(list); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == RANDOM_EXCEPTION_ID); } stTryEnd for(int32_t i = 0; i < 10; i++) { stList_append(list, stIntTuple_construct(1, i)); } for(int32_t i = 0; i < 100; i++) { CuAssertTrue(testCase, stList_contains(list, st_randomChoice(list))); } stList_destruct(list); }
static void readWriteAndRemoveRecordsLotsIteration(CuTest *testCase, int numRecords, bool reopenDatabase) { //Make a big old list of records.. stSortedSet *set = stSortedSet_construct3((int(*)(const void *, const void *)) stIntTuple_cmpFn, (void(*)(void *)) stIntTuple_destruct); while (stSortedSet_size(set) < numRecords) { int32_t key = st_randomInt(0, 100 * numRecords); stIntTuple *tuple = stIntTuple_construct(1, key); if (stSortedSet_search(set, tuple) == NULL) { CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, key)); stSortedSet_insert(set, tuple); stKVDatabase_insertRecord(database, key, &key, sizeof(int32_t)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, key)); } else { CuAssertTrue(testCase, stKVDatabase_containsRecord(database, key)); stIntTuple_destruct(tuple); // already in db } } readWriteAndRemoveRecordsLotsCheck(testCase, set, 1); //Update all records to negate values stSortedSetIterator *it = stSortedSet_getIterator(set); stIntTuple *tuple; while ((tuple = stSortedSet_getNext(it)) != NULL) { int32_t *value = (int32_t *) stKVDatabase_getRecord(database, stIntTuple_getPosition(tuple, 0)); *value *= -1; stKVDatabase_updateRecord(database, stIntTuple_getPosition(tuple, 0), value, sizeof(int32_t)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); free(value); } stSortedSet_destructIterator(it); readWriteAndRemoveRecordsLotsCheck(testCase, set, -1); //Try optionally committing the transaction and reloading the database.. if (reopenDatabase) { //stKVDatabase_commitTransaction(database); stKVDatabase_destruct(database); database = stKVDatabase_construct(conf, false); //stKVDatabase_startTransaction(database); } //Now remove each one.. it = stSortedSet_getIterator(set); while ((tuple = stSortedSet_getNext(it)) != NULL) { CuAssertTrue(testCase, stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); stKVDatabase_removeRecord(database, stIntTuple_getPosition(tuple, 0)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); //Test we get exception if we remove twice. stTry { stKVDatabase_removeRecord(database, stIntTuple_getPosition(tuple, 0)); CuAssertTrue(testCase, 0); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; } stSortedSet_destructIterator(it); CuAssertIntEquals(testCase, 0, stKVDatabase_getNumberOfRecords(database)); stSortedSet_destruct(set); }
static void partialRecordRetrieval(CuTest *testCase) { setup(); //Make some number of large records stList *records = stList_construct3(0, free); stList *recordSizes = stList_construct3(0, (void(*)(void *)) stIntTuple_destruct); for (int32_t i = 0; i < 300; i++) { int32_t size = st_randomInt(0, 80); size = size * size * size; //Use cubic size distribution char *randomRecord = st_malloc(size * sizeof(char)); for (int32_t j = 0; j < size; j++) { randomRecord[j] = (char) st_randomInt(0, 100); } stList_append(records, randomRecord); stList_append(recordSizes, stIntTuple_construct(1, size)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, i)); stKVDatabase_insertRecord(database, i, randomRecord, size * sizeof(char)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, i)); //st_uglyf("I am creating the record %i %i\n", i, size); } while (st_random() > 0.001) { int32_t recordKey = st_randomInt(0, stList_length(records)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, recordKey)); char *record = stList_get(records, recordKey); int32_t size = stIntTuple_getPosition(stList_get(recordSizes, recordKey), 0); //Get partial record int32_t start = size > 0 ? st_randomInt(0, size) : 0; int32_t partialSize = size - start > 0 ? st_randomInt(start, size) - start : 0; assert(start >= 0); assert(partialSize >= 0); assert(partialSize + start <= size); //st_uglyf("I am getting record %i %i %i %i\n", recordKey, start, partialSize, size); char *partialRecord = stKVDatabase_getPartialRecord(database, recordKey, start * sizeof(char), partialSize * sizeof(char), size * sizeof(char)); //Check they are equivalent.. for (int32_t i = 0; i < partialSize; i++) { if (record[start + i] != partialRecord[i]) { st_uglyf("There was a difference %i %i for record %i %i\n", record[start + i], partialRecord[i], i, partialSize); } //CuAssertTrue(testCase, record[start + i] == partialRecord[i]); } //Check we can not get out of bounds.. (start less than zero) stTry { stKVDatabase_getPartialRecord(database, recordKey, -1, 1, size * sizeof(char)); }stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; //Check we can not get out of bounds.. (start greater than index start) stTry { stKVDatabase_getPartialRecord(database, recordKey, size, 1, size * sizeof(char)); }stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; //Check we can not get out of bounds.. (total size if greater than record length) stTry { stKVDatabase_getPartialRecord(database, recordKey, 0, size + 1, size * sizeof(char)); }stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; //Check we can not get non existent record stTry { stKVDatabase_getPartialRecord(database, 1000000, 0, size, size * sizeof(char)); }stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; } stList_destruct(records); stList_destruct(recordSizes); teardown(); }