/*! ****************************************************************************** * * 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.tableoutput; import static org.mockito.Mockito.*; import static org.junit.Assert.*; import java.util.List; import org.junit.Before; import org.junit.Test; import org.pentaho.di.core.database.DatabaseInterface; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleXMLException; import org.pentaho.di.core.row.RowMeta; import org.pentaho.di.core.xml.XMLHandler; import org.pentaho.di.repository.Repository; import org.pentaho.di.repository.StringObjectId; import org.pentaho.di.trans.steps.loadsave.MemoryRepository; import org.pentaho.di.utils.TestUtils; import org.pentaho.metastore.api.IMetaStore; import org.w3c.dom.Node; public class TableOutputMetaTest { private List<DatabaseMeta> databases; private IMetaStore metaStore; @SuppressWarnings( "unchecked" ) @Before public void setUp() { databases = mock( List.class ); metaStore = mock( IMetaStore.class ); } /** * @see * <a href=http://jira.pentaho.com/browse/BACKLOG-377>http://jira.pentaho.com/browse/BACKLOG-377</a> * @throws KettleException */ @Test public void testReadRep() throws KettleException { //check variable String commitSize = "${test}"; Repository rep = new MemoryRepository(); rep.saveStepAttribute( null, null, "commit", commitSize ); TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.readRep( rep, metaStore, null, databases ); assertEquals( commitSize, tableOutputMeta.getCommitSize() ); //check integer size int commitSizeInt = 1; Repository rep2 = new MemoryRepository(); rep2.saveStepAttribute( null, null, "commit", commitSizeInt ); TableOutputMeta tableOutputMeta2 = new TableOutputMeta(); tableOutputMeta2.readRep( rep2, metaStore, null, databases ); assertEquals( String.valueOf( commitSizeInt ), tableOutputMeta2.getCommitSize() ); } @Test public void testIsReturningGeneratedKeys() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(), tableOutputMetaSpy = spy( tableOutputMeta ); DatabaseMeta databaseMeta = mock( DatabaseMeta.class ); doReturn( true ).when( databaseMeta ).supportsAutoGeneratedKeys(); doReturn( databaseMeta ).when( tableOutputMetaSpy ).getDatabaseMeta(); tableOutputMetaSpy.setReturningGeneratedKeys( true ); assertTrue( tableOutputMetaSpy.isReturningGeneratedKeys() ); doReturn( false ).when( databaseMeta ).supportsAutoGeneratedKeys(); assertFalse( tableOutputMetaSpy.isReturningGeneratedKeys() ); tableOutputMetaSpy.setReturningGeneratedKeys( true ); assertFalse( tableOutputMetaSpy.isReturningGeneratedKeys() ); tableOutputMetaSpy.setReturningGeneratedKeys( false ); assertFalse( tableOutputMetaSpy.isReturningGeneratedKeys() ); } @Test public void testProvidesModeler() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.setFieldDatabase( new String[] {"f1", "f2", "f3"} ); tableOutputMeta.setFieldStream( new String[] {"s4", "s5", "s6"} ); TableOutputData tableOutputData = new TableOutputData(); tableOutputData.insertRowMeta = mock( RowMeta.class ); assertEquals( tableOutputData.insertRowMeta, tableOutputMeta.getRowMeta( tableOutputData ) ); tableOutputMeta.setSpecifyFields( false ); assertEquals( 0, tableOutputMeta.getDatabaseFields().size() ); assertEquals( 0, tableOutputMeta.getStreamFields().size() ); tableOutputMeta.setSpecifyFields( true ); assertEquals( 3, tableOutputMeta.getDatabaseFields().size() ); assertEquals( "f1", tableOutputMeta.getDatabaseFields().get( 0 ) ); assertEquals( "f2", tableOutputMeta.getDatabaseFields().get( 1 ) ); assertEquals( "f3", tableOutputMeta.getDatabaseFields().get( 2 ) ); assertEquals( 3, tableOutputMeta.getStreamFields().size() ); assertEquals( "s4", tableOutputMeta.getStreamFields().get( 0 ) ); assertEquals( "s5", tableOutputMeta.getStreamFields().get( 1 ) ); assertEquals( "s6", tableOutputMeta.getStreamFields().get( 2 ) ); } @Test public void testLoadXml() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.loadXML( getTestNode(), databases, metaStore ); assertEquals( "1000", tableOutputMeta.getCommitSize() ); assertEquals( null, tableOutputMeta.getGeneratedKeyField() ); assertEquals( "public", tableOutputMeta.getSchemaName() ); assertEquals( "sales_csv", tableOutputMeta.getTableName() ); assertEquals( null, tableOutputMeta.getPartitioningField() ); assertTrue( tableOutputMeta.truncateTable() ); assertTrue( tableOutputMeta.specifyFields() ); assertFalse( tableOutputMeta.ignoreErrors() ); assertFalse( tableOutputMeta.isPartitioningEnabled() ); assertTrue( tableOutputMeta.useBatchUpdate() ); assertFalse( tableOutputMeta.isTableNameInField() ); assertTrue( tableOutputMeta.isTableNameInTable() ); assertFalse( tableOutputMeta.isReturningGeneratedKeys() ); String expectedXml = "" + " <connection/>\n" + " <schema>public</schema>\n" + " <table>sales_csv</table>\n" + " <commit>1000</commit>\n" + " <truncate>Y</truncate>\n" + " <ignore_errors>N</ignore_errors>\n" + " <use_batch>Y</use_batch>\n" + " <specify_fields>Y</specify_fields>\n" + " <partitioning_enabled>N</partitioning_enabled>\n" + " <partitioning_field/>\n" + " <partitioning_daily>N</partitioning_daily>\n" + " <partitioning_monthly>Y</partitioning_monthly>\n" + " <tablename_in_field>N</tablename_in_field>\n" + " <tablename_field/>\n" + " <tablename_in_table>Y</tablename_in_table>\n" + " <return_keys>N</return_keys>\n" + " <return_field/>\n" + " <fields>\n" + " <field>\n" + " <column_name>ORDERNUMBER</column_name>\n" + " <stream_name>ORDERNUMBER</stream_name>\n" + " </field>\n" + " <field>\n" + " <column_name>QUANTITYORDERED</column_name>\n" + " <stream_name>QUANTITYORDERED</stream_name>\n" + " </field>\n" + " <field>\n" + " <column_name>PRICEEACH</column_name>\n" + " <stream_name>PRICEEACH</stream_name>\n" + " </field>\n" + " </fields>\n"; String actualXml = TestUtils.toUnixLineSeparators( tableOutputMeta.getXML() ); assertEquals( expectedXml, actualXml ); } @Test public void testSaveRep() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.loadXML( getTestNode(), databases, metaStore ); StringObjectId id_step = new StringObjectId( "stepid" ); StringObjectId id_transformation = new StringObjectId( "transid" ); Repository rep = mock( Repository.class ); tableOutputMeta.saveRep( rep, metaStore, id_transformation, id_step ); verify( rep ).saveDatabaseMetaStepAttribute( id_transformation, id_step, "id_connection", null ); verify( rep ).saveStepAttribute( id_transformation, id_step, "schema", "public" ); verify( rep ).saveStepAttribute( id_transformation, id_step, "table", "sales_csv" ); verify( rep ).saveStepAttribute( id_transformation, id_step, "commit", "1000" ); verify( rep ).saveStepAttribute( id_transformation, id_step, "truncate", true ); verify( rep ).saveStepAttribute( id_transformation, id_step, "ignore_errors", false ); verify( rep ).saveStepAttribute( id_transformation, id_step, "use_batch", true ); verify( rep ).saveStepAttribute( id_transformation, id_step, "specify_fields", true ); verify( rep ).saveStepAttribute( id_transformation, id_step, "partitioning_enabled", false ); verify( rep ).saveStepAttribute( id_transformation, id_step, "partitioning_field", null ); verify( rep ).saveStepAttribute( id_transformation, id_step, "partitioning_daily", false ); verify( rep ).saveStepAttribute( id_transformation, id_step, "partitioning_monthly", true ); verify( rep ).saveStepAttribute( id_transformation, id_step, "tablename_in_field", false ); verify( rep ).saveStepAttribute( id_transformation, id_step, "tablename_field", null ); verify( rep ).saveStepAttribute( id_transformation, id_step, "tablename_in_table", true ); verify( rep ).saveStepAttribute( id_transformation, id_step, "return_keys", false ); verify( rep ).saveStepAttribute( id_transformation, id_step, "return_field", null ); verify( rep ).saveStepAttribute( id_transformation, id_step, 0, "column_name", "ORDERNUMBER" ); verify( rep ).saveStepAttribute( id_transformation, id_step, 0, "stream_name", "ORDERNUMBER" ); verify( rep ).saveStepAttribute( id_transformation, id_step, 1, "column_name", "QUANTITYORDERED" ); verify( rep ).saveStepAttribute( id_transformation, id_step, 1, "stream_name", "QUANTITYORDERED" ); verify( rep ).saveStepAttribute( id_transformation, id_step, 2, "column_name", "PRICEEACH" ); verify( rep ).saveStepAttribute( id_transformation, id_step, 2, "stream_name", "PRICEEACH" ); verifyNoMoreInteractions( rep ); } @Test public void testSetupDefault() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.setDefault(); assertEquals( "", tableOutputMeta.getTableName() ); assertEquals( "1000", tableOutputMeta.getCommitSize() ); assertFalse( tableOutputMeta.isPartitioningEnabled() ); assertTrue( tableOutputMeta.isPartitioningMonthly() ); assertEquals( "", tableOutputMeta.getPartitioningField() ); assertTrue( tableOutputMeta.isTableNameInTable() ); assertEquals( "", tableOutputMeta.getTableNameField() ); assertFalse( tableOutputMeta.specifyFields() ); } @Test public void testClone() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); tableOutputMeta.setDefault(); tableOutputMeta.setFieldStream( new String[] {"1", "2", "3"} ); tableOutputMeta.setFieldDatabase( new String[] {"d1", "d2", "d3"} ); TableOutputMeta clone = (TableOutputMeta) tableOutputMeta.clone(); assertNotSame( clone, tableOutputMeta ); assertEquals( clone.getXML(), tableOutputMeta.getXML() ); } @Test public void testSupportsErrorHandling() throws Exception { TableOutputMeta tableOutputMeta = new TableOutputMeta(); DatabaseMeta dbMeta = mock( DatabaseMeta.class ); tableOutputMeta.setDatabaseMeta( dbMeta ); DatabaseInterface databaseInterface = mock( DatabaseInterface.class ); when( dbMeta.getDatabaseInterface() ).thenReturn( databaseInterface ); when( databaseInterface.supportsErrorHandling() ).thenReturn( true, false ); assertTrue( tableOutputMeta.supportsErrorHandling() ); assertFalse( tableOutputMeta.supportsErrorHandling() ); tableOutputMeta.setDatabaseMeta( null ); assertTrue( tableOutputMeta.supportsErrorHandling() ); } private Node getTestNode() throws KettleXMLException { String xml = " <step>\n" + " <name>Table output</name>\n" + " <type>TableOutput</type>\n" + " <description/>\n" + " <distribute>Y</distribute>\n" + " <custom_distribution/>\n" + " <copies>1</copies>\n" + " <partitioning>\n" + " <method>none</method>\n" + " <schema_name/>\n" + " </partitioning>\n" + " <connection>local postgres</connection>\n" + " <schema>public</schema>\n" + " <table>sales_csv</table>\n" + " <commit>1000</commit>\n" + " <truncate>Y</truncate>\n" + " <ignore_errors>N</ignore_errors>\n" + " <use_batch>Y</use_batch>\n" + " <specify_fields>Y</specify_fields>\n" + " <partitioning_enabled>N</partitioning_enabled>\n" + " <partitioning_field/>\n" + " <partitioning_daily>N</partitioning_daily>\n" + " <partitioning_monthly>Y</partitioning_monthly>\n" + " <tablename_in_field>N</tablename_in_field>\n" + " <tablename_field/>\n" + " <tablename_in_table>Y</tablename_in_table>\n" + " <return_keys>N</return_keys>\n" + " <return_field/>\n" + " <fields>\n" + " <field>\n" + " <column_name>ORDERNUMBER</column_name>\n" + " <stream_name>ORDERNUMBER</stream_name>\n" + " </field>\n" + " <field>\n" + " <column_name>QUANTITYORDERED</column_name>\n" + " <stream_name>QUANTITYORDERED</stream_name>\n" + " </field>\n" + " <field>\n" + " <column_name>PRICEEACH</column_name>\n" + " <stream_name>PRICEEACH</stream_name>\n" + " </field>\n" + " </fields>\n" + " <cluster_schema/>\n" + " <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>\n" + " <xloc>368</xloc>\n" + " <yloc>64</yloc>\n" + " <draw>Y</draw>\n" + " </GUI>\n" + " </step>\n"; return XMLHandler.loadXMLString( xml, "step" ); } }