001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.util;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertTrue;
023import static org.junit.Assert.fail;
024
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Iterator;
028import java.util.List;
029import java.util.NoSuchElementException;
030import org.apache.hadoop.hbase.HBaseClassTestRule;
031import org.apache.hadoop.hbase.testclassification.MiscTests;
032import org.apache.hadoop.hbase.testclassification.SmallTests;
033import org.junit.ClassRule;
034import org.junit.Test;
035import org.junit.experimental.categories.Category;
036
037@Category({MiscTests.class, SmallTests.class})
038public class TestConcatenatedLists {
039
040  @ClassRule
041  public static final HBaseClassTestRule CLASS_RULE =
042      HBaseClassTestRule.forClass(TestConcatenatedLists.class);
043
044  @Test
045  public void testUnsupportedOps() {
046    // If adding support, add tests.
047    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
048    c.addSublist(Arrays.asList(0L, 1L));
049    try {
050      c.add(2L);
051      fail("Should throw");
052    } catch (UnsupportedOperationException ex) {
053    }
054    try {
055      c.addAll(Arrays.asList(2L, 3L));
056      fail("Should throw");
057    } catch (UnsupportedOperationException ex) {
058    }
059    try {
060      c.remove(0L);
061      fail("Should throw");
062    } catch (UnsupportedOperationException ex) {
063    }
064    try {
065      c.removeAll(Arrays.asList(0L, 1L));
066      fail("Should throw");
067    } catch (UnsupportedOperationException ex) {
068    }
069    try {
070      c.clear();
071      fail("Should throw");
072    } catch (UnsupportedOperationException ex) {
073    }
074    try {
075      c.retainAll(Arrays.asList(0L, 2L));
076      fail("Should throw");
077    } catch (UnsupportedOperationException ex) {
078    }
079    Iterator<Long> iter = c.iterator();
080    iter.next();
081    try {
082      iter.remove();
083      fail("Should throw");
084    } catch (UnsupportedOperationException ex) {
085    }
086  }
087
088  @Test
089  public void testEmpty() {
090    verify(new ConcatenatedLists<>(), -1);
091  }
092
093  @Test
094  public void testOneOne() {
095    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
096    c.addSublist(Arrays.asList(0L));
097    verify(c, 0);
098  }
099
100  @Test
101  public void testOneMany() {
102    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
103    c.addSublist(Arrays.asList(0L, 1L, 2L));
104    verify(c, 2);
105  }
106
107  @Test
108  @SuppressWarnings("unchecked")
109  public void testManyOne() {
110    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
111    c.addSublist(Arrays.asList(0L));
112    c.addAllSublists(Arrays.asList(Arrays.asList(1L), Arrays.asList(2L)));
113    verify(c, 2);
114  }
115
116  @Test
117  @SuppressWarnings("unchecked")
118  public void testManyMany() {
119    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
120    c.addAllSublists(Arrays.asList(Arrays.asList(0L, 1L)));
121    c.addSublist(Arrays.asList(2L, 3L, 4L));
122    c.addAllSublists(Arrays.asList(Arrays.asList(5L), Arrays.asList(6L, 7L)));
123    verify(c, 7);
124  }
125
126  @SuppressWarnings("ModifyingCollectionWithItself")
127  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="DMI_VACUOUS_SELF_COLLECTION_CALL",
128    justification="Intended vacuous containsAll call on 'c'")
129  private void verify(ConcatenatedLists<Long> c, int last) {
130    assertEquals((last == -1), c.isEmpty());
131    assertEquals(last + 1, c.size());
132    // This check is O(n^2), test with care
133    assertTrue(c.containsAll(c));
134    Long[] array = c.toArray(new Long[c.size()]);
135    List<Long> all = new ArrayList<>();
136    Iterator<Long> iter = c.iterator();
137    for (Long i = 0L; i <= last; ++i) {
138      assertTrue(iter.hasNext());
139      assertEquals(i, iter.next());
140      assertEquals(i, array[i.intValue()]);
141      assertTrue(c.contains(i));
142      assertTrue(c.containsAll(Arrays.asList(i)));
143      all.add(i);
144    }
145    assertTrue(c.containsAll(all));
146    assertFalse(iter.hasNext());
147    try {
148      iter.next();
149      fail("Should have thrown");
150    } catch (NoSuchElementException nsee) {
151    }
152  }
153}