This project has retired. For details please refer to its Attic page.
BlockTestingUtils xref
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  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.Iterator;
25  import java.util.Random;
26  
27  import org.apache.giraph.block_app.framework.piece.AbstractPiece;
28  
29  import com.google.common.base.Preconditions;
30  import com.google.common.collect.Iterables;
31  
32  import it.unimi.dsi.fastutil.ints.IntArrayList;
33  
34  @SuppressWarnings({"unchecked", "rawtypes"})
35  public class BlockTestingUtils {
36  
37    BlockTestingUtils() { }
38  
39    private static final int NUM_TRIALS = 10;
40    private static final int REPEAT_TIMES = 10;
41  
42    public static int testSequential(
43        Iterable<? extends AbstractPiece> referenceImpl,
44        Iterable<? extends AbstractPiece> testImpl) {
45      int length = 0;
46  
47      CheckIterator checkIterator = new CheckIterator(
48          referenceImpl.iterator(), testImpl.iterator());
49      while (checkIterator.hasNext()) {
50        checkIterator.next();
51        length++;
52      }
53  
54      System.out.println("Length is : " + length);
55      return length;
56    }
57  
58    private static boolean anyHasNext(ArrayList<? extends Iterator> arr) {
59      for (Iterator t : arr) {
60        if (t.hasNext()) {
61          return true;
62        }
63      }
64      return false;
65    }
66  
67    private static void testRandom(int length,
68                                   Iterable<? extends AbstractPiece> referenceImpl,
69                                   Iterable<? extends AbstractPiece> testImpl) {
70      Random rand = new Random();
71  
72      ArrayList<CheckIterator<AbstractPiece>> arr = new ArrayList<>();
73      IntArrayList lengths = new IntArrayList(NUM_TRIALS);
74      for (int i = 0; i < NUM_TRIALS; i++) {
75        lengths.add(0);
76      }
77      for (int i = 0; i < NUM_TRIALS; i++) {
78        arr.add(new CheckIterator(referenceImpl.iterator(), testImpl.iterator()));
79      }
80  
81      int totalCount = 0;
82      while (anyHasNext(arr)) {
83        int index = rand.nextInt(NUM_TRIALS);
84        while (!arr.get(index).hasNext()) {
85          index = rand.nextInt(NUM_TRIALS);
86        }
87        CheckIterator it = arr.get(index);
88        it.next();
89        int itLength = lengths.getInt(index);
90        lengths.set(index, itLength + 1);
91        totalCount++;
92      }
93      assertEquals("TotalCount should be length * NUM_TRIALS", length * NUM_TRIALS, totalCount);
94      System.out.println("Final count is : " + totalCount);
95    }
96  
97    /**
98     * Tests both the length of the iterator returned by the block, as-well as the deterministic behavior
99     * expected by calling .iterator() against the referenceImpl.
100    * @param referenceImpl : A list of pieces in the expected order
101    * @param testImpl : A list of pieces to test against (the Block)
102    */
103   public static void testIndependence(Iterable<? extends AbstractPiece> referenceImpl,
104                                       Iterable<? extends AbstractPiece> testImpl) {
105     int length = testSequential(referenceImpl, testImpl);
106     testRandom(length, referenceImpl, testImpl);
107   }
108 
109   /**
110    * Test how the block interacts with a repeatBlock. The expected result is to
111    * see the pieces in referenceImpl show up REPEAT_TIMES many times.
112    * @param referenceImpl : A list of pieces in the expected order
113    * @param block : The block to test
114    */
115   public static void testNestedRepeatBlock(Iterable<? extends AbstractPiece> referenceImpl, Block block) {
116     Block repeatBlock = new RepeatBlock(
117       REPEAT_TIMES,
118       block
119     );
120     testIndependence(
121             Iterables.concat(Collections.nCopies(REPEAT_TIMES, referenceImpl)),
122             repeatBlock
123     );
124   }
125 
126   public static class CheckIterator<T> implements Iterator {
127 
128     private final Iterator<T> fst;
129     private final Iterator<T> snd;
130 
131     public CheckIterator(Iterator<T> fst, Iterator<T> snd) {
132       this.fst = fst;
133       this.snd = snd;
134     }
135 
136     @Override
137     public boolean hasNext() {
138       boolean fstHasNxt = fst.hasNext();
139       boolean sndHasNxt = snd.hasNext();
140       Preconditions.checkArgument(fstHasNxt == sndHasNxt, "Expect hasNext() on " +
141               "both iterators to be identical. Got: " + fst.hasNext() + " and " + snd.hasNext());
142       return fstHasNxt;
143     }
144 
145     @Override
146     public Object next() {
147       T fstNxt = fst.next();
148       T sndNxt = snd.next();
149       Preconditions.checkArgument(fstNxt == sndNxt, "Expect objs returned by " +
150               "both iterators to be identical. Got: " + fstNxt + " and " + sndNxt);
151       return fstNxt;
152     }
153 
154     @Override
155     public void remove() {
156       throw new RuntimeException("Not implemented");
157     }
158 
159   }
160 
161 }