public abstract class ConnectorOutputTest extends Object
This framework makes it possible to define tests that start a connector, record the change events output by the connector, and compare these change events to expected results. Connectors are defined via properties files, and the expected results are recorded to or read from files containing the sequence of change events serialized as an array of JSON documents. The test can also define an optional environment properties file in which test-specific parameters can be specified.
Other fields may vary every time the database is started. For example, a MySQL server that is configured to use GTIDs will
generate a new server_uuid value when it is initialized, and this value is then used in all GTIDs generated by
that server instance. Since multiple builds will start up and initialize a new MySQL server (in a Docker container), the
GTID will vary with each build. The framework can handle this by allowing the expected results to contain variables in
the form of ${variableName1}, and the framework will use values supplied during test setup to replace these
variables prior to parsing the JSON document for each expected change event. The framework allows the test setup to
supply a function that provides the replacement variable values given the connector configuration. So the MySQL connector
tests, for example, can connect to the MySQL server and return all of the system variables as the variable values;
the framework does all the rest.
@Test
public void shouldCaptureChangesFromMySqlWithNoGtids() {
runConnector(usingSpec("test1", "src/test/resources/expected/test1"));
}
The framework uses a test specification that encapsulates the connector configuration, the environment properties, how
to obtain the variable values, and where to find the results. This example creates a test specification with the name
test1 and the connector properties file, the environment properties file, and the expected results file all defined
in a directory named src/test/resources/expected/test1. Once again, the test will write out the expected results
file if none exists; otherwise, it will read in the expected results and compare them to the events output by the connector.
The framework supports other variations, and the specWith method is a simple convenience method that replaces
explicitly building up the test specification by using lots of defaults. Consequently, the framework offers a great deal
of flexibility.
To see more detail about the actual and expected records, turn on Debezium's test debug mode by using this line
before the runConnector call:
Testing.Debug.enable();
| Modifier and Type | Class and Description |
|---|---|
private static class |
ConnectorOutputTest.ConsumerCompletion |
private static class |
ConnectorOutputTest.ExecutionResult |
protected static interface |
ConnectorOutputTest.InputStreamSupplier |
protected static interface |
ConnectorOutputTest.OutputStreamSupplier |
private static class |
ConnectorOutputTest.SchemaAndValueConverter |
static interface |
ConnectorOutputTest.TestData |
static class |
ConnectorOutputTest.TestSpecification |
protected static interface |
ConnectorOutputTest.VariableSupplier |
| Modifier and Type | Field and Description |
|---|---|
static Path |
CONNECTOR_OUTPUT_PATH
Before each test this class will delete the "target/connector-output" directory under the project in which the test is run.
|
static String |
CONTROL_END |
static String |
CONTROL_KEY |
static String |
CONTROL_RESTART |
static String |
CONTROL_STOP |
static String |
DEFAULT_CONNECTOR_PROPERTIES_FILENAME |
static String |
DEFAULT_ENV_PROPERTIES_FILENAME |
static String |
DEFAULT_EXPECTED_RECORDS_FILENAME |
static String |
ENV_CONNECTOR_TIMEOUT_IN_SECONDS |
static String |
ENV_IGNORE_FIELDS |
protected static Path |
OFFSET_STORE_PATH |
| Constructor and Description |
|---|
ConnectorOutputTest() |
| Modifier and Type | Method and Description |
|---|---|
protected void |
addValueComparatorsByFieldPath(BiConsumer<String,VerifyRecord.RecordValueComparator> comparatorsByPath) |
protected void |
addValueComparatorsBySchemaName(BiConsumer<String,VerifyRecord.RecordValueComparator> comparatorsByPath) |
void |
afterEachTestMethod() |
private void |
applyCommand(Document record,
ConnectorOutputTest.ConsumerCompletion result) |
private void |
assertSourceRecordMatch(org.apache.kafka.connect.source.SourceRecord actual,
org.apache.kafka.connect.source.SourceRecord expected,
Predicate<String> ignoreFields,
Map<String,VerifyRecord.RecordValueComparator> comparatorsByName,
Map<String,VerifyRecord.RecordValueComparator> comparatorsBySchemaName) |
void |
cleanOffsetStorage() |
private <T> Queue<T> |
fixedSizeQueue(int size) |
private String |
getCommand(Document record) |
protected String[] |
globallyIgnorableFieldNames()
Return the names of the fields that should always be ignored for all tests.
|
private boolean |
isCommand(Document record) |
private boolean |
isEndCommand(Document record) |
private org.apache.kafka.connect.source.SourceRecord |
rehydrateSourceRecord(Document record,
ConnectorOutputTest.SchemaAndValueConverter keyConverter,
ConnectorOutputTest.SchemaAndValueConverter valueConverter) |
protected static File |
replaceVariables(InputStream stream,
AvailableVariables variables)
Read the contents of the supplied
InputStream, replace all variables found in the content, and write the
result to a temporary file. |
protected void |
runConnector(ConnectorOutputTest.TestSpecification spec)
Run the connector described by the supplied test specification.
|
protected void |
runConnector(ConnectorOutputTest.TestSpecification spec,
io.debezium.embedded.EmbeddedEngine.CompletionCallback callback)
Run the connector described by the supplied test specification.
|
protected void |
runConnector(String testName,
Path directory)
Run the connector that uses the files in the given directory for the connector configuration, environment configuration,
and expected results.
|
protected void |
runConnector(String testName,
Path configFile,
Path expectedRecordsFile,
Path envFile)
Run the connector described by the supplied test specification.
|
protected void |
runConnector(String testName,
String directory)
Run the connector that uses the files in the given directory for the connector configuration, environment configuration,
and expected results.
|
protected void |
runConnector(String testName,
String configFile,
String expectedRecordsFile,
String envFile)
Run the connector described by the supplied test specification.
|
private Document |
serializeSourceRecord(org.apache.kafka.connect.source.SourceRecord record,
ConnectorOutputTest.SchemaAndValueConverter keyConverter,
ConnectorOutputTest.SchemaAndValueConverter valueConverter)
Serialize the source record to document form.
|
private Map<String,?> |
toMap(Document doc) |
protected ConnectorOutputTest.TestSpecification |
usingSpec(String name)
Create a new test specification with the given name.
|
protected ConnectorOutputTest.TestSpecification |
usingSpec(String name,
Path directory)
Create a new test specification that uses the files in the given directory for the connector configuration, environment
configuration, and expected results.
|
protected ConnectorOutputTest.TestSpecification |
usingSpec(String name,
Path configFile,
Path expectedRecordsFile,
Path envFile)
Create a new test specification that uses the given files for the configuration, environment, and expected results.
|
protected ConnectorOutputTest.TestSpecification |
usingSpec(String name,
String directory)
Create a new test specification that uses the files in the given directory for the connector configuration, environment
configuration,
and expected results.
|
protected ConnectorOutputTest.TestSpecification |
usingSpec(String name,
String configFile,
String expectedRecordsFile,
String envFile)
Create a new test specification that uses the given files for the configuration, environment, and expected results.
|
public static final String DEFAULT_CONNECTOR_PROPERTIES_FILENAME
public static final String DEFAULT_ENV_PROPERTIES_FILENAME
public static final String DEFAULT_EXPECTED_RECORDS_FILENAME
public static final String ENV_CONNECTOR_TIMEOUT_IN_SECONDS
public static final String ENV_IGNORE_FIELDS
public static final Path CONNECTOR_OUTPUT_PATH
protected static final Path OFFSET_STORE_PATH
public static final String CONTROL_KEY
public static final String CONTROL_RESTART
public static final String CONTROL_STOP
public static final String CONTROL_END
protected void addValueComparatorsByFieldPath(BiConsumer<String,VerifyRecord.RecordValueComparator> comparatorsByPath)
protected void addValueComparatorsBySchemaName(BiConsumer<String,VerifyRecord.RecordValueComparator> comparatorsByPath)
protected ConnectorOutputTest.TestSpecification usingSpec(String name)
name - the name of the testprotected ConnectorOutputTest.TestSpecification usingSpec(String name, String directory)
name - the name of the testdirectory - the path to the directory that contains the test files; may not be nullprotected ConnectorOutputTest.TestSpecification usingSpec(String name, Path directory)
name - the name of the testdirectory - the path to the directory that contains the test files; may not be nullprotected ConnectorOutputTest.TestSpecification usingSpec(String name, String configFile, String expectedRecordsFile, String envFile)
name - the name of the test or test run; may not be nullconfigFile - the path to the configuration file; may not be nullexpectedRecordsFile - the path to the file where the expected records can be read or where they are to be written;
may not be nullenvFile - the path to the file containing the environment properties; may be null if there is no such fileprotected ConnectorOutputTest.TestSpecification usingSpec(String name, Path configFile, Path expectedRecordsFile, Path envFile)
name - the name of the test or test run; may not be nullconfigFile - the path to the configuration file; may not be nullexpectedRecordsFile - the path to the file where the expected records can be read or where they are to be written;
may not be nullenvFile - the path to the file containing the environment properties; may be null if there is no such filepublic void cleanOffsetStorage()
public void afterEachTestMethod()
protected String[] globallyIgnorableFieldNames()
null.protected void runConnector(String testName, String directory)
testName - the name of the test or test run; may not be nulldirectory - the path to the directory that contains the test files; may not be nullprotected void runConnector(String testName, Path directory)
testName - the name of the test or test run; may not be nulldirectory - the path to the directory that contains the test files; may not be nullprotected void runConnector(String testName, String configFile, String expectedRecordsFile, String envFile)
testName - the name of the test or test run; may not be nullconfigFile - the path to the configuration file; may not be nullexpectedRecordsFile - the path to the file where the expected records can be read or where they are to be written;
may not be nullenvFile - the path to the file containing the environment properties; may be null if there is no such fileprotected void runConnector(String testName, Path configFile, Path expectedRecordsFile, Path envFile)
testName - the name of the test or test run; may not be nullconfigFile - the path to the configuration file; may not be nullexpectedRecordsFile - the path to the file where the expected records can be read or where they are to be written;
may not be nullenvFile - the path to the file containing the environment properties; may be null if there is no such fileprotected void runConnector(ConnectorOutputTest.TestSpecification spec)
spec - the test specificationprotected void runConnector(ConnectorOutputTest.TestSpecification spec, io.debezium.embedded.EmbeddedEngine.CompletionCallback callback)
spec - the test specificationcallback - the function that should be called when the connector is stoppedprivate void applyCommand(Document record, ConnectorOutputTest.ConsumerCompletion result)
private boolean isCommand(Document record)
private boolean isEndCommand(Document record)
private org.apache.kafka.connect.source.SourceRecord rehydrateSourceRecord(Document record, ConnectorOutputTest.SchemaAndValueConverter keyConverter, ConnectorOutputTest.SchemaAndValueConverter valueConverter) throws IOException
IOExceptionprivate Document serializeSourceRecord(org.apache.kafka.connect.source.SourceRecord record, ConnectorOutputTest.SchemaAndValueConverter keyConverter, ConnectorOutputTest.SchemaAndValueConverter valueConverter) throws IOException
record - the record; may not be nullkeyConverter - the converter for the record key's schema and payloadvalueConverter - the converter for the record value's schema and payloadIOException - if there is an error converting the key or valueprivate void assertSourceRecordMatch(org.apache.kafka.connect.source.SourceRecord actual,
org.apache.kafka.connect.source.SourceRecord expected,
Predicate<String> ignoreFields,
Map<String,VerifyRecord.RecordValueComparator> comparatorsByName,
Map<String,VerifyRecord.RecordValueComparator> comparatorsBySchemaName)
private <T> Queue<T> fixedSizeQueue(int size)
protected static File replaceVariables(InputStream stream, AvailableVariables variables) throws IOException
InputStream, replace all variables found in the content, and write the
result to a temporary file.stream - the input stream containing zero or more variable expressionsvariables - the variablesIOException - if there is a problem reading the input stream or writing to the temporary fileCopyright © 2018 JBoss by Red Hat. All rights reserved.