All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.stratosphere.core.testing.TestPlan Maven / Gradle / Ivy

The newest version!
/***********************************************************************************************************************
 *
 * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 **********************************************************************************************************************/

package eu.stratosphere.core.testing;

import java.util.Collection;

import eu.stratosphere.api.common.operators.GenericDataSink;
import eu.stratosphere.api.common.operators.GenericDataSource;
import eu.stratosphere.api.common.operators.Operator;
import eu.stratosphere.types.Record;
import eu.stratosphere.types.Value;

/**
 * The primary resource to test one or more implemented PACT stubs. It is
 * created in a unit tests and performs the following operations.
 * 
    *
  • Adds {@link GenericDataSource}s and {@link GenericDataSink}s if not explicitly specified, *
  • locally runs the PACT stubs, *
  • checks the results against the pairs as specified in {@link #getExpectedOutput(Class, Class...)}, and *
  • provides comfortable access to the results with {@link #getActualOutput()}.
    *
*
* The typical usage is inside a unit test. And might look like one of the * following examples.
*
* Test complete plan
*
 *    // build plan
 *    GenericDataSource<Key, Value> source = ...;
 *    MapOperator<Key, Value, Key, Value> map = new MapOperator<Key, Value, Key, Value>(IdentityMap.class, "Map");
 *    map.setInput(source);    
 *    GenericDataSink<Key, Value> output = ...;
 *    output.setInput(map);
 *    // configure test
 *    TestPlan testPlan = new TestPlan(output);
 *    testPlan.getExpectedOutput(output).fromFile(...);
 *    testPlan.run();
 * 
Test plan with ad-hoc source and sink
*
 *    // build plan
 *    MapOperator<Key, Value, Key, Value> map = new MapOperator<Key, Value, Key, Value>(IdentityMap.class, "Map");
 *    // configure test
 *    TestPlan testPlan = new TestPlan(map);
 *    testPlan.getInput().add(pair1).add(pair2).add(pair3);
 *    testPlan.getExpectedOutput(output).add(pair1).add(pair2).add(pair3);
 *    testPlan.run();
 * 
Access ad-hoc source and sink of Testplan
*
 *    // build plan
 *    MapOperator<Key, Value, Key, Value> map = new MapOperator<Key, Value, Key, Value>(IdentityMap.class, "Map");
 *    // configure test
 *    TestPlan testPlan = new TestPlan(map);
 *    testPlan.getInput().add(randomInput1).add(randomInput2).add(randomInput3);
 *    testPlan.run();
 *    // custom assertions
 *    Assert.assertEquals(testPlan.getInput(), testPlan.getOutput());
 * 

*/ public class TestPlan extends GenericTestPlan { /** * Initializes TestPlan for the given contracts. Sinks and Sources are automatically added in case the contracts are * not already fully connected. */ @SuppressWarnings("unchecked") public TestPlan(final Collection contracts) { super(TestRecords.getRecordConfig(new Class[0]), contracts); } /** * Initializes TestPlan for the given contracts. Sinks and Sources are automatically added in case the contracts are * not already fully connected. */ @SuppressWarnings("unchecked") public TestPlan(final Operator... contracts) { super(TestRecords.getRecordConfig(new Class[0]), contracts); } /** * Returns the first actual output {@link TestRecords} with the given schema of the TestPlan. * * @return the first actual output {@link TestRecords} of the TestPlan */ public TestRecords getActualOutput(final Class[] schema) { return this.getActualOutput(TestRecords.getRecordConfig(schema)); } /** * Returns the expected output {@link TestRecords} with the given schema of the TestPlan * associated with the given sink. This is the recommended method to set expected * output records for more complex TestPlans. * * @return the expected output {@link TestRecords} of the TestPlan associated * with the given sink */ public TestRecords getExpectedOutput(final Class values, final Class... additionalFields) { return this.getExpectedOutput(TestRecords.getRecordConfig(SchemaUtils.combineSchema(values, additionalFields))); } /** * Returns the expected output {@link TestRecords} with the given schema of the TestPlan * associated with the given sink. This is the recommended method to set expected * output records for more complex TestPlans. * * @param sink * the sink of which the associated expected output TestRecords * should be returned * @return the expected output {@link TestRecords} of the TestPlan associated * with the given sink */ public TestRecords getExpectedOutput(final GenericDataSink sink, final Class[] schema) { return this.getExpectedOutput(sink, TestRecords.getRecordConfig(schema)); } /** * Returns the expected output {@link TestRecords} with the given schema of the TestPlan * associated with the given sink. This is the recommended method to set expected * output records for more complex TestPlans. * * @param sink * the sink of which the associated expected output TestRecords * should be returned * @return the expected output {@link TestRecords} of the TestPlan associated * with the given sink */ public TestRecords getExpectedOutput(final int sink, final Class[] schema) { return this.getExpectedOutput(sink, TestRecords.getRecordConfig(schema)); } /** * Returns the schema. * * @return the schema */ public Class[] getSchema() { return ((RecordEqualer) this.getDefaultConfig().getEqualer()).getSchema(); } /* * (non-Javadoc) * @see eu.stratosphere.core.testing.GenericTestPlan#run() */ @Override public void run() { this.inferSchemaOfAdhocInputs(); super.run(); } /** * Sets the default schema of all input and outputs. */ public void setSchema(final Class firstField, final Class... additionalFields) { this.setSchema(SchemaUtils.combineSchema(firstField, additionalFields)); } /** * Sets the default schema of all input and outputs. * * @param schema * the schema to set */ public void setSchema(final Class[] schema) { if (schema == null) throw new NullPointerException("schema must not be null"); this.setDefaultConfig(TestRecords.getRecordConfig(schema)); } /** * Sets the default schema of all input and outputs. */ public TestPlan withSchema(final Class firstField, final Class... additionalFields) { this.setSchema(SchemaUtils.combineSchema(firstField, additionalFields)); return this; } /** * Sets the default schema of all input and outputs. * * @param schema * the schema to set */ public TestPlan withSchema(final Class[] schema) { this.setSchema(schema); return this; } /* * (non-Javadoc) * @see eu.stratosphere.core.testing.GenericTestPlan#createTestRecords(eu.stratosphere.core.testing.TypeConfig) */ @Override protected TestRecords createTestRecords(final TypeConfig typeConfig) { return new TestRecords(typeConfig); } /** * */ private void inferSchemaOfAdhocInputs() { for (final GenericDataSource source : this.getSources()) { final TestRecords input = this.getInput(source); if (input.isAdhoc() && input.getTypeConfig() == null) input.inferTypeConfig(); } } }