View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.giraph.block_app.framework.block;
19  
20  import static org.junit.Assert.assertEquals;
21  import it.unimi.dsi.fastutil.ints.IntArrayList;
22  
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.Iterator;
26  import java.util.Random;
27  
28  import org.apache.giraph.block_app.framework.piece.AbstractPiece;
29  
30  import com.google.common.base.Preconditions;
31  import com.google.common.collect.Iterables;
32  
33  @SuppressWarnings({"unchecked", "rawtypes"})
34  public class BlockTestingUtils {
35  
36    BlockTestingUtils() { }
37  
38    private static final int NUM_TRIALS = 10;
39    private static final int REPEAT_TIMES = 10;
40  
41    private static int testSequential(Iterator<? extends AbstractPiece> referenceImpl,
42                                      Iterator<? extends AbstractPiece> testImpl) {
43      int length = 0;
44  
45      CheckIterator checkIterator = new CheckIterator(referenceImpl, testImpl);
46      while (checkIterator.hasNext()) {
47        checkIterator.next();
48        length++;
49      }
50  
51      System.out.println("Length is : " + length);
52      return length;
53    }
54  
55    private static boolean anyHasNext(ArrayList<? extends Iterator> arr) {
56      for (Iterator t : arr) {
57        if (t.hasNext()) {
58          return true;
59        }
60      }
61      return false;
62    }
63  
64    private static void testRandom(int length,
65                                   Iterable<? extends AbstractPiece> referenceImpl,
66                                   Iterable<? extends AbstractPiece> testImpl) {
67      Random rand = new Random();
68  
69      ArrayList<CheckIterator<AbstractPiece>> arr = new ArrayList<>();
70      IntArrayList lengths = new IntArrayList(NUM_TRIALS);
71      for (int i = 0; i < NUM_TRIALS; i++) {
72        lengths.add(0);
73      }
74      for (int i = 0; i < NUM_TRIALS; i++) {
75        arr.add(new CheckIterator(referenceImpl.iterator(), testImpl.iterator()));
76      }
77  
78      int totalCount = 0;
79      while (anyHasNext(arr)) {
80        int index = rand.nextInt(NUM_TRIALS);
81        while (!arr.get(index).hasNext()) {
82          index = rand.nextInt(NUM_TRIALS);
83        }
84        CheckIterator it = arr.get(index);
85        it.next();
86        int itLength = lengths.getInt(index);
87        lengths.set(index, itLength + 1);
88        totalCount++;
89      }
90      assertEquals("TotalCount should be length * NUM_TRIALS", length * NUM_TRIALS, totalCount);
91      System.out.println("Final count is : " + totalCount);
92    }
93  
94    /**
95     * Tests both the length of the iterator returned by the block, as-well as the deterministic behavior
96     * expected by calling .iterator() against the referenceImpl.
97     * @param referenceImpl : A list of pieces in the expected order
98     * @param testImpl : A list of pieces to test against (the Block)
99     */
100   public static void testIndependence(Iterable<? extends AbstractPiece> referenceImpl,
101                                       Iterable<? extends AbstractPiece> testImpl) {
102     int length = testSequential(referenceImpl.iterator(), testImpl.iterator());
103     testRandom(length, referenceImpl, testImpl);
104   }
105 
106   /**
107    * Test how the block interacts with a repeatBlock. The expected result is to
108    * see the pieces in referenceImpl show up REPEAT_TIMES many times.
109    * @param referenceImpl : A list of pieces in the expected order
110    * @param block : The block to test
111    */
112   public static void testNestedRepeatBlock(Iterable<? extends AbstractPiece> referenceImpl, Block block) {
113     Block repeatBlock = new RepeatBlock(
114       REPEAT_TIMES,
115       block
116     );
117     testIndependence(
118             Iterables.concat(Collections.nCopies(REPEAT_TIMES, referenceImpl)),
119             repeatBlock
120     );
121   }
122 
123   public static class CheckIterator<T> implements Iterator {
124 
125     private final Iterator<T> fst;
126     private final Iterator<T> snd;
127 
128     public CheckIterator(Iterator<T> fst, Iterator<T> snd) {
129       this.fst = fst;
130       this.snd = snd;
131     }
132 
133     @Override
134     public boolean hasNext() {
135       boolean fstHasNxt = fst.hasNext();
136       boolean sndHasNxt = snd.hasNext();
137       Preconditions.checkArgument(fstHasNxt == sndHasNxt, "Expect hasNext() on " +
138               "both iterators to be identical. Got: " + fst.hasNext() + " and " + snd.hasNext());
139       return fstHasNxt;
140     }
141 
142     @Override
143     public Object next() {
144       T fstNxt = fst.next();
145       T sndNxt = snd.next();
146       Preconditions.checkArgument(fstNxt == sndNxt, "Expect objs returned by " +
147               "both iterators to be identical. Got: " + fstNxt + " and " + sndNxt);
148       return fstNxt;
149     }
150 
151     @Override
152     public void remove() {
153       throw new RuntimeException("Not implemented");
154     }
155 
156   }
157 
158 }