/*! ******************************************************************************
*
* 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.core.row.value;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.owasp.encoder.Encode;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.database.DatabaseInterface;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.database.NetezzaDatabaseMeta;
import org.pentaho.di.core.database.Vertica5DatabaseMeta;
import org.pentaho.di.core.exception.KettleDatabaseException;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleValueException;
import org.pentaho.di.core.logging.KettleLogStore;
import org.pentaho.di.core.logging.KettleLoggingEvent;
import org.pentaho.di.core.logging.KettleLoggingEventListener;
import org.pentaho.di.core.logging.LogChannelInterface;
import org.pentaho.di.core.logging.LoggingObject;
import org.pentaho.di.core.logging.LoggingRegistry;
import org.pentaho.di.core.plugins.DatabasePluginType;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.i18n.BaseMessages;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import static org.junit.Assert.*;
public class ValueMetaBaseTest {
private static final String TEST_NAME = "TEST_NAME";
private static final String LOG_FIELD = "LOG_FIELD";
public static final int MAX_TEXT_FIELD_LEN = 5;
// Get PKG from class under test
private static Class<?> PKG = ( new ValueMetaBase() {
public Class<?> getPackage() {
return PKG;
}
} ).getPackage();
private StoreLoggingEventListener listener;
@BeforeClass
public static void setUpBeforeClass() throws KettleException {
PluginRegistry.addPluginType( ValueMetaPluginType.getInstance() );
PluginRegistry.addPluginType( DatabasePluginType.getInstance() );
PluginRegistry.init( true );
KettleLogStore.init();
}
@Before
public void setUp() {
listener = new StoreLoggingEventListener();
KettleLogStore.getAppender().addLoggingEventListener( listener );
}
@After
public void tearDown() {
KettleLogStore.getAppender().removeLoggingEventListener( listener );
listener = new StoreLoggingEventListener();
}
@Test
public void testDefaultCtor() {
ValueMetaBase base = new ValueMetaBase();
assertNotNull( base );
assertNull( base.getName() );
assertEquals( base.getType(), ValueMetaInterface.TYPE_NONE );
}
@Test
public void testCtorName() {
ValueMetaBase base = new ValueMetaBase( "myValueMeta" );
assertEquals( base.getName(), "myValueMeta" );
assertEquals( base.getType(), ValueMetaInterface.TYPE_NONE );
assertNotNull( base.getTypeDesc() );
}
@Test
public void testCtorNameAndType() {
ValueMetaBase base = new ValueMetaBase( "myStringType", ValueMetaInterface.TYPE_STRING );
assertEquals( base.getName(), "myStringType" );
assertEquals( base.getType(), ValueMetaInterface.TYPE_STRING );
assertEquals( base.getTypeDesc(), "String" );
}
@Test
public void test4ArgCtor() {
ValueMetaBase base =
new ValueMetaBoolean( "Hello, is it me you're looking for?", 4, 9 );
assertEquals( base.getName(), "Hello, is it me you're looking for?" );
assertEquals( base.getType(), ValueMetaInterface.TYPE_BOOLEAN );
assertEquals( base.getLength(), 4 );
assertEquals( base.getPrecision(), -1 );
assertEquals( base.getStorageType(), ValueMetaInterface.STORAGE_TYPE_NORMAL );
}
/**
* PDI-10877 Table input step returns no data when pulling a timestamp column from IBM Netezza
*
* @throws Exception
*/
@Test
public void testGetValueFromSqlTypeNetezza() throws Exception {
ValueMetaBase obj = new ValueMetaBase();
DatabaseInterface databaseInterface = new NetezzaDatabaseMeta();
ResultSet resultSet = Mockito.mock( ResultSet.class );
ResultSetMetaData metaData = Mockito.mock( ResultSetMetaData.class );
Mockito.when( resultSet.getMetaData() ).thenReturn( metaData );
Mockito.when( metaData.getColumnType( 1 ) ).thenReturn( Types.DATE );
Mockito.when( metaData.getColumnType( 2 ) ).thenReturn( Types.TIME );
obj.type = ValueMetaInterface.TYPE_DATE;
// call to testing method
obj.getValueFromResultSet( databaseInterface, resultSet, 0 );
// for jdbc Date type getDate method called
Mockito.verify( resultSet, Mockito.times( 1 ) ).getDate( Mockito.anyInt() );
obj.getValueFromResultSet( databaseInterface, resultSet, 1 );
// for jdbc Time type getTime method called
Mockito.verify( resultSet, Mockito.times( 1 ) ).getTime( Mockito.anyInt() );
}
@Test
public void testGetDataXML() throws IOException {
BigDecimal bigDecimal = BigDecimal.ONE;
ValueMetaBase valueDoubleMetaBase =
new ValueMetaBase( String.valueOf( bigDecimal ), ValueMetaInterface.TYPE_BIGNUMBER );
assertEquals(
"<value-data>" + Encode.forXml( String.valueOf( bigDecimal ) ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
valueDoubleMetaBase.getDataXML( bigDecimal ) );
boolean valueBoolean = Boolean.TRUE;
ValueMetaBase valueBooleanMetaBase =
new ValueMetaBase( String.valueOf( valueBoolean ), ValueMetaInterface.TYPE_BOOLEAN );
assertEquals(
"<value-data>" + Encode.forXml( String.valueOf( valueBoolean ) ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
valueBooleanMetaBase.getDataXML( valueBoolean ) );
Date date = new Date( 0 );
ValueMetaBase dateMetaBase =
new ValueMetaBase( date.toString(), ValueMetaInterface.TYPE_DATE );
SimpleDateFormat formaterData = new SimpleDateFormat( ValueMetaBase.DEFAULT_DATE_FORMAT_MASK );
assertEquals(
"<value-data>" + Encode.forXml( formaterData.format( date ) ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
dateMetaBase.getDataXML( date ) );
InetAddress inetAddress = InetAddress.getByName( "127.0.0.1" );
ValueMetaBase inetAddressMetaBase =
new ValueMetaBase( inetAddress.toString(), ValueMetaInterface.TYPE_INET );
assertEquals( "<value-data>" + Encode.forXml( inetAddress.toString() ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
inetAddressMetaBase.getDataXML( inetAddress ) );
long value = Long.MAX_VALUE;
ValueMetaBase integerMetaBase = new ValueMetaBase( String.valueOf( value ), ValueMetaInterface.TYPE_INTEGER );
assertEquals( "<value-data>" + Encode.forXml( String.valueOf( value ) ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
integerMetaBase.getDataXML( value ) );
String stringValue = "TEST_STRING";
ValueMetaBase valueMetaBase = new ValueMetaString( stringValue );
assertEquals( "<value-data>" + Encode.forXml( stringValue ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
valueMetaBase.getDataXML( stringValue ) );
Timestamp timestamp = new Timestamp( 0 );
ValueMetaBase valueMetaBaseTimeStamp = new ValueMetaBase( timestamp.toString(), ValueMetaInterface.TYPE_TIMESTAMP );
SimpleDateFormat formater = new SimpleDateFormat( ValueMetaBase.DEFAULT_TIMESTAMP_FORMAT_MASK );
assertEquals(
"<value-data>" + Encode.forXml( formater.format( timestamp ) ) + "</value-data>" + SystemUtils.LINE_SEPARATOR,
valueMetaBaseTimeStamp.getDataXML( timestamp ) );
byte[] byteTestValues = { 0, 1, 2, 3 };
ValueMetaBase valueMetaBaseByteArray = new ValueMetaBase( byteTestValues.toString(), ValueMetaInterface.TYPE_STRING );
valueMetaBaseByteArray.setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING );
assertEquals(
"<value-data><binary-string>" + Encode.forXml( XMLHandler.encodeBinaryData( byteTestValues ) )
+ "</binary-string>" + Const.CR + "</value-data>",
valueMetaBaseByteArray.getDataXML( byteTestValues ) );
}
@Test
public void testGetBinaryWithLength_WhenBinarySqlTypesOfVertica() throws Exception {
final int binaryColumnIndex = 1;
final int varbinaryColumnIndex = 2;
final int expectedBinarylength = 1;
final int expectedVarBinarylength = 80;
ValueMetaBase obj = new ValueMetaBase();
DatabaseMeta dbMeta = Mockito.spy( new DatabaseMeta() );
DatabaseInterface databaseInterface = new Vertica5DatabaseMeta();
dbMeta.setDatabaseInterface( databaseInterface );
ResultSet resultSet = Mockito.mock( ResultSet.class );
ResultSetMetaData metaData = Mockito.mock( ResultSetMetaData.class );
Mockito.when( resultSet.getMetaData() ).thenReturn( metaData );
Mockito.when( metaData.getColumnType( binaryColumnIndex ) ).thenReturn( Types.BINARY );
Mockito.when( metaData.getPrecision( binaryColumnIndex ) ).thenReturn( expectedBinarylength );
Mockito.when( metaData.getColumnDisplaySize( binaryColumnIndex ) ).thenReturn( expectedBinarylength * 2 );
Mockito.when( metaData.getColumnType( varbinaryColumnIndex ) ).thenReturn( Types.BINARY );
Mockito.when( metaData.getPrecision( varbinaryColumnIndex ) ).thenReturn( expectedVarBinarylength );
Mockito.when( metaData.getColumnDisplaySize( varbinaryColumnIndex ) ).thenReturn( expectedVarBinarylength * 2 );
// get value meta for binary type
ValueMetaInterface binaryValueMeta =
obj.getValueFromSQLType( dbMeta, TEST_NAME, metaData, binaryColumnIndex, false, false );
assertNotNull( binaryValueMeta );
assertTrue( TEST_NAME.equals( binaryValueMeta.getName() ) );
assertTrue( ValueMetaInterface.TYPE_BINARY == binaryValueMeta.getType() );
assertTrue( expectedBinarylength == binaryValueMeta.getLength() );
Assert.assertFalse( binaryValueMeta.isLargeTextField() );
// get value meta for varbinary type
ValueMetaInterface varbinaryValueMeta =
obj.getValueFromSQLType( dbMeta, TEST_NAME, metaData, varbinaryColumnIndex, false, false );
assertNotNull( varbinaryValueMeta );
assertTrue( TEST_NAME.equals( varbinaryValueMeta.getName() ) );
assertTrue( ValueMetaInterface.TYPE_BINARY == varbinaryValueMeta.getType() );
assertTrue( expectedVarBinarylength == varbinaryValueMeta.getLength() );
Assert.assertFalse( varbinaryValueMeta.isLargeTextField() );
}
@Test
public void testGetValueFromSQLTypeTypeOverride() throws Exception {
final int varbinaryColumnIndex = 2;
ValueMetaBase valueMetaBase = new ValueMetaBase(),
valueMetaBaseSpy = Mockito.spy( valueMetaBase );
DatabaseMeta dbMeta = Mockito.mock( DatabaseMeta.class );
DatabaseInterface databaseInterface = Mockito.mock( DatabaseInterface.class );
Mockito.doReturn( databaseInterface ).when( dbMeta ).getDatabaseInterface();
ResultSetMetaData metaData = Mockito.mock( ResultSetMetaData.class );
valueMetaBaseSpy.getValueFromSQLType( dbMeta, TEST_NAME, metaData, varbinaryColumnIndex, false, false );
Mockito.verify( databaseInterface, Mockito.times( 1 ) ).customizeValueFromSQLType( Mockito.any( ValueMetaInterface.class ),
Mockito.any( ResultSetMetaData.class ), Mockito.anyInt() );
}
@Test
public void testVerticaTimeType() throws Exception {
// PDI-12244
ResultSet resultSet = Mockito.mock( ResultSet.class );
ResultSetMetaData metaData = Mockito.mock( ResultSetMetaData.class );
ValueMetaInterface valueMetaInterface = Mockito.mock( ValueMetaInternetAddress.class );
Mockito.when( resultSet.getMetaData() ).thenReturn( metaData );
Mockito.when( metaData.getColumnType( 1 ) ).thenReturn( Types.TIME );
Mockito.when( resultSet.getTime( 1 ) ).thenReturn( new Time( 0 ) );
Mockito.when( valueMetaInterface.getOriginalColumnType() ).thenReturn( Types.TIME );
Mockito.when( valueMetaInterface.getType() ).thenReturn( ValueMetaInterface.TYPE_DATE );
DatabaseInterface databaseInterface = new Vertica5DatabaseMeta();
Object ret = databaseInterface.getValueFromResultSet( resultSet, valueMetaInterface, 0 );
assertEquals( new Time( 0 ), ret );
}
@Test
public void testConvertStringToBoolean() {
assertNull( ValueMetaBase.convertStringToBoolean( null ) );
assertNull( ValueMetaBase.convertStringToBoolean( "" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "Y" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "y" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "Yes" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "YES" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "yES" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "TRUE" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "True" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "true" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "tRuE" ) );
assertTrue( ValueMetaBase.convertStringToBoolean( "Y" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "N" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "No" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "no" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "Yeah" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "False" ) );
Assert.assertFalse( ValueMetaBase.convertStringToBoolean( "NOT false" ) );
}
@Test
public void testConvertDataFromStringToString() throws KettleValueException {
ValueMetaBase inValueMetaString = new ValueMetaString();
ValueMetaBase outValueMetaString = new ValueMetaString();
String inputValueEmptyString = StringUtils.EMPTY;
String inputValueNullString = null;
String nullIf = null;
String ifNull = null;
int trim_type = 0;
Object result;
System.setProperty( Const.KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL, "N" );
result =
outValueMetaString.convertDataFromString( inputValueEmptyString, inValueMetaString, nullIf, ifNull, trim_type );
assertEquals( "KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL = N: "
+ "Conversion from empty string to string must return empty string", StringUtils.EMPTY, result );
result =
outValueMetaString.convertDataFromString( inputValueNullString, inValueMetaString, nullIf, ifNull, trim_type );
assertEquals( "KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL = N: "
+ "Conversion from null string must return null", null, result );
System.setProperty( Const.KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL, "Y" );
result =
outValueMetaString.convertDataFromString( inputValueEmptyString, inValueMetaString, nullIf, ifNull, trim_type );
assertEquals( "KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL = Y: "
+ "Conversion from empty string to string must return empty string", StringUtils.EMPTY, result );
result =
outValueMetaString.convertDataFromString( inputValueNullString, inValueMetaString, nullIf, ifNull, trim_type );
assertEquals( "KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL = Y: "
+ "Conversion from null string must return empty string", StringUtils.EMPTY, result );
}
@Test
public void testConvertDataFromStringToDate() throws KettleValueException {
ValueMetaBase inValueMetaString = new ValueMetaString();
ValueMetaBase outValueMetaDate = new ValueMetaDate();
String inputValueEmptyString = StringUtils.EMPTY;
String nullIf = null;
String ifNull = null;
int trim_type = 0;
Object result;
result =
outValueMetaDate.convertDataFromString( inputValueEmptyString, inValueMetaString, nullIf, ifNull, trim_type );
assertEquals( "Conversion from empty string to date must return null", result, null );
}
@Test( expected = KettleValueException.class )
public void testConvertDataFromStringForNullMeta() throws KettleValueException {
ValueMetaBase valueMetaBase = new ValueMetaBase();
String inputValueEmptyString = StringUtils.EMPTY;
ValueMetaInterface valueMetaInterface = null;
String nullIf = null;
String ifNull = null;
int trim_type = 0;
valueMetaBase.convertDataFromString( inputValueEmptyString, valueMetaInterface, nullIf, ifNull, trim_type );
}
@Test( expected = KettleValueException.class )
public void testGetBigDecimalThrowsKettleValueException() throws KettleValueException {
ValueMetaBase valueMeta = new ValueMetaBigNumber();
valueMeta.getBigNumber( "1234567890" );
}
@Test( expected = KettleValueException.class )
public void testGetIntegerThrowsKettleValueException() throws KettleValueException {
ValueMetaBase valueMeta = new ValueMetaInteger();
valueMeta.getInteger( "1234567890" );
}
@Test( expected = KettleValueException.class )
public void testGetNumberThrowsKettleValueException() throws KettleValueException {
ValueMetaBase valueMeta = new ValueMetaNumber();
valueMeta.getNumber( "1234567890" );
}
@Test
public void testIsNumeric() {
int[] numTypes = { ValueMetaInterface.TYPE_INTEGER, ValueMetaInterface.TYPE_NUMBER, ValueMetaInterface.TYPE_BIGNUMBER };
for ( int type : numTypes ) {
assertTrue( Integer.toString( type ), ValueMetaBase.isNumeric( type ) );
}
int[] notNumTypes = { ValueMetaInterface.TYPE_INET, ValueMetaInterface.TYPE_BOOLEAN, ValueMetaInterface.TYPE_BINARY, ValueMetaInterface.TYPE_DATE, ValueMetaInterface.TYPE_STRING };
for ( int type : notNumTypes ) {
Assert.assertFalse( Integer.toString( type ), ValueMetaBase.isNumeric( type ) );
}
}
@Test
public void testGetAllTypes() {
Assert.assertArrayEquals( ValueMetaBase.getAllTypes(), ValueMetaFactory.getAllValueMetaNames() );
}
@Test
public void testGetTrimTypeByCode() {
assertEquals( ValueMetaBase.getTrimTypeByCode( "none" ), ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByCode( "left" ), ValueMetaInterface.TRIM_TYPE_LEFT );
assertEquals( ValueMetaBase.getTrimTypeByCode( "right" ), ValueMetaInterface.TRIM_TYPE_RIGHT );
assertEquals( ValueMetaBase.getTrimTypeByCode( "both" ), ValueMetaInterface.TRIM_TYPE_BOTH );
assertEquals( ValueMetaBase.getTrimTypeByCode( null ), ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByCode( "" ), ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByCode( "fake" ), ValueMetaInterface.TRIM_TYPE_NONE );
}
@Test
public void testGetTrimTypeCode() {
assertEquals( ValueMetaBase.getTrimTypeCode( ValueMetaInterface.TRIM_TYPE_NONE ), "none" );
assertEquals( ValueMetaBase.getTrimTypeCode( ValueMetaInterface.TRIM_TYPE_LEFT ), "left" );
assertEquals( ValueMetaBase.getTrimTypeCode( ValueMetaInterface.TRIM_TYPE_RIGHT ), "right" );
assertEquals( ValueMetaBase.getTrimTypeCode( ValueMetaInterface.TRIM_TYPE_BOTH ), "both" );
}
@Test
public void testGetTrimTypeByDesc() {
assertEquals( ValueMetaBase.getTrimTypeByDesc( BaseMessages.getString( PKG, "ValueMeta.TrimType.None" ) ),
ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByDesc( BaseMessages.getString( PKG, "ValueMeta.TrimType.Left" ) ),
ValueMetaInterface.TRIM_TYPE_LEFT );
assertEquals( ValueMetaBase.getTrimTypeByDesc( BaseMessages.getString( PKG, "ValueMeta.TrimType.Right" ) ),
ValueMetaInterface.TRIM_TYPE_RIGHT );
assertEquals( ValueMetaBase.getTrimTypeByDesc( BaseMessages.getString( PKG, "ValueMeta.TrimType.Both" ) ),
ValueMetaInterface.TRIM_TYPE_BOTH );
assertEquals( ValueMetaBase.getTrimTypeByDesc( null ), ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByDesc( "" ), ValueMetaInterface.TRIM_TYPE_NONE );
assertEquals( ValueMetaBase.getTrimTypeByDesc( "fake" ), ValueMetaInterface.TRIM_TYPE_NONE );
}
@Test
public void testGetTrimTypeDesc() {
assertEquals( ValueMetaBase.getTrimTypeDesc( ValueMetaInterface.TRIM_TYPE_NONE ), BaseMessages.getString( PKG,
"ValueMeta.TrimType.None" ) );
assertEquals( ValueMetaBase.getTrimTypeDesc( ValueMetaInterface.TRIM_TYPE_LEFT ), BaseMessages.getString( PKG,
"ValueMeta.TrimType.Left" ) );
assertEquals( ValueMetaBase.getTrimTypeDesc( ValueMetaInterface.TRIM_TYPE_RIGHT ), BaseMessages.getString( PKG,
"ValueMeta.TrimType.Right" ) );
assertEquals( ValueMetaBase.getTrimTypeDesc( ValueMetaInterface.TRIM_TYPE_BOTH ), BaseMessages.getString( PKG,
"ValueMeta.TrimType.Both" ) );
assertEquals( ValueMetaBase.getTrimTypeDesc( -1 ), BaseMessages.getString( PKG, "ValueMeta.TrimType.None" ) );
assertEquals( ValueMetaBase.getTrimTypeDesc( 10000 ), BaseMessages.getString( PKG, "ValueMeta.TrimType.None" ) );
}
@Test
public void testOrigin() {
ValueMetaBase base = new ValueMetaBase();
base.setOrigin( "myOrigin" );
assertEquals( base.getOrigin(), "myOrigin" );
base.setOrigin( null );
assertNull( base.getOrigin() );
base.setOrigin( "" );
assertEquals( base.getOrigin(), "" );
}
@Test
public void testName() {
ValueMetaBase base = new ValueMetaBase();
base.setName( "myName" );
assertEquals( base.getName(), "myName" );
base.setName( null );
assertNull( base.getName() );
base.setName( "" );
assertEquals( base.getName(), "" );
}
@Test
public void testLength() {
ValueMetaBase base = new ValueMetaBase();
base.setLength( 6 );
assertEquals( base.getLength(), 6 );
base.setLength( -1 );
assertEquals( base.getLength(), -1 );
}
@Test
public void testPrecision() {
ValueMetaBase base = new ValueMetaBase();
base.setPrecision( 6 );
assertEquals( base.getPrecision(), 6 );
base.setPrecision( -1 );
assertEquals( base.getPrecision(), -1 );
}
@Test
public void testCompareIntegers() throws KettleValueException {
ValueMetaBase intMeta = new ValueMetaBase( "int", ValueMetaInterface.TYPE_INTEGER );
Long int1 = new Long( 6223372036854775804L );
Long int2 = new Long( -6223372036854775804L );
assertEquals( 1, intMeta.compare( int1, int2 ) );
assertEquals( -1, intMeta.compare( int2, int1 ) );
assertEquals( 0, intMeta.compare( int1, int1 ) );
assertEquals( 0, intMeta.compare( int2, int2 ) );
int1 = new Long( 9223372036854775804L );
int2 = new Long( -9223372036854775804L );
assertEquals( 1, intMeta.compare( int1, int2 ) );
assertEquals( -1, intMeta.compare( int2, int1 ) );
assertEquals( 0, intMeta.compare( int1, int1 ) );
assertEquals( 0, intMeta.compare( int2, int2 ) );
int1 = new Long( 6223372036854775804L );
int2 = new Long( -9223372036854775804L );
assertEquals( 1, intMeta.compare( int1, int2 ) );
assertEquals( -1, intMeta.compare( int2, int1 ) );
assertEquals( 0, intMeta.compare( int1, int1 ) );
int1 = new Long( 9223372036854775804L );
int2 = new Long( -6223372036854775804L );
assertEquals( 1, intMeta.compare( int1, int2 ) );
assertEquals( -1, intMeta.compare( int2, int1 ) );
assertEquals( 0, intMeta.compare( int1, int1 ) );
int1 = null;
int2 = new Long( 6223372036854775804L );
assertEquals( -1, intMeta.compare( int1, int2 ) );
intMeta.setSortedDescending( true );
assertEquals( 1, intMeta.compare( int1, int2 ) );
}
@Test
public void testCompareDate() throws KettleValueException {
ValueMetaBase dateMeta = new ValueMetaBase( "int", ValueMetaInterface.TYPE_DATE );
Date date1 = new Date( 6223372036854775804L );
Date date2 = new Date( -6223372036854775804L );
assertEquals( 1, dateMeta.compare( date1, date2 ) );
assertEquals( -1, dateMeta.compare( date2, date1 ) );
assertEquals( 0, dateMeta.compare( date1, date1 ) );
}
@Test
public void testDateParsing8601() throws Exception {
ValueMetaBase dateMeta = new ValueMetaBase( "date", ValueMetaInterface.TYPE_DATE );
dateMeta.setDateFormatLenient( false );
// try to convert date by 'start-of-date' make - old behavior
dateMeta.setConversionMask( "yyyy-MM-dd" );
assertEquals( local( 1918, 3, 25, 0, 0, 0, 0 ), dateMeta.convertStringToDate( "1918-03-25T07:40:03.012+03:00" ) );
// convert ISO-8601 date - supported since Java 7
dateMeta.setConversionMask( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" );
assertEquals( utc( 1918, 3, 25, 5, 10, 3, 12 ), dateMeta.convertStringToDate( "1918-03-25T07:40:03.012+02:30" ) );
assertEquals( utc( 1918, 3, 25, 7, 40, 3, 12 ), dateMeta.convertStringToDate( "1918-03-25T07:40:03.012Z" ) );
// convert date
dateMeta.setConversionMask( "yyyy-MM-dd" );
assertEquals( local( 1918, 3, 25, 0, 0, 0, 0 ), dateMeta.convertStringToDate( "1918-03-25" ) );
// convert date with spaces at the end
assertEquals( local( 1918, 3, 25, 0, 0, 0, 0 ), dateMeta.convertStringToDate( "1918-03-25 \n" ) );
}
@Test
public void testDateToStringParse() throws Exception {
ValueMetaBase dateMeta = new ValueMetaString( "date" );
dateMeta.setDateFormatLenient( false );
// try to convert date by 'start-of-date' make - old behavior
dateMeta.setConversionMask( "yyyy-MM-dd" );
assertEquals( local( 1918, 3, 25, 0, 0, 0, 0 ), dateMeta.convertStringToDate( "1918-03-25T07:40:03.012+03:00" ) );
}
@Test
public void testSetPreparedStatementStringValueDontLogTruncated() throws KettleDatabaseException {
ValueMetaBase valueMetaString = new ValueMetaBase( "LOG_FIELD", ValueMetaInterface.TYPE_STRING, LOG_FIELD.length(), 0 );
DatabaseMeta databaseMeta = Mockito.mock( DatabaseMeta.class );
PreparedStatement preparedStatement = Mockito.mock( PreparedStatement.class );
Mockito.when( databaseMeta.getMaxTextFieldLength() ).thenReturn( LOG_FIELD.length() );
List<KettleLoggingEvent> events = listener.getEvents();
assertEquals( 0, events.size() );
valueMetaString.setPreparedStatementValue( databaseMeta, preparedStatement, 0, LOG_FIELD );
//no logging occurred as max string length equals to logging text length
assertEquals( 0, events.size() );
}
@Test
public void testSetPreparedStatementStringValueLogTruncated() throws KettleDatabaseException {
ValueMetaBase valueMetaString = new ValueMetaBase( "LOG_FIELD", ValueMetaInterface.TYPE_STRING, LOG_FIELD.length(), 0 );
DatabaseMeta databaseMeta = Mockito.mock( DatabaseMeta.class );
PreparedStatement preparedStatement = Mockito.mock( PreparedStatement.class );
Mockito.when( databaseMeta.getMaxTextFieldLength() ).thenReturn( MAX_TEXT_FIELD_LEN );
List<KettleLoggingEvent> events = listener.getEvents();
assertEquals( 0, events.size() );
valueMetaString.setPreparedStatementValue( databaseMeta, preparedStatement, 0, LOG_FIELD );
//check that truncated string was logged
assertEquals( 1, events.size() );
}
@Test
public void testValueMetaBaseOnlyHasOneLogger() throws NoSuchFieldException, IllegalAccessException {
Field log = ValueMetaBase.class.getDeclaredField( "log" );
assertTrue( Modifier.isStatic( log.getModifiers() ) );
assertTrue( Modifier.isFinal( log.getModifiers() ) );
log.setAccessible( true );
try {
assertEquals( LoggingRegistry.getInstance().findExistingLoggingSource( new LoggingObject( "ValueMetaBase" ) )
.getLogChannelId(),
( (LogChannelInterface) log.get( null ) ).getLogChannelId() );
} finally {
log.setAccessible( false );
}
}
Date local( int year, int month, int dat, int hrs, int min, int sec, int ms ) {
GregorianCalendar cal = new GregorianCalendar( year, month - 1, dat, hrs, min, sec );
cal.set( Calendar.MILLISECOND, ms );
return cal.getTime();
}
Date utc( int year, int month, int dat, int hrs, int min, int sec, int ms ) {
GregorianCalendar cal = new GregorianCalendar( year, month - 1, dat, hrs, min, sec );
cal.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
cal.set( Calendar.MILLISECOND, ms );
return cal.getTime();
}
@Test
public void testGetNativeDataTypeClass() {
ValueMetaInterface base = new ValueMetaBase();
Class<?> clazz = null;
try {
clazz = base.getNativeDataTypeClass();
Assert.fail();
} catch ( KettleValueException expected ) {
// ValueMetaBase should throw an exception, as all sub-classes should override
Assert.assertNull( clazz );
}
}
@Test
public void testConvertDataUsingConversionMetaDataForCustomMeta() {
ValueMetaBase baseMeta = new ValueMetaBase( "CUSTOM_VALUEMETA_STRING", ValueMetaInterface.TYPE_STRING );
baseMeta.setConversionMetadata( new ValueMetaBase( "CUSTOM", 999 ) );
Object customData = new Object();
try {
baseMeta.convertDataUsingConversionMetaData( customData );
Assert.fail( "Should have thrown a Kettle Value Exception with a proper message. Not a NPE stack trace" );
} catch ( KettleValueException e ) {
String expectedMessage = "CUSTOM_VALUEMETA_STRING String : I can't convert the specified value to data type : 999";
assertEquals( expectedMessage, e.getMessage().trim() );
}
}
@Test
public void testConvertDataUsingConversionMetaData() throws KettleValueException, ParseException {
ValueMetaString base = new ValueMetaString();
double DELTA = 1e-15;
base.setConversionMetadata( new ValueMetaString( "STRING" ) );
Object defaultStringData = "STRING DATA";
String convertedStringData = (String) base.convertDataUsingConversionMetaData( defaultStringData );
assertEquals( "STRING DATA", convertedStringData );
base.setConversionMetadata( new ValueMetaInteger( "INTEGER" ) );
Object defaultIntegerData = "1";
long convertedIntegerData = (long) base.convertDataUsingConversionMetaData( defaultIntegerData );
assertEquals( 1, convertedIntegerData );
base.setConversionMetadata( new ValueMetaNumber( "NUMBER" ) );
Object defaultNumberData = "1.999";
double convertedNumberData = (double) base.convertDataUsingConversionMetaData( defaultNumberData );
assertEquals( 1.999, convertedNumberData, DELTA );
ValueMetaInterface dateConversionMeta = new ValueMetaDate( "DATE" );
dateConversionMeta.setDateFormatTimeZone( TimeZone.getTimeZone( "CST" ) );
base.setConversionMetadata( dateConversionMeta );
Object defaultDateData = "1990/02/18 00:00:00.000";
Date date1 = new Date( 635320800000L );
Date convertedDateData = (Date) base.convertDataUsingConversionMetaData( defaultDateData );
assertEquals( date1, convertedDateData );
base.setConversionMetadata( new ValueMetaBigNumber( "BIG_NUMBER" ) );
Object defaultBigNumber = String.valueOf( BigDecimal.ONE );
BigDecimal convertedBigNumber = (BigDecimal) base.convertDataUsingConversionMetaData( defaultBigNumber );
assertEquals( BigDecimal.ONE, convertedBigNumber );
base.setConversionMetadata( new ValueMetaBoolean( "BOOLEAN" ) );
Object defaultBoolean = "true";
boolean convertedBoolean = (boolean) base.convertDataUsingConversionMetaData( defaultBoolean );
assertEquals( true, convertedBoolean );
}
@Test
public void testGetCompatibleString() throws KettleValueException {
ValueMetaInteger valueMetaInteger = new ValueMetaInteger( "INTEGER" );
valueMetaInteger.setType( 5 ); // Integer
valueMetaInteger.setStorageType( 1 ); // STORAGE_TYPE_BINARY_STRING
assertEquals( "2", valueMetaInteger.getCompatibleString( new Long( 2 ) ) ); //BACKLOG-15750
}
@Test
public void testReadDataInet() throws Exception {
InetAddress localhost = InetAddress.getByName( "127.0.0.1" );
byte[] address = localhost.getAddress();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream( byteArrayOutputStream );
dataOutputStream.writeBoolean( false );
dataOutputStream.writeInt( address.length );
dataOutputStream.write( address );
DataInputStream dis = new DataInputStream( new ByteArrayInputStream( byteArrayOutputStream.toByteArray() ) );
ValueMetaBase vm = new ValueMetaInternetAddress();
assertEquals( localhost, vm.readData( dis ) );
}
@Test
public void testWriteDataInet() throws Exception {
InetAddress localhost = InetAddress.getByName( "127.0.0.1" );
byte[] address = localhost.getAddress();
ByteArrayOutputStream out1 = new ByteArrayOutputStream();
DataOutputStream dos1 = new DataOutputStream( out1 );
dos1.writeBoolean( false );
dos1.writeInt( address.length );
dos1.write( address );
byte[] expected = out1.toByteArray();
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
DataOutputStream dos2 = new DataOutputStream( out2 );
ValueMetaBase vm = new ValueMetaInternetAddress();
vm.writeData( dos2, localhost );
byte[] actual = out2.toByteArray();
assertArrayEquals( expected, actual );
}
private class StoreLoggingEventListener implements KettleLoggingEventListener {
private List<KettleLoggingEvent> events = new ArrayList<>();
@Override
public void eventAdded( KettleLoggingEvent event ) {
events.add( event );
}
public List<KettleLoggingEvent> getEvents() {
return events;
}
}
@Test
public void testConvertBigNumberToBoolean() {
ValueMetaBase vmb = new ValueMetaBase();
System.out.println( vmb.convertBigNumberToBoolean( new BigDecimal( "-234" ) ) );
System.out.println( vmb.convertBigNumberToBoolean( new BigDecimal( "234" ) ) );
System.out.println( vmb.convertBigNumberToBoolean( new BigDecimal( "0" ) ) );
System.out.println( vmb.convertBigNumberToBoolean( new BigDecimal( "1.7976E308" ) ) );
Assert.assertTrue( vmb.convertBigNumberToBoolean( new BigDecimal( "-234" ) ) );
Assert.assertTrue( vmb.convertBigNumberToBoolean( new BigDecimal( "234" ) ) );
Assert.assertFalse( vmb.convertBigNumberToBoolean( new BigDecimal( "0" ) ) );
Assert.assertTrue( vmb.convertBigNumberToBoolean( new BigDecimal( "1.7976E308" ) ) );
}
}