Class ConcurrentTestCommandGenerator
- java.lang.Object
-
- org.apache.calcite.test.concurrent.ConcurrentTestCommandGenerator
-
- Direct Known Subclasses:
ConcurrentTestCommandScript
,ConcurrentTestTimedCommandGenerator
public class ConcurrentTestCommandGenerator extends java.lang.Object
ConcurrentTestCommandGenerator creates instances ofConcurrentTestCommand
that perform specific actions in a specific order and within the context of a test thread (ConcurrentTestCommandExecutor
).Typical actions include preparing a SQL statement for execution, executing the statement and verifying its result set, and closing the statement.
A single ConcurrentTestCommandGenerator creates commands for multiple threads. Each thread is represented by an integer "thread ID". Thread IDs may take on any positive integer value and may be a sparse set (e.g. 1, 2, 5).
When each command is created, it is associated with a thread and given an execution order. Execution order values are positive integers, must be unique within a thread, and may be a sparse set.
There are no restrictions on the order of command creation.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static class
ConcurrentTestCommandGenerator.AbstractCommand
abstract base to handle SQLExceptions(package private) static class
ConcurrentTestCommandGenerator.AutoSynchronizationCommand
AutoSynchronizationCommand is idential to SynchronizationCommand, except that it is generated automatically by the test harness and is not counted when displaying the step number in which an error occurred.private static class
ConcurrentTestCommandGenerator.CloseCommand
CloseCommand closes a previously prepared statement.private static class
ConcurrentTestCommandGenerator.CommandWithTimeout
Command that executes statements with a given timeout.private static class
ConcurrentTestCommandGenerator.CommitCommand
CommitCommand commits pending transactions viaConnection.commit()
.private static class
ConcurrentTestCommandGenerator.DdlCommand
DdlCommand executes DDL commands.private static class
ConcurrentTestCommandGenerator.ExplainCommand
ExplainCommand executes explain plan commands.static class
ConcurrentTestCommandGenerator.FailedThread
Describes a thread that failedprivate static class
ConcurrentTestCommandGenerator.FetchAndCompareCommand
FetchAndCompareCommand executes a previously prepared statement stored in the ConcurrentTestCommandExecutor and then validates the returned rows against expected data.private static class
ConcurrentTestCommandGenerator.InsertCommand
InsertCommand exeutes an insert, update or delete SQL statement.private static class
ConcurrentTestCommandGenerator.PrepareCommand
PrepareCommand creates aPreparedStatement
.private static class
ConcurrentTestCommandGenerator.RollbackCommand
RollbackCommand rolls back pending transactions viaConnection.rollback()
.private static class
ConcurrentTestCommandGenerator.SleepCommand
SleepCommand causes the execution thread to wait for all other threads in the test before continuing.(package private) static class
ConcurrentTestCommandGenerator.SynchronizationCommand
SynchronizationCommand causes the execution thread to wait for all other threads in the test before continuing.
-
Field Summary
Fields Modifier and Type Field Description private static char
APOS
private static char
COMMA
protected boolean
debug
protected java.io.PrintStream
debugStream
private java.util.List<ConcurrentTestCommandGenerator.FailedThread>
failedThreads
Collects threads that failed.protected java.util.Properties
jdbcProps
protected java.lang.String
jdbcURL
private static char
LEFT_BRACKET
private static char
RIGHT_BRACKET
private java.util.TreeMap<java.lang.Integer,java.util.TreeMap<java.lang.Integer,ConcurrentTestCommand>>
threadMap
Maps Integer thread IDs to a TreeMap.private java.util.TreeMap<java.lang.Integer,java.lang.String>
threadNameMap
Maps Integer thread IDs to thread names.
-
Constructor Summary
Constructors Constructor Description ConcurrentTestCommandGenerator()
Constructs a new ConcurrentTestCommandGenerator.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description ConcurrentTestCommand
addCloseCommand(int threadId, int order)
Closes a previouslyprepared
SQL statement.protected ConcurrentTestCommand
addCommand(int threadId, int order, ConcurrentTestCommand command)
Handles adding a command tothreadMap
.ConcurrentTestCommand
addCommitCommand(int threadId, int order)
Commits pending transaction on the thread's connection.ConcurrentTestCommand
addDdlCommand(int threadId, int order, java.lang.String ddl)
Executes a DDL statement immediately.ConcurrentTestCommand
addExplainCommand(int threadId, int order, java.lang.String sql)
Adds an "explain plan" command.ConcurrentTestCommand
addFetchAndCompareCommand(int threadId, int order, int timeout, java.lang.String expected)
Executes a previouslyprepared
SQL statement and compares itsResultSet
to the given data.ConcurrentTestCommand
addInsertCommand(int threadId, int order, int timeout, java.lang.String sql)
Executes the given SQL viaStatement.executeUpdate(String)
.ConcurrentTestCommand
addPrepareCommand(int threadId, int order, java.lang.String sql)
Creates aPreparedStatement
for the given SQL.ConcurrentTestCommand
addRollbackCommand(int threadId, int order)
Rolls back pending transaction on the thread's connection.ConcurrentTestCommand
addSleepCommand(int threadId, int order, long millis)
Causes the given thread to sleep for the indicated number of milliseconds.ConcurrentTestCommand
addSynchronizationCommand(int threadId, int order)
Adds a synchronization commands.(package private) void
customErrorHandler(ConcurrentTestCommandExecutor executor)
Custom error handling occurs here ifrequiresCustomErrorHandling()
returns true.void
execute()
Creates aConcurrentTestCommandExecutor
object for each define thread, and then runs them all.boolean
failed()
Returns whether any test thread failed.(package private) java.lang.Iterable<ConcurrentTestCommand>
getCommandIterable(int threadId)
Returns anIterator
ofConcurrentTestCommand
objects for the given thread ID.(package private) java.util.Collection<ConcurrentTestCommand>
getCommands(int threadId)
Returns aCollection
ofConcurrentTestCommand
objects for the given thread ID.java.util.List<ConcurrentTestCommandGenerator.FailedThread>
getFailedThreads()
protected java.util.Set<java.lang.Integer>
getThreadIds()
Returns a set of thread IDs.protected java.lang.String
getThreadName(java.lang.Integer threadId)
Retrieves the name of a given thread.boolean
hasValidSynchronization()
Validates that all threads have the same number of SynchronizationCommands (otherwise a deadlock is guaranteed).protected ConcurrentTestCommandExecutor[]
innerExecute()
protected void
postExecute(ConcurrentTestCommandExecutor[] threads)
(package private) void
printCommands(java.io.PrintStream out, java.lang.Integer threadId)
Prints a description of the commands to be executed for a given thread.(package private) boolean
requiresCustomErrorHandling()
Indicates whether commands generated by this generator require special handling.void
setDataSource(java.lang.String jdbcURL, java.util.Properties jdbcProps)
Sets the jdbc data source for executing the command threads.protected void
setDebug(boolean enabled)
protected void
setDebug(boolean enabled, java.io.PrintStream alternatePrintStream)
void
setThreadName(int threadId, java.lang.String name)
Configures a human-readable name for a given thread identifier.void
synchronizeCommandSets()
Insures that the number of commands is the same for each thread, fills missing order value with null commands, and interleaves a synchronization command before each actual command.
-
-
-
Field Detail
-
APOS
private static final char APOS
- See Also:
- Constant Field Values
-
COMMA
private static final char COMMA
- See Also:
- Constant Field Values
-
LEFT_BRACKET
private static final char LEFT_BRACKET
- See Also:
- Constant Field Values
-
RIGHT_BRACKET
private static final char RIGHT_BRACKET
- See Also:
- Constant Field Values
-
debug
protected boolean debug
-
debugStream
protected java.io.PrintStream debugStream
-
jdbcURL
protected java.lang.String jdbcURL
-
jdbcProps
protected java.util.Properties jdbcProps
-
threadMap
private java.util.TreeMap<java.lang.Integer,java.util.TreeMap<java.lang.Integer,ConcurrentTestCommand>> threadMap
Maps Integer thread IDs to a TreeMap. The TreeMap vaules map an Integer execution order to aConcurrentTestCommand
.
-
threadNameMap
private java.util.TreeMap<java.lang.Integer,java.lang.String> threadNameMap
Maps Integer thread IDs to thread names.
-
failedThreads
private java.util.List<ConcurrentTestCommandGenerator.FailedThread> failedThreads
Collects threads that failed. Cleared when execution starts, valid whe/n execution has ended. Only failed threads appear in the list, so after a successful test the list is empty.
-
-
Method Detail
-
addSynchronizationCommand
public ConcurrentTestCommand addSynchronizationCommand(int threadId, int order)
Adds a synchronization commands. When a thread reaches a synchronization command it stops and waits for all other threads to reach their synchronization commands. When all threads have reached their synchronization commands, they are all released simultaneously (or as close as one can get withObject.notifyAll()
). Each thread must have exactly the same number of synchronization commands.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution order- Returns:
- the newly-added command
-
addSleepCommand
public ConcurrentTestCommand addSleepCommand(int threadId, int order, long millis)
Causes the given thread to sleep for the indicated number of milliseconds. Thread executesThread.sleep(long)
.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution ordermillis
- the length of time to sleep in milliseconds (must not be negative)- Returns:
- the newly-added command
-
addExplainCommand
public ConcurrentTestCommand addExplainCommand(int threadId, int order, java.lang.String sql)
Adds an "explain plan" command.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution ordersql
- the explain plan SQL (e.g."explain plan for select * from t"
)- Returns:
- the newly-added command
-
addPrepareCommand
public ConcurrentTestCommand addPrepareCommand(int threadId, int order, java.lang.String sql)
Creates aPreparedStatement
for the given SQL. This command does not execute the SQL, it merely creates a PreparedStatement and stores it in the ConcurrentTestCommandExecutor.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution ordersql
- the SQL to prepare (e.g."select * from t"
)- Returns:
- the newly-added command
- See Also:
addFetchAndCompareCommand(int, int, int, String)
-
addFetchAndCompareCommand
public ConcurrentTestCommand addFetchAndCompareCommand(int threadId, int order, int timeout, java.lang.String expected)
Executes a previouslyprepared
SQL statement and compares itsResultSet
to the given data.Expected data format:
{ 'row1, col1 value', 'row1, col2 value', ... }, { 'row2, col1 value', 'row2, col2 value', ... }, ...
- For string data: enclose value in apostrophes, use doubled apostrophe to include an apostrophe in the value.
- For integer or real data: simply use the stringified value (e.g. 123, 12.3, 0.65). No scientific notation is allowed.
- For null values, use the word
null
without quotes.
{ 'foo', 10, 3.14, null }
Note on timeout: If the previously prepared statement's
Statement.setQueryTimeout(int)
method throws anUnsupportedOperationException
it is ignored and no timeout is set.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution ordertimeout
- the query timeout, in seconds (see above)expected
- the expected results (see above)- Returns:
- the newly-added command
-
addCloseCommand
public ConcurrentTestCommand addCloseCommand(int threadId, int order)
Closes a previouslyprepared
SQL statement.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution order- Returns:
- the newly-added command
-
addInsertCommand
public ConcurrentTestCommand addInsertCommand(int threadId, int order, int timeout, java.lang.String sql)
Executes the given SQL viaStatement.executeUpdate(String)
. May be used for update as well as insert statements.Note on timeout: If the previously prepared statement's
Statement.setQueryTimeout(int)
method throws anUnsupportedOperationException
it is ignored and no timeout is set.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution ordertimeout
- the query timeout, in seconds (see above)sql
- the insert/update/delete SQL- Returns:
- the newly-added command
-
addCommitCommand
public ConcurrentTestCommand addCommitCommand(int threadId, int order)
Commits pending transaction on the thread's connection.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution order- Returns:
- the newly-added command
-
addRollbackCommand
public ConcurrentTestCommand addRollbackCommand(int threadId, int order)
Rolls back pending transaction on the thread's connection.- Parameters:
threadId
- the thread that should execute this commandorder
- the execution order- Returns:
- the newly-added command
-
addDdlCommand
public ConcurrentTestCommand addDdlCommand(int threadId, int order, java.lang.String ddl)
Executes a DDL statement immediately. Assumes the statement returns no information.- Returns:
- the newly-added command
-
addCommand
protected ConcurrentTestCommand addCommand(int threadId, int order, ConcurrentTestCommand command)
Handles adding a command tothreadMap
.- Returns:
- the newly-added command
-
setThreadName
public void setThreadName(int threadId, java.lang.String name)
Configures a human-readable name for a given thread identifier. Does not imply that the thread will be created -- that only happens if there are commands added to the thread.
-
setDebug
protected void setDebug(boolean enabled)
-
setDebug
protected void setDebug(boolean enabled, java.io.PrintStream alternatePrintStream)
-
setDataSource
public void setDataSource(java.lang.String jdbcURL, java.util.Properties jdbcProps)
Sets the jdbc data source for executing the command threads.
-
execute
public void execute() throws java.lang.Exception
Creates aConcurrentTestCommandExecutor
object for each define thread, and then runs them all.- Throws:
java.lang.Exception
- if no connection found or if a thread operation is interrupted
-
innerExecute
protected ConcurrentTestCommandExecutor[] innerExecute() throws java.lang.Exception
- Throws:
java.lang.Exception
-
postExecute
protected void postExecute(ConcurrentTestCommandExecutor[] threads) throws java.lang.Exception
- Throws:
java.lang.Exception
-
failed
public boolean failed()
Returns whether any test thread failed. Valid afterexecute()
has returned.
-
getFailedThreads
public java.util.List<ConcurrentTestCommandGenerator.FailedThread> getFailedThreads()
- Returns:
- the list of failed threads (unmodifiable)
-
synchronizeCommandSets
public void synchronizeCommandSets()
Insures that the number of commands is the same for each thread, fills missing order value with null commands, and interleaves a synchronization command before each actual command. These steps are required for synchronized execution in FarragoConcurrencyTestCase.
-
hasValidSynchronization
public boolean hasValidSynchronization()
Validates that all threads have the same number of SynchronizationCommands (otherwise a deadlock is guaranteed).- Returns:
- true when valid, false when invalid.
-
getThreadIds
protected java.util.Set<java.lang.Integer> getThreadIds()
Returns a set of thread IDs.
-
getThreadName
protected java.lang.String getThreadName(java.lang.Integer threadId)
Retrieves the name of a given thread. If no thread names were configured, returns the concatenation of "#" and the thread's numeric identifier.- Returns:
- human-readable thread name
-
requiresCustomErrorHandling
boolean requiresCustomErrorHandling()
Indicates whether commands generated by this generator require special handling. Default implement returns false.
-
customErrorHandler
void customErrorHandler(ConcurrentTestCommandExecutor executor)
Custom error handling occurs here ifrequiresCustomErrorHandling()
returns true. Default implementation does nothing.
-
getCommands
java.util.Collection<ConcurrentTestCommand> getCommands(int threadId)
Returns aCollection
ofConcurrentTestCommand
objects for the given thread ID.
-
getCommandIterable
java.lang.Iterable<ConcurrentTestCommand> getCommandIterable(int threadId)
Returns anIterator
ofConcurrentTestCommand
objects for the given thread ID.- Parameters:
threadId
- Thread id
-
printCommands
void printCommands(java.io.PrintStream out, java.lang.Integer threadId)
Prints a description of the commands to be executed for a given thread.
-
-