1 /* 2 * Copyright (C) 2017 The Android Open Source Project 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.android.internal.util; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNull; 21 import static org.junit.Assert.fail; 22 23 import android.support.test.filters.SmallTest; 24 import android.support.test.runner.AndroidJUnit4; 25 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 import java.util.Arrays; 29 import java.util.Objects; 30 31 32 @SmallTest 33 @RunWith(AndroidJUnit4.class) 34 public class RingBufferTest { 35 36 @Test testEmptyRingBuffer()37 public void testEmptyRingBuffer() { 38 RingBuffer<String> buffer = new RingBuffer<>(String.class, 100); 39 40 assertArraysEqual(new String[0], buffer.toArray()); 41 } 42 43 @Test testIncorrectConstructorArguments()44 public void testIncorrectConstructorArguments() { 45 try { 46 RingBuffer<String> buffer = new RingBuffer<>(String.class, -10); 47 fail("Should not be able to create a negative capacity RingBuffer"); 48 } catch (IllegalArgumentException expected) { 49 } 50 51 try { 52 RingBuffer<String> buffer = new RingBuffer<>(String.class, 0); 53 fail("Should not be able to create a 0 capacity RingBuffer"); 54 } catch (IllegalArgumentException expected) { 55 } 56 } 57 58 @Test testRingBufferWithNoWrapping()59 public void testRingBufferWithNoWrapping() { 60 RingBuffer<String> buffer = new RingBuffer<>(String.class, 100); 61 62 buffer.append("a"); 63 buffer.append("b"); 64 buffer.append("c"); 65 buffer.append("d"); 66 buffer.append("e"); 67 68 String[] expected = {"a", "b", "c", "d", "e"}; 69 assertArraysEqual(expected, buffer.toArray()); 70 } 71 72 @Test testRingBufferWithCapacity1()73 public void testRingBufferWithCapacity1() { 74 RingBuffer<String> buffer = new RingBuffer<>(String.class, 1); 75 76 buffer.append("a"); 77 assertArraysEqual(new String[]{"a"}, buffer.toArray()); 78 79 buffer.append("b"); 80 assertArraysEqual(new String[]{"b"}, buffer.toArray()); 81 82 buffer.append("c"); 83 assertArraysEqual(new String[]{"c"}, buffer.toArray()); 84 85 buffer.append("d"); 86 assertArraysEqual(new String[]{"d"}, buffer.toArray()); 87 88 buffer.append("e"); 89 assertArraysEqual(new String[]{"e"}, buffer.toArray()); 90 } 91 92 @Test testRingBufferWithWrapping()93 public void testRingBufferWithWrapping() { 94 int capacity = 100; 95 RingBuffer<String> buffer = new RingBuffer<>(String.class, capacity); 96 97 buffer.append("a"); 98 buffer.append("b"); 99 buffer.append("c"); 100 buffer.append("d"); 101 buffer.append("e"); 102 103 String[] expected1 = {"a", "b", "c", "d", "e"}; 104 assertArraysEqual(expected1, buffer.toArray()); 105 106 String[] expected2 = new String[capacity]; 107 int firstIndex = 0; 108 int lastIndex = capacity - 1; 109 110 expected2[firstIndex] = "e"; 111 for (int i = 1; i < capacity; i++) { 112 buffer.append("x"); 113 expected2[i] = "x"; 114 } 115 assertArraysEqual(expected2, buffer.toArray()); 116 117 buffer.append("x"); 118 expected2[firstIndex] = "x"; 119 assertArraysEqual(expected2, buffer.toArray()); 120 121 for (int i = 0; i < 10; i++) { 122 for (String s : expected2) { 123 buffer.append(s); 124 } 125 } 126 assertArraysEqual(expected2, buffer.toArray()); 127 128 buffer.append("a"); 129 expected2[lastIndex] = "a"; 130 assertArraysEqual(expected2, buffer.toArray()); 131 } 132 133 @Test testGetNextSlot()134 public void testGetNextSlot() { 135 int capacity = 100; 136 RingBuffer<DummyClass1> buffer = new RingBuffer<>(DummyClass1.class, capacity); 137 138 final DummyClass1[] actual = new DummyClass1[capacity]; 139 final DummyClass1[] expected = new DummyClass1[capacity]; 140 for (int i = 0; i < capacity; ++i) { 141 final DummyClass1 obj = buffer.getNextSlot(); 142 obj.x = capacity * i; 143 actual[i] = obj; 144 expected[i] = new DummyClass1(); 145 expected[i].x = capacity * i; 146 } 147 assertArraysEqual(expected, buffer.toArray()); 148 149 for (int i = 0; i < capacity; ++i) { 150 if (actual[i] != buffer.getNextSlot()) { 151 fail("getNextSlot() should re-use objects if available"); 152 } 153 } 154 155 RingBuffer<DummyClass2> buffer2 = new RingBuffer<>(DummyClass2.class, capacity); 156 assertNull("getNextSlot() should return null if the object can't be initiated " 157 + "(No nullary constructor)", buffer2.getNextSlot()); 158 159 RingBuffer<DummyClass3> buffer3 = new RingBuffer<>(DummyClass3.class, capacity); 160 assertNull("getNextSlot() should return null if the object can't be initiated " 161 + "(Inaccessible class)", buffer3.getNextSlot()); 162 } 163 164 public static final class DummyClass1 { 165 int x; 166 equals(Object o)167 public boolean equals(Object o) { 168 if (o instanceof DummyClass1) { 169 final DummyClass1 other = (DummyClass1) o; 170 return other.x == this.x; 171 } 172 return false; 173 } 174 } 175 176 public static final class DummyClass2 { DummyClass2(int x)177 public DummyClass2(int x) {} 178 } 179 180 private static final class DummyClass3 {} 181 assertArraysEqual(T[] expected, T[] got)182 static <T> void assertArraysEqual(T[] expected, T[] got) { 183 if (expected.length != got.length) { 184 fail(Arrays.toString(expected) + " and " + Arrays.toString(got) 185 + " did not have the same length"); 186 } 187 188 for (int i = 0; i < expected.length; i++) { 189 if (!Objects.equals(expected[i], got[i])) { 190 fail(Arrays.toString(expected) + " and " + Arrays.toString(got) 191 + " were not equal"); 192 } 193 } 194 } 195 } 196