/** * 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.jena.jdbc; import java.io.File ; import java.io.FileWriter ; import java.io.IOException ; import java.sql.Connection ; import java.sql.SQLException ; import java.util.Iterator ; import java.util.Properties ; import org.apache.jena.graph.Node ; import org.apache.jena.jdbc.connections.JenaConnection ; import org.apache.jena.jdbc.postprocessing.ResultsEcho ; import org.apache.jena.jdbc.postprocessing.ResultsPostProcessor ; import org.apache.jena.jdbc.preprocessing.CommandPreProcessor ; import org.apache.jena.jdbc.preprocessing.Echo ; import org.apache.jena.query.ARQ ; import org.apache.jena.system.JenaSystem ; import org.junit.Assert ; import org.junit.Assume ; import org.junit.Test ; /** * Abstract tests for {@link JenaDriver} implementations * */ public abstract class AbstractJenaDriverTests { static { JenaSystem.init() ; } /** * Method which derived classes must implement to return an instance of * their driver implementation. */ protected abstract JenaDriver getDriver() throws SQLException; /** * Method which derived classes must implement to provide a connection URL * for an empty database. * <p> * {@code null} may be returned if this is not supported by the driver * implementation. If this is the case then relevant tests will be skipped. * </p> * * @return Connection URL or null * @throws SQLException */ protected abstract String getConnectionUrl() throws SQLException; /** * Method which derives classes must implement to provide a connection URL * which is known to result in a creation error in the form of a * {@link SQLException} when the * {@link JenaDriver#connect(String, java.util.Properties)} is called with * it. * <p> * {@code null} may be returned if there are no invalid connection URLs for * the driver (this is considered highly unlikely) * </p> * * @return Bad Connection URL or null */ protected abstract String getBadConnectionUrl(); /** * Test that an implementation will accept its own URLs * * @throws SQLException */ @Test public void driver_accepts_01() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); JenaDriver driver = this.getDriver(); Assert.assertTrue(driver.acceptsURL(url)); } /** * Tests that an implementation will not accept an arbitrary URL * * @throws SQLException */ @Test public void driver_accepts_02() throws SQLException { String url = "jdbc:unknown:http://example.org"; JenaDriver driver = this.getDriver(); Assert.assertFalse(driver.acceptsURL(url)); } /** * Tests using a driver to create a connection with its own URLs * * @throws SQLException */ @Test public void driver_connect_01() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); JenaDriver driver = this.getDriver(); Connection conn = driver.connect(url, null); Assert.assertFalse(conn.isClosed()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard JDBC compatibility parameter * * @throws SQLException */ @Test public void driver_connect_02() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_JDBC_COMPATIBILITY + "=" + JdbcCompatibility.LOW; JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Assert.assertEquals(JdbcCompatibility.LOW, conn.getJdbcCompatibilityLevel()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard JDBC compatibility parameter * * @throws SQLException */ @Test public void driver_connect_03() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_JDBC_COMPATIBILITY + "=" + Integer.MIN_VALUE; JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Assert.assertEquals(JdbcCompatibility.LOW, conn.getJdbcCompatibilityLevel()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard JDBC compatibility parameter * * @throws SQLException */ @Test public void driver_connect_04() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_JDBC_COMPATIBILITY + "=" + JdbcCompatibility.HIGH; JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Assert.assertEquals(JdbcCompatibility.HIGH, conn.getJdbcCompatibilityLevel()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard JDBC compatibility parameter * * @throws SQLException */ @Test public void driver_connect_05() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_JDBC_COMPATIBILITY + "=" + Integer.MAX_VALUE; JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Assert.assertEquals(JdbcCompatibility.HIGH, conn.getJdbcCompatibilityLevel()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard pre-processor parameter * * @throws SQLException */ @Test public void driver_connect_06() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName(); JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Iterator<CommandPreProcessor> iter = conn.getPreProcessors(); Assert.assertTrue(iter.hasNext()); iter.next(); Assert.assertFalse(iter.hasNext()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard pre-processor parameter * * @throws SQLException */ @Test public void driver_connect_07() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // We can register it twice if we want url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName(); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName(); JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Iterator<CommandPreProcessor> iter = conn.getPreProcessors(); Assert.assertTrue(iter.hasNext()); iter.next(); Assert.assertTrue(iter.hasNext()); iter.next(); Assert.assertFalse(iter.hasNext()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests using a driver to create a connection with its own URLs plus the * standard pre-processor and post-processor parameter * * @throws SQLException */ @Test public void driver_connect_08() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName(); url = url + "&" + JenaDriver.PARAM_POST_PROCESSOR + "=" + ResultsEcho.class.getCanonicalName(); JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Assert.assertFalse(conn.isClosed()); Iterator<CommandPreProcessor> iter = conn.getPreProcessors(); Assert.assertTrue(iter.hasNext()); Assert.assertTrue(iter.next() instanceof Echo); Assert.assertFalse(iter.hasNext()); Iterator<ResultsPostProcessor> iter2 = conn.getPostProcessors(); Assert.assertTrue(iter2.hasNext()); Assert.assertTrue(iter2.next() instanceof ResultsEcho); Assert.assertFalse(iter2.hasNext()); conn.close(); Assert.assertTrue(conn.isClosed()); } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException */ @Test public void driver_config_precedence_01() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&test=url"; JenaDriver driver = this.getDriver(); Properties ps = new Properties(); ps.put("test", "props"); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("props", actual.getProperty("test")); conn.close(); } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException */ @Test public void driver_config_precedence_02() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&test=url"; JenaDriver driver = this.getDriver(); Properties ps = new Properties(); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("url", actual.getProperty("test")); conn.close(); } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException * @throws IOException */ @Test public void driver_config_precedence_03() throws SQLException, IOException { File f = null; try { f = File.createTempFile("config", ".properties"); FileWriter writer = new FileWriter(f); writer.write("test=external"); writer.close(); String url = this.getConnectionUrl(); Assume.assumeNotNull(url); Assume.assumeFalse(url.contains(JenaDriver.PARAM_CONFIG + "=")); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&" + JenaDriver.PARAM_CONFIG + "=" + f.getAbsolutePath(); JenaDriver driver = this.getDriver(); Properties ps = new Properties(); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("external", actual.getProperty("test")); conn.close(); } finally { if (f != null && f.exists()) { f.delete(); } } } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException * @throws IOException */ @Test public void driver_config_precedence_04() throws SQLException, IOException { File f = null; try { f = File.createTempFile("config", ".properties"); FileWriter writer = new FileWriter(f); writer.write("test=external"); writer.close(); String url = this.getConnectionUrl(); Assume.assumeNotNull(url); Assume.assumeFalse(url.contains(JenaDriver.PARAM_CONFIG + "=")); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&test=url&" + JenaDriver.PARAM_CONFIG + "=" + f.getAbsolutePath(); JenaDriver driver = this.getDriver(); Properties ps = new Properties(); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("url", actual.getProperty("test")); conn.close(); } finally { if (f != null && f.exists()) { f.delete(); } } } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException * @throws IOException */ @Test public void driver_config_precedence_05() throws SQLException, IOException { File f = null; try { f = File.createTempFile("config", ".properties"); FileWriter writer = new FileWriter(f); writer.write("test=external"); writer.close(); String url = this.getConnectionUrl(); Assume.assumeNotNull(url); Assume.assumeFalse(url.contains(JenaDriver.PARAM_CONFIG + "=")); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&test=url&" + JenaDriver.PARAM_CONFIG + "=" + f.getAbsolutePath(); JenaDriver driver = this.getDriver(); Properties ps = new Properties(); ps.put("test", "props"); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("props", actual.getProperty("test")); conn.close(); } finally { if (f != null && f.exists()) { f.delete(); } } } /** * Tests the precedence rules for connection URL parameters * * @throws SQLException * @throws IOException */ @Test public void driver_config_precedence_06() throws SQLException, IOException { File f1 = null, f2 = null; try { f1 = File.createTempFile("config", ".properties"); FileWriter writer = new FileWriter(f1); writer.write("test=external-url"); writer.close(); f2 = File.createTempFile("config", ".properties"); writer = new FileWriter(f2); writer.write("test=external-props"); writer.close(); String url = this.getConnectionUrl(); Assume.assumeNotNull(url); Assume.assumeFalse(url.contains(JenaDriver.PARAM_CONFIG + "=")); url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Echo.class.getCanonicalName() + "&" + JenaDriver.PARAM_CONFIG + "=" + f1.getAbsolutePath(); JenaDriver driver = this.getDriver(); Properties ps = new Properties(); ps.put(JenaDriver.PARAM_CONFIG, f2.getAbsolutePath()); JenaConnection conn = (JenaConnection) driver.connect(url, ps); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); Echo echo = (Echo) preProcessors.next(); Properties actual = echo.getProperties(); Assert.assertEquals("external-props", actual.getProperty("test")); conn.close(); } finally { if (f1 != null && f1.exists()) { f1.delete(); } if (f2 != null && f2.exists()) { f2.delete(); } } } /** * Tests that multiple values for properties are supported by external * config when comma separated lists are used * * @throws SQLException * @throws IOException */ @Test public void driver_external_config_01() throws SQLException, IOException { File f = null; try { f = File.createTempFile("config", ".properties"); FileWriter writer = new FileWriter(f); writer.write("pre-processor=" + Echo.class.getCanonicalName() + "," + Echo.class.getCanonicalName()); writer.close(); String url = this.getConnectionUrl(); Assume.assumeNotNull(url); Assume.assumeFalse(url.contains(JenaDriver.PARAM_CONFIG + "=")); url = url + "&" + JenaDriver.PARAM_CONFIG + "=" + f.getAbsolutePath(); JenaDriver driver = this.getDriver(); JenaConnection conn = (JenaConnection) driver.connect(url, null); Iterator<CommandPreProcessor> preProcessors = conn.getPreProcessors(); Assert.assertTrue(preProcessors.hasNext()); preProcessors.next(); Assert.assertTrue(preProcessors.hasNext()); preProcessors.next(); Assert.assertFalse(preProcessors.hasNext()); conn.close(); } finally { if (f != null && f.exists()) { f.delete(); } } } /** * Tests using a driver to create a connection with its own URLs which are * known to be bad * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_01() throws SQLException { String url = this.getBadConnectionUrl(); Assume.assumeNotNull(url); JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard pre-processor parameter but setting the pre-processor to a value * that creates an error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_02() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a class that doesn't exist url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=NoSuchClass"; JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard pre-processor parameter but setting the pre-processor to a value * that creates an error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_03() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a class that exists but isn't a CommandPreProcessor url = url + "&" + JenaDriver.PARAM_PRE_PROCESSOR + "=" + Node.class.getCanonicalName(); JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard post-processor parameter but setting the post-processor to a * value that creates an error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_04() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a class that doesn't exist url = url + "&" + JenaDriver.PARAM_POST_PROCESSOR + "=NoSuchClass"; JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard post-processor parameter but setting the post-processor to a * value that creates an error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_05() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a class that exists but isn't a ResultsPostProcessor url = url + "&" + JenaDriver.PARAM_POST_PROCESSOR + "=" + Node.class.getCanonicalName(); JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard logging parameter but setting it to a value that creates an * error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_06() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a non-existent file/class path resource url = url + "&" + JenaDriver.PARAM_LOGGING + "=/nosuch.properties"; JenaDriver driver = this.getDriver(); driver.connect(url, null); } /** * Tests using a driver to create a connection with its own URLs plus the * standard config parameter but setting it to a value that creates an error * * @throws SQLException */ @Test(expected = SQLException.class) public void driver_connect_bad_07() throws SQLException { String url = this.getConnectionUrl(); Assume.assumeNotNull(url); // Try to use a non-existent file/class path resource url = url + "&" + JenaDriver.PARAM_CONFIG + "=/nosuch.properties"; JenaDriver driver = this.getDriver(); driver.connect(url, null); } }