This project has retired. For details please refer to its Attic page.
TestGraphUtils 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.test_setup;
19  
20  import org.apache.giraph.block_app.framework.BlockUtils;
21  import org.apache.giraph.conf.BulkConfigurator;
22  import org.apache.giraph.block_app.framework.api.local.LocalBlockRunner;
23  import org.apache.giraph.conf.BooleanConfOption;
24  import org.apache.giraph.conf.GiraphConfiguration;
25  import org.apache.giraph.function.Supplier;
26  import org.apache.hadoop.io.DoubleWritable;
27  import org.apache.hadoop.io.NullWritable;
28  import org.apache.hadoop.io.Writable;
29  import org.apache.hadoop.io.WritableComparable;
30  
31  /**
32   * Utility functions for running TestGraph unit tests.
33   */
34  public class TestGraphUtils {
35    /** modify locally for running full Digraph tests from IDE */
36    public static final
37    BooleanConfOption USE_FULL_GIRAPH_ENV_IN_TESTS = new BooleanConfOption(
38        "giraph.blocks.test_setup.use_full_giraph_env_in_tests", false,
39        "Whether to use full giraph environemnt for tests, " +
40        "or only local implementation");
41  
42    // if you want to check stability of the test and make sure it passes always
43    // test it with larger number, like ~10.
44    private static int TEST_REPEAT_TIMES = 1;
45  
46    private TestGraphUtils() { }
47  
48    /**
49     * Creates configuration using configurator, initializes the graph using
50     * graphInitializer, and checks it via graphChecker.
51     *
52     * Supports using TEST_REPEAT_TIMES for running the same test multiple times.
53     */
54    public static
55    <I extends WritableComparable, V extends Writable, E extends Writable>
56    void runTest(
57        final TestGraphModifier<? super I, ? super V, ? super E> graphInitializer,
58        final TestGraphChecker<? super I, ? super V, ? super E> graphChecker,
59        final BulkConfigurator configurator) throws Exception {
60      repeat(
61          repeatTimes(),
62          new OneTest() {
63            @Override
64            public void test() throws Exception {
65              GiraphConfiguration conf = new GiraphConfiguration();
66              configurator.configure(conf);
67              BlockUtils.initAndCheckConfig(conf);
68              runTest(graphInitializer, graphChecker, conf);
69            }
70          });
71    }
72  
73    /**
74     * Uses provided configuration, initializes the graph using
75     * graphInitializer, and checks it via graphChecker.
76     */
77    public static
78    <I extends WritableComparable, E extends Writable, V extends Writable>
79    void runTest(
80        TestGraphModifier<? super I, ? super V, ? super E> graphInitializer,
81        TestGraphChecker<? super I, ? super V, ? super E> graphChecker,
82        GiraphConfiguration conf) throws Exception {
83      NumericTestGraph<I, V, E> graph = new NumericTestGraph<>(conf);
84      graphInitializer.modifyGraph((NumericTestGraph) graph);
85      runTest(graph, graphChecker);
86    }
87  
88    /**
89     * Base of runTest. Takes a created graph, a graph-checker and conf and runs
90     * the test.
91     */
92    public static
93    <I extends WritableComparable, E extends Writable, V extends Writable>
94    void runTest(
95        NumericTestGraph<I, V, E> graph,
96        TestGraphChecker<? super I, ? super V, ? super E> graphChecker
97    ) throws Exception {
98      graph = new NumericTestGraph<I, V, E>(
99        LocalBlockRunner.runApp(
100           graph.getTestGraph(), useFullDigraphTests(graph.getConf())));
101     if (graphChecker != null) {
102       graphChecker.checkOutput((NumericTestGraph) graph);
103     }
104   }
105 
106   /**
107    * Chain execution of multiple TestGraphModifier into one.
108    */
109   @SafeVarargs
110   public static
111   <I extends WritableComparable, V extends Writable, E extends Writable>
112   TestGraphModifier<I, V, E> chainModifiers(
113           final TestGraphModifier<I, V, E>... graphModifiers) {
114     return new TestGraphModifier<I, V, E>() {
115       @Override
116       public void modifyGraph(
117           NumericTestGraph<I, V, E> graph) {
118         for (TestGraphModifier<I, V, E> graphModifier : graphModifiers) {
119           graphModifier.modifyGraph(graph);
120         }
121       }
122     };
123   }
124 
125   /**
126    * Chain execution of multiple BulkConfigurators into one.
127    *
128    * Order might matter, if they are setting the same fields.
129    * (later one will override what previous one already set).
130    */
131   public static BulkConfigurator chainConfigurators(
132       final BulkConfigurator... configurators) {
133     return new BulkConfigurator() {
134       @Override
135       public void configure(GiraphConfiguration conf) {
136         for (BulkConfigurator configurator : configurators) {
137           configurator.configure(conf);
138         }
139       }
140     };
141   }
142 
143 
144   public static Supplier<DoubleWritable> doubleSupplier(final double value) {
145     return new Supplier<DoubleWritable>() {
146       @Override
147       public DoubleWritable get() {
148         return new DoubleWritable(value);
149       }
150     };
151   }
152 
153   public static Supplier<NullWritable> nullSupplier() {
154     return new Supplier<NullWritable>() {
155       @Override
156       public NullWritable get() {
157         return NullWritable.get();
158       }
159     };
160   }
161 
162   /** Interface for running a single test that can throw an exception */
163   interface OneTest {
164     void test() throws Exception;
165   }
166 
167   private static void repeat(int times, OneTest test) throws Exception {
168     if (times == 1) {
169       test.test();
170     } else {
171       int failures = 0;
172       StringBuilder failureMsgs = new StringBuilder();
173       AssertionError firstError = null;
174       for (int i = 0; i < times; i++) {
175         try {
176           test.test();
177         } catch (AssertionError error) {
178           failures++;
179           failureMsgs.append("\n").append(error.getMessage());
180           if (firstError == null) {
181             firstError = error;
182           }
183         }
184       }
185 
186       if (failures > 0) {
187         throw new AssertionError(
188             "Failed " + failures + " times out of " + times +
189             " runs, messages: " + failureMsgs,
190             firstError);
191       }
192     }
193   }
194 
195   private static boolean useFullDigraphTests(GiraphConfiguration conf) {
196     return USE_FULL_GIRAPH_ENV_IN_TESTS.get(conf) ||
197         System.getProperty("test_setup.UseFullGiraphEnvInTests") != null;
198   }
199 
200   private static int repeatTimes() {
201     String value = System.getProperty("test_setup.TestRepeatTimes");
202     return value != null ? Integer.parseInt(value) : TEST_REPEAT_TIMES;
203   }
204 
205   public static void setTestRepeatTimes(int testRepeatTimes) {
206     TestGraphUtils.TEST_REPEAT_TIMES = testRepeatTimes;
207   }
208 }