Testing
Test Environments
Orbital uses a test framework called Nebula to spin up test environments.
Nebula allows declaring services which are deployed as docker containers (using TestContainers), and scripting their behaviour, using Kotlin code.
For example, to deploy a Kafka broker which emits stock quotes every 100ms, you’d declare the following:
stack { kafka { producer("100ms".duration(), "stockQuotes") { jsonMessage { mapOf( "symbol" to listOf("GBP/USD", "AUD/USD", "NZD/USD").random(), "price" to Random.nextDouble(0.8, 0.95).toBigDecimal() ) } } }}Orbital has first-class support for Nebula, automatically deploying the test environments declared in *.nebula.kts files.
Enabling test environments
Support for Nebula-powered test environments is turned off by default, to ensure that you don’t accidentally deploy Nebula support into production.
In a local environment, start Orbital with the following parameter:
--orbital.toggles.nebula-enabled=true(The older --vyne.toggles.nebulaEnabled=true still works, but Orbital logs a warning asking you to migrate it.)
The Docker Compose file from start.orbitalhq.com already sets this, and runs Nebula for you.
Deploying a Nebula server
Nebula runs on a standalone docker container.
Inside your Docker Compose, the following should be declared:
services: # Nebula powers Orbital's test environments. # You can use Nebula to quickly deploy and script test infrastructure, such as # Kafka brokers, databases, HTTP servers, AWS instances and more. # # See more at https://github.com/orbitalapi/nebula # # This is optional, and shouldn't be deployed in production. nebula: image: orbitalhq/nebula:next networks: - nebula_network expose: - 8099 ports: - "8099:8099" volumes: - /var/run/docker.sock:/var/run/docker.sock # Allow nebula to control Docker environment: - DOCKER_HOST=unix:///var/run/docker.sock - TESTCONTAINERS_RYUK_DISABLED=true # Mac and Windows only - remove on Linux. Lets the containers Nebula starts # be reached from Orbital through Docker Desktop's host address. - TESTCONTAINERS_HOST_OVERRIDE=host.docker.internalOrbital and Nebula need to share a network (nebula_network above) so that http://nebula:8099 resolves from Orbital.
Alternatively, to just run Nebula outside of compose as a standalone Docker container, run:
docker run -v /var/run/docker.sock:/var/run/docker.sock --privileged --network host orbitalhq/nebulaIf you generated a Docker Compose from start.orbitalhq.com/compose.yml with Nebula support enabled, then this might already be done for you.
Docker compose OS variations
Nebula uses docker directly to download and start images, based on the *.nebula.kts file.
The config for allowing this in Docker Compose varies slightly between Linux, Mac and Windows.
We have os-specific docker compose files prepared which include support for Nebula. It is reccomended to use these. By default, when you visit start.orbitalhq.com/compose.yml in a browser, we’ll detect your OS and serve the correct variation. (The start script does this for you.)
However, if you’re scripting this, you can force the OS using one of the following links:
- Windows: https://start.orbitalhq.com/compose.yml?os=windows
- Mac: https://start.orbitalhq.com/compose.yml?os=mac
- Linux: https://start.orbitalhq.com/compose.yml?os=linux
Configuring services.conf
Orbital will attempt to contact Nebula at http://nebula. If you’re running on K8s or Docker Compose, the default DNS
will resolve this.
However, if you need to deploy Nebula somewhere else, you can configure this be modifying the services.conf file:
services { nebula { url="http://localhost:8099" }}Defining test environments in your project
Once test environment support is enabled, you can add Nebula files (*.nebula.kts) in your Taxi project.
First, add a Nebula section in your Taxi project’s additionalSources:
name: com.acme/demoversion: 0.1.0sourceRoot: src/additionalSources: { "@orbital/config" : "orbital/config/*.conf", "@orbital/nebula" : "orbital/nebula/**"}You can now add Nebula files into your orbital/nebula directory. (The ** glob ships the whole directory with the
stack, so a stack can read data files - a CSV to seed a table with, say - that sit beside it. The narrower
orbital/nebula/*.nebula.kts still works, but then only the stack files themselves are sent to Nebula.)
http { get("/ticketPrices/{cinemaId}") { call -> val price = Random.nextDouble(9.99, 19.99).toBigDecimal().setScale(2, RoundingMode.HALF_UP) call.respondText("""{ "price" : $price }""", ContentType.parse("application/json")) } }For more information on Nebula, and how to declare stacks, consult the Nebula docs
Starting and updating test environments
Orbital will automatically submit Nebula config files found in any of the Taxi projects through to Nebula.
As the Nebula stack files change, updates are automatically submitted through to Nebula.
The active Nebula stacks are listed on the Local environments page in the sidebar, grouped by the project and stack file they came from. The page also shows whether Orbital can reach the Nebula server. Select a component to see the container it’s running in, and the connection details it published:
Nebula environment variables
As services start and stop, various configuration parameters change - such as ports, paths, database names, etc.
Nebula exposes these variables back to Orbital, and Orbital makes them available as variables you can refer to in your connections.
The Environment variables tab of a component on the Local environments page lists the variables it has published.
Each value is available under several names, from the most convenient (NEBULA_FILMS_DB_PORT) to the most
specific (NEBULA_COM_DEMO_FILMS_STACK_FILMS_DB_PORT, which includes the project and stack name), so you can pick
the shortest one that doesn’t clash with another stack:
You can then use these environment variables in your connections.conf files that define your connections:
aws { my-aws-account { # Optional Parameter. When not provided Orbital will use the [AWS default credentials provider](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default) by default. accessKey = ${NEBULA_S3_ACCESS_KEY} connectionName = my-aws-account # Optional parameter for development and testing purposes to point to a different endpoint such as a LocalStack installation. endPointOverride = ${NEBULA_S3_ENDPOINT_OVERRIDE} # Mandatory region = eu-west-1 # Optional Parameter. When not provided Orbital will use the [AWS default credentials provider](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default) by default. secretKey = ${NEBULA_S3_SECRET_KEY} }}For HTTP based services, you can configure a services.conf file in your project:
services { ticketsApi { url="http://localhost:"${NEBULA_HTTP_PORT}"" }}Now, services with urls pointing at a ticketsApi host will resolve to http://localhost with the port exposed by Nebula.
service TicketsApi { @HttpOperation(method = "GET", url = "https://ticketsApi/tickets") operation getAllTickets(): Ticket[]}Related links:
- Learn more about overriding server urls using
services.conffiles - Be careful of common mistakes with URL substitution in HOCON files