1 /* 2 * Copyright 2015 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.cloud; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static junit.framework.TestCase.assertFalse; 21 import static junit.framework.TestCase.assertTrue; 22 import static org.junit.Assert.assertArrayEquals; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertNull; 25 26 import com.google.cloud.spi.ServiceRpcFactory; 27 import java.io.IOException; 28 import java.io.Serializable; 29 import java.nio.ByteBuffer; 30 import java.nio.channels.ClosedChannelException; 31 import java.util.Arrays; 32 import java.util.Random; 33 import org.junit.Before; 34 import org.junit.Test; 35 36 public class BaseWriteChannelTest { 37 38 private abstract static class CustomService implements Service<CustomServiceOptions> {} 39 40 private abstract static class CustomServiceOptions 41 extends ServiceOptions<CustomService, CustomServiceOptions> { 42 43 private static final long serialVersionUID = 3302358029307467197L; 44 CustomServiceOptions( Class<? extends ServiceFactory<CustomService, CustomServiceOptions>> serviceFactoryClass, Class<? extends ServiceRpcFactory<CustomServiceOptions>> rpcFactoryClass, Builder<CustomService, CustomServiceOptions, ?> builder)45 protected CustomServiceOptions( 46 Class<? extends ServiceFactory<CustomService, CustomServiceOptions>> serviceFactoryClass, 47 Class<? extends ServiceRpcFactory<CustomServiceOptions>> rpcFactoryClass, 48 Builder<CustomService, CustomServiceOptions, ?> builder) { 49 super(serviceFactoryClass, rpcFactoryClass, builder, null); 50 } 51 } 52 53 private static final Serializable ENTITY = 42L; 54 private static final String UPLOAD_ID = "uploadId"; 55 private static final byte[] CONTENT = {0xD, 0xE, 0xA, 0xD}; 56 private static final int MIN_CHUNK_SIZE = 256 * 1024; // 256 KiB 57 private static final int DEFAULT_CHUNK_SIZE = 60 * MIN_CHUNK_SIZE; // 15MiB 58 private static final Random RANDOM = new Random(); 59 private static BaseWriteChannel channel; 60 61 @Before setUp()62 public void setUp() { 63 channel = 64 new BaseWriteChannel<CustomServiceOptions, Serializable>(null, ENTITY, UPLOAD_ID) { 65 @Override 66 public RestorableState<WriteChannel> capture() { 67 return null; 68 } 69 70 @Override 71 protected void flushBuffer(int length, boolean last) {} 72 73 @Override 74 protected BaseState.Builder<CustomServiceOptions, Serializable> stateBuilder() { 75 return null; 76 } 77 }; 78 } 79 80 @Test testConstructor()81 public void testConstructor() { 82 assertEquals(null, channel.getOptions()); 83 assertEquals(ENTITY, channel.getEntity()); 84 assertEquals(0, channel.getPosition()); 85 assertEquals(UPLOAD_ID, channel.getUploadId()); 86 assertEquals(0, channel.getLimit()); 87 assertTrue(channel.isOpen()); 88 assertArrayEquals(new byte[0], channel.getBuffer()); 89 assertEquals(DEFAULT_CHUNK_SIZE, channel.getChunkSize()); 90 } 91 92 @Test testClose()93 public void testClose() throws IOException { 94 channel.close(); 95 assertFalse(channel.isOpen()); 96 assertNull(channel.getBuffer()); 97 } 98 99 @Test(expected = ClosedChannelException.class) testValidateOpen()100 public void testValidateOpen() throws IOException { 101 channel.close(); 102 channel.write(ByteBuffer.allocate(42)); 103 } 104 105 @Test testChunkSize()106 public void testChunkSize() { 107 channel.setChunkSize(42); 108 assertThat(channel.getChunkSize() >= MIN_CHUNK_SIZE).isTrue(); 109 assertThat(channel.getChunkSize() % MIN_CHUNK_SIZE).isEqualTo(0); 110 111 channel.setChunkSize(2 * MIN_CHUNK_SIZE); 112 assertThat(channel.getChunkSize() >= MIN_CHUNK_SIZE).isTrue(); 113 assertThat(channel.getChunkSize() % MIN_CHUNK_SIZE).isEqualTo(0); 114 115 channel.setChunkSize(2 * MIN_CHUNK_SIZE + 1); 116 assertThat(channel.getChunkSize() >= MIN_CHUNK_SIZE).isTrue(); 117 assertThat(channel.getChunkSize() % MIN_CHUNK_SIZE).isEqualTo(0); 118 } 119 120 @Test testWrite()121 public void testWrite() throws IOException { 122 channel.write(ByteBuffer.wrap(CONTENT)); 123 assertEquals(CONTENT.length, channel.getLimit()); 124 assertEquals(DEFAULT_CHUNK_SIZE, channel.getBuffer().length); 125 assertArrayEquals(Arrays.copyOf(CONTENT, DEFAULT_CHUNK_SIZE), channel.getBuffer()); 126 } 127 128 @Test testWriteAndFlush()129 public void testWriteAndFlush() throws IOException { 130 ByteBuffer content = randomBuffer(DEFAULT_CHUNK_SIZE + 1); 131 channel.write(content); 132 assertEquals(DEFAULT_CHUNK_SIZE, channel.getPosition()); 133 assertEquals(1, channel.getLimit()); 134 byte[] newContent = new byte[DEFAULT_CHUNK_SIZE]; 135 newContent[0] = content.get(DEFAULT_CHUNK_SIZE); 136 assertArrayEquals(newContent, channel.getBuffer()); 137 } 138 randomBuffer(int size)139 private static ByteBuffer randomBuffer(int size) { 140 byte[] byteArray = new byte[size]; 141 RANDOM.nextBytes(byteArray); 142 return ByteBuffer.wrap(byteArray); 143 } 144 } 145