Repository: sqoop Updated Branches: refs/heads/sqoop2 2a9ae314e -> fa3c77b6a
http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/TestOracleUtilities.java ---------------------------------------------------------------------- diff --git a/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/TestOracleUtilities.java b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/TestOracleUtilities.java new file mode 100644 index 0000000..0ad78d2 --- /dev/null +++ b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/TestOracleUtilities.java @@ -0,0 +1,613 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sqoop.connector.jdbc.oracle; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.sqoop.connector.jdbc.oracle.configuration.FromJobConfig; +import org.apache.sqoop.connector.jdbc.oracle.util.OracleTable; +import org.apache.sqoop.connector.jdbc.oracle.util.OracleUtilities; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Unit tests for OraOopUtilities. + */ +public class TestOracleUtilities { + + @Test + public void testdecodeOracleTableName() { + + OracleTable context = null; + + // These are the possibilities for double-quote location... + // table + // "table" + // schema.table + // schema."table" + // "schema".table + // "schema"."table" + + // table + context = OracleUtilities.decodeOracleTableName("oraoop", "junk"); + Assert.assertEquals(context.getSchema(), "ORAOOP"); + Assert.assertEquals(context.getName(), "JUNK"); + + // "table" + context = OracleUtilities.decodeOracleTableName("oraoop", "\"Junk\""); + Assert.assertEquals(context.getSchema(), "ORAOOP"); + Assert.assertEquals(context.getName(), "Junk"); + + // schema.table + context = + OracleUtilities.decodeOracleTableName("oraoop", "targusr.junk"); + Assert.assertEquals(context.getSchema(), "TARGUSR"); + Assert.assertEquals(context.getName(), "JUNK"); + + // schema."table" + context = + OracleUtilities.decodeOracleTableName("oraoop", "targusr.\"Junk\""); + Assert.assertEquals(context.getSchema(), "TARGUSR"); + Assert.assertEquals(context.getName(), "Junk"); + + // "schema".table + context = + OracleUtilities.decodeOracleTableName("oraoop", "\"Targusr\".junk"); + Assert.assertEquals(context.getSchema(), "Targusr"); + Assert.assertEquals(context.getName(), "JUNK"); + + // "schema"."table" + String inputStr = "\"Targusr\".\"Junk\""; + context = OracleUtilities.decodeOracleTableName("oraoop", inputStr); + Assert.assertEquals(context.getSchema(), "Targusr"); + Assert.assertEquals(context.getName(), "Junk"); + + // Test for "." within schema... + context = + OracleUtilities.decodeOracleTableName("oraoop", "\"targ.usr\".junk"); + Assert.assertEquals(context.getSchema(), "targ.usr"); + Assert.assertEquals(context.getName(), "JUNK"); + + // Test for "." within table... + context = + OracleUtilities.decodeOracleTableName("oraoop", + "targusr.\"junk.tab.with.dots\""); + Assert.assertEquals(context.getSchema(), "TARGUSR"); + Assert.assertEquals(context.getName(), "junk.tab.with.dots"); + + // Test for "." within schema and within table... + context = + OracleUtilities.decodeOracleTableName("oraoop", + "\"targ.usr\".\"junk.tab.with.dots\""); + Assert.assertEquals(context.getSchema(), "targ.usr"); + Assert.assertEquals(context.getName(), "junk.tab.with.dots"); + } + + @Test + public void testgetCurrentMethodName() { + + String actual = OracleUtilities.getCurrentMethodName(); + String expected = "testgetCurrentMethodName()"; + + Assert.assertEquals(expected, actual); + + } + + @Test + public void testgenerateDataChunkId() { + + String expected; + String actual; + + expected = "1_1"; + actual = OracleUtilities.generateDataChunkId(1, 1); + Assert.assertEquals(expected, actual); + + expected = "1234_99"; + actual = OracleUtilities.generateDataChunkId(1234, 99); + Assert.assertEquals(expected, actual); + } + +/* @Test + public void testgetDuplicatedStringArrayValues() { + + try { + OracleUtilities.getDuplicatedStringArrayValues(null, false); + Assert.fail("An IllegalArgumentException should be been thrown."); + } catch (IllegalArgumentException ex) { + // This is what we want to happen. + } + + String[] duplicates = null; + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] {}, false); + Assert.assertEquals(0, duplicates.length); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "a", "b", + "c", }, false); + Assert.assertEquals(0, duplicates.length); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "a", "A", + "b", }, false); + Assert.assertEquals(0, duplicates.length); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "a", "A", + "b", }, true); + Assert.assertEquals(1, duplicates.length); + Assert.assertEquals("A", duplicates[0]); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "A", "a", + "b", }, true); + Assert.assertEquals(1, duplicates.length); + Assert.assertEquals("a", duplicates[0]); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "A", "a", + "b", "A", }, false); + Assert.assertEquals(1, duplicates.length); + Assert.assertEquals("A", duplicates[0]); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "A", "a", + "b", "A", }, true); + Assert.assertEquals(2, duplicates.length); + Assert.assertEquals("a", duplicates[0]); + Assert.assertEquals("A", duplicates[1]); + + duplicates = + OraOopUtilities.getDuplicatedStringArrayValues(new String[] { "A", "a", + "b", "A", "A", }, true); + Assert.assertEquals(2, duplicates.length); + Assert.assertEquals("a", duplicates[0]); + Assert.assertEquals("A", duplicates[1]); + }*/ + + @Test + public void testgetFullExceptionMessage() { + + try { + + try { + try { + throw new IOException("lorem ipsum!"); + } catch (IOException ex) { + throw new SQLException("dolor sit amet", ex); + } + } catch (SQLException ex) { + throw new RuntimeException("consectetur adipisicing elit", ex); + } + + } catch (Exception ex) { + String msg = OracleUtilities.getFullExceptionMessage(ex); + if (!msg.contains("IOException") || !msg.contains("lorem ipsum!")) { + Assert + .fail("Inner exception text has not been included in the message"); + } + if (!msg.contains("SQLException") || !msg.contains("dolor sit amet")) { + Assert + .fail("Inner exception text has not been included in the message"); + } + if (!msg.contains("RuntimeException") + || !msg.contains("consectetur adipisicing elit")) { + Assert + .fail("Outer exception text has not been included in the message"); + } + } + } + +/* @Test + public void testGetOraOopOracleDataChunkMethod() { + try { + OracleUtilities.getOraOopOracleDataChunkMethod(null); + Assert.fail("An IllegalArgumentException should be been thrown."); + } catch (IllegalArgumentException ex) { + // This is what we want to happen. + } + + OraOopConstants.OraOopOracleDataChunkMethod dataChunkMethod; + Configuration conf = new Configuration(); + + // Check the default is ROWID + dataChunkMethod = OraOopUtilities.getOraOopOracleDataChunkMethod(conf); + Assert.assertEquals(OraOopConstants.OraOopOracleDataChunkMethod.ROWID, + dataChunkMethod); + + // Invalid value specified + OraOopUtilities.LOG.setCacheLogEntries(true); + OraOopUtilities.LOG.clearCache(); + conf.set(OraOopConstants.ORAOOP_ORACLE_DATA_CHUNK_METHOD, "loremipsum"); + dataChunkMethod = OraOopUtilities.getOraOopOracleDataChunkMethod(conf); + String logText = OraOopUtilities.LOG.getLogEntries(); + OraOopUtilities.LOG.setCacheLogEntries(false); + if (!logText.toLowerCase().contains("loremipsum")) { + Assert + .fail("The LOG should inform the user they've selected an invalid " + + "data chunk method - and what that was."); + } + Assert.assertEquals("Should have used the default value", + OraOopConstants.ORAOOP_ORACLE_DATA_CHUNK_METHOD_DEFAULT, + dataChunkMethod); + + // Valid value specified + conf.set(OraOopConstants.ORAOOP_ORACLE_DATA_CHUNK_METHOD, "partition"); + dataChunkMethod = OraOopUtilities.getOraOopOracleDataChunkMethod(conf); + Assert.assertEquals(OraOopConstants.OraOopOracleDataChunkMethod.PARTITION, + dataChunkMethod); + }*/ + + /*@Test + public void testgetOraOopOracleBlockToSplitAllocationMethod() { + + // Invalid arguments test... + try { + OraOopUtilities.getOraOopOracleBlockToSplitAllocationMethod(null, + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.RANDOM); + Assert.fail("An IllegalArgumentException should be been thrown."); + } catch (IllegalArgumentException ex) { + // This is what we want to happen. + } + + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod allocationMethod; + org.apache.hadoop.conf.Configuration conf = new Configuration(); + + // No configuration property - and RANDOM used by default... + allocationMethod = + OraOopUtilities.getOraOopOracleBlockToSplitAllocationMethod(conf, + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.RANDOM); + Assert.assertEquals( + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.RANDOM, + allocationMethod); + + // No configuration property - and SEQUENTIAL used by default... + allocationMethod = + OraOopUtilities.getOraOopOracleBlockToSplitAllocationMethod( + conf, + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.SEQUENTIAL); + Assert.assertEquals( + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.SEQUENTIAL, + allocationMethod); + + // An invalid property value specified... + OraOopUtilities.LOG.setCacheLogEntries(true); + OraOopUtilities.LOG.clearCache(); + conf.set(OraOopConstants.ORAOOP_ORACLE_BLOCK_TO_SPLIT_ALLOCATION_METHOD, + "loremipsum"); + allocationMethod = + OraOopUtilities.getOraOopOracleBlockToSplitAllocationMethod( + conf, + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.SEQUENTIAL); + String logText = OraOopUtilities.LOG.getLogEntries(); + OraOopUtilities.LOG.setCacheLogEntries(false); + if (!logText.toLowerCase().contains("loremipsum")) { + Assert + .fail("The LOG should inform the user they've selected an invalid " + + "allocation method - and what that was."); + } + + if (!logText.contains("ROUNDROBIN or SEQUENTIAL or RANDOM")) { + Assert.fail("The LOG should inform the user what the valid choices are."); + } + + // An valid property value specified... + conf.set(OraOopConstants.ORAOOP_ORACLE_BLOCK_TO_SPLIT_ALLOCATION_METHOD, + "sequential"); + allocationMethod = + OraOopUtilities.getOraOopOracleBlockToSplitAllocationMethod( + conf, + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.SEQUENTIAL); + Assert.assertEquals( + OraOopConstants.OraOopOracleBlockToSplitAllocationMethod.SEQUENTIAL, + allocationMethod); + }*/ + + /*@Test + public void testgetOraOopTableImportWhereClauseLocation() { + + // Invalid arguments test... + try { + OraOopUtilities.getOraOopTableImportWhereClauseLocation(null, + OraOopConstants.OraOopTableImportWhereClauseLocation.SPLIT); + Assert.fail("An IllegalArgumentException should be been thrown."); + } catch (IllegalArgumentException ex) { + // This is what we want to happen. + } + + OraOopConstants.OraOopTableImportWhereClauseLocation location; + org.apache.hadoop.conf.Configuration conf = new Configuration(); + + // No configuration property - and SPLIT used by default... + location = + OraOopUtilities.getOraOopTableImportWhereClauseLocation(conf, + OraOopConstants.OraOopTableImportWhereClauseLocation.SPLIT); + Assert.assertEquals( + OraOopConstants.OraOopTableImportWhereClauseLocation.SPLIT, location); + + // An invalid property value specified... + OraOopUtilities.LOG.setCacheLogEntries(true); + OraOopUtilities.LOG.clearCache(); + conf.set(OraOopConstants.ORAOOP_TABLE_IMPORT_WHERE_CLAUSE_LOCATION, + "loremipsum"); + location = + OraOopUtilities.getOraOopTableImportWhereClauseLocation(conf, + OraOopConstants.OraOopTableImportWhereClauseLocation.SPLIT); + String logText = OraOopUtilities.LOG.getLogEntries(); + OraOopUtilities.LOG.setCacheLogEntries(false); + if (!logText.toLowerCase().contains("loremipsum")) { + Assert + .fail("The LOG should inform the user they've selected an invalid " + + "where-clause-location - and what that was."); + } + + if (!logText.contains("SUBSPLIT or SPLIT")) { + Assert.fail("The LOG should inform the user what the valid choices are."); + } + + // An valid property value specified... + conf.set(OraOopConstants.ORAOOP_TABLE_IMPORT_WHERE_CLAUSE_LOCATION, + "split"); + location = + OraOopUtilities.getOraOopTableImportWhereClauseLocation(conf, + OraOopConstants.OraOopTableImportWhereClauseLocation.SUBSPLIT); + Assert.assertEquals( + OraOopConstants.OraOopTableImportWhereClauseLocation.SPLIT, location); + + }*/ + + /*@Test + public void testpadLeft() { + + String expected = " a"; + String actual = OracleUtilities.padLeft("a", 4); + Assert.assertEquals(expected, actual); + + expected = "abcd"; + actual = OraOopUtilities.padLeft("abcd", 3); + Assert.assertEquals(expected, actual); + } + + @Test + public void testpadRight() { + + String expected = "a "; + String actual = OraOopUtilities.padRight("a", 4); + Assert.assertEquals(expected, actual); + + expected = "abcd"; + actual = OraOopUtilities.padRight("abcd", 3); + Assert.assertEquals(expected, actual); + }*/ + + /*@Test + public void testReplaceConfigurationExpression() { + + org.apache.hadoop.conf.Configuration conf = new Configuration(); + + // Default value used... + String actual = + OraOopUtilities.replaceConfigurationExpression( + "alter session set timezone = '{oracle.sessionTimeZone|GMT}';", + conf); + String expected = "alter session set timezone = 'GMT';"; + Assert.assertEquals("OraOop configuration expression failure.", expected, + actual); + + // Configuration property value exists... + conf.set("oracle.sessionTimeZone", "Africa/Algiers"); + actual = + OraOopUtilities.replaceConfigurationExpression( + "alter session set timezone = '{oracle.sessionTimeZone|GMT}';", + conf); + expected = "alter session set timezone = 'Africa/Algiers';"; + Assert.assertEquals("OraOop configuration expression failure.", expected, + actual); + + // Multiple properties in one expression... + conf.set("expr1", "1"); + conf.set("expr2", "2"); + conf.set("expr3", "3"); + conf.set("expr4", "4"); + actual = + OraOopUtilities.replaceConfigurationExpression("set {expr1}={expr2};", + conf); + expected = "set 1=2;"; + Assert.assertEquals("OraOop configuration expression failure.", expected, + actual); + + actual = + OraOopUtilities.replaceConfigurationExpression( + "set {expr4|0}={expr5|5};", conf); + expected = "set 4=5;"; + Assert.assertEquals("OraOop configuration expression failure.", expected, + actual); + }*/ + + /*@Test + public void testStackContainsClass() { + + if (OracleUtilities.stackContainsClass("lorem.ipsum.dolor")) { + Assert.fail("There's no way the stack actually contains this!"); + } + + String expected = "org.apache.sqoop.manager.oracle.TestOraOopUtilities"; + if (!OracleUtilities.stackContainsClass(expected)) { + Assert.fail("The stack should contain the class:" + expected); + } + }*/ + + @Test + public void testGetImportHint() { + FromJobConfig jobConfig = new FromJobConfig(); + + String hint = OracleUtilities.getImportHint(jobConfig); + Assert.assertEquals(hint, "/*+ NO_INDEX(t) */ ", "Default import hint"); + + jobConfig.queryHint = "NO_INDEX(t) SCN_ASCENDING"; + hint = OracleUtilities.getImportHint(jobConfig); + Assert.assertEquals(hint, "/*+ NO_INDEX(t) SCN_ASCENDING */ ", + "Changed import hint"); + + jobConfig.queryHint = " "; + hint = OracleUtilities.getImportHint(jobConfig); + Assert.assertEquals(hint, "", "Whitespace import hint"); + + } + + @Test + public void testSplitStringList() { + List<String> result = null; + List<String> expected = null; + + expected = new ArrayList<String>(); + expected.add("abcde"); + expected.add("ghijklm"); + result = OracleUtilities.splitStringList("abcde,ghijklm"); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("\"abcde\""); + expected.add("\"ghijklm\""); + result = OracleUtilities.splitStringList("\"abcde\",\"ghijklm\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("abcde"); + expected.add("\"ghijklm\""); + result = OracleUtilities.splitStringList("abcde,\"ghijklm\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("\"abcde\""); + expected.add("ghijklm"); + result = OracleUtilities.splitStringList("\"abcde\",ghijklm"); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("\"ab,cde\""); + expected.add("ghijklm"); + result = OracleUtilities.splitStringList("\"ab,cde\",ghijklm"); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("abcde"); + expected.add("\"ghi,jklm\""); + result = OracleUtilities.splitStringList("abcde,\"ghi,jklm\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("\"ab,cde\""); + expected.add("\"ghi,jklm\""); + result = OracleUtilities.splitStringList("\"ab,cde\",\"ghi,jklm\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("\"ab,cde\""); + expected.add("\"ghi,jklm\""); + expected.add("\",Lorem\""); + expected.add("\"ip!~sum\""); + expected.add("\"do,lo,,r\""); + expected.add("\"s#it\""); + expected.add("\"am$e$t\""); + result = + OracleUtilities + .splitStringList("\"ab,cde\",\"ghi,jklm\",\",Lorem\",\"ip!~sum\"," + + "\"do,lo,,r\",\"s#it\",\"am$e$t\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("LOREM"); + expected.add("IPSUM"); + expected.add("DOLOR"); + expected.add("SIT"); + expected.add("AMET"); + result = OracleUtilities.splitStringList("LOREM,IPSUM,DOLOR,SIT,AMET"); + Assert.assertEquals(expected, result); + } + + @Test + public void testSplitOracleStringList() { + List<String> result = null; + List<String> expected = null; + + expected = new ArrayList<String>(); + expected.add("LOREM"); + expected.add("IPSUM"); + expected.add("DOLOR"); + expected.add("SIT"); + expected.add("AMET"); + result = + OracleUtilities.splitOracleStringList("lorem,ipsum,dolor,sit,amet"); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("LOREM"); + expected.add("ipsum"); + expected.add("dolor"); + expected.add("SIT"); + expected.add("amet"); + result = + OracleUtilities + .splitOracleStringList("lorem,\"ipsum\",\"dolor\",sit,\"amet\""); + Assert.assertEquals(expected, result); + + expected = new ArrayList<String>(); + expected.add("LOREM"); + expected.add("ip,sum"); + expected.add("dol$or"); + expected.add("SIT"); + expected.add("am!~#et"); + result = + OracleUtilities + .splitOracleStringList("lorem,\"ip,sum\",\"dol$or\",sit,\"am!~#et\""); + Assert.assertEquals(expected, result); + } + + /*@Test + public void testAppendJavaSecurityEgd() { + String confProperty = "mapred.child.java.opts"; + String confValue = "-Djava.security.egd=file:///dev/urandom"; + Configuration conf = new Configuration(); + + String expected = confValue; + String actual = null; + conf.set(confProperty, ""); + OraOopUtilities.appendJavaSecurityEgd(conf); + actual = conf.get(confProperty); + Assert.assertEquals("Append to empty string", expected, actual); + + expected = "-Djava.security.egd=file:/dev/random"; + conf.set(confProperty, expected); + OraOopUtilities.appendJavaSecurityEgd(conf); + actual = conf.get(confProperty); + Assert.assertEquals("Append to empty string", expected, actual); + + expected = confValue + " -Xmx201m"; + conf.set(confProperty, "-Xmx201m"); + OraOopUtilities.appendJavaSecurityEgd(conf); + actual = conf.get(confProperty); + Assert.assertEquals("Append to empty string", expected, actual); + }*/ +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleConnectionFactoryTest.java ---------------------------------------------------------------------- diff --git a/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleConnectionFactoryTest.java b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleConnectionFactoryTest.java new file mode 100644 index 0000000..a4caa85 --- /dev/null +++ b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleConnectionFactoryTest.java @@ -0,0 +1,497 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sqoop.connector.jdbc.oracle.integration; + +import java.io.StringWriter; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import org.apache.log4j.Layout; +import org.apache.log4j.Logger; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.WriterAppender; +import org.apache.sqoop.connector.jdbc.oracle.OracleJdbcConnectorConstants; +import org.apache.sqoop.connector.jdbc.oracle.configuration.ConnectionConfig; +import org.apache.sqoop.connector.jdbc.oracle.util.OracleConnectionFactory; +import org.apache.sqoop.connector.jdbc.oracle.util.OracleQueries; +import org.apache.sqoop.connector.jdbc.oracle.util.OracleTable; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Test OracleConnectionFactory class including initialization statements. + */ +public class OracleConnectionFactoryTest extends OracleTestCase { + + private static final String TEST_TABLE_NAME = "sqoop_conn_test"; + + private static final String SQL_TABLE = + "WITH sqltable AS " + + " ( " + + " SELECT executions, rows_processed, fetches, " + + " ROUND (rows_processed / executions, 2) AS rows_per_exec, " + + " ROUND (rows_processed / fetches, 2) AS rows_per_fetch, " + + " ROUND (LEAST ( ROUND (rows_processed / fetches, 2) " + + " / LEAST (rows_processed / executions, 10), " + + " 1 " + + " ), " + + " 2 " + + " ) batch_efficiency, " + + " sql_text, u.username parsing_schema_name, buffer_gets, " + + " disk_reads, cpu_time/1000 cpu_time, elapsed_time/1000" + + " elapsed_time, hash_value sql_id, child_number " + + " FROM v$sql s join all_users u on (u.user_id=s.parsing_user_id) " + + " WHERE fetches > 0 AND executions > 0 AND rows_processed > 0 " + + " AND parsing_schema_id <> 0 AND sql_text like " + + " 'select%dba_objects' )" + + "SELECT sql_id, child_number, array_wastage, " + + " rows_processed, fetches, rows_per_exec, " + + " rows_per_fetch, parsing_schema_name, buffer_gets, disk_reads, " + + " cpu_time, elapsed_time, sql_text,executions " + + " FROM (SELECT sql_id, " + + " child_number, " + + " rows_processed * (1 - batch_efficiency) array_wastage, " + + " rows_processed, " + " fetches, " + + " rows_per_exec, " + + " rows_per_fetch, " + " sql_text, " + + " parsing_schema_name, " + + " buffer_gets, " + " disk_reads, " + + " cpu_time, " + " elapsed_time, " + + " executions " + " FROM sqltable) "; + + @Test + public void testSetJdbcFetchSize() { + setAndCheckJdbcFetchSize(45); + setAndCheckJdbcFetchSize(2000); + } + + private void setAndCheckJdbcFetchSize(int jdbcFetchSize) { + + try { + Connection conn = getConnection(); + + String uniqueJunk = + (new SimpleDateFormat("yyyyMMddHHmmsszzz")).format(new Date()) + + jdbcFetchSize; + + OracleQueries.setJdbcFetchSize(conn, Integer.valueOf(jdbcFetchSize)); + + String uniqueSql = + String.format("select /*%s*/ * from dba_objects", uniqueJunk); + // Usually dba_objects will have a lot of rows + ResultSet resultSet1 = conn.createStatement().executeQuery(uniqueSql); + while (resultSet1.next()) { + // Nothing to do + continue; + } + + ResultSet resultSet2 = + conn.createStatement().executeQuery(SQL_TABLE); + boolean sqlFound = false; + double rowsPerFetch = 0; + while (resultSet2.next()) { + String sqlText = resultSet2.getString("SQL_TEXT"); + if (sqlText.contains(uniqueJunk)) { + sqlFound = true; + rowsPerFetch = resultSet2.getDouble("ROWS_PER_FETCH"); + break; + } + } + + if (!sqlFound) { + Assert + .fail("Unable to find the performance metrics for the SQL " + + "statement being used to check the JDBC fetch size."); + } + + if (rowsPerFetch < jdbcFetchSize * 0.95 + || rowsPerFetch > jdbcFetchSize * 1.05) { + Assert + .fail(String + .format( + "The measured JDBC fetch size is not within 5%% of what we " + + "expected. Expected=%s rows/fetch, actual=%s rows/fetch", + jdbcFetchSize, rowsPerFetch)); + } + + } catch (SQLException ex) { + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testCreateOracleJdbcConnectionBadUserName() { + + try { + OracleConnectionFactory.createOracleJdbcConnection( + OracleJdbcConnectorConstants.ORACLE_JDBC_DRIVER_CLASS, + provider.getConnectionUrl(), + provider.getConnectionUsername() + "_INVALID", + provider.getConnectionPassword()); + + Assert + .fail("OracleConnectionFactory should have thrown an exception in " + + "response to a rubbish user name."); + + } catch (SQLException ex) { + Assert.assertEquals(ex.getErrorCode(), 1017); // <- ORA-01017 invalid + // username/password; logon denied. + } + } + + @Test + public void testCreateOracleJdbcConnectionBadPassword() { + + try { + OracleConnectionFactory.createOracleJdbcConnection( + OracleJdbcConnectorConstants.ORACLE_JDBC_DRIVER_CLASS, + provider.getConnectionUrl(), + provider.getConnectionUsername(), + "a" + provider.getConnectionPassword()); + + Assert + .fail("OracleConnectionFactory should have thrown an exception in " + + "response to a rubbish password."); + + } catch (SQLException ex) { + Assert.assertEquals(ex.getErrorCode(), 1017); // <- ORA-01017 invalid + // username/password; logon denied. + } + } + + @Test + public void testCreateOracleJdbcConnectionOk() { + + try { + Connection conn = getConnection(); + + Assert.assertEquals(conn.isValid(15), true, + "The connection to the Oracle database does not appear to be valid."); + + ResultSet resultSet = + conn.createStatement().executeQuery( + "select instance_name from v$instance"); + if (!resultSet.next() || resultSet.getString(1).isEmpty()) { + Assert.fail("Got blank instance name from v$instance"); + } + } catch (SQLException ex) { + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testExecuteOraOopSessionInitializationStatements() { + + Logger log = Logger.getLogger(OracleConnectionFactory.class); + StringWriter stringWriter = new StringWriter(); + Layout layout = new PatternLayout("%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n"); + WriterAppender writerAppender = new WriterAppender(layout, stringWriter); + log.addAppender(writerAppender); + + // Check that the default session-initialization statements are reflected in + // the log... + stringWriter.getBuffer().setLength(0); + checkExecuteOraOopSessionInitializationStatements(null); + checkLogContainsText(stringWriter.toString(), + "Initializing Oracle session with SQL : alter session disable " + + "parallel query"); + checkLogContainsText( + stringWriter.toString(), + "Initializing Oracle session with SQL : alter session set " + + "\"_serial_direct_read\"=true"); + + // Check that the absence of session-initialization statements is reflected + // in the log... + stringWriter.getBuffer().setLength(0); + checkExecuteOraOopSessionInitializationStatements(";"); + checkLogContainsText(stringWriter.toString(), + "No Oracle 'session initialization' statements were found to execute"); + + // This should throw an exception, as Oracle won't know what to do with + // this... + stringWriter.getBuffer().setLength(0); + checkExecuteOraOopSessionInitializationStatements("loremipsum"); + checkLogContainsText(stringWriter.toString(), "loremipsum"); + checkLogContainsText(stringWriter.toString(), + "ORA-00900: invalid SQL statement"); + + Connection conn = getConnection(); + try { + + // Try a session-initialization statement that creates a table... + dropTable(conn, TEST_TABLE_NAME); + checkExecuteOraOopSessionInitializationStatements("create table " + + TEST_TABLE_NAME + " (col1 varchar2(1))"); + if (!doesTableExist(conn, TEST_TABLE_NAME)) { + Assert.fail("The session-initialization statement to create the table " + + TEST_TABLE_NAME + " did not work."); + } + + // Try a sequence of a few statements... + dropTable(conn, TEST_TABLE_NAME); + checkExecuteOraOopSessionInitializationStatements("create table " + + TEST_TABLE_NAME + " (col1 number);insert into " + + TEST_TABLE_NAME + " values (1) ; --update " + + TEST_TABLE_NAME + " set col1 = col1 + 1; update " + + TEST_TABLE_NAME + + " set col1 = col1 + 1; commit ;;"); + + ResultSet resultSet = + conn.createStatement().executeQuery( + "select col1 from " + TEST_TABLE_NAME); + resultSet.next(); + int actualValue = resultSet.getInt("col1"); + if (actualValue != 2) { + Assert.fail("The table " + TEST_TABLE_NAME + + " does not contain the data we expected."); + } + + dropTable(conn, TEST_TABLE_NAME); + + } catch (Exception ex) { + Assert.fail(ex.getMessage()); + } + log.removeAppender(writerAppender); + } + + @Test + public void testParseOraOopSessionInitializationStatements() { + + List<String> statements = null; + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(null); + Assert.assertEquals(0, statements.size()); + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(""); + Assert.assertEquals(0, statements.size()); + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(";"); + Assert.assertEquals(0, statements.size()); + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(";--;\t--"); + Assert.assertEquals(0, statements.size()); + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements("\ta"); + Assert.assertEquals(1, statements.size()); + if (!statements.get(0).equalsIgnoreCase("a")) { + Assert.fail("Expected a session initialization statement of \"a\""); + } + + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements("a;b;--c;d;"); + Assert.assertEquals(3, statements.size()); + if (!statements.get(0).equalsIgnoreCase("a")) { + Assert.fail("Expected a session initialization statement of \"a\""); + } + if (!statements.get(1).equalsIgnoreCase("b")) { + Assert.fail("Expected a session initialization statement of \"b\""); + } + if (!statements.get(2).equalsIgnoreCase("d")) { + Assert.fail("Expected a session initialization statement of \"d\""); + } + + // Expressions without default values... + /*conf.set(OraOopConstants.ORAOOP_SESSION_INITIALIZATION_STATEMENTS, + "set a={expr1};b={expr2}/{expr3};"); + conf.set("expr1", "1"); + conf.set("expr2", "2"); + conf.set("expr3", "3"); + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(conf); + Assert.assertEquals(2, statements.size()); + String actual = statements.get(0); + String expected = "set a=1"; + if (!actual.equalsIgnoreCase(expected)) { + Assert.fail(String.format( + "Expected a session initialization statement of \"%s\", but got \"%s\"." + , expected, actual)); + } + actual = statements.get(1); + expected = "b=2/3"; + if (!actual.equalsIgnoreCase(expected)) { + Assert.fail(String.format( + "Expected a session initialization statement of \"%s\", but got \"%s\"." + , expected, actual)); + } + + // Expressions with default values... + conf.set(OraOopConstants.ORAOOP_SESSION_INITIALIZATION_STATEMENTS, + "set c={expr3|66};d={expr4|15}/{expr5|90};"); + conf.set("expr3", "20"); + // conf.set("expr4", "21"); + // conf.set("expr5", "23"); + statements = + OracleConnectionFactory + .parseOraOopSessionInitializationStatements(conf); + Assert.assertEquals(2, statements.size()); + actual = statements.get(0); + expected = "set c=20"; + if (!actual.equalsIgnoreCase(expected)) { + Assert.fail(String.format( + "Expected a session initialization statement of \"%s\", but got \"%s\"." + , expected, actual)); + } + actual = statements.get(1); + expected = "d=15/90"; + if (!actual.equalsIgnoreCase(expected)) { + Assert.fail(String.format( + "Expected a session initialization statement of \"%s\", but got \"%s\"." + , expected, actual)); + }*/ + + } + + private void dropTable(Connection conn, String tableName) { + + try { + conn.createStatement().executeQuery("drop table " + tableName); + + if (doesTableExist(conn, tableName)) { + Assert.fail("Unable to drop the table " + tableName); + } + } catch (SQLException ex) { + if (ex.getErrorCode() != 942) { // <- Table or view does not exist + Assert.fail(ex.getMessage()); + } + } + } + + private boolean doesTableExist(Connection conn, String tableName) { + + boolean result = false; + try { + List<OracleTable> tables = OracleQueries.getTables(conn); + + for (int idx = 0; idx < tables.size(); idx++) { + if (tables.get(idx).getName().equalsIgnoreCase(tableName)) { + result = true; + break; + } + } + } catch (SQLException ex) { + Assert.fail(ex.getMessage()); + } + return result; + } + + private void checkLogContainsText(String log, String text) { + + if (!log.toLowerCase().contains(text.toLowerCase())) { + Assert.fail( + "The LOG does not contain the following text (when it should):\n\t" + + text); + } + } + + private void checkExecuteOraOopSessionInitializationStatements( + String statements) { + + Connection conn = getConnection(); + + OracleConnectionFactory.executeOraOopSessionInitializationStatements( + conn, statements); + } + + @Test + public void testSetSessionClientInfo() { + + Connection conn = getConnection(); + + ConnectionConfig connectionConfig = new ConnectionConfig(); + + String moduleName = OracleJdbcConnectorConstants.ORACLE_SESSION_MODULE_NAME; + String actionName = + (new SimpleDateFormat("yyyyMMddHHmmsszzz")).format(new Date()); + + connectionConfig.actionName = actionName; + + try { + PreparedStatement statement = + conn.prepareStatement("select process, module, action " + + "from v$session " + "where module = ? and action = ?"); + statement.setString(1, moduleName); + statement.setString(2, actionName); + + // Check no session have this action name - because we haven't applied to + // our session yet... + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) { + Assert + .fail("There should be no Oracle sessions with an action name of " + + actionName); + } + + // Apply this action name to our session... + OracleConnectionFactory.setSessionClientInfo(conn, connectionConfig); + + // Now check there is a session with our action name... + int sessionFoundCount = 0; + resultSet = statement.executeQuery(); + while (resultSet.next()) { + sessionFoundCount++; + } + + if (sessionFoundCount < 1) { + Assert + .fail("Unable to locate an Oracle session with the expected module " + + "and action."); + } + + if (sessionFoundCount > 1) { + Assert + .fail("Multiple sessions were found with the expected module and " + + "action - we only expected to find one."); + } + } catch (SQLException ex) { + Assert.fail(ex.getMessage()); + } + + } + + private Connection getConnection() { + + try { + return OracleConnectionFactory.createOracleJdbcConnection( + OracleJdbcConnectorConstants.ORACLE_JDBC_DRIVER_CLASS, + provider.getConnectionUrl(), + provider.getConnectionUsername(), provider.getConnectionPassword()); + } catch (SQLException ex) { + Assert.fail(ex.getMessage()); + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleQueriesTest.java ---------------------------------------------------------------------- diff --git a/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleQueriesTest.java b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleQueriesTest.java new file mode 100644 index 0000000..48ab922 --- /dev/null +++ b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleQueriesTest.java @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sqoop.connector.jdbc.oracle.integration; + +import java.sql.Connection; +import java.sql.PreparedStatement; + +import org.apache.sqoop.connector.jdbc.oracle.util.OracleQueries; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Test Oracle queries against Oracle database. + */ +public class OracleQueriesTest extends OracleTestCase { + + @Test + public void testGetCurrentSchema() throws Exception { + Connection conn = provider.getConnection(); + + String schema = OracleQueries.getCurrentSchema(conn); + Assert.assertEquals(schema.toUpperCase(), + provider.getConnectionUsername().toUpperCase()); + + PreparedStatement stmt = + conn.prepareStatement("ALTER SESSION SET CURRENT_SCHEMA=SYS"); + stmt.execute(); + + schema = OracleQueries.getCurrentSchema(conn); + Assert.assertEquals(schema, "SYS"); + } + +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleTestCase.java ---------------------------------------------------------------------- diff --git a/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleTestCase.java b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleTestCase.java new file mode 100644 index 0000000..7be9a15 --- /dev/null +++ b/connector/connector-oracle-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/oracle/integration/OracleTestCase.java @@ -0,0 +1,41 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sqoop.connector.jdbc.oracle.integration; + +import org.apache.sqoop.common.test.db.OracleProvider; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +@Test(groups = "oracle") +public abstract class OracleTestCase { + + protected static OracleProvider provider; + + @BeforeGroups(value = "oracle") + public static void startProvider() throws Exception { + provider = new OracleProvider(); + provider.start(); + } + + @AfterGroups(value = "oracle") + public static void stopProvider() { + provider.stop(); + } + +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/connector/pom.xml ---------------------------------------------------------------------- diff --git a/connector/pom.xml b/connector/pom.xml index 1b69180..be8fcb1 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -40,6 +40,7 @@ limitations under the License. <module>connector-kafka</module> <module>connector-ftp</module> <module>connector-sftp</module> + <module>connector-oracle-jdbc</module> <!-- Uncomment and finish connectors after sqoop framework will become stable <module>connector-mysql-jdbc</module> <module>connector-mysql-fastpath</module> http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index ab505f4..f33958c 100644 --- a/pom.xml +++ b/pom.xml @@ -381,6 +381,17 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sqoop.connector</groupId> + <artifactId>sqoop-connector-oracle-jdbc</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.sqoop.connector</groupId> + <artifactId>sqoop-connector-oracle-jdbc</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.apache.sqoop.connector</groupId> <artifactId>sqoop-connector-mysql-jdbc</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/sqoop/blob/fa3c77b6/server/pom.xml ---------------------------------------------------------------------- diff --git a/server/pom.xml b/server/pom.xml index ca068e0..370a6a2 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -108,6 +108,11 @@ limitations under the License. </dependency> <dependency> + <groupId>org.apache.sqoop.connector</groupId> + <artifactId>sqoop-connector-oracle-jdbc</artifactId> + </dependency> + + <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <scope>provided</scope>
