//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldCloseUnexhaustedCursorsOnReaderClose() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldCloseUnexhaustedCursorsOnReaderClose() { // GIVEN GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree)); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor1 = mock(typeof(RawCursor)); when(cursor1.Next()).thenReturn(false); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor2 = mock(typeof(RawCursor)); when(cursor2.Next()).thenReturn(false); when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor1, cursor2); // WHEN using (NativeLabelScanReader reader = new NativeLabelScanReader(index)) { // first check test invariants reader.NodesWithLabel(LABEL_ID); reader.NodesWithLabel(LABEL_ID); verify(cursor1, never()).close(); verify(cursor2, never()).close(); } // THEN verify(cursor1, times(1)).close(); verify(cursor2, times(1)).close(); }
// Timeout because test verify no infinite loop //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test(timeout = 10_000L) public void shouldHandleDescendingWithEmptyRange() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldHandleDescendingWithEmptyRange() { long[] seeds = new long[] { 0, 1, 4 }; using (GBPTree <KEY, VALUE> index = CreateIndex()) { // Write using (Writer <KEY, VALUE> writer = CreateWriter(index)) { foreach (long seed in seeds) { KEY key = _layout.key(seed); VALUE value = _layout.value(0); writer.Put(key, value); } } KEY from = _layout.key(3); KEY to = _layout.key(1); using (RawCursor <Hit <KEY, VALUE>, IOException> seek = index.Seek(from, to)) { assertFalse(seek.Next()); } index.Checkpoint(Org.Neo4j.Io.pagecache.IOLimiter_Fields.Unlimited); } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private org.neo4j.cursor.RawCursor<org.neo4j.index.internal.gbptree.Hit<KEY,VALUE>, java.io.IOException> scan(org.neo4j.index.internal.gbptree.GBPTree<KEY,VALUE> tree) throws java.io.IOException private RawCursor <Hit <KEY, VALUE>, IOException> Scan(GBPTree <KEY, VALUE> tree) { KEY lowest = Layout.newKey(); lowest.initialize(long.MinValue); lowest.initValueAsLowest(0, ValueGroup.UNKNOWN); KEY highest = Layout.newKey(); highest.initialize(long.MaxValue); highest.initValueAsHighest(0, ValueGroup.UNKNOWN); return(tree.Seek(lowest, highest)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldHandleRemoveEntireTree() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldHandleRemoveEntireTree() { // given using (GBPTree <KEY, VALUE> index = CreateIndex()) { int numberOfNodes = 200_000; using (Writer <KEY, VALUE> writer = CreateWriter(index)) { for (int i = 0; i < numberOfNodes; i++) { writer.Put(Key(i), Value(i)); } } // when BitArray removed = new BitArray(); using (Writer <KEY, VALUE> writer = CreateWriter(index)) { for (int i = 0; i < numberOfNodes - numberOfNodes / 10; i++) { int candidate; do { candidate = Random.Next(max(1, Random.Next(numberOfNodes))); } while (removed.Get(candidate)); removed.Set(candidate, true); writer.Remove(Key(candidate)); } } int next = 0; using (Writer <KEY, VALUE> writer = CreateWriter(index)) { for (int i = 0; i < numberOfNodes / 10; i++) { next = removed.nextClearBit(next); removed.Set(next, true); writer.Remove(Key(next)); } } // then using (RawCursor <Hit <KEY, VALUE>, IOException> seek = index.Seek(Key(0), Key(numberOfNodes))) { assertFalse(seek.Next()); } // and finally index.ConsistencyCheck(); } }
/* Randomized tests */ //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSplitCorrectly() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSplitCorrectly() { // GIVEN using (GBPTree <KEY, VALUE> index = index()) { // WHEN int count = 1_000; IList <KEY> seen = new List <KEY>(count); using (Writer <KEY, VALUE> writer = index.Writer()) { for (int i = 0; i < count; i++) { KEY key; do { key = key(_random.Next(100_000)); } while (ListContains(seen, key)); VALUE value = value(i); writer.Put(key, value); seen.Add(key); } } // THEN using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(0), Key(long.MaxValue))) { long prev = -1; while (cursor.Next()) { KEY hit = cursor.get().key(); long hitSeed = _layout.keySeed(hit); if (hitSeed < prev) { fail(hit + " smaller than prev " + prev); } prev = hitSeed; assertTrue(RemoveFromList(seen, hit)); } if (seen.Count > 0) { fail("expected hits " + seen); } } } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private void shouldWriteAndReadEntriesOfRandomSizes(int minKeySize, int maxKeySize, int minValueSize, int maxValueSize) throws java.io.IOException private void ShouldWriteAndReadEntriesOfRandomSizes(int minKeySize, int maxKeySize, int minValueSize, int maxValueSize) { // given using (GBPTree <RawBytes, RawBytes> tree = CreateIndex(Layout())) { // when ISet <string> generatedStrings = new HashSet <string>(); IList <Pair <RawBytes, RawBytes> > entries = new List <Pair <RawBytes, RawBytes> >(); using (Writer <RawBytes, RawBytes> writer = tree.Writer()) { for (int i = 0; i < 1_000; i++) { // value, based on i RawBytes value = new RawBytes(); value.Bytes = new sbyte[Random.Next(minValueSize, maxValueSize)]; Random.NextBytes(value.Bytes); // key, randomly generated string @string; do { @string = Random.nextAlphaNumericString(minKeySize, maxKeySize); } while (!generatedStrings.Add(@string)); RawBytes key = new RawBytes(); key.Bytes = UTF8.encode(@string); entries.Add(Pair.of(key, value)); // write writer.Put(key, value); } } // then foreach (Pair <RawBytes, RawBytes> entry in entries) { using (RawCursor <Hit <RawBytes, RawBytes>, IOException> seek = tree.Seek(entry.First(), entry.First())) { assertTrue(seek.Next()); assertArrayEquals(entry.First().Bytes, seek.get().key().bytes); assertArrayEquals(entry.Other().Bytes, seek.get().value().bytes); assertFalse(seek.Next()); } } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Test public void shouldFindMultipleNodesInEachRange() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldFindMultipleNodesInEachRange() { // GIVEN GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree)); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor = mock(typeof(RawCursor)); when(cursor.Next()).thenReturn(true, true, true, false); when(cursor.get()).thenReturn(Hit(0, 0b1000_1000__1100_0010L), Hit(1, 0b0000_0010__0000_1000L), Hit(3, 0b0010_0000__1010_0001L), null); when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor); using (NativeLabelScanReader reader = new NativeLabelScanReader(index)) { // WHEN LongIterator iterator = reader.NodesWithLabel(LABEL_ID); // THEN assertArrayEquals(new long[] { 1, 6, 7, 11, 15, 64 + 3, 64 + 9, 192 + 0, 192 + 5, 192 + 7, 192 + 13 }, asArray(iterator)); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldStartFromGivenId() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldStartFromGivenId() { // given GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree)); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor = mock(typeof(RawCursor)); when(cursor.Next()).thenReturn(true, true, false); when(cursor.get()).thenReturn(Hit(1, 0b0001_1000__0101_1110L), Hit(3, 0b0010_0000__1010_0001L), null); when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor); // when long fromId = LabelScanValue.RangeSize + 3; using (NativeLabelScanReader reader = new NativeLabelScanReader(index), PrimitiveLongResourceIterator iterator = reader.NodesWithAnyOfLabels(fromId, LABEL_ID)) { // then assertArrayEquals(new long[] { 64 + 4, 64 + 6, 64 + 11, 64 + 12, 192 + 0, 192 + 5, 192 + 7, 192 + 13 }, asArray(iterator)); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSeeSimpleInsertions() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSeeSimpleInsertions() { using (GBPTree <KEY, VALUE> index = index()) { int count = 1000; using (Writer <KEY, VALUE> writer = index.Writer()) { for (int i = 0; i < count; i++) { writer.Put(Key(i), Value(i)); } } using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(0), Key(long.MaxValue))) { for (int i = 0; i < count; i++) { assertTrue(cursor.Next()); AssertEqualsKey(Key(i), cursor.get().key()); } assertFalse(cursor.Next()); } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSupportMultipleOpenCursorsConcurrently() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSupportMultipleOpenCursorsConcurrently() { // GIVEN GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree)); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor1 = mock(typeof(RawCursor)); when(cursor1.Next()).thenReturn(false); RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor2 = mock(typeof(RawCursor)); when(cursor2.Next()).thenReturn(false); when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor1, cursor2); // WHEN using (NativeLabelScanReader reader = new NativeLabelScanReader(index)) { // first check test invariants verify(cursor1, never()).close(); verify(cursor2, never()).close(); LongIterator first = reader.NodesWithLabel(LABEL_ID); LongIterator second = reader.NodesWithLabel(LABEL_ID); // getting the second iterator should not have closed the first one verify(cursor1, never()).close(); verify(cursor2, never()).close(); // exhausting the first one should have closed only the first one Exhaust(first); verify(cursor1, times(1)).close(); verify(cursor2, never()).close(); // exhausting the second one should close it Exhaust(second); verify(cursor1, times(1)).close(); verify(cursor2, times(1)).close(); } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: static void verify(org.neo4j.storageengine.api.NodePropertyAccessor nodePropertyAccessor, IndexLayout<SpatialIndexKey,NativeIndexValue> layout, org.neo4j.index.internal.gbptree.GBPTree<SpatialIndexKey,NativeIndexValue> tree, org.neo4j.storageengine.api.schema.StoreIndexDescriptor descriptor) throws org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException internal static void Verify(NodePropertyAccessor nodePropertyAccessor, IndexLayout <SpatialIndexKey, NativeIndexValue> layout, GBPTree <SpatialIndexKey, NativeIndexValue> tree, StoreIndexDescriptor descriptor) { SpatialIndexKey from = layout.newKey(); SpatialIndexKey to = layout.newKey(); InitializeKeys(from, to); try { using (RawCursor <Hit <SpatialIndexKey, NativeIndexValue>, IOException> seek = tree.Seek(from, to)) { ScanAndVerifyDuplicates(nodePropertyAccessor, descriptor, seek); } } catch (IOException e) { throw new UncheckedIOException(e); } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public void verifyContent(java.io.File storeFile) throws java.io.IOException public override void VerifyContent( File storeFile ) { PageCache pageCache = _pageCacheRule.getPageCache( GlobalFs.get() ); using ( GBPTree<MutableLong, MutableLong> tree = ( new GBPTreeBuilder<MutableLong, MutableLong>( pageCache, storeFile, Layout ) ).build() ) { { // WHEN reading from the tree // THEN initial keys should be there tree.ConsistencyCheck(); using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( long.MaxValue ) ) ) { foreach ( long? expectedKey in _initialKeys ) { AssertHit( cursor, expectedKey ); } assertFalse( cursor.Next() ); } } { // WHEN writing more to the tree // THEN we should not see any format conflicts using ( Writer<MutableLong, MutableLong> writer = tree.Writer() ) { while ( _keysToAdd.Count > 0 ) { int next = _random.Next( _keysToAdd.Count ); Put( writer, _keysToAdd[next] ); _keysToAdd.RemoveAt( next ); } } } { // WHEN reading from the tree again // THEN all keys including newly added should be there tree.ConsistencyCheck(); using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( 2 * INITIAL_KEY_COUNT ) ) ) { foreach ( long? expectedKey in _allKeys ) { AssertHit( cursor, expectedKey ); } assertFalse( cursor.Next() ); } } { // WHEN randomly removing half of tree content // THEN we should not see any format conflicts using ( Writer<MutableLong, MutableLong> writer = tree.Writer() ) { int size = _allKeys.Count; while ( _allKeys.Count > size / 2 ) { int next = _random.Next( _allKeys.Count ); MutableLong key = Layout.key( _allKeys[next] ); writer.Remove( key ); _allKeys.RemoveAt( next ); } } } { // WHEN reading from the tree after remove // THEN we should see everything that is left in the tree tree.ConsistencyCheck(); using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( 2 * INITIAL_KEY_COUNT ) ) ) { foreach ( long? expectedKey in _allKeys ) { AssertHit( cursor, expectedKey ); } assertFalse( cursor.Next() ); } } } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private void doShouldRecoverFromAnything(boolean replayRecoveryExactlyFromCheckpoint) throws Exception private void DoShouldRecoverFromAnything(bool replayRecoveryExactlyFromCheckpoint) { AssertInitialized(); // GIVEN // a tree which has had random updates and checkpoints in it, load generated with specific seed File file = _directory.file("index"); IList <Action> load = GenerateLoad(); IList <Action> shuffledLoad = RandomCausalAwareShuffle(load); int lastCheckPointIndex = IndexOfLastCheckpoint(load); { // _,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_ // ^ ^ // | |------------ crash flush index // |-------------------------- last checkpoint index // PageCache pageCache = CreatePageCache(); GBPTree <KEY, VALUE> index = CreateIndex(pageCache, file); // Execute all actions up to and including last checkpoint ... Execute(shuffledLoad.subList(0, lastCheckPointIndex + 1), index); // ... a random amount of the remaining "unsafe" actions ... int numberOfRemainingActions = shuffledLoad.Count - lastCheckPointIndex - 1; int crashFlushIndex = lastCheckPointIndex + _random.Next(numberOfRemainingActions) + 1; Execute(shuffledLoad.subList(lastCheckPointIndex + 1, crashFlushIndex), index); // ... flush ... pageCache.FlushAndForce(); // ... execute the remaining actions Execute(shuffledLoad.subList(crashFlushIndex, shuffledLoad.Count), index); // ... and finally crash _fs.snapshot(throwing(() => { index.Dispose(); pageCache.Close(); })); } // WHEN doing recovery IList <Action> recoveryActions; if (replayRecoveryExactlyFromCheckpoint) { recoveryActions = recoveryActions(load, lastCheckPointIndex + 1); } else { recoveryActions = recoveryActions(load, _random.Next(lastCheckPointIndex + 1)); } // first crashing during recovery int numberOfCrashesDuringRecovery = _random.intBetween(0, 3); for (int i = 0; i < numberOfCrashesDuringRecovery; i++) { using (PageCache pageCache = CreatePageCache(), GBPTree <KEY, VALUE> index = CreateIndex(pageCache, file)) { int numberOfActionsToRecoverBeforeCrashing = _random.intBetween(1, recoveryActions.Count); Recover(recoveryActions.subList(0, numberOfActionsToRecoverBeforeCrashing), index); // ... crash } } // to finally apply all actions after last checkpoint and verify tree using (PageCache pageCache = CreatePageCache(), GBPTree <KEY, VALUE> index = CreateIndex(pageCache, file)) { Recover(recoveryActions, index); // THEN // we should end up with a consistent index containing all the stuff load says index.ConsistencyCheck(); long[] aggregate = ExpectedSortedAggregatedDataFromGeneratedLoad(load); using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(long.MinValue), Key(long.MaxValue))) { for (int i = 0; i < aggregate.Length;) { assertTrue(cursor.Next()); Hit <KEY, VALUE> hit = cursor.get(); AssertEqualsKey(Key(aggregate[i++]), hit.Key()); AssertEqualsValue(Value(aggregate[i++]), hit.Value()); } assertFalse(cursor.Next()); } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldStayCorrectAfterRandomModifications() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldStayCorrectAfterRandomModifications() { // GIVEN using (GBPTree <KEY, VALUE> index = CreateIndex()) { IComparer <KEY> keyComparator = _layout; IDictionary <KEY, VALUE> data = new SortedDictionary <KEY, VALUE>(keyComparator); int count = 100; int totalNumberOfRounds = 10; for (int i = 0; i < count; i++) { data[RandomKey(Random.random())] = RandomValue(Random.random()); } // WHEN using (Writer <KEY, VALUE> writer = CreateWriter(index)) { foreach (KeyValuePair <KEY, VALUE> entry in data.SetOfKeyValuePairs()) { writer.Put(entry.Key, entry.Value); } } for (int round = 0; round < totalNumberOfRounds; round++) { // THEN for (int i = 0; i < count; i++) { KEY first = RandomKey(Random.random()); KEY second = RandomKey(Random.random()); KEY from; KEY to; if (_layout.keySeed(first) < _layout.keySeed(second)) { from = first; to = second; } else { from = second; to = first; } IDictionary <KEY, VALUE> expectedHits = expectedHits(data, from, to, keyComparator); using (RawCursor <Hit <KEY, VALUE>, IOException> result = index.Seek(from, to)) { while (result.Next()) { KEY key = result.get().key(); if (expectedHits.Remove(key) == null) { fail("Unexpected hit " + key + " when searching for " + from + " - " + to); } assertTrue(keyComparator.Compare(key, from) >= 0); if (keyComparator.Compare(from, to) != 0) { assertTrue(keyComparator.Compare(key, to) < 0); } } if (expectedHits.Count > 0) { fail("There were results which were expected to be returned, but weren't:" + expectedHits + " when searching range " + from + " - " + to); } } } index.Checkpoint(Org.Neo4j.Io.pagecache.IOLimiter_Fields.Unlimited); RandomlyModifyIndex(index, data, Random.random(), (double)round / totalNumberOfRounds); } // and finally index.ConsistencyCheck(); } }