/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 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.job;
import org.junit.Before;
import org.junit.Test;
import org.pentaho.di.core.NotePadMeta;
import org.pentaho.di.core.exception.IdNotFoundException;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.exception.LookupReferencesException;
import org.pentaho.di.core.gui.Point;
import org.pentaho.di.core.listeners.ContentChangedListener;
import org.pentaho.di.job.entries.empty.JobEntryEmpty;
import org.pentaho.di.job.entries.trans.JobEntryTrans;
import org.pentaho.di.job.entry.JobEntryCopy;
import org.pentaho.di.repository.ObjectRevision;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.resource.ResourceDefinition;
import org.pentaho.di.resource.ResourceNamingInterface;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.*;
public class JobMetaTest {
private static final String JOB_META_NAME = "jobName";
private JobMeta jobMeta;
private RepositoryDirectoryInterface directoryJob;
private ContentChangedListener listener;
private ObjectRevision objectRevision;
@Before
public void setUp() {
jobMeta = new JobMeta();
// prepare
directoryJob = mock( RepositoryDirectoryInterface.class );
when( directoryJob.getPath() ).thenReturn( "directoryPath" );
listener = mock( ContentChangedListener.class );
objectRevision = mock( ObjectRevision.class );
when( objectRevision.getName() ).thenReturn( "revisionName" );
jobMeta.addContentChangedListener( listener );
jobMeta.setRepositoryDirectory( directoryJob );
jobMeta.setName( JOB_META_NAME );
jobMeta.setObjectRevision( objectRevision );
}
@Test
public void testPathExist() throws KettleXMLException, IOException, URISyntaxException {
assertTrue( testPath( "je1-je4" ) );
}
@Test
public void testPathNotExist() throws KettleXMLException, IOException, URISyntaxException {
assertFalse( testPath( "je2-je4" ) );
}
private boolean testPath( String branch ) {
JobEntryEmpty je1 = new JobEntryEmpty();
je1.setName( "je1" );
JobEntryEmpty je2 = new JobEntryEmpty();
je2.setName( "je2" );
JobHopMeta hop = new JobHopMeta( new JobEntryCopy( je1 ), new JobEntryCopy( je2 ) );
jobMeta.addJobHop( hop );
JobEntryEmpty je3 = new JobEntryEmpty();
je3.setName( "je3" );
hop = new JobHopMeta( new JobEntryCopy( je1 ), new JobEntryCopy( je3 ) );
jobMeta.addJobHop( hop );
JobEntryEmpty je4 = new JobEntryEmpty();
je4.setName( "je4" );
hop = new JobHopMeta( new JobEntryCopy( je3 ), new JobEntryCopy( je4 ) );
jobMeta.addJobHop( hop );
if ( branch.equals( "je1-je4" ) ) {
return jobMeta.isPathExist( je1, je4 );
} else if ( branch.equals( "je2-je4" ) ) {
return jobMeta.isPathExist( je2, je4 );
} else {
return false;
}
}
@Test
public void testContentChangeListener() throws Exception {
jobMeta.setChanged();
jobMeta.setChanged( true );
verify( listener, times( 2 ) ).contentChanged( same( jobMeta ) );
jobMeta.clearChanged();
jobMeta.setChanged( false );
verify( listener, times( 2 ) ).contentSafe( same( jobMeta ) );
jobMeta.removeContentChangedListener( listener );
jobMeta.setChanged();
jobMeta.setChanged( true );
verifyNoMoreInteractions( listener );
}
@Test
public void testLookupRepositoryReferences() throws Exception {
jobMeta.clear();
JobEntryTrans jobEntryMock = mock( JobEntryTrans.class );
when( jobEntryMock.hasRepositoryReferences() ).thenReturn( true );
JobEntryTrans brokenJobEntryMock = mock( JobEntryTrans.class );
when( brokenJobEntryMock.hasRepositoryReferences() ).thenReturn( true );
doThrow( mock( IdNotFoundException.class ) ).when( brokenJobEntryMock ).lookupRepositoryReferences( any(
Repository.class ) );
JobEntryCopy jobEntryCopy1 = mock( JobEntryCopy.class );
when( jobEntryCopy1.getEntry() ).thenReturn( jobEntryMock );
jobMeta.addJobEntry( 0, jobEntryCopy1 );
JobEntryCopy jobEntryCopy2 = mock( JobEntryCopy.class );
when( jobEntryCopy2.getEntry() ).thenReturn( brokenJobEntryMock );
jobMeta.addJobEntry( 1, jobEntryCopy2 );
JobEntryCopy jobEntryCopy3 = mock( JobEntryCopy.class );
when( jobEntryCopy3.getEntry() ).thenReturn( jobEntryMock );
jobMeta.addJobEntry( 2, jobEntryCopy3 );
try {
jobMeta.lookupRepositoryReferences( mock( Repository.class ) );
fail( "no exception for broken entry" );
} catch ( LookupReferencesException e ) {
// ok
}
verify( jobEntryMock, times( 2 ) ).lookupRepositoryReferences( any( Repository.class ) );
}
/**
* Given job meta object. <br/>
* When the job is called to export resources, then the existing current directory should be used as a context to
* locate resources.
*/
@Test
public void shouldUseExistingRepositoryDirectoryWhenExporting() throws KettleException {
final JobMeta jobMetaSpy = spy( jobMeta );
JobMeta jobMeta = new JobMeta() {
@Override
public Object realClone( boolean doClear ) {
return jobMetaSpy;
}
};
jobMeta.setRepositoryDirectory( directoryJob );
jobMeta.setName( JOB_META_NAME );
jobMeta.exportResources( null, new HashMap<String, ResourceDefinition>( 4 ), mock( ResourceNamingInterface.class ),
null, null );
// assert
verify( jobMetaSpy ).setRepositoryDirectory( directoryJob );
}
@Test
public void shouldUseCoordinatesOfItsStepsAndNotesWhenCalculatingMinimumPoint() {
Point jobEntryPoint = new Point( 500, 500 );
Point notePadMetaPoint = new Point( 400, 400 );
JobEntryCopy jobEntryCopy = mock( JobEntryCopy.class );
when( jobEntryCopy.getLocation() ).thenReturn( jobEntryPoint );
NotePadMeta notePadMeta = mock( NotePadMeta.class );
when( notePadMeta.getLocation() ).thenReturn( notePadMetaPoint );
// empty Job return 0 coordinate point
Point point = jobMeta.getMinimum();
assertEquals( 0, point.x );
assertEquals( 0, point.y );
// when Job contains a single step or note, then jobMeta should return coordinates of it, subtracting borders
jobMeta.addJobEntry( 0, jobEntryCopy );
Point actualStepPoint = jobMeta.getMinimum();
assertEquals( jobEntryPoint.x - JobMeta.BORDER_INDENT, actualStepPoint.x );
assertEquals( jobEntryPoint.y - JobMeta.BORDER_INDENT, actualStepPoint.y );
// when Job contains step or notes, then jobMeta should return minimal coordinates of them, subtracting borders
jobMeta.addNote( notePadMeta );
Point stepPoint = jobMeta.getMinimum();
assertEquals( notePadMetaPoint.x - JobMeta.BORDER_INDENT, stepPoint.x );
assertEquals( notePadMetaPoint.y - JobMeta.BORDER_INDENT, stepPoint.y );
}
@Test
public void testEquals_oneNameNull() {
assertFalse( testEquals( null, null, null, null ) );
}
@Test
public void testEquals_secondNameNull() {
jobMeta.setName( null );
assertFalse( testEquals( JOB_META_NAME, null, null, null ) );
}
@Test
public void testEquals_sameNameOtherDir() {
RepositoryDirectoryInterface otherDirectory = mock( RepositoryDirectoryInterface.class );
when( otherDirectory.getPath() ).thenReturn( "otherDirectoryPath" );
assertFalse( testEquals( JOB_META_NAME, otherDirectory, null, null ) );
}
@Test
public void testEquals_sameNameSameDirNullRev() {
assertFalse( testEquals( JOB_META_NAME, directoryJob, null, null ) );
}
@Test
public void testEquals_sameNameSameDirDiffRev() {
ObjectRevision otherRevision = mock( ObjectRevision.class );
when( otherRevision.getName() ).thenReturn( "otherRevision" );
assertFalse( testEquals( JOB_META_NAME, directoryJob, otherRevision, null ) );
}
@Test
public void testEquals_sameNameSameDirSameRev() {
assertTrue( testEquals( JOB_META_NAME, directoryJob, objectRevision, null ) );
}
@Test
public void testEquals_sameNameSameDirSameRevFilename() {
assertFalse( testEquals( JOB_META_NAME, directoryJob, objectRevision, "Filename" ) );
}
@Test
public void testEquals_sameFilename() {
String newFilename = "Filename";
jobMeta.setFilename( newFilename );
assertFalse( testEquals( null, null, null, newFilename ) );
}
@Test
public void testEquals_difFilenameSameName() {
jobMeta.setFilename( "Filename" );
assertFalse( testEquals( JOB_META_NAME, null, null, "OtherFileName" ) );
}
@Test
public void testEquals_sameFilenameSameName() {
String newFilename = "Filename";
jobMeta.setFilename( newFilename );
assertTrue( testEquals( JOB_META_NAME, null, null, newFilename ) );
}
@Test
public void testEquals_sameFilenameDifName() {
String newFilename = "Filename";
jobMeta.setFilename( newFilename );
assertFalse( testEquals( "OtherName", null, null, newFilename ) );
}
private boolean testEquals( String name, RepositoryDirectoryInterface repDirectory, ObjectRevision revision,
String filename ) {
JobMeta jobMeta2 = new JobMeta();
jobMeta2.setName( name );
jobMeta2.setRepositoryDirectory( repDirectory );
jobMeta2.setObjectRevision( revision );
jobMeta2.setFilename( filename );
return jobMeta.equals( jobMeta2 );
}
}