TEST(RocksIndexTest, Isolation) { const std::unique_ptr<HarnessHelper> harnessHelper(newHarnessHelper()); const std::unique_ptr<SortedDataInterface> sorted(harnessHelper->newSortedDataInterface(true)); { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT(sorted->isEmpty(opCtx.get())); } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); { WriteUnitOfWork uow(opCtx.get()); ASSERT_OK(sorted->insert(opCtx.get(), key1, loc1, false)); ASSERT_OK(sorted->insert(opCtx.get(), key2, loc2, false)); uow.commit(); } } { const std::unique_ptr<OperationContext> t1(harnessHelper->newOperationContext()); const std::unique_ptr<OperationContext> t2(harnessHelper->newOperationContext()); const std::unique_ptr<WriteUnitOfWork> w1(new WriteUnitOfWork(t1.get())); const std::unique_ptr<WriteUnitOfWork> w2(new WriteUnitOfWork(t2.get())); ASSERT_OK(sorted->insert(t1.get(), key3, loc3, false)); ASSERT_OK(sorted->insert(t2.get(), key4, loc4, false)); // this should throw ASSERT_THROWS(sorted->insert(t2.get(), key3, loc5, false), WriteConflictException); w1->commit(); // this should succeed } { const std::unique_ptr<OperationContext> t1(harnessHelper->newOperationContext()); const std::unique_ptr<OperationContext> t2(harnessHelper->newOperationContext()); const std::unique_ptr<WriteUnitOfWork> w2(new WriteUnitOfWork(t2.get())); // ensure we start w2 transaction ASSERT_OK(sorted->insert(t2.get(), key4, loc4, false)); { const std::unique_ptr<WriteUnitOfWork> w1(new WriteUnitOfWork(t1.get())); { WriteUnitOfWork w(t1.get()); ASSERT_OK(sorted->insert(t1.get(), key5, loc3, false)); w.commit(); } w1->commit(); } // this should throw ASSERT_THROWS(sorted->insert(t2.get(), key5, loc3, false), WriteConflictException); } }
// static std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(double timestamp, ConsoleAPIType type, const std::vector<v8::Local<v8::Value>>& arguments, std::unique_ptr<V8StackTrace> stackTrace, InspectedContext* context) { std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16())); if (stackTrace && !stackTrace->isEmpty()) { message->m_url = stackTrace->topSourceURL(); message->m_lineNumber = stackTrace->topLineNumber(); message->m_columnNumber = stackTrace->topColumnNumber(); } message->m_stackTrace = std::move(stackTrace); message->m_type = type; message->m_contextId = context->contextId(); for (size_t i = 0; i < arguments.size(); ++i) message->m_arguments.push_back(wrapUnique(new v8::Global<v8::Value>(context->isolate(), arguments.at(i)))); if (arguments.size()) message->m_message = V8ValueStringBuilder::toString(arguments[0], context->isolate()); MessageLevel level = LogMessageLevel; if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount || type == ConsoleAPIType::kTimeEnd) level = DebugMessageLevel; if (type == ConsoleAPIType::kError || type == ConsoleAPIType::kAssert) level = ErrorMessageLevel; if (type == ConsoleAPIType::kWarning) level = WarningMessageLevel; if (type == ConsoleAPIType::kInfo) level = InfoMessageLevel; context->debugger()->client()->consoleAPIMessage(context->contextGroupId(), level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); return message; }
// Call savePosition() on a reverse cursor without ever calling restorePosition(). // May be useful to run this test under valgrind to verify there are no leaks. TEST( SortedDataInterface, SavePositionWithoutRestoreReversed ) { const std::unique_ptr<HarnessHelper> harnessHelper( newHarnessHelper() ); const std::unique_ptr<SortedDataInterface> sorted( harnessHelper->newSortedDataInterface( false ) ); { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT( sorted->isEmpty( opCtx.get() ) ); } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); { WriteUnitOfWork uow( opCtx.get() ); ASSERT_OK( sorted->insert( opCtx.get(), key1, loc1, true ) ); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT_EQUALS( 1, sorted->numEntries( opCtx.get() ) ); } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false) ); cursor->savePositioned(); } }
// Insert multiple keys and verify that fullValidate() either sets // the `numKeysOut` as the number of entries in the index, or as -1. TEST(SortedDataInterface, FullValidate) { const std::unique_ptr<HarnessHelper> harnessHelper(newHarnessHelper()); const std::unique_ptr<SortedDataInterface> sorted(harnessHelper->newSortedDataInterface(false)); { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT(sorted->isEmpty(opCtx.get())); } int nToInsert = 10; for (int i = 0; i < nToInsert; i++) { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); { WriteUnitOfWork uow(opCtx.get()); BSONObj key = BSON("" << i); RecordId loc(42, i * 2); ASSERT_OK(sorted->insert(opCtx.get(), key, loc, true)); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT_EQUALS(nToInsert, sorted->numEntries(opCtx.get())); } { long long numKeysOut; const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); sorted->fullValidate(opCtx.get(), &numKeysOut, NULL); // fullValidate() can set numKeysOut as the number of existing keys or -1. ASSERT(numKeysOut == nToInsert || numKeysOut == -1); } }
// Verify that isEmpty() returns true when the index is empty, // returns false when a key is inserted, and returns true again // when that is unindex. TEST(SortedDataInterface, IsEmpty) { const std::unique_ptr<HarnessHelper> harnessHelper(newHarnessHelper()); const std::unique_ptr<SortedDataInterface> sorted(harnessHelper->newSortedDataInterface(true)); { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT(sorted->isEmpty(opCtx.get())); } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); { WriteUnitOfWork uow(opCtx.get()); ASSERT_OK(sorted->insert(opCtx.get(), key1, loc1, false)); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT(!sorted->isEmpty(opCtx.get())); } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); { WriteUnitOfWork uow(opCtx.get()); sorted->unindex(opCtx.get(), key1, loc1, false); ASSERT(sorted->isEmpty(opCtx.get())); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx(harnessHelper->newOperationContext()); ASSERT(sorted->isEmpty(opCtx.get())); } }
// Insert multiple keys and try to iterate through all of them // using a reverse cursor while calling savePosition() and // restorePosition() in succession. TEST( SortedDataInterface, SaveAndRestorePositionWhileIterateCursorReversed ) { const std::unique_ptr<HarnessHelper> harnessHelper( newHarnessHelper() ); const std::unique_ptr<SortedDataInterface> sorted( harnessHelper->newSortedDataInterface( false ) ); { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT( sorted->isEmpty( opCtx.get() ) ); } int nToInsert = 10; for ( int i = 0; i < nToInsert; i++ ) { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); { WriteUnitOfWork uow( opCtx.get() ); BSONObj key = BSON( "" << i ); RecordId loc( 42, i * 2 ); ASSERT_OK( sorted->insert( opCtx.get(), key, loc, true ) ); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT_EQUALS( nToInsert, sorted->numEntries( opCtx.get() ) ); } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false) ); int i = nToInsert - 1; for (auto entry = cursor->seek(maxKey, true); entry; i--, entry = cursor->next()) { ASSERT_GTE(i, 0); ASSERT_EQ(entry, IndexKeyEntry(BSON( "" << i), RecordId(42, i * 2))); cursor->savePositioned(); cursor->restore( opCtx.get() ); } ASSERT( !cursor->next() ); ASSERT_EQ(i, -1); } }
// Insert the same key multiple times and try to iterate through each // occurrence using a forward cursor while calling savePosition() and // restorePosition() in succession. Verify that the RecordId is saved // as part of the current position of the cursor. TEST( SortedDataInterface, SaveAndRestorePositionWhileIterateCursorWithDupKeys ) { const std::unique_ptr<HarnessHelper> harnessHelper( newHarnessHelper() ); const std::unique_ptr<SortedDataInterface> sorted( harnessHelper->newSortedDataInterface( false ) ); { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT( sorted->isEmpty( opCtx.get() ) ); } int nToInsert = 10; for ( int i = 0; i < nToInsert; i++ ) { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); { WriteUnitOfWork uow( opCtx.get() ); RecordId loc( 42, i * 2 ); ASSERT_OK( sorted->insert( opCtx.get(), key1, loc, true /* allow duplicates */ ) ); uow.commit(); } } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); ASSERT_EQUALS( nToInsert, sorted->numEntries( opCtx.get() ) ); } { const std::unique_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() ); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get()) ); int i = 0; for (auto entry = cursor->seek(minKey, true); entry; i++, entry = cursor->next()) { ASSERT_LT(i, nToInsert); ASSERT_EQ(entry, IndexKeyEntry(key1, RecordId(42, i * 2))); cursor->savePositioned(); cursor->restore( opCtx.get() ); } ASSERT( !cursor->next() ); ASSERT_EQ(i, nToInsert); } }
void RejectedPromises::processQueueNow(std::unique_ptr<MessageQueue> queue) { // Remove collected handlers. for (size_t i = 0; i < m_reportedAsErrors.size();) { if (m_reportedAsErrors.at(i)->isCollected()) m_reportedAsErrors.remove(i); else ++i; } while (!queue->isEmpty()) { std::unique_ptr<Message> message = queue->takeFirst(); if (message->isCollected()) continue; if (!message->hasHandler()) { message->report(); message->makePromiseWeak(); m_reportedAsErrors.append(std::move(message)); if (m_reportedAsErrors.size() > maxReportedHandlersPendingResolution) m_reportedAsErrors.remove(0, maxReportedHandlersPendingResolution / 10); } } }
// static std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(double timestampMS, MessageType type, MessageLevel level, const String16& messageText, std::vector<v8::Local<v8::Value>>* arguments, std::unique_ptr<V8StackTrace> stackTrace, InspectedContext* context) { v8::Isolate* isolate = context->isolate(); int contextId = context->contextId(); int contextGroupId = context->contextGroupId(); V8DebuggerImpl* debugger = context->debugger(); String16 url; unsigned lineNumber = 0; unsigned columnNumber = 0; if (stackTrace && !stackTrace->isEmpty()) { url = stackTrace->topSourceURL(); lineNumber = stackTrace->topLineNumber(); columnNumber = stackTrace->topColumnNumber(); } String16 actualMessage = messageText; Arguments messageArguments; if (arguments && arguments->size()) { for (size_t i = 0; i < arguments->size(); ++i) messageArguments.push_back(wrapUnique(new v8::Global<v8::Value>(isolate, arguments->at(i)))); if (actualMessage.isEmpty()) actualMessage = V8ValueStringBuilder::toString(messageArguments.at(0)->Get(isolate), isolate); } std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(timestampMS, ConsoleAPIMessageSource, level, actualMessage, url, lineNumber, columnNumber, std::move(stackTrace), 0 /* scriptId */, String16() /* requestIdentifier */)); message->m_type = type; if (messageArguments.size()) { message->m_contextId = contextId; message->m_arguments.swap(messageArguments); } debugger->client()->messageAddedToConsole(contextGroupId, message->m_source, message->m_level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); return message; }