A tool to enable the generation of data, and passing it to a system-under-test at a specified rate, all whilst having the ability to record the performance of the system.
When running the Kapacity engine, a few implementations must be defined, which ultimately control how data is generated, where the data is posted, and how results are collated. The interfaces that require implementations are:
-
com.stuforbes.kapacity.data.DataLoader
Implementations of this interface load the data to be posted, returning a list of scenarios to be executed
-
com.stuforbes.kapacity.runner.data.DataPoster
Describes how the data item should be posted to the system
-
com.stuforbes.kapacity.recorder.FlightRecorder
Used to record the performance of the system under test. Returns the results when it is stopped
-
com.stuforbes.kapacity.result.ResultPrinter
Prints the results of the test upon completion
There is a sample application, under the folder sample/application. This application has 2 different methods to kapacity test:
- An Http REST endpoint
- A Kafka consumer and producer
There is a project to kapacity test this sample application, under the folder sample/kapacity-test.
You will need both Gradle and Docker installed locally to start up the application. To start everything up, run the script run.sh from the application folder. This will:
- Build the application jar file using Gradle
- Build the Docker image for the application
- Start up the application and it's dependent services using Docker Compose
From the sample/kapacity-test folder, run the command gradle kapacity-test
. This will run the tests against the sample
application for a duration of 20 seconds, and print the results to the console.
The test execution is configured in the build.gradle file as follows:
kapacity { duration = 20000 dataLoader = "com.stuforbes.kapacity.sample.data.SampleDataLoader" timeSeriesDataSorter = "com.stuforbes.kapacity.data.StandardTimeSeriesDataSorter" dataPoster = "com.stuforbes.kapacity.sample.data.KafkaDataPosterImpl" flightRecorder = "com.stuforbes.kapacity.sample.recorder.PrometheusFlightRecorderImpl" resultFormatter = "com.stuforbes.kapacity.recorder.prometheus.PrometheusResultFormatter" }
All configuration should be added to a file in the src/main/resources
folder, named test.properties
. These properties
can be accessed using extension functions in the class com.stuforbes.kapacity.configuration.ConfigKt. These extension functions are:
- intConfig()
- longConfig()
- stringConfig()
- booleanConfig()
Examples of how to use them can be found in com.stuforbes.kapacity.sample.data.SampleDataLoader
The versatility of Kapacity is in the various combinations of components that can be configured. The sections below describe the different component interfaces, and where applicable, some implementations that are provided.
A Mechanism to load the data that will be used in the test run. Data is to be provided in a list of Scenarios (com.stuforbes.kapacity.model.Scenario). Each scenario should be used to describe all interactions for a particular entity. For example, when kapacity testing a standard website, a scenario could describe a single users interactions with the site.
Classes implementing the interface must override the function loadData()
which takes no arguments and returns a list of scenarios.
Implementations of this interface will post a single data item into the system-under-test.
This interface has a single function that requires implementing: post(data: T)
where data is the object that will be
posted.
Kapacity includes 2 implementations of DataPoster out of the box:
-
com.stuforbes.kapacity.runner.data.HttpDataPoster
Data items are serialised to JSON and sent via an HTTP POST request to the specified url. Response status codes and response times are recorded via the flight recorder, if the flight recorder also implements
DataPointRecordingFlightRecorder<Int, HttpResults>
. e.g. seecom.stuforbes.kapacity.recorder.http.HttpResponseRecorder
-
com.stuforbes.kapacity.runner.data.KafkaDataPoster
Data items are serialised to JSON and sent via the Kafka topic.
There are 2 functions that require implementing for this interface:
start()
Start recordingstop(): Result
Stop recording and return the results
Kapacity provides 3 implementations of FlightRecorder:
-
com.stuforbes.kapacity.recorder.NoOpFlightRecorder
No recording takes place within Kapacity
-
com.stuforbes.kapacity.recorder.http.HttpResponseRecorder
This recorder also extends the
com.stuforbes.kapacity.recorder.DataPointRecorder
interface, which records the response times of each request. When complete, the results are returned in acom.stuforbes.kapacity.recorder.http.HttpResults
object. -
com.stuforbes.kapacity.recorder.prometheus.PrometheusFlightRecorder
Queries the desired latency metric from Prometheus for the duration between start() and stop() being invoked. The results are returned in a
com.stuforbes.kapacity.recorder.prometheus.PrometheusResult
object.
Prints the results to the required output stream. The ResultPrinter is configured with an implementation of
com.stuforbes.kapacity.result.ResultFormatter
, which describes how to render the result in a string format.
There are 2 implementations of ResultPrinter provided out of the box:
-
com.stuforbes.kapacity.result.ResultPrinterKt.consoleResultPrinter
Renders the results to the console upon completion
-
com.stuforbes.kapacity.result.ResultPrinterKt.fileResultPrinter
Renders the results to the specified file upon completion