| /* |
| * 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.openjpa.persistence.test; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.apache.openjpa.lib.jdbc.JDBCListener; |
| |
| /** |
| * Base class for tests that need to check generated SQL. |
| * Extends SingleEMFTestCase, which will cleanup the EMF it provides, |
| * along with any EMs generated by that EMF. |
| * |
| * @author Patrick Linskey |
| */ |
| public abstract class SQLListenerTestCase |
| extends SingleEMFTestCase { |
| private static String _nl = System.getProperty("line.separator"); |
| protected List<String> sql = new ArrayList<>(); |
| |
| @Override |
| public void setUp(Object... props) { |
| Object[] copy = new Object[props.length + 2]; |
| System.arraycopy(props, 0, copy, 0, props.length); |
| copy[copy.length - 2] = "openjpa.jdbc.JDBCListeners"; |
| copy[copy.length - 1] = new JDBCListener[] { new FilteringJDBCListener(sql) }; |
| super.setUp(copy); |
| } |
| |
| @Override |
| public void tearDown() throws Exception { |
| super.tearDown(); |
| resetSQL(); |
| } |
| |
| /** |
| * Confirm that the specified SQL has been executed. |
| * |
| * @param sqlExp the SQL expression. E.g., "SELECT FOO .*" |
| */ |
| public void assertSQL(String sqlExp) { |
| for (String statement : sql) { |
| if (statement.matches(sqlExp)) |
| return; |
| } |
| |
| fail("Expected regular expression\r\n <" + sqlExp |
| + ">\r\n to have existed in SQL statements: \r\n" + toString(sql)); |
| } |
| |
| /** |
| * Confirm that the specified SQL has not been executed. |
| * |
| * @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*" |
| */ |
| public void assertNotSQL(String sqlExp) { |
| for (String statement : sql) { |
| if (statement.matches(sqlExp)) { |
| fail("Regular expression\r\n <" |
| + sqlExp |
| + ">\r\n should not have been executed in SQL statements:" |
| + "\r\n" + toString(sql)); |
| break; |
| } |
| } |
| } |
| |
| /** |
| * Confirm that the executed SQL String contains the specified sqlExp. |
| * |
| * @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*" |
| */ |
| public void assertContainsSQL(String sqlExp) { |
| for (String statement : sql) { |
| if (statement.contains(sqlExp)) |
| return; |
| } |
| |
| fail("Expected regular expression\r\n <" + sqlExp + ">\r\n to be" |
| + " contained in SQL statements: \r\n" + toString(sql)); |
| } |
| |
| /** |
| * Confirm the list of expected SQL expressions have been executed in the |
| * order specified. I.e. additional SQL statements can be executed in |
| * between expected SQLs. |
| * |
| * @param expected |
| * SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*") |
| */ |
| public void assertAllSQLInOrder(String... expected) { |
| assertSQLInOrder(false, expected); |
| } |
| |
| /** |
| * Confirm the list of expected SQL expressions have been executed in the |
| * exact number and order specified. |
| * |
| * @param expected |
| * SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*") |
| */ |
| public void assertAllExactSQLInOrder(String... expected) { |
| assertSQLInOrder(true, expected); |
| } |
| |
| private void assertSQLInOrder(boolean exact, String... expected) { |
| boolean match = false; |
| int sqlSize = sql.size(); |
| if (expected.length <= sqlSize) { |
| int hits = 0; |
| for (String executedSQL : sql) { |
| if (executedSQL.matches(expected[hits])) { |
| if (++hits == expected.length) |
| break; |
| } |
| } |
| match = hits == (exact ? sqlSize : expected.length); |
| } |
| |
| if (!match) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("Did not find SQL in expected order : ").append(_nl); |
| for (String s : expected) { |
| sb.append(s).append(_nl); |
| } |
| |
| sb.append("SQL Statements issued : "); |
| for (String s : sql) { |
| sb.append(s).append(_nl); |
| } |
| fail(sb.toString()); |
| } |
| } |
| |
| /** |
| * Confirm the list of expected SQL expressions have executed in any order. |
| * |
| * @param expected |
| * SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*") |
| */ |
| public void assertAllSQLAnyOrder(String... expected) { |
| for (String statement : expected) { |
| assertSQL(statement); |
| } |
| } |
| |
| /** |
| * Confirm the list of expected SQL expressions have not executed in any |
| * order. |
| * |
| * @param expected |
| * SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*") |
| */ |
| public void assertNoneSQLAnyOrder(String... expected) { |
| for (String statement : expected) { |
| assertNotSQL(statement); |
| } |
| } |
| |
| /** |
| * Confirm the any of expected SQL expressions have executed in any order. |
| * |
| * @param expected |
| * SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*") |
| */ |
| public void assertAnySQLAnyOrder(String... expected) { |
| for (String sqlExp : expected) { |
| for (String statement : sql) { |
| if (statement.matches(sqlExp)) |
| return; |
| } |
| } |
| fail("Expected regular expression\r\n <" |
| + toString(Arrays.asList(expected)) + ">\r\n to be" |
| + " contained in SQL statements: \r\n" + toString(sql)); |
| } |
| |
| /** |
| * Gets the number of SQL issued since last reset. |
| */ |
| public int getSQLCount() { |
| return sql.size(); |
| } |
| |
| /** |
| * Resets SQL count. |
| * @return number of SQL counted since last reset. |
| */ |
| public int resetSQL() { |
| int tmp = sql.size(); |
| sql.clear(); |
| return tmp; |
| } |
| |
| public String toString(List<String> list) { |
| StringBuilder buf = new StringBuilder(); |
| for (String s : list) |
| buf.append(s).append("\r\n"); |
| return buf.toString(); |
| } |
| |
| /** |
| * Returns the last SQL executed or the empty string if the list is |
| * empty. |
| */ |
| public String getLastSQL(List<String> list) { |
| if (list != null && list.size() > 0) |
| return list.get(list.size() -1); |
| return ""; |
| } |
| |
| public enum SQLAssertType { |
| SQL, NotSQL, ContainsSQL, AllSQLInOrder, AllExactSQLInOrder, |
| AllSQLAnyOrder, NoneSQLAnyOrder, AnySQLAnyOrder |
| } |
| |
| public class SQLAssertions { |
| SQLAssertType type; |
| String[] template; |
| |
| public SQLAssertions(SQLAssertType type, String... template) { |
| this.type = type; |
| this.template = template; |
| } |
| |
| public void validate() { |
| switch (type) { |
| case SQL: |
| assertSQL(template[0]); |
| break; |
| case NotSQL: |
| assertNotSQL(template[0]); |
| break; |
| case ContainsSQL: |
| assertContainsSQL(template[0]); |
| break; |
| case AllSQLInOrder: |
| assertAllSQLInOrder(template); |
| break; |
| case AllExactSQLInOrder: |
| assertAllExactSQLInOrder(template); |
| break; |
| case AllSQLAnyOrder: |
| assertAllSQLAnyOrder(template); |
| break; |
| case AnySQLAnyOrder: |
| assertAnySQLAnyOrder(template); |
| break; |
| case NoneSQLAnyOrder: |
| assertNoneSQLAnyOrder(template); |
| } |
| } |
| } |
| } |