Skip to content

Commit

Permalink
docs: documented assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
nirga committed Feb 22, 2023
1 parent 25cc18d commit 0f04a30
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 227 deletions.
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
</p>
<h1 align="center">Jest OpenTelemetry</h1>
<p align="center">
<p align="center">End to end tests done right</p>
<p align="center">End to end tests with 10 lines of code</p>
</p>
<h4 align="center">
<a href="https://join.slack.com/t/traceloopcommunity/shared_invite/zt-1plpfpm6r-zOHKI028VkpcWdobX65C~g">Slack</a> |
<a href="https://docs.traceloop.dev">Docs</a> |
<a href="https://docs.traceloop.dev/jest-otel/introduction">Docs</a> |
<a href="https://www.traceloop.dev">Website</a>
</h4>

Expand Down Expand Up @@ -44,16 +44,54 @@ npm i --save-dev @traceloop/jest-opentelemetry
Then, you can start testing your microservices:

```js
const traceloop = new TraceLoop();

await traceloop.axiosInstance.post('http://my.awesome.website/orders/create');
await traceloop.fetchTraces();

expectTrace(traceloop.serviceByName('emails-service'))
.toReceiveHttpRequest()
.ofMethod('POST')
.withBody({ emailTemplate: 'orderCreated', itemId: '123' });
```

## What can you test?

Jest OpenTelemetry can be used to test anything that's happening in your system.
We're constantly adding more, and you're welcome to [suggest yours](https://github.com/traceloop/jest-opentelemetry/issues).

### Service Assertions

- [x] [REST](http://docs.traceloop.dev/jest-otel/syntax/services-rest)
- [ ] GraphQL
- [ ] GRPC

### Database Assertions

- [x] [PostgreSQL](http://docs.traceloop.dev/jest-otel/syntax/db-pg)
- [ ] MongoDB
- [ ] Redis
- [ ] S3

### Analytics Reporting Assertions

- [ ] Segment
- [ ] Snowflake
- [ ] BigQuery
- [ ] Posthog

### External Systems Assertions

- [ ] SendGrid
- [ ] Stripe

## 🌱 Contributing

Whether it's big or small, we love contributions ❤️ Check out our guide to see how to [get started](https://docs.traceloop.dev/contributing/overview).

Not sure where to get started? You can:

- [Book a free, non-pressure pairing sessions with one of our teammates](mailto:nir@traceloop.dev?subject=Pairing%20session&body=I'd%20like%20to%20do%20a%20pairing%20session!)!
- [Book a free pairing session with one of our teammates](mailto:nir@traceloop.dev?subject=Pairing%20session&body=I'd%20like%20to%20do%20a%20pairing%20session!)!
- Join our <a href="https://join.slack.com/t/enrollacommunity/shared_invite/zt-1naxh3lia-wIvFcLyCEXTYzAuO1U688Q">Slack</a>, and ask us any questions there.

## 💚 Community & Support
Expand Down
89 changes: 2 additions & 87 deletions docs/jest-otel/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ title: 'Getting Started'
---

Jest OpenTelemetry requires that you have OpenTelemetry installed and configured in your microservices.
For most languages, this can be done by merely installing the OpenTelemetry SDK or configuring a Kubernetes init container that does that.

[Odigo](https://docs.odigos.io/intro) is a new open source project that can do this for you without a single line of code.

You can find more information on how to do this in the [OpenTelemetry documentation](https://opentelemetry.io/docs/js/getting-started/).
[Follow the instructions](no-otel) to get it done in 5 minutes without any code changes!

Feel free to contact us at dev@traceloop.dev if you need any help.

Expand All @@ -27,88 +23,7 @@ Feel free to contact us at dev@traceloop.dev if you need any help.
};
```

3. Update or create your OpenTelemetry collector configuration:

<CodeGroup>

```yaml docker-compose (otel-collector-config.yaml)
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
timeout: 100ms

exporters:
otlphttp:
endpoint: http://host.docker.internal:4123

service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
```
```yaml Kubernetes (otel-collector.yaml)
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel
spec:
config: |
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
timeout: 100ms
exporters:
otlphttp:
endpoint: http://host.docker.internal:4123
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
```
</CodeGroup>
4. If you don't have an OpenTelemetry collector set up, you can set it up in 5 minutes by following the instructions below.
<CodeGroup>
```yaml docker-compose.yaml
services:
...
otel-collector:
image: otel/opentelemetry-collector-contrib:0.71.0
ports:
- 4317:4317
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
command:
- --config=/etc/otel-collector-config.yaml
```
```bash Kubernetes
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
kubectl apply -f otel-collector.yaml
```

</CodeGroup>

5. Start writing tests following our [syntax](syntax/introduction).
3. Start writing tests following our [syntax](syntax/introduction).

## Typescript configuration

Expand Down
19 changes: 9 additions & 10 deletions docs/jest-otel/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ title: 'Introduction'
Jest OpenTelemetry is an engine for writing end to end tests for distributed systems with 10 lines of code.

```js
const sequence = await traces(async () => {
await axios.post('http://orders-service/orders/create', {
productId: 5,
quantity: 2,
});
});

expect(sequence.service('emails-service')).toReceiveHttpRequest({
order: { productId: 5, quantity: 2 },
});
const traceloop = new TraceLoop();

await traceloop.axiosInstance.post('http://my.awesome.website/orders/create');
await traceloop.fetchTraces();

expectTrace(traceloop.serviceByName('emails-service'))
.toReceiveHttpRequest()
.ofMethod('POST')
.withBody({ emailTemplate: 'orderCreated', itemId: '123' });
```

Everything is running locally on your system and can connect to services running locally on your machine,
Expand Down
123 changes: 123 additions & 0 deletions docs/jest-otel/no-otel.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: "What if I don't have OpenTelemetry installed?"
---

No worries! You can install it in any existing Kubernetes environment in under 5 minutes by running the following set of commands.
**No code changes are needed**.

Feel free to contact us at dev@traceloop.dev if you need any help.

<Accordion title="Other options">
[Odigo](https://docs.odigos.io/intro) is a new open source project that can do this for you without a single line of code.

You can also find more information on [OpenTelemetry documentation](https://opentelemetry.io/docs/js/getting-started/).

</Accordion>

1. Install cert-manager. This is required for the OpenTelemetry operator to work.

```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
```

2. Install the [OpenTelemetry operator](https://opentelemetry.io/docs/k8s-operator/) so that metrics will be generated and collected automatically.

```bash
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
```

3. Create a config file named `otel-collector.yaml` for your OpenTelemetry configurations:

```yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: otel-instrumentation
spec:
nodejs:
image: traceloop/instrument-opentelemetry:node-0.3.0
exporter:
endpoint: http://otel-collector:4317
propagators:
- tracecontext
- baggage
- b3

---
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel
spec:
config: |
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
timeout: 100ms
exporters:
otlphttp:
endpoint: http://host.docker.internal:4123
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
```
<Accordion title="What are we doing here?">
We configure 2 separate things:
1. The Instrumentation, which is an init-container which will run on any pod you explictly mark (see step 5).
We are using our own init-container to get more data about your application (like the body of HTTP requests).
You can always remove these lines to use the standard open telemetry init-container:
```yaml
nodejs:
image: traceloop/instrument-opentelemetry:node-0.3.0
```
2. The OpenTelemetry collector, which will collect the metrics from the init-container and send them to the test runner.
What's amazing here is that you can add other exporters to this config file to send the metrics to other services like Datadog and others.
</Accordion>
4. Apply the config file:
```bash
kubectl apply -f otel-collector.yaml
```

5. Update any service you want to instrument with the following annotations (Change the 2 occurances of `my-service` to the name of your service):

<Note>
We add an env var named `SERVICE_NAME` to your service so that you can
later identify it in the tests.
</Note>

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 1
template:
annotations:
instrumentation.opentelemetry.io/inject-nodejs: 'true'
spec:
containers:
env:
- name: SERVICE_NAME
value: 'my-service'
```
This will automatically instrument your service with OpenTelemetry and send the metrics to the OpenTelemetry collector.
Apply those changes and you're done! You can start writing end to end tests.
32 changes: 32 additions & 0 deletions docs/jest-otel/syntax/db-pg.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: 'PostgreSQL'
---

Each assrtion should start with defining the service that's sending requests to the Database you want to check. You do this by:

```js
expectTrace(traceloop.serviceByName('service-name'))...
```

These are the options you can use for service selection:

- `serviceByName` - the name of the service as reported in the `service.name` attribute
(automatically reported by [Traceloop's init container](/jest-otel/no-otel))
- `serviceByK8sPodName` - the name of the pod as reported by Kubernetes
- `serviceByCustomAttribute` - any custom attribute reported by your service to OpenTelemetry

Following that, you can use any of the following assertions:

- `toQueryPostgreSQL`

Then, you can specifically assert for each of the properties of the request:

- `withDatabaseName`

So, a complete assertion can look like:

```js
expectTrace(traceloop.serviceByName('orders-service'))
.toQueryPostgreSQL()
.withDatabaseName('postgres');
```
Empty file.
Loading

0 comments on commit 0f04a30

Please sign in to comment.