/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* 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 org.pentaho.di.trans.steps.transexecutor;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaPluginType;
import org.pentaho.di.trans.step.StepIOMetaInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.errorhandling.StreamInterface;
import org.pentaho.di.trans.steps.loadsave.LoadSaveTester;
import org.pentaho.di.trans.steps.loadsave.validator.ArrayLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.FieldLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.IntLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.PrimitiveIntArrayLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.StringLoadSaveValidator;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class TransExecutorMetaTest {
LoadSaveTester loadSaveTester;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
PluginRegistry.addPluginType( ValueMetaPluginType.getInstance() );
PluginRegistry.init( true );
}
@Before
public void setUp() throws Exception {
List<String> attributes =
Arrays.asList( "fileName", "transName", "directoryPath", "groupSize", "groupField", "groupTime",
"executionTimeField", "executionFilesRetrievedField", "executionLogTextField",
"executionLogChannelIdField", "executionResultField", "executionNrErrorsField", "executionLinesReadField",
"executionLinesWrittenField", "executionLinesInputField", "executionLinesOutputField",
"executionLinesRejectedField", "executionLinesUpdatedField", "executionLinesDeletedField",
"executionExitStatusField", "outputRowsField", "outputRowsType", "outputRowsLength",
"outputRowsPrecision" );
// executionResultTargetStepMeta -? (see for switch case meta)
Map<String, String> getterMap = new HashMap<String, String>();
Map<String, String> setterMap = new HashMap<String, String>();
Map<String, FieldLoadSaveValidator<?>> attrValidatorMap = new HashMap<String, FieldLoadSaveValidator<?>>();
FieldLoadSaveValidator<String[]> stringArrayLoadSaveValidator =
new ArrayLoadSaveValidator<String>( new StringLoadSaveValidator(), 1 );
// don't want the random value given by the default getTestObject...
IntLoadSaveValidator intValidator = spy( new IntLoadSaveValidator() );
doReturn( ValueMetaInterface.TYPE_INTEGER ).when( intValidator ).getTestObject();
FieldLoadSaveValidator<int[]> intArrayLoadSaveValidator =
new PrimitiveIntArrayLoadSaveValidator( intValidator, 1 );
attrValidatorMap.put( "outputRowsField", stringArrayLoadSaveValidator );
attrValidatorMap.put( "outputRowsType", intArrayLoadSaveValidator );
attrValidatorMap.put( "outputRowsLength", intArrayLoadSaveValidator );
attrValidatorMap.put( "outputRowsPrecision", intArrayLoadSaveValidator );
Map<String, FieldLoadSaveValidator<?>> typeValidatorMap = new HashMap<String, FieldLoadSaveValidator<?>>();
typeValidatorMap.put( int[].class.getCanonicalName(), new PrimitiveIntArrayLoadSaveValidator(
new IntLoadSaveValidator(), 1 ) );
loadSaveTester =
new LoadSaveTester( TransExecutorMeta.class, attributes, getterMap, setterMap, attrValidatorMap, typeValidatorMap );
}
@Test
public void testSerialization() throws KettleException {
loadSaveTester.testSerialization();
}
@Test
public void firstStreamIsExecutionStatistics() throws Exception {
StreamInterface stream = mockStream();
StepIOMetaInterface stepIo = mockStepIo( stream, 0 );
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
when( meta.getStepIOMeta() ).thenReturn( stepIo );
doCallRealMethod().when( meta ).handleStreamSelection( any( StreamInterface.class ) );
meta.handleStreamSelection( stream );
assertEquals( stream.getStepMeta(), meta.getExecutionResultTargetStepMeta() );
}
@Test
public void secondStreamIsInternalTransformationsOutput() throws Exception {
StreamInterface stream = mockStream();
StepIOMetaInterface stepIo = mockStepIo( stream, 1 );
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
when( meta.getStepIOMeta() ).thenReturn( stepIo );
doCallRealMethod().when( meta ).handleStreamSelection( any( StreamInterface.class ) );
meta.handleStreamSelection( stream );
assertEquals( stream.getStepMeta(), meta.getOutputRowsSourceStepMeta() );
}
@Test
public void thirdStreamIsExecutionResultFiles() throws Exception {
StreamInterface stream = mockStream();
StepIOMetaInterface stepIo = mockStepIo( stream, 2 );
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
when( meta.getStepIOMeta() ).thenReturn( stepIo );
doCallRealMethod().when( meta ).handleStreamSelection( any( StreamInterface.class ) );
meta.handleStreamSelection( stream );
assertEquals( stream.getStepMeta(), meta.getResultFilesTargetStepMeta() );
}
@Test
public void forthStreamIsExecutorsInput() throws Exception {
StreamInterface stream = mockStream();
StepIOMetaInterface stepIo = mockStepIo( stream, 3 );
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
when( meta.getStepIOMeta() ).thenReturn( stepIo );
doCallRealMethod().when( meta ).handleStreamSelection( any( StreamInterface.class ) );
meta.handleStreamSelection( stream );
assertEquals( stream.getStepMeta(), meta.getExecutorsOutputStepMeta() );
}
@Test
public void testPrepareExecutionResultsFields() throws Exception {
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
RowMetaInterface row = mock( RowMetaInterface.class );
StepMeta nextStep = mock( StepMeta.class );
meta.setExecutionResultTargetStepMeta( nextStep );
meta.setExecutionTimeField( "time" );
StepMeta parent = mock( StepMeta.class );
doReturn( parent ).when( meta ).getParentStepMeta();
when( parent.getName() ).thenReturn( "parent step" );
meta.prepareExecutionResultsFields( row, nextStep );
// make sure we get the name of the parent step meta... used for the origin step
verify( parent ).getName();
ArgumentCaptor<ValueMetaInterface> argumentCaptor = ArgumentCaptor.forClass( ValueMetaInterface.class );
verify( row ).addValueMeta( argumentCaptor.capture() );
assertEquals( "parent step", argumentCaptor.getValue().getOrigin() );
}
@Test
public void testPrepareExecutionResultsFileFields() throws Exception {
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
RowMetaInterface row = mock( RowMetaInterface.class );
StepMeta nextStep = mock( StepMeta.class );
meta.setResultFilesTargetStepMeta( nextStep );
meta.setResultFilesFileNameField( "file_name" );
StepMeta parent = mock( StepMeta.class );
doReturn( parent ).when( meta ).getParentStepMeta();
when( parent.getName() ).thenReturn( "parent step" );
meta.prepareExecutionResultsFileFields( row, nextStep );
// make sure we get the name of the parent step meta... used for the origin step
verify( parent ).getName();
ArgumentCaptor<ValueMetaInterface> argumentCaptor = ArgumentCaptor.forClass( ValueMetaInterface.class );
verify( row ).addValueMeta( argumentCaptor.capture() );
assertEquals( "parent step", argumentCaptor.getValue().getOrigin() );
}
@Test
public void testPrepareResultsRowsFields() throws Exception {
TransExecutorMeta meta = new TransExecutorMeta();
String[] outputFieldNames = new String[]{ "one", "two" };
int[] outputFieldTypes = new int[]{ 0, 1 };
int[] outputFieldLength = new int[]{ 4, 8 };
int[] outputFieldPrecision = new int[]{ 2, 4 };
meta.setOutputRowsField( outputFieldNames );
meta.setOutputRowsType( outputFieldTypes );
meta.setOutputRowsLength( outputFieldLength );
meta.setOutputRowsPrecision( outputFieldPrecision );
meta = spy( meta );
RowMetaInterface row = mock( RowMetaInterface.class );
StepMeta parent = mock( StepMeta.class );
doReturn( parent ).when( meta ).getParentStepMeta();
when( parent.getName() ).thenReturn( "parent step" );
meta.prepareResultsRowsFields( row );
// make sure we get the name of the parent step meta... used for the origin step
verify( parent, times( outputFieldNames.length ) ).getName();
ArgumentCaptor<ValueMetaInterface> argumentCaptor = ArgumentCaptor.forClass( ValueMetaInterface.class );
verify( row, times( outputFieldNames.length ) ).addValueMeta( argumentCaptor.capture() );
assertEquals( "parent step", argumentCaptor.getValue().getOrigin() );
}
@Test
public void testGetFields() throws Exception {
TransExecutorMeta meta = new TransExecutorMeta();
meta = spy( meta );
StepMeta nextStep = mock( StepMeta.class );
// Test null
meta.getFields( null, null, null, nextStep, null, null, null );
verify( meta, never() ).addFieldToRow( any( RowMetaInterface.class ), anyString(), anyInt() );
RowMetaInterface rowMeta = mock( RowMetaInterface.class );
meta.getFields( rowMeta, null, null, nextStep, null, null, null );
verify( rowMeta, never() ).clear();
StepMeta executionResultTargetStepMeta = mock( StepMeta.class );
meta.setExecutionResultTargetStepMeta( executionResultTargetStepMeta );
meta.getFields( rowMeta, null, null, nextStep, null, null, null );
verify( rowMeta, atMost( 1 ) ).clear();
meta.setExecutionResultTargetStepMeta( null );
StepMeta resultFilesTargetStepMeta = mock( StepMeta.class );
meta.setResultFilesTargetStepMeta( resultFilesTargetStepMeta );
meta.getFields( rowMeta, null, null, nextStep, null, null, null );
verify( rowMeta, atMost( 1 ) ).clear();
meta.setResultFilesTargetStepMeta( null );
StepMeta outputRowsSourceStepMeta = mock( StepMeta.class );
meta.setOutputRowsSourceStepMeta( outputRowsSourceStepMeta );
meta.getFields( rowMeta, null, null, nextStep, null, null, null );
verify( rowMeta, atMost( 1 ) ).clear();
meta.setOutputRowsSourceStepMeta( null );
}
@Test
public void testClone() throws Exception {
TransExecutorMeta meta = new TransExecutorMeta();
meta.setOutputRowsField( new String[] { "field1", "field2" } );
meta.setOutputRowsLength( new int[] { 5, 5 } );
meta.setOutputRowsPrecision( new int[] { 5, 5 } );
meta.setOutputRowsType( new int[] { 0, 0 } );
TransExecutorMeta cloned = (TransExecutorMeta) meta.clone();
assertFalse( cloned.getOutputRowsField() == meta.getOutputRowsField() );
assertTrue( Arrays.equals( cloned.getOutputRowsField(), meta.getOutputRowsField() ) );
assertFalse( cloned.getOutputRowsLength() == meta.getOutputRowsLength() );
assertTrue( Arrays.equals( cloned.getOutputRowsLength(), meta.getOutputRowsLength() ) );
assertFalse( cloned.getOutputRowsPrecision() == meta.getOutputRowsPrecision() );
assertTrue( Arrays.equals( cloned.getOutputRowsPrecision(), meta.getOutputRowsPrecision() ) );
assertFalse( cloned.getOutputRowsType() == meta.getOutputRowsType() );
assertTrue( Arrays.equals( cloned.getOutputRowsType(), meta.getOutputRowsType() ) );
}
@SuppressWarnings( "unchecked" )
private static StepIOMetaInterface mockStepIo( StreamInterface stream, int desiredIndex ) {
List<StreamInterface> list = mock( List.class );
when( list.indexOf( stream ) ).thenReturn( desiredIndex );
when( list.get( eq( desiredIndex ) ) ).thenReturn( stream );
StepIOMetaInterface stepIo = mock( StepIOMetaInterface.class );
when( stepIo.getTargetStreams() ).thenReturn( list );
return stepIo;
}
private static StreamInterface mockStream() {
StepMeta stepMeta = mock( StepMeta.class );
StreamInterface stream = mock( StreamInterface.class );
when( stream.getStepMeta() ).thenReturn( stepMeta );
return stream;
}
@Test
public void testRemoveHopFrom() throws Exception {
TransExecutorMeta transExecutorMeta = new TransExecutorMeta();
transExecutorMeta.setExecutionResultTargetStepMeta( new StepMeta() );
transExecutorMeta.setOutputRowsSourceStepMeta( new StepMeta() );
transExecutorMeta.setResultFilesTargetStepMeta( new StepMeta() );
transExecutorMeta.setExecutorsOutputStepMeta( new StepMeta() );
transExecutorMeta.cleanAfterHopFromRemove();
assertNull( transExecutorMeta.getExecutionResultTargetStepMeta() );
assertNull( transExecutorMeta.getOutputRowsSourceStepMeta() );
assertNull( transExecutorMeta.getResultFilesTargetStepMeta() );
assertNull( transExecutorMeta.getExecutorsOutputStepMeta() );
}
}