/* * Copyright (c) 2002-2017 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.neo4j.driver.internal.net; import org.hamcrest.MatcherAssert; import org.junit.Test; import org.neo4j.driver.internal.util.BytePrinter; import org.neo4j.driver.v1.util.RecordingByteChannel; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; public class ChunkedOutputTest { private final RecordingByteChannel channel = new RecordingByteChannel(); private final ChunkedOutput out = new ChunkedOutput( 16, channel ); @Test public void shouldChunkSingleMessage() throws Throwable { // When out.writeByte( (byte) 1 ).writeShort( (short) 2 ); out.messageBoundaryHook().run(); out.flush(); // Then MatcherAssert.assertThat( BytePrinter.hex( channel.getBytes() ), equalTo( "00 03 01 00 02 00 00 " ) ); } @Test public void shouldChunkMessageSpanningMultipleChunks() throws Throwable { // When out.writeLong( 1 ) .writeLong( 2 ) .writeLong( 3 ); out.messageBoundaryHook().run(); out.flush(); // Then assertThat( BytePrinter.hex( channel.getBytes() ), equalTo( String.format( "00 08 00 00 00 00 00 00 00 01 00 08 00 00 00 00 " + "00 00 00 02 00 08 00 00 00 00 00 00 00 03 00 00%n" ) ) ); } @Test public void shouldReserveSpaceForChunkHeaderWhenWriteDataToNewChunk() throws Throwable { // Given 2 bytes left in buffer + chunk is closed out.writeBytes( new byte[10], 0, 10 ); // 2 (header) + 10 out.messageBoundaryHook().run(); // 2 (ending) // When write 2 bytes out.writeShort( (short) 33 ); // 2 (header) + 2 // Then the buffer should auto flash if space left (2) is smaller than new data and chunk header (2 + 2) assertThat( BytePrinter.hex( channel.getBytes() ), equalTo( "00 0a 00 00 00 00 00 00 00 00 00 00 00 00 " ) ); } @Test public void shouldSendOutDataWhoseSizeIsGreaterThanOutputBufferCapacity() throws Throwable { // Given byte[] data = new byte[32]; for ( int i = 0; i < data.length; i++ ) { data[i] = (byte) (i % 128); } // When out.writeBytes( data, 4, 16 ); out.messageBoundaryHook().run(); out.flush(); // Then assertThat( BytePrinter.hex( channel.getBytes() ), equalTo( "00 0c 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 00 " ) ); } }