Class ConcurrentTestCommandGenerator

  • Direct Known Subclasses:
    ConcurrentTestCommandScript, ConcurrentTestTimedCommandGenerator

    public class ConcurrentTestCommandGenerator
    extends java.lang.Object
    ConcurrentTestCommandGenerator creates instances of ConcurrentTestCommand 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.

    • Field Detail

      • 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 a ConcurrentTestCommand.
      • 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.
    • Constructor Detail

      • ConcurrentTestCommandGenerator

        public ConcurrentTestCommandGenerator()
        Constructs a new ConcurrentTestCommandGenerator.
    • 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 with Object.notifyAll()). Each thread must have exactly the same number of synchronization commands.
        Parameters:
        threadId - the thread that should execute this command
        order - 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 executes Thread.sleep(long).
        Parameters:
        threadId - the thread that should execute this command
        order - the execution order
        millis - 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 command
        order - the execution order
        sql - 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 a PreparedStatement 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 command
        order - the execution order
        sql - 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 previously prepared SQL statement and compares its ResultSet 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.
        Example: { 'foo', 10, 3.14, null }

        Note on timeout: If the previously prepared statement's Statement.setQueryTimeout(int) method throws an UnsupportedOperationException it is ignored and no timeout is set.

        Parameters:
        threadId - the thread that should execute this command
        order - the execution order
        timeout - 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 previously prepared SQL statement.
        Parameters:
        threadId - the thread that should execute this command
        order - 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 via Statement.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 an UnsupportedOperationException it is ignored and no timeout is set.

        Parameters:
        threadId - the thread that should execute this command
        order - the execution order
        timeout - 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 command
        order - 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 command
        order - 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
      • 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 a ConcurrentTestCommandExecutor 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
      • failed

        public boolean failed()
        Returns whether any test thread failed. Valid after execute() has returned.
      • 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.
      • getCommandIterable

        java.lang.Iterable<ConcurrentTestCommand> getCommandIterable​(int threadId)
        Returns an Iterator of ConcurrentTestCommand 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.