Class ProtocolFactory

java.lang.Object
io.camunda.zeebe.test.broker.protocol.ProtocolFactory

public final class ProtocolFactory extends Object
A Record factory which produces randomized records deterministically. A seed can be given on construction to reproduce the same records. On failure, the seed can be fetched via getSeed(). By default, calling ProtocolFactory() will always return a factory which produces the same records. This is useful for reproducible tests, such that running the same test twice (regardless of the environment, e.g. CI or locally) will produce the same results.

Every property is fully randomized and cannot be relied upon semantically, except the value type, the value, and the intent. These will always all match the implicit assumptions of the protocol. For example, if the ValueType is ValueType.JOB, then the record's value is going to be an instance of JobRecordValue, and the intent is going to be an instance of JobIntent. This is done to enable using this factory with tests that expect to serialize and deserialize the records.

  • Constructor Details

    • ProtocolFactory

      public ProtocolFactory()
      Every call to this constructor will always return a factory which produces the exact same record. This is useful for reproducible tests. If you want a different behavior, then you can use ProtocolFactory(long) and pass something like ThreadLocalRandom.nextLong().
    • ProtocolFactory

      public ProtocolFactory(long seed)
      Returns a factory with the given seed for the initial randomization. This enables you to reproduce past results if you know the seed. Note that you will need to also effectively reproduce the same steps as in the past; the seed by itself is not enough. So if you have a seed, and want to reproduce the 10th record generated, you will need to generate 10 records again.
      Parameters:
      seed - the seed to use
  • Method Details

    • generateRecords

      public <T extends RecordValue> Stream<Record<T>> generateRecords()
      Returns:
      a stream of random records
    • generateRecords

      public <T extends RecordValue> Stream<Record<T>> generateRecords(UnaryOperator<ImmutableRecord.Builder<T>> modifier)
      Generates a modifiable stream of records.
      Parameters:
      modifier - applied to the builder after all the properties have been filled as the last step; cannot be null
      Returns:
      a stream of random records
      Throws:
      NullPointerException - if modifier is null
    • generateForAllValueTypes

      public <T extends RecordValue> Stream<Record<T>> generateForAllValueTypes()
      Generates a stream of records, one record for each known ValueType (except the values created by SBE, i.e. NULL_VAL and SBE_UNKNOWN).
      Returns:
      a stream of records, one for each value type
    • generateForAllValueTypes

      public <T extends RecordValue> Stream<Record<T>> generateForAllValueTypes(UnaryOperator<ImmutableRecord.Builder<T>> modifier)
      Generates a stream of records, one record for each known ValueType (except the values created by SBE, i.e. NULL_VAL and SBE_UNKNOWN).
      Returns:
      a stream of records, one for each value type
      Throws:
      NullPointerException - if modifier is null
    • generateRecord

      public <T extends RecordValue> Record<T> generateRecord()
      Returns:
      a random record with a random value type
    • generateRecord

      public <T extends RecordValue> Record<T> generateRecord(UnaryOperator<ImmutableRecord.Builder<T>> modifier)
      Generates a record with the given modifier applied to its builder as the last step in the generation process.
      Parameters:
      modifier - applied to the builder after all the properties have been filled as the last step; cannot be null
      Returns:
      a randomly generated record
      Throws:
      NullPointerException - if modifier is null
    • generateRecord

      public <T extends RecordValue> Record<T> generateRecord(ValueType valueType)
      Generates a record with the given valueType. The value and intent properties will be picked from the appropriate types based on the given valueType. This means, if you pass ValueType.ERROR, the value will be of type ErrorRecordValue, and the intent of type ErrorIntent. Each of these will, of course, be randomly generated as well.
      Parameters:
      valueType - the expected value type of the record
      Returns:
      a randomized record with the given value type, with the value and intent being of the expected types
      Throws:
      NullPointerException - if valueType is null
    • generateRecordWithIntent

      public <T extends RecordValue> Record<T> generateRecordWithIntent(ValueType valueType, Intent intent)
      Generates a record with the given valueType and intent. The value will be picked from the appropriate types based on the given valueType. This means, if you pass ValueType.ERROR, the value will be of type ErrorRecordValue, and the intent of type ErrorIntent. Each of these will, of course, be randomly generated as well.
      Parameters:
      valueType - the expected value type of the record
      intent - the expected intent of the record (if it is null, a random intent will be chosen)
      Returns:
      a randomized record with the given value type, with the value being of the expected types
      Throws:
      NullPointerException - if valueType is null
    • generateRecord

      public <T extends RecordValue> Record<T> generateRecord(ValueType valueType, UnaryOperator<ImmutableRecord.Builder<T>> modifier)
      Generates a record with the given valueType. The value and intent properties will be picked from the appropriate types based on the given valueType. This means, if you pass ValueType.ERROR, the value will be of type ErrorRecordValue, and the intent of type ErrorIntent. Each of these will, of course, be randomly generated as well.

      The given modifier is applied to the final builder as the last step of the generation.

      Parameters:
      valueType - the expected value type of the record
      modifier - applied to the builder after all the properties have been filled as the last * step; cannot be null
      Returns:
      a randomized record with the given value type, with the value and intent being of the expected types
      Throws:
      NullPointerException - if modifier is null or if valueType is null
    • generateRecord

      public <T extends RecordValue> Record<T> generateRecord(ValueType valueType, UnaryOperator<ImmutableRecord.Builder<T>> modifier, Intent intent)
      Generates a record with the given valueType. The value property will be picked from the appropriate types based on the given valueType. This means, if you pass ValueType.ERROR, the value will be of type ErrorRecordValue, and the intent of type ErrorIntent. Each of these will, of course, be randomly generated as well.

      The given modifier is applied to the final builder as the last step of the generation.

      Parameters:
      valueType - the expected value type of the record
      modifier - applied to the builder after all the properties have been filled as the last * step; cannot be null
      intent - the expected intent of the record (if it is null, a random intent will be chosen)
      Returns:
      a randomized record with the given value type, with the value and intent being of the expected types
      Throws:
      NullPointerException - if modifier is null or if valueType is null
    • generateObject

      public <T> T generateObject(Class<T> objectClass)
      Generates a random object. Can be used, for example, to generate a random ErrorRecordValue.

      This is a convenience method if you wish to generate further random objects but want everything to be reproducible, i.e. using the same seed/randomization.

      Parameters:
      objectClass - the class of the object ot generate
      Throws:
      NullPointerException - if objectClass is null
    • getSeed

      public long getSeed()
      Returns:
      the seed used when creating this factory