MojErr handleResponse(MojObject& payload, MojErr errCode) { MojTestAssert(m_pendingCount > 0); MojTestAssert(payload == m_expected); m_pendingCount--; return MojErrNone; }
MojErr MojDbIndexTest::deletedTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(true)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojObject prop; MojErr err = prop.putString(MojDbIndex::NameKey, _T("foo")); MojTestErrCheck(err); err = index.addProp(prop); MojTestErrCheck(err); index.incDel(true); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":1}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 1 && ti.m_delCount == 0 && ti.m_set.size() == 1); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = del(index, 1, _T("{\"foo\":1}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 2 && ti.m_delCount == 1 && ti.m_set.size() == 1); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = del(index, 1, _T("{\"foo\":1,\"_del\":true}"), true); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 2 && ti.m_delCount == 2 && ti.m_set.size() == 0); return MojErrNone; }
MojErr testCancel() { const MojChar* echoStr = _T("{\"hello\":\"world\"}"); MojObject expectedResponse; MojErr err = formatEchoResponse(echoStr, expectedResponse); MojTestErrCheck(err); MojRefCountedPtr<MojServiceRequest> req; err = m_service.createRequest(req); MojTestErrCheck(err); int callbackCount = 2; MojRefCountedPtr<EchoMultiResponseHdlr> handler(new EchoMultiResponseHdlr(expectedResponse, ++m_pendingResponseCount, callbackCount)); MojTestAssert(handler.get()); MojObject payload; err = payload.fromJson(echoStr); MojTestErrCheck(err); err = req->send(handler->m_slot, ServiceName, _T("cancellableecho"), payload, MojServiceRequest::Unlimited); MojTestErrCheck(err); err = receiveResponses(); MojTestErrCheck(err); MojTestAssert(handler->callbacksRemaining() == 1); // still have callback registered because 1 more response is expected // cancel request handler->m_slot.cancel(); sleep(1); return MojErrNone; }
MojErr MojDbIndexTest::tokenizeTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojErr err = indexFromObject(index, _T("{\"name\":\"test\",\"props\":[") _T("{\"name\":\"foo\",\"tokenize\":\"all\",\"collate\":\"primary\"}") _T("]}")); MojErrCheck(err); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":\"four score and seven years ago\"}"), NULL); MojTestErrCheck(err); err = assertContainsText(ti, 1, _T("four")); MojTestErrCheck(err); err = assertContainsText(ti, 1, _T("score")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 6 && ti.m_delCount == 0 && ti.m_set.size() == 6); err = put(index, 1, _T("{\"foo\":\"our fathers put\"}"), _T("{\"foo\":\"four score and seven years ago\"}")); MojTestErrCheck(err); err = assertContainsText(ti, 1, _T("fathers")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 9 && ti.m_delCount == 6 && ti.m_set.size() == 3); err = index.close(); MojTestErrCheck(err); return MojErrNone; }
static MojErr MojThreadTestFn(void* arg) { static MojThreadLocalValue<int, MojThreadLocalValueZeroCtor<int> > s_localVal; MojThreadTestArgs* targs = (MojThreadTestArgs*) arg; MojTestAssert(targs); for (int i = 0; i < MojTestNumIterations; ++i) { targs->m_atomicCounter.increment(); MojThreadGuard guard(targs->m_mutex, false); if (!guard.tryLock()) guard.lock(); ++(targs->m_counter); if (targs->m_counter == (MojTestNumThreads * MojTestNumIterations)) { MojErr err = targs->m_countCond.signal(); MojTestErrCheck(err); } } MojErr err = MojThreadYield(); MojTestErrCheck(err); MojThreadGuard guard(targs->m_mutex); while (targs->m_wait) { err = targs->m_waitCond.wait(targs->m_mutex); MojTestErrCheck(err); } guard.unlock(); int* localVal = NULL; err = s_localVal.get(localVal); MojTestErrCheck(err); MojTestAssert(localVal && *localVal == 0); for (int i = 0; i < MojTestNumIterations; ++i) { ++(*localVal); targs->m_atomicCounter.decrement(); { MojThreadReadGuard readGuard(targs->m_rwlock); MojTestAssert(targs->m_counter > 0); } MojThreadReadGuard readGuard(targs->m_rwlock, false); if (!readGuard.tryLock()) readGuard.lock(); MojTestAssert(targs->m_counter > 0); readGuard.unlock(); { MojThreadWriteGuard writeGuard(targs->m_rwlock); ++(targs->m_counter); } MojThreadWriteGuard writeGuard(targs->m_rwlock, false); if (!writeGuard.tryLock()) writeGuard.lock(); targs->m_counter -= 2; } MojTestAssert(*localVal == MojTestNumIterations); return MojErrNone; }
MojErr MojDbTextTokenizerTest::check(const MojChar* text, const MojChar* tokens) { // tokenize string MojString textStr; MojErr err = textStr.assign(text); MojTestErrCheck(err); MojSet<MojDbKey> set; MojRefCountedPtr<MojDbTextTokenizer> tokenizer(new MojDbTextTokenizer); MojAllocCheck(tokenizer.get()); err = tokenizer->init(_T("en_US")); MojTestErrCheck(err); err = tokenizer->tokenize(textStr, NULL, set); MojTestErrCheck(err); // check that tokens match MojObject obj; err = obj.fromJson(tokens); MojTestErrCheck(err); MojSize objSize = obj.size(); MojSize setSize = set.size(); MojTestAssert(objSize == setSize); for (MojObject::ConstArrayIterator i = obj.arrayBegin(); i != obj.arrayEnd(); ++i) { MojDbKey key; err = key.assign(*i); MojTestErrCheck(err); MojTestAssert(set.contains(key)); } return MojErrNone; }
MojErr MojDbQuotaTest::testErrors() { #ifdef MOJ_USE_BDB MojRefCountedPtr<MojDbStorageEngine> engine(new MojDbBerkeleyEngine()); #elif MOJ_USE_LDB MojRefCountedPtr<MojDbStorageEngine> engine(new MojDbLevelEngine()); #else MojRefCountedPtr<MojDbStorageEngine> engine; #endif MojAllocCheck(engine.get()); MojRefCountedPtr<MojDbTestStorageEngine> testEngine(new MojDbTestStorageEngine(engine.get())); MojAllocCheck(testEngine.get()); MojErr err = testEngine->open(MojDbTestDir); MojTestErrCheck(err); MojDb db; err = db.open(MojDbTestDir, testEngine.get()); MojTestErrCheck(err); // test that failed put does not affect quota MojInt64 quotaUsage1 = 0; err = getQuotaUsage(db, _T("com.foo.*"), quotaUsage1); MojTestErrCheck(err); err = testEngine->setNextError(_T("txn.commit"), MojErrDbDeadlock); MojTestErrCheck(err); err = put(db, MojTestKind3Objects[1]); MojTestErrExpected(err, MojErrDbDeadlock); MojInt64 quotaUsage2 = 0; err = getQuotaUsage(db, _T("com.foo.*"), quotaUsage2); MojTestErrCheck(err); MojTestAssert(quotaUsage2 == quotaUsage1); // test that failed putQuota has no effect err = testEngine->setNextError(_T("txn.commit"), MojErrDbDeadlock); MojTestErrCheck(err); MojObject obj; err = obj.fromJson(_T("{\"owner\":\"com.foo.boo\",\"size\":1000}")); MojErrCheck(err); err = db.putQuotas(&obj, &obj + 1); MojTestErrExpected(err, MojErrDbDeadlock); MojInt64 quotaUsage3 = 0; err = getQuotaUsage(db, _T("com.foo.*"), quotaUsage3); MojTestErrCheck(err); MojTestAssert(quotaUsage3 == quotaUsage1); // test that failed putKind has no effect err = testEngine->setNextError(_T("txn.commit"), MojErrDbDeadlock); MojTestErrCheck(err); err = obj.fromJson(MojTestKind3Str2); MojTestErrCheck(err); err = db.putKind(obj); MojTestErrExpected(err, MojErrDbDeadlock); MojInt64 quotaUsage4 = 0; err = getQuotaUsage(db, _T("com.foo.*"), quotaUsage4); MojTestErrCheck(err); MojTestAssert(quotaUsage4 == quotaUsage1); err = db.close(); MojTestErrCheck(err); return MojErrNone; }
MojErr handleResponse(MojObject& payload, MojErr errCode) { MojTestAssert(m_pendingCount > 0); MojTestAssert(payload == m_expected); m_pendingCount--; MojTestAssert(m_callbacksRemaining > 0); if (--m_callbacksRemaining == 0) { m_slot.cancel(); } return MojErrNone; }
MojErr MojDbIndexTest::simpleTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojObject prop; MojErr err = prop.putString(MojDbIndex::NameKey, _T("foo")); MojTestErrCheck(err); err = index.addProp(prop); MojTestErrCheck(err); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":1}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 1 && ti.m_delCount == 0 && ti.m_set.size() == 1); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":2}"), _T("{\"foo\":1}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 2 && ti.m_delCount == 1 && ti.m_set.size() == 1); err = assertContains(ti, 1, 2); MojTestErrCheck(err); err = del(index, 1, _T("{\"foo\":2}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 2 && ti.m_delCount == 2 && ti.m_set.size() == 0); err = put(index, 2, _T("{\"foo\":[3,4,5]}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 5 && ti.m_delCount == 2 && ti.m_set.size() == 3); err = assertContains(ti, 2, 3); MojTestErrCheck(err); err = assertContains(ti, 2, 4); MojTestErrCheck(err); err = assertContains(ti, 2, 5); MojTestErrCheck(err); err = put(index, 2, _T("{\"foo\":[5,6]}"), _T("{\"foo\":[3,4,4,4,3,3,4,3,5]}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 6 && ti.m_delCount == 4 && ti.m_set.size() == 2); err = assertContains(ti, 2, 5); MojTestErrCheck(err); err = assertContains(ti, 2, 6); MojTestErrCheck(err); err = index.close(); MojTestErrCheck(err); return MojErrNone; }
MojErr MojDbRevTest::checkRevEq(MojDb& db, const MojObject& id, const MojObject& rev) { MojObject obj; bool found = false; MojErr err = db.get(id, obj, found); MojTestErrCheck(err); MojTestAssert(found); MojObject rev2; err = obj.getRequired(MojDb::RevKey, rev2); MojTestErrCheck(err); MojTestAssert(rev == rev2); return MojErrNone; }
MojErr MojDbPurgeTest::checkObjectsPurged(MojDb& db, const MojUInt32& count, const MojSize& expectedCount, const MojSize& expectedNumObjects, const MojSize& expectedNumRevTimestampObjects, const MojObject& expectedLastPurgeRevNum) { //check number of objects purged MojTestAssert(count == expectedCount); //there should still be expectedNumObjects test objects MojDbQuery query; MojErr err = query.from(_T("PurgeTest:1")); MojTestErrCheck(err); MojDbCursor cursor; err = db.find(query, cursor); MojTestErrCheck(err); MojUInt32 objCount; err = cursor.count(objCount); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); MojTestAssert(objCount == expectedNumObjects); //there should be expectedNumRevTimestampObjects RevTimestamp objects MojDbQuery revQuery; err = revQuery.from(MojDbKindEngine::RevTimestampId); MojTestErrCheck(err); MojDbCursor revCursor; err = db.find(revQuery, revCursor); MojTestErrCheck(err); MojUInt32 revTimestampObjCount; err = revCursor.count(revTimestampObjCount); MojTestErrCheck(err); err = revCursor.close(); MojTestErrCheck(err); MojTestAssert(revTimestampObjCount == expectedNumRevTimestampObjects); //lastPurgedRevNum should be equal to the expectedLastPurgeRevNum MojObject revNum; err = db.purgeStatus(revNum); MojTestErrCheck(err); MojTestAssert(revNum == expectedLastPurgeRevNum); return MojErrNone; }
MojErr handleCancel(MojServiceMessage* msg) { MojTestAssert(m_cCancellableEchos > 0); m_cCancellableEchos--; return MojErrNone; }
MojErr MojDbQuotaTest::testEnforce(MojDb& db) { // set quota size to current usage MojInt64 quotaUsage1 = 0; MojErr err = getQuotaUsage(db, _T("com.foo.bar"), quotaUsage1); MojTestErrCheck(err); MojObject obj; err = obj.putString(_T("owner"), _T("com.foo.bar")); MojErrCheck(err); err = obj.putInt(_T("size"), quotaUsage1); MojErrCheck(err); err = db.putQuotas(&obj, &obj + 1); MojErrCheck(err); err = put(db, MojTestKind1Objects[3]); MojTestErrExpected(err, MojErrDbQuotaExceeded); // make sure we can delete the kind MojString kindStr; err = kindStr.assign(_T("Test:1")); MojTestErrCheck(err); bool found = false; err = db.delKind(kindStr, found); MojTestErrCheck(err); MojTestAssert(found); return MojErrNone; }
MojErr MojDbIndexTest::assertCanAnswer(const MojChar* propsJson, const MojChar* queryJson, bool result, bool indexIncludeDeleted) { MojObject propsObj; MojErr err = propsObj.fromJson(propsJson); MojTestErrCheck(err); MojObject queryObj; err = queryObj.fromJson(queryJson); MojTestErrCheck(err); MojDbIndex index(NULL, NULL); MojObject prop; MojSize i = 0; for (;;) { if(propsObj.at(i++, prop)) { err = index.addProp(prop); MojTestErrCheck(err); } else { break; } } index.incDel(indexIncludeDeleted); MojRefCountedPtr<MojDbStorageIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); MojDbQuery query; err = query.fromObject(queryObj); MojTestErrCheck(err); MojTestAssert(index.canAnswer(query) == result); return MojErrNone; }
MojErr MojDbQuotaTest::testEnforce(MojDb& db) { // set quota size to current usage MojInt64 quotaUsage1 = 0; MojErr err = getQuotaUsage(db, _T("com.foo.bar"), quotaUsage1); MojTestErrCheck(err); MojObject obj; err = obj.putString(_T("owner"), _T("com.foo.bar")); MojErrCheck(err); err = obj.putInt(_T("size"), quotaUsage1); MojErrCheck(err); err = db.putQuotas(&obj, &obj + 1); MojErrCheck(err); err = put(db, MojTestKind1Objects[3]); MojTestErrExpected(err, MojErrDbQuotaExceeded); // Try to delete the kind MojString kindStr; err = kindStr.assign(_T("Test:1")); MojTestErrCheck(err); bool found = false; err = db.delKind(kindStr, found); //The delete should be failure, because it contain sub kind "Test2:1" MojTestErrExpected(err,MojErrDbKindHasSubKinds); MojTestAssert(!found); return MojErrNone; }
MojErr MojDbWatchTest::gtTest(MojDb& db) { MojDbQuery query; MojErr err = query.from(_T("WatchTest:1")); MojTestErrCheck(err); err = query.where(_T("foo"), MojDbQuery::OpGreaterThan, 1); MojTestErrCheck(err); MojRefCountedPtr<TestWatcher> watcher(new TestWatcher); MojTestAssert(watcher.get()); MojDbCursor cursor; err = db.find(query, cursor, watcher->m_slot); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); MojRefCountedPtr<TestWatcher> watcher2(new TestWatcher); MojTestAssert(watcher2.get()); MojDbQuery queryWithRev; err = queryWithRev.from(_T("WatchTest:1")); MojTestErrCheck(err); err = queryWithRev.where(_T("foo"), MojDbQuery::OpEq, 2); MojTestErrCheck(err); err = queryWithRev.where(_T("_rev"), MojDbQuery::OpGreaterThan, m_rev); MojTestErrCheck(err); bool fired = false; err = db.watch(queryWithRev, cursor, watcher2->m_slot, fired); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); MojTestAssert(!fired); MojObject id; err = put(db, 1, 1, id, m_rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); MojTestAssert(watcher2->m_count == 0); err = put(db, 2, 2, id, m_rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 1); MojTestAssert(watcher2->m_count == 1); err = put(db, 2, 2, id, m_rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 1); MojTestAssert(watcher2->m_count == 1); return MojErrNone; }
MojErr MojDbPerfUpdateTest::updateObjsViaPut(MojDb& db, const MojChar* kindId, MojErr (MojDbPerfTest::*createFn) (MojObject&, MojUInt64)) { // register all the kinds MojTime time; MojErr err = putKinds(db, time); MojTestErrCheck(err); // put objects using createFn MojObject objs; err = putObjs(db, kindId, numInsertForPut, createFn, objs); MojTestErrCheck(err); MojObject midObj; bool found = objs.at(numInsertForPut/2, midObj); MojTestAssert(found); MojTime objTime; err = putObj(db, midObj, objTime); MojTestErrCheck(err); MojUInt64 putTime = objTime.microsecs(); err = MojPrintF("\n -------------------- \n"); MojTestErrCheck(err); err = MojPrintF(" putting single object - index %llu - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/2, kindId, numPutIterations, putTime); MojTestErrCheck(err); err = MojPrintF(" time per put: %llu microsecs", (putTime) / (numPutIterations)); MojTestErrCheck(err); err = MojPrintF("\n\n"); MojTestErrCheck(err); MojString buf; err = buf.format("Put single object - index %llu - %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/2, numPutIterations, kindId, putTime, putTime/numPutIterations, putTime/(1*numPutIterations)); MojTestErrCheck(err); err = fileWrite(file, buf); MojTestErrCheck(err); MojTime batchTime; MojObject::ArrayIterator beginArr; err = objs.arrayBegin(beginArr); MojErrCheck(err); err = batchPutObj(db, beginArr, beginArr + (numInsertForPut / 10), batchTime); putTime = batchTime.microsecs(); MojTestErrCheck(err); err = MojPrintF(" putting batch - %llu objects - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/10, kindId, numBatchPutIterations, putTime); MojTestErrCheck(err); err = MojPrintF(" time per batch put: %llu microsecs\n", (putTime) / (numBatchPutIterations)); MojTestErrCheck(err); err = MojPrintF(" time per object: %llu microsecs", (putTime) / (numInsertForPut/10 * numBatchPutIterations)); MojTestErrCheck(err); err = MojPrintF("\n\n"); MojTestErrCheck(err); err = buf.format("Batch put %llu objects %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/10, numBatchPutIterations, kindId, putTime, putTime/numBatchPutIterations, putTime/(numInsertForPut/10*numBatchPutIterations)); MojTestErrCheck(err); err = fileWrite(file, buf); MojTestErrCheck(err); return MojErrNone; }
MojErr MojDbSearchCacheTest::testQueryKey() { MojDbQuery query1; MojErr err=query1.from(_T("test:1")); MojTestErrCheck(err); err=query1.where(_T("attr1"), MojDbQuery::OpGreaterThan, 1); MojTestErrCheck(err); MojDbSearchCache::QueryKey key1; key1.fromQuery(query1, 1234); // Verify fromQuery() works fine. MojTestAssert(key1.getKind() == _T("test:1")); MojTestAssert(key1.getRev() == 1234); MojDbSearchCache::QueryKey key2; key2.fromQuery(query1, 1235); // key1 shall be less then key2. // MojTestAssert(key1 < key2); MojTestAssert(!(key2 < key1)); MojTestAssert(!(key1 == key2)); // key1 shall be equal to key1. // MojTestAssert(!(key1 < key1)); MojTestAssert(key1 == key1); return MojErrNone; }
MojErr MojDbIndexTest::wildcardTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojObject prop; MojErr err = prop.putString(MojDbIndex::NameKey, _T("foo.*.bar")); MojTestErrCheck(err); err = index.addProp(prop); MojTestErrCheck(err); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":{\"bar\":1}}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 0 && ti.m_delCount == 0 && ti.m_set.size() == 0); err = put(index, 1, _T("{\"foo\":{\"1\":{\"bar\":1},\"2\":{\"bar\":2},\"3\":{\"bar\":3}}}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 3 && ti.m_delCount == 0 && ti.m_set.size() == 3); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = assertContains(ti, 1, 2); MojTestErrCheck(err); err = assertContains(ti, 1, 3); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":{\"2\":{\"bar\":2},\"3\":{\"bar\":3}}}"), _T("{\"foo\":{\"1\":{\"bar\":1},\"2\":{\"bar\":2},\"3\":{\"bar\":3}}}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 3 && ti.m_delCount == 1 && ti.m_set.size() == 2); err = assertContains(ti, 1, 2); MojTestErrCheck(err); err = assertContains(ti, 1, 3); MojTestErrCheck(err); err = del(index, 1, _T("{\"foo\":{\"2\":{\"bar\":2},\"3\":{\"bar\":3}}}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 3 && ti.m_delCount == 3 && ti.m_set.size() == 0); err = index.close(); MojTestErrCheck(err); return MojErrNone; }
MojErr MojThreadTest::basicTest() { MojVector<MojThreadT> threads; MojThreadTestArgs args; for (int i = 0; i < MojTestNumThreads; ++i) { MojThreadT thread = MojInvalidThread; MojErr err = MojThreadCreate(thread, MojThreadTestFn, &args); MojTestErrCheck(err); MojTestAssert(thread != MojInvalidThread); err = threads.push(thread); MojTestErrCheck(err); } { MojThreadGuard guard(args.m_mutex); while (args.m_counter < (MojTestNumThreads * MojTestNumIterations)) { MojErr err = args.m_countCond.wait(args.m_mutex); MojErrCheck(err); } MojTestAssert(args.m_counter == (MojTestNumThreads * MojTestNumIterations)); MojTestAssert(args.m_atomicCounter == (MojTestNumThreads * MojTestNumIterations)); guard.unlock(); MojErr err = MojSleep(MojMillisecs(500)); MojTestErrCheck(err); guard.lock(); args.m_wait = false; err = args.m_waitCond.broadcast(); MojTestErrCheck(err); } for (MojVector<MojThreadT>::ConstIterator i = threads.begin(); i != threads.end(); ++i) { MojErr threadErr = MojErrNone; MojErr err = MojThreadJoin(*i, threadErr); MojTestErrCheck(err); MojTestErrCheck(threadErr); } MojTestAssert(args.m_counter == 0); MojTestAssert(args.m_atomicCounter == 0); return MojErrNone; }
MojErr MojHashMapTest::check(MojHashMap<int, int> map, int maxExpected, int& numFound) { MojVector<bool> v; numFound = 0; MojErr err = v.resize(maxExpected, false); MojTestErrCheck(err); for (MojHashMap<int, int>::ConstIterator i = map.begin(); i != map.end(); ++i) { int key = i.key(); int val = i.value(); MojTestAssert(key == val); MojTestAssert(key >= 0 && key <= maxExpected); MojTestAssert(!v.at(key)); err = v.setAt(key, true); MojTestErrCheck(err); ++numFound; } return MojErrNone; }
MojErr MojDbIndexTest::multiTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojErr err = indexFromObject(index, _T("{\"name\":\"test\",\"props\":[") _T("{\"name\":\"multiprop\",\"type\":\"multi\",\"include\":[{\"name\":\"foo\"},{\"name\":\"bar\"},{\"name\":\"baz\"}]}") _T("]}")); MojErrCheck(err); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":1,\"bar\":2,\"baz\":3}"), NULL); MojTestErrCheck(err); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = assertContains(ti, 1, 2); MojTestErrCheck(err); err = assertContains(ti, 1, 3); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 3 && ti.m_delCount == 0 && ti.m_set.size() == 3); err = put(index, 1, _T("{\"foo\":5}"), _T("{\"foo\":1,\"bar\":2,\"baz\":3}")); MojTestErrCheck(err); err = assertContains(ti, 1, 5); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 4 && ti.m_delCount == 3 && ti.m_set.size() == 1); err = put(index, 1, _T("{\"bar\":6}"), _T("{\"foo\":5}")); MojTestErrCheck(err); err = assertContains(ti, 1, 6); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 5 && ti.m_delCount == 4 && ti.m_set.size() == 1); err = index.close(); MojTestErrCheck(err); return MojErrNone; }
MojErr receiveResponses() { MojTestAssert(m_pendingResponseCount > 0); // block until response received while (m_pendingResponseCount > 0) { MojErr err = m_service.dispatch(); MojTestErrCheck(err); } return MojErrNone; }
MojErr MojDbDistinctTest::check(MojDb& db, const MojDbQuery& query, MojDbCursor& cursor, const MojChar* queryString, const MojChar* expectedIdsJson) { MojErr err = db.find(query, cursor); MojTestErrCheck(err); MojObjectBuilder builder; err = builder.beginArray(); MojTestErrCheck(err); err = cursor.visit(builder); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); err = builder.endArray(); MojTestErrCheck(err); MojObject results = builder.object(); MojString json; err = results.toJson(json); MojTestErrCheck(err); MojObject expected; err = expected.fromJson(expectedIdsJson); MojTestErrCheck(err); // size check MojTestAssert(expected.size() == results.size()); // value check MojObject::ConstArrayIterator j = results.arrayBegin(); for (MojObject::ConstArrayIterator i = expected.arrayBegin(); i != expected.arrayEnd(); ++i, ++j) { MojObject value; err = j->getRequired(queryString, value); MojTestErrCheck(err); MojTestAssert(*i == value); } return MojErrNone; }
MojErr MojDbSearchTest::check(MojDb& db, const MojDbQuery& query, const MojChar* expectedIdsJson) { MojString str; MojDbSearchCursor cursor(str); MojErr err = db.find(query, cursor); MojTestErrCheck(err); MojObjectBuilder builder; err = builder.beginArray(); MojTestErrCheck(err); err = cursor.visit(builder); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); err = builder.endArray(); MojTestErrCheck(err); MojObject results = builder.object(); MojString json; err = results.toJson(json); MojTestErrCheck(err); MojObject expected; err = expected.fromJson(expectedIdsJson); MojTestErrCheck(err); MojTestAssert(expected.size() == results.size()); MojObject::ConstArrayIterator j = results.arrayBegin(); for (MojObject::ConstArrayIterator i = expected.arrayBegin(); i != expected.arrayEnd(); ++i, ++j) { MojObject id; err = j->getRequired(MojDb::IdKey, id); MojTestErrCheck(err); MojTestAssert(*i == id); } return MojErrNone; }
MojErr MojSignalTest::run() { MojErr err = test0(); MojTestErrCheck(err); err = test1(); MojTestErrCheck(err); err = test2(); MojTestErrCheck(err); err = test3(); MojTestErrCheck(err); MojTestAssert(TestHandler::s_instances == 0); return MojErrNone; }
MojErr MojDbIndexTest::nestedTest() { MojDbIndex index(NULL, NULL); MojRefCountedPtr<TestIndex> storageIndex(new TestIndex(false)); MojAllocCheck(storageIndex.get()); TestIndex& ti = *storageIndex; MojObject prop; MojErr err = prop.putString(MojDbIndex::NameKey, _T("foo.bar.baz")); MojTestErrCheck(err); err = index.addProp(prop); MojTestErrCheck(err); MojDbReq req; err = index.open(storageIndex.get(), (MojInt64) 0, req); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":1}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 0 && ti.m_delCount == 0 && ti.m_set.size() == 0); err = put(index, 1, _T("{\"foo.bar.baz\":1}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 0 && ti.m_delCount == 0 && ti.m_set.size() == 0); err = put(index, 1, _T("{\"foo\":{\"bar\":{\"baz\":1}}}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 1 && ti.m_delCount == 0 && ti.m_set.size() == 1); err = assertContains(ti, 1, 1); MojTestErrCheck(err); err = put(index, 1, _T("{\"foo\":{\"bar\":{\"baz\":[2,3,4]}}}"), _T("{\"foo\":{\"bar\":{\"baz\":1}}}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 4 && ti.m_delCount == 1 && ti.m_set.size() == 3); err = assertContains(ti, 1, 2); MojTestErrCheck(err); err = assertContains(ti, 1, 3); MojTestErrCheck(err); err = assertContains(ti, 1, 4); MojTestErrCheck(err); err = del(index, 1, _T("{\"foo\":{\"bar\":{\"baz\":[2,3,4]}}}")); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 4 && ti.m_delCount == 4 && ti.m_set.size() == 0); err = put(index, 1, _T("{\"foo\":{\"bar\":[{\"baz\":5},{\"baz\":6},{\"baz\":7},{\"baz\":8}]}}"), NULL); MojTestErrCheck(err); MojTestAssert(ti.m_putCount == 8 && ti.m_delCount == 4 && ti.m_set.size() == 4); err = assertContains(ti, 1, 5); MojTestErrCheck(err); err = assertContains(ti, 1, 6); MojTestErrCheck(err); err = assertContains(ti, 1, 7); MojTestErrCheck(err); err = assertContains(ti, 1, 8); MojTestErrCheck(err); err = index.close(); MojTestErrCheck(err); return MojErrNone; }
MojErr MojDbIndexTest::assertContains(TestIndex& ti, MojObject id, const MojDbKey& key) { MojDbKey prefixedKey(key); MojErr err = prefixedKey.byteVec().insert(0, 1, MojObjectWriter::MarkerZeroIntValue); MojErrCheck(err); if (ti.m_incDel) { MojDbKey::ByteVec vec = prefixedKey.byteVec(); MojErr err = vec.insert(1, 1, MojObjectWriter::MarkerTrueValue); MojTestErrCheck(err); MojDbKey keyTrue; err = keyTrue.assign(vec.begin(), vec.size()); MojTestErrCheck(err); err = vec.setAt(1, MojObjectWriter::MarkerFalseValue); MojTestErrCheck(err); MojDbKey keyFalse; err = keyFalse.assign(vec.begin(), vec.size()); MojTestErrCheck(err); MojTestAssert(ti.m_set.contains(keyTrue) || ti.m_set.contains(keyFalse)); } else { MojTestAssert(ti.m_set.contains(prefixedKey)); } return MojErrNone; }
MojErr MojSchemaTest::checkValid(const MojChar* schemaJson, const MojChar* instanceJson, bool expected) { MojObject schemaObj; MojErr err = schemaObj.fromJson(schemaJson); MojTestErrCheck(err); MojSchema schema; err = schema.fromObject(schemaObj); MojTestErrCheck(err); MojObject instance; err = instance.fromJson(instanceJson); MojTestErrCheck(err); MojSchema::Result res; err = schema.validate(instance, res); MojTestErrCheck(err); MojTestAssert(res.valid() == expected); return MojErrNone; }
MojErr MojDbWatchTest::rangeTest(MojDb& db) { MojDbQuery query; MojErr err = query.from(_T("WatchTest:1")); MojTestErrCheck(err); err = query.where(_T("foo"), MojDbQuery::OpGreaterThan, 5); MojTestErrCheck(err); err = query.where(_T("foo"), MojDbQuery::OpLessThan, 100); MojTestErrCheck(err); MojRefCountedPtr<TestWatcher> watcher(new TestWatcher); MojTestAssert(watcher.get()); MojDbCursor cursor; err = db.find(query, cursor, watcher->m_slot); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); MojObject id; MojInt64 rev; err = put(db, 5, 5, id, rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); err = put(db, 100, 100, id, rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); err = put(db, 6, 6, id, rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 1); watcher.reset(new TestWatcher); MojTestAssert(watcher.get()); err = db.find(query, cursor, watcher->m_slot); MojTestErrCheck(err); err = cursor.close(); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 0); err = put(db, 99, 99, id, rev); MojTestErrCheck(err); MojTestAssert(watcher->m_count == 1); return MojErrNone; }