# Test Environments

Source: https://orbitalhq.com/docs/testing/test-environments

**Note: Turn it on**
Test environments are disabled by default, to prevent you deploying these to production.
 

Orbital uses a test framework called [Nebula](https://nebula.orbitalhq.com) to spin up test environments.

Nebula allows declaring services which are deployed as docker containers (using [TestContainers](https://testcontainers.com/)),
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:

```kotlin 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:

```
--vyne.toggles.nebulaEnabled=true
```

### Deploying a Nebula server
Nebula runs on a standalone docker container. 

Inside your Docker Compose, the following should be declared: 

```yaml
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
     expose:
       - 8099
     ports:
       - "8099:8099"
     # Nebula starts other docker containers, such as Kafka etc., so needs to 
     # run on the host network
     # 
     network_mode: "host"
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock  # Allow nebula to control Docker
     environment:
       - DOCKER_HOST=tcp://localhost:2375
```

Alternatively, to just run Nebula outside of compose as a standalone Docker container, run:

```bash
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](https://start.orbitalhq.com/compose.yml) with Nebula support enabled, then this might already be done for you.

**Warning: Not intended for production**
You should never deploy Orbital to production with Nebula support enabled, as it allows running of arbitrary code.
    
  For this reason, Nebula is disabled by default in our docker images.
    
  The Docker Compose provided at [start.orbitalhq.com/compose.yml](https://start.orbitalhq.com/compose.yml) is intended for rapidly deploying local development enviroments, so enables Nebula

### Docker compose OS variations

**Note: OS Specific**
The docker compose config for Nebula is subtly different between Windows, Mac and Linux.

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](https://start.orbitalhq.com/compose.yml) in a browser, we'll detect your OS and serve
the correct variation. (The [start script](/docs#what-the-install-script-does) 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](https://start.orbitalhq.com/compose.yml?os=windows)
 * Mac: [https://start.orbitalhq.com/compose.yml?os=mac](https://start.orbitalhq.com/compose.yml?os=mac)
 * Linux: [https://start.orbitalhq.com/compose.yml?os=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](/docs/deploying/configuring-orbital#configuring-where-orbital-finds-other-orbital-services) file:

```hocon
services {
   nebula {
      url="http://localhost:8099"
   }
}
```

## Defining test environments in your project
Once test environment support is [enabled](#enabling-test-environments), you can add Nebula files (`*.nebula.kts`) in your Taxi project.

First, add a Nebula section in your Taxi project's additionalSources:

```hocon
    name: com.acme/demo
    version: 0.1.0
    sourceRoot: src/
    additionalSources: {
       "@orbital/config" : "orbital/config/*.conf",
>      "@orbital/nebula" : "orbital/nebula/*.nebula.kts"
    }
```

You can now add Nebula files into your `orbital/nebula` directory.

```kotlin 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](https://nebula.orbitalhq.com)

## 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 list of active Nebula stacks is displayed in the Test Environments tab:

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

Clicking on a server in the Test Environments view displays the environment variables exposed for the container:

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

```hocon 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:

```hocon 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.

```taxi
   service TicketsApi {
>      @HttpOperation(method = "GET", url = "https://ticketsApi/tickets")
       operation getAllTickets(): Ticket[]
   }
```

Related links:
 * Learn more about [overriding server urls](/docs/describing-data-sources/http#modifying-server-ur-ls) using `services.conf` files 
 * Be careful of common mistakes with [URL substitution in HOCON files](/docs/deploying/configuring-orbital#correctly-handling-substitutions-in-urls)
