+1

Echo Dales suggestion for Duration over int for time.

-Jake


On Wed, Jul 18, 2018 at 12:58 PM Dan Smith <dsm...@pivotal.io> wrote:

> Hi Helena,
>
> Looks great! I think this will make writing multithreaded tests a lot less
> error prone. A couple of minor comments below:
>
> I'm not sure we need runInSeries, someone could do that without using this
> test helper.
>
> Could we make the default timeout something more like 5 minutes? See this
> thread https://markmail.org/thread/yrcvdlbixqojl6oh
>
>
> -Dan
>
> On Wed, Jul 18, 2018 at 12:16 PM, Dale Emery <dem...@pivotal.io> wrote:
>
> > Hi Helena,
> >
> > I like it!
> >
> > A few suggestions:
> >
> > - For the durations (repeatForDuration() and setTimeout()), consider
> using
> > a java.time.Duration rather than an int to express the duration. The
> > Duration class lets most of the code not have to keep track of the time
> > units. The caller creates the Duration using whatever time unit they
> want.
> > When some other code needs to convert it to a specific time unit, there
> are
> > methods for that. The rest of the code doesn’t have to care about the
> time
> > units. And there are methods for adding, subtracting, and comparing
> > Durations and Instants, all handling the time units nicely.
> >
> > - Consider adding a version of runAndExpectValue that takes a Predicate
> > instead of a value. And maybe one taking a Hamcrest Matcher.
> >
> > - Consider specifying the type of the Callable, and preferably for the
> > value passed to runAndExpectValue()). And definitely for Predicates and
> > Matchers, if you add those methods.
> >
> > Cheers,
> > Dale
> >
> > > On Jul 18, 2018, at 11:53 AM, Helena Bales <hba...@pivotal.io> wrote:
> > >
> > > Hello All,
> > >
> > > Below I have included a proposed API for a concurrency test helper. The
> > > goal of this test helper is to make it easier for tests to use multiple
> > > threads. I believe providing a helper for this will reduce the number
> of
> > > tests that incorrectly use threads, and help make our DUnit tests more
> > > readable.
> > >
> > > I would like feedback on the API below. I have provided the method
> > > signatures that I plan on implementing, as well as an example usage.
> > Please
> > > let me know if there are any methods that seem unnecessary or if there
> > are
> > > any important use cases that I missed here.
> > >
> > > Thank you,
> > > Helena Bales
> > >
> > > public class ConcurrencyTestHelper {
> > >  private List<Callable<T>> toRun;
> > >  private Integer timeout;
> > >
> > >  private final Integer DEFAULT_TIMEOUT = 30;
> > >
> > >  /**
> > >   * A default constructor that sets the timeout to a default of 30
> > seconds
> > >   */
> > >  public ConcurrencyTestHelper() {
> > >    toRun = new ArrayList<Callable<T>>();
> > >    timeout = DEFAULT_TIMEOUT;
> > >  }
> > >
> > >  /**
> > >   * Run the given Runnable and assert that an exception of the given
> > > type is thrown. The thread
> > >   * will be cancelled when the class timeout is reached.
> > >   * @param runnable a Runnable that throws an exception and responds
> > > to cancellation signal
> > >   * @param exceptionType a Class of Exception that is expected to be
> > > thrown by the runnable
> > >   */
> > >  public void runAndExpectException(Runnable runnable, Class
> > exceptionType);
> > >
> > >  /**
> > >   * Run the given Runnable and assert that no exceptions are thrown.
> > > The thread will be cancelled
> > >   * when the class timeout is reached.
> > >   * @param runnable a Runnable that does not throw an exception and
> > > responds to cancellation signal
> > >   */
> > >  public void runAndExpectNoException(Runnable runnable);
> > >
> > >  /**
> > >   * Run the given Callable and assert that the result of that
> > > callable is the given expected value.
> > >   * The thread will be cancelled when the class timeout is reached.
> > >   * @param callable a Callable that returns an object, does not throw
> > > exceptions and responds to
> > >   * cancellation signal
> > >   * @param value an Object that is the expected return value from the
> > Callable.
> > >   */
> > >  public void runAndExpectValue(Callable callable, Object value);
> > >
> > >  /**
> > >   * Run the given runnable in a loop until the rest of the threads
> > > complete. Fails if the runnable
> > >   * throws an exception during any iteration. After the rest of the
> > > threads complete the loop will
> > >   * not restart the runnable. The running iteration will be cancelled
> > > when the timeout set on the
> > >   * class is reached. A cancellation will result in a test failure.
> > >   * @param runnable a Runnable that does not throw an exception and
> > > responds to cancellation signal
> > >   */
> > >  public void repeatUntilAllThreadsComplete(Runnable runnable);
> > >
> > >  /**
> > >   * Run the given runnable in a loop for some number of iterations.
> > > Fails if the runnable throws an
> > >   * exception in any iteration. After the number of iterations has
> > > been met, the loop will not
> > >   * restart the runnable. The running iteration of the Runnable will
> > > be cancelled when the
> > >   * timeout set on the class is reached, regardless of if the number
> > > of desired iterations has
> > >   * been reached. A cancellation will result in a test failure.
> > >   * @param runnable a Runnable that does not throw an exception and
> > > responds to cancellation signal
> > >   * @param iterations a maximum number of iterations to repeat for
> > >   */
> > >  public void repeatForIterations(Runnable runnable, Integer
> iterations);
> > >
> > >  /**
> > >   * Run the given runnable in a loop for a certain duration. Fails if
> > > the runnable throws an
> > >   * exception in any iteration. After the duration has been exceeded,
> > > the loop will not restart
> > >   * the runnable, however the current iteration will not be cancelled
> > > until the timeout value for
> > >   * the class has been reached. A cancellation will result in a test
> > failure.
> > >   * @param runnable a Runnable that does not throw exceptions and
> > > responds to cancellation signal
> > >   * @param duration a maximum amount of time to repeat for
> > >   */
> > >  public void repeatForDuration(Runnable runnable, Integer duration);
> > >
> > >  /**
> > >   * Set the timeout for the threads. After the timeout is reached,
> > > the threads will be interrupted
> > >   * and will throw a CancellationException
> > >   */
> > >  public void setTimeout(Integer seconds) {
> > >    timeout = seconds;
> > >  }
> > >
> > >  /**
> > >   * Runs all callables in toRun in parallel and fail if threads'
> > > conditions were not met. Runs
> > >   * until timeout is reached.
> > >   * @throws InterruptedException if interrupted before timeout
> > >   */
> > >  public void executeInParallel();
> > >
> > >  /**
> > >   * Runs all callables in toRun in the order that they were added and
> > > fail if threads' conditions
> > >   * were not met. Runs until timeout is reached.
> > >   * @throws InterruptedException if interrupted before timeout
> > >   */
> > >  public void executeInSeries();
> > > }
> > >
> > > // example usage:
> > > new ConcurrentTestHelper()
> > >       .runAndExpectException(runnable, UnsupportedOperationException.
> > class)
> > >       .runAndExpectNoException(runnable)
> > >       .runAndExpectValue(callable, result)
> > >       .repeatUntilAllOtherRunnablesFinish(runnable)
> > >       .repeatFor(runnable, time)  //keep doing this for time amount of
> > time
> > >       .repeat(runnable, iterations)  //keep doing this for N times
> > >       .setTimeout(seconds) //Throws exception if test takes too long
> > >       .executeInParallel();
> >
> > —
> > Dale Emery
> > dem...@pivotal.io
> >
> >
> >
> >
> >
>

Reply via email to