Tester (Java Application API for IBM Streams)
Date: 2020-08-07

com.ibm.streamsx.topology.tester

## Interface Tester

-     public interface Tester

  A `Tester` adds the ability to test a topology in a test framework such as JUnit. The main feature is the ability to capture tuples from a `TStream` in order to perform some form of verification on them. There are two mechanisms to perform verifications:
  - `Condition` - Provides the ability to check if a common pattern is `valid`, such as did the stream produce the `correct number of tuples`.
  - `StreamHandler` - Provides the ability to add an arbitrary handler to a stream, that will be called for every tuple on the stream. A number of implementations of `StreamHandler` are in the `com.ibm.streams.flow.handlers` provided by the IBM Streams Java Operator API.
  The stream being verified must not be connected, but may have multiple conditions or handlers added.
  Currently, only streams that are instances of `SPLStream` or `TStream<String>` can have conditions or handlers attached.

  A `Tester` only modifies its `Topology` if the topology is submitted to a tester `StreamsContext`, of type `StreamsContext.Type.EMBEDDED_TESTER`, `StreamsContext.Type.STANDALONE_TESTER`, `StreamsContext.Type.DISTRIBUTED_TESTER`, `StreamsContext.Type.STREAMING_ANALYTICS_SERVICE_TESTER`.

  When running a test using `StreamsContext.Type.STANDALONE_TESTER` or `StreamsContext.Type.DISTRIBUTED_TESTER` a TCP server is setup within the JVM running the test (e.g. the JVM running the JUnit tests} and the topology is modified to send tuples from streams being tested to the TCP server. The port used by the TCP server is in the ephemeral port range.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static java.lang.String` | `TEST_TRACE_LEVEL` System property to set the trace level of application under tests.

  - ### Method Summary

    All Methods Instance Methods Abstract Methods Deprecated Methods
    Modifier and Type | Method and Description
    --- | ---
    `Condition<java.lang.Long>` | `atLeastTupleCount(TStream<?> stream, long expectedCount)` Return a condition that evaluates if `stream` has submitted at least `expectedCount` number of tuples.
    `boolean` | `complete(StreamsContext<?> context, Condition<?> endCondition, long timeout, java.util.concurrent.TimeUnit unit)` Submit the topology for this tester and wait for it to complete, or reach an end condition.
    `boolean` | `complete(StreamsContext<?> context, java.util.Map<java.lang.String,java.lang.Object> config, Condition<?> endCondition, long timeout, java.util.concurrent.TimeUnit unit)`
    `void` | `complete(StreamsContext<?> context)` Submit the topology for this tester and wait for it to complete.
    `Condition<java.util.List<java.lang.String>>` | `completeAndTestStringOutput(StreamsContext<?> context, java.util.Map<java.lang.String,java.lang.Object> config, TStream<?> output, long timeout, java.util.concurrent.TimeUnit unit, java.lang.String... contents)`
    `Condition<java.util.List<java.lang.String>>` | `completeAndTestStringOutput(StreamsContext<?> context, TStream<?> output, long timeout, java.util.concurrent.TimeUnit unit, java.lang.String... contents)`
    `Topology` | `getTopology()` Get the topology for this tester.
    `Condition<java.lang.Void>` | `resetConsistentRegions(java.lang.Integer minimumResets)` Create a condition that randomly resets consistent regions.
    `<T extends com.ibm.streams.flow.handlers.StreamHandler<com.ibm.streams.operator.Tuple>> T` | `splHandler(SPLStream stream, T handler)` Deprecated. Since 1.11. In most distributed environments stream contents cannot be obtained due to network isolation. An alternative is to use `stringTupleTester` to perform a per-tuple check.
    `Condition<java.util.List<java.lang.String>>` | `stringContents(TStream<java.lang.String> stream, java.lang.String... values)` Return a condition that evaluates if `stream` has submitted at tuples matching `values` in the same order.
    `Condition<java.util.List<java.lang.String>>` | `stringContentsUnordered(TStream<java.lang.String> stream, java.lang.String... values)` Return a condition that evaluates if `stream` has submitted at tuples matching `values` in any order.
    `Condition<java.lang.String>` | `stringTupleTester(TStream<java.lang.String> stream, Predicate<java.lang.String> tester)` Return a condition that evaluates if every tuple on `stream` evaluates to `true` with `tester`.
    `Condition<java.util.List<com.ibm.streams.operator.Tuple>>` | `tupleContents(SPLStream stream, com.ibm.streams.operator.Tuple... values)` Return a condition that evaluates if `stream` has submitted at tuples matching `values` in the same order.
    `Condition<java.lang.Long>` | `tupleCount(TStream<?> stream, long expectedCount)` Return a condition that evaluates if `stream` has submitted exactly `expectedCount` number of tuples.

- - ### Field Detail

    - #### TEST_TRACE_LEVEL

          static final java.lang.String TEST_TRACE_LEVEL

      System property to set the trace level of application under tests. For jobs to submitted to `StreamsContext.Type#STANDALONE_TESTER`, `StreamsContext.Type#DISTRIBUTED_TESTER` and `StreamsContext.Type#STREAMING_ANALYTICS_SERVICE_TESTER` contexts setting this property overrides any default trace level or any trace level set by a test.

      The value should be one of the enumeration names of `java.util.logging.Level`.

      - `SEVERE` - IBM Streams `error`.
      - `WARNING` - IBM Streams `warn`.
      - `INFO` - IBM Streams `info`.
      - `FINE` - IBM Streams `debug`.
      - `FINEST`, `ALL` - IBM Streams `trace`.
      - `OFF`- IBM Streams `off`.
      Since:
        1.11
      See Also:
        Constant Field Values

  - ### Method Detail

    - #### getTopology

          Topology getTopology()

      Get the topology for this tester.
      Returns:
        the topology for this tester.

    - #### splHandler

          <T extends com.ibm.streams.flow.handlers.StreamHandler<com.ibm.streams.operator.Tuple>> T splHandler(SPLStream stream,
                                                                                                               T handler)

      Deprecated. Since 1.11. In most distributed environments stream contents cannot be obtained due to network isolation. An alternative is to use `stringTupleTester` to perform a per-tuple check.
      Adds `handler` to capture the output of `stream`.

      Not supported when testing using `STREAMING_ANALYTICS_SERVICE_TESTER` context.

      Parameters:
        `stream` - Stream to have its tuples captured.
        `handler` - `StreamHandler` to capture tuples.
      Returns:
        `handler`

    - #### tupleCount

          Condition<java.lang.Long> tupleCount(TStream<?> stream,
                                               long expectedCount)

      Return a condition that evaluates if `stream` has submitted exactly `expectedCount` number of tuples.

      Note: Since 1.11 `getResult()` from the returned `Condition` is deprecated and tests should not rely on it returning the tuple count seen on the stream.
      The `result` of the returned `Condition` is the number of tuples seen on `stream` so far.

      Parameters:
        `stream` - Stream to be tested.
        `expectedCount` - Number of tuples expected on `stream`.
      Returns:
        Exact tuple count condition.

    - #### atLeastTupleCount

          Condition<java.lang.Long> atLeastTupleCount(TStream<?> stream,
                                                      long expectedCount)

      Return a condition that evaluates if `stream` has submitted at least `expectedCount` number of tuples.

      Note: Since 1.11 `getResult()` from the returned `Condition` is deprecated and tests should not rely on it returning the tuple count seen on the stream.
      The `result` of the returned `Condition` is the number of tuples seen on `stream` so far.

      Parameters:
        `stream` - Stream to be tested.
        `expectedCount` - Number of tuples expected on `stream`.
      Returns:
        At least tuple count condition.

    - #### stringContents

          Condition<java.util.List<java.lang.String>> stringContents(TStream<java.lang.String> stream,
                                                                     java.lang.String... values)

      Return a condition that evaluates if `stream` has submitted at tuples matching `values` in the same order.

      Note: Since 1.11 `getResult()` from the returned `Condition` is deprecated and tests should not rely on it returning the tuple count seen on the stream.
      The `result` of the returned `Condition` is the tuples seen on `stream` so far.

      Parameters:
        `stream` - Stream to be tested.
        `values` - Expected tuples on `stream`.
      Returns:
        Tuple contents condition.

    - #### tupleContents

          Condition<java.util.List<com.ibm.streams.operator.Tuple>> tupleContents(SPLStream stream,
                                                                                  com.ibm.streams.operator.Tuple... values)

      Return a condition that evaluates if `stream` has submitted at tuples matching `values` in the same order.

      Note: Since 1.11 `getResult()` from the returned `Condition` is deprecated and tests should not rely on it returning the tuple count seen on the stream.
      The `result` of the returned `Condition` is the tuples seen on `stream` so far.

      Parameters:
        `stream` - Stream to be tested.
        `values` - Expected tuples on `stream`.
      Returns:
        Tuple contents condition.

    - #### stringContentsUnordered

          Condition<java.util.List<java.lang.String>> stringContentsUnordered(TStream<java.lang.String> stream,
                                                                              java.lang.String... values)

      Return a condition that evaluates if `stream` has submitted at tuples matching `values` in any order.

      Note: Since 1.11 `getResult()` from the returned `Condition` is deprecated and tests should not rely on it returning the tuple count seen on the stream.
      The `result` of the returned `Condition` is the tuples seen on `stream` so far.

      Parameters:
        `stream` - Stream to be tested.
        `values` - Expected tuples on `stream`.
      Returns:
        Unordered tuple contents condition..

    - #### stringTupleTester

          Condition<java.lang.String> stringTupleTester(TStream<java.lang.String> stream,
                                                        Predicate<java.lang.String> tester)

      Return a condition that evaluates if every tuple on `stream` evaluates to `true` with `tester`.
      Parameters:
        `stream` - Stream to be tested.
        `tester` - Predicate that will be executed against each tuple.
      Returns:
        Condition whose result is the first tuple to fail the condition (when the result is available).

    - #### resetConsistentRegions

          Condition<java.lang.Void> resetConsistentRegions(java.lang.Integer minimumResets)

      Create a condition that randomly resets consistent regions. The condition becomes valid when each consistent region in the application under test has been reset `minimumResets` times by the tester.

      A region is reset by initiating a request though the Job Control Plane. The reset is not driven by any injected failure, such as a PE restart.

      Parameters:
        `minimumResets` - - Minimum number of resets for each region, defaults to 10.
      Returns:
        Condition with no result object.
      Throws:
        `java.lang.IllegalArgumentException` - `minimumResets` less than zero.
      Since:
        1.9 Only supported for Streaming Analytics.

    - #### complete

          void complete(StreamsContext<?> context)
                 throws java.lang.Exception

      Submit the topology for this tester and wait for it to complete. A topology can only complete if it is executing as embedded or standalone, thus only these stream context types are supported: `StreamsContext.Type.EMBEDDED_TESTER` and `StreamsContext.Type.STANDALONE_TESTER`.

      A topology completes when the IBM Streams runtime determines that there is no more processing to be performed, which is typically once all sources have indicated there is no more data to be processed, and all of the source tuples have been fully processed by the topology.
      Note that many topologies will never complete, for example those including polling or event sources. In this case a test case should use `complete(StreamsContext, Condition, long, TimeUnit)`.

      Parameters:
        `context` - Context to be used for submission.
      Throws:
        `java.lang.Exception` - Failure submitting or executing the topology.
        `java.lang.IllegalStateException` - `StreamsContext.getType()` is not supported.

    - #### complete

          boolean complete(StreamsContext<?> context,
                           Condition<?> endCondition,
                           long timeout,
                           java.util.concurrent.TimeUnit unit)
                    throws java.lang.Exception

      Submit the topology for this tester and wait for it to complete, or reach an end condition. If the topology does not complete or reach its end condition before `timeout` then it is terminated.
      This is suitable for testing topologies that never complete or any topology running in a `distributed` context.

      End condition is usually a `Condition` returned from `atLeastTupleCount(TStream, long)` or `tupleCount(TStream, long)` so that this method returns once the stream has submitted a sufficient number of tuples.
      Note that the condition will be only checked periodically up to `timeout`, so that if the condition is only valid for a brief period of time, then its valid state may not be seen, and thus this method will wait for the timeout period.

      Parameters:
        `context` - Context to be used for submission.
        `endCondition` - Condition that will cause this method to return if it is true.
        `timeout` - Maximum time to wait for the topology to complete or reach its end condition.
        `unit` - Unit for `timeout`.
      Returns:
        The value of `endCondition.valid()`.
      Throws:
        `java.lang.Exception` - Failure submitting or executing the topology.
        `java.lang.IllegalStateException` - `StreamsContext.getType()` is not supported.
      See Also:
        `complete(StreamsContext)`

    - #### complete

          boolean complete(StreamsContext<?> context,
                           java.util.Map<java.lang.String,java.lang.Object> config,
                           Condition<?> endCondition,
                           long timeout,
                           java.util.concurrent.TimeUnit unit)
                    throws java.lang.Exception

      Throws:
        `java.lang.Exception`

    - #### completeAndTestStringOutput

          Condition<java.util.List<java.lang.String>> completeAndTestStringOutput(StreamsContext<?> context,
                                                                                  TStream<?> output,
                                                                                  long timeout,
                                                                                  java.util.concurrent.TimeUnit unit,
                                                                                  java.lang.String... contents)
                                                                           throws java.lang.Exception

      Throws:
        `java.lang.Exception`

    - #### completeAndTestStringOutput

          Condition<java.util.List<java.lang.String>> completeAndTestStringOutput(StreamsContext<?> context,
                                                                                  java.util.Map<java.lang.String,java.lang.Object> config,
                                                                                  TStream<?> output,
                                                                                  long timeout,
                                                                                  java.util.concurrent.TimeUnit unit,
                                                                                  java.lang.String... contents)
                                                                           throws java.lang.Exception

      Throws:
        `java.lang.Exception`