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.nebula.kts
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.internal

Orbital 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/nebula

If 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:

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.)

stack.nebula.kts
 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:

Local environments, showing a stack with a Postgres database and an HTTP server

Local environments, showing a stack with a Postgres database and an HTTP server

Local environments, showing a stack with a Postgres database and an HTTP server

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:

The environment variables published by a Postgres container

The environment variables published by a Postgres container

The environment variables published by a Postgres container

You can then use these environment variables in your connections.conf files that define your connections:

connections.conf
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.conf
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: