Skip to content

Commit 0738e0a

Browse files
authored
Merge pull request #102 from Infisical/PLATFRM-128-more-tests-for-a-vertical-slice
improvement: add e2e test for relay and gateway
2 parents f46adeb + f34770d commit 0738e0a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2455
-7320
lines changed

e2e/.env.sample

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# E2E Test Configuration
2+
# Copy this file to .env and update the values as needed.
3+
# The .env file is automatically loaded when running e2e tests.
4+
5+
# =============================================================================
6+
# Required Configuration
7+
# =============================================================================
8+
9+
# Path to the Infisical backend directory
10+
# This should point to the backend folder of the infisical repository
11+
# Example: /Users/your-username/workspace/infisical/backend
12+
INFISICAL_BACKEND_DIR=/path/to/infisical/backend
13+
14+
# =============================================================================
15+
# Optional Configuration
16+
# =============================================================================
17+
18+
# Dockerfile to use for building the backend service
19+
# Defaults to "Dockerfile.dev.fips" if not set
20+
# INFISICAL_BACKEND_DOCKERFILE=Dockerfile.dev.fips
21+
22+
# Path to the CLI executable to use for testing
23+
# If not set, the test will look for ./infisical-merge in the e2e directory
24+
# This is only needed when using the "subprocess" run method
25+
# INFISICAL_CLI_EXECUTABLE=./infisical-merge
26+
27+
# Default run method for CLI commands in tests
28+
# Valid values: "functionCall" (default) or "subprocess"
29+
# - functionCall: Calls CLI functions directly (better for IDE debugging, can collect stdout/stderr)
30+
# Note: Since all commands run in the same process, make sure to properly reset any global state between test cases
31+
# - subprocess: Runs CLI as a separate process (simulates real user interaction, better isolation, can collect stdout/stderr)
32+
# CLI_E2E_DEFAULT_RUN_METHOD=subprocess
33+
34+
# =============================================================================
35+
# Development & Debugging Options
36+
# =============================================================================
37+
38+
# Disable the compose container cache
39+
# When enabled (default), tests will reuse existing containers to speed up development
40+
# Set to "1" to disable caching and always start fresh containers
41+
# CLI_E2E_DISABLE_COMPOSE_CACHE=1
42+
43+
# Disable Ryuk container cleanup
44+
# When enabled, testcontainers will keep containers running after tests complete
45+
# This is useful for debugging backend issues
46+
# Set to "true" to disable automatic container cleanup
47+
# TESTCONTAINERS_RYUK_DISABLED=true

e2e/Makefile

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
1-
.PHONY: filter-api generate-client clean
2-
3-
# Variables
4-
API_JSON := api.json
5-
ALLOWED_ENDPOINTS := allowed-endpoints.json
6-
FILTERED_API_JSON := api-filtered.json
7-
OPENAPI_CFG := openapi-cfg.yaml
8-
9-
# Filter API JSON to only include allowed endpoints
10-
filter-api:
11-
@echo "Filtering API JSON using allowed endpoints..."
12-
@jq --slurpfile allowed $(ALLOWED_ENDPOINTS) \
13-
'.paths |= with_entries(select(.key as $$k | $$allowed[0] | index($$k)))' \
14-
$(API_JSON) > $(FILTERED_API_JSON)
15-
@echo "Filtered API JSON written to $(FILTERED_API_JSON)"
1+
.PHONY: generate-code api.json
162

173
# Generate OpenAPI client using oapi-codegen
18-
generate-client: filter-api
4+
generate-code:
195
@echo "Generating OpenAPI client..."
20-
@go tool oapi-codegen -config $(OPENAPI_CFG) $(FILTERED_API_JSON)
6+
@go generate
217
@echo "Client generated successfully"
228

23-
# Clean generated files
24-
clean:
25-
@echo "Cleaning generated files..."
26-
@rm -f $(FILTERED_API_JSON)
27-
@echo "Clean complete"
9+
# Fetch API docs and format with jq
10+
api.json:
11+
@echo "Fetching API docs..."
12+
@set -o pipefail && curl -f http://localhost:4000/api/docs/json | jq . > api.json.tmp && mv api.json.tmp api.json
13+
@echo "API docs saved to api.json"

e2e/README.md

Lines changed: 145 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,33 @@ Please feel free to reach out to @fangpenlin on the Slack channel if you encount
1111

1212
The main subject of testing is a CLI executable program, i.e., the `infisical` command.
1313
Currently we support two approaches to test the CLI.
14-
The default run method is `subprocess`.
15-
You can set the `CLI_E2E_DEFAULT_RUN_METHOD` environment variable to change the default run method.
16-
For example:
14+
The default run method is `functionCall`.
15+
You can set the `CLI_E2E_DEFAULT_RUN_METHOD` environment variable to change the default run method, either in your `.env` file or as an environment variable:
1716

1817
```bash
19-
export CLI_E2E_DEFAULT_RUN_METHOD=functionCall
18+
# In .env file:
19+
CLI_E2E_DEFAULT_RUN_METHOD=subprocess
20+
21+
# Or as environment variable:
22+
export CLI_E2E_DEFAULT_RUN_METHOD=subprocess
2023
```
2124

2225
### The `subprocess` run method
2326

2427
The most straightforward way to run a CLI command and test it is to start a new subprocess with the command executable, control the input by environment vars, stdin, args and see how it connects to the server and what it outputs (stdout and stderr).
2528
The benefit of this approach is that it simulates what a user really does and we can collect the stdout and stderr easily.
29+
It also provides better isolation between test cases with less side effects from previous test cases.
30+
For example, if a previous test case forgot to reset a global state, it won't affect subsequent test cases since each command runs in a fresh process.
2631
The drawback of this approach is that attaching a debugger to the CLI command requires some extra work (like finding the PID and attaching to it by using the PID from the debugger).
27-
This is the default run method if not specified.
2832

2933
When using this run method, you need to make sure the executable is at the default location `./infisical-merge`.
30-
Otherwise, you can also specify the path to the executable by setting the `INFISICAL_CLI_EXECUTABLE` environment variable like this:
34+
Otherwise, you can also specify the path to the executable by setting the `INFISICAL_CLI_EXECUTABLE` environment variable, either in your `.env` file or as an environment variable:
3135

3236
```bash
37+
# In .env file:
38+
INFISICAL_CLI_EXECUTABLE=/path/to/infisical-merge
39+
40+
# Or as environment variable:
3341
export INFISICAL_CLI_EXECUTABLE=/path/to/infisical-merge
3442
```
3543

@@ -42,11 +50,70 @@ go build .
4250
### The `functionCall` run method
4351

4452
The function call method calls the `main` command function directly from the e2e test case.
45-
The benefit is that you can attach a debugger directly to the CLI process without extra effort.
46-
The drawback is that currently we cannot collect stdout and stderr.
47-
Some extra efforts might be needed to update the CLI code to abstract the stdout and stderr output from logs to make it possible.
48-
In the meantime, since this is not available, we didn't set it as the default value.
53+
The benefit is that you can attach a debugger directly to the CLI process without extra effort, and we can collect stdout and stderr just like with the subprocess method.
4954
With this run method, since we are linking the e2e test build with the CLI as a library directly, there's no need to build the executable separately.
55+
This is the default run method if not specified.
56+
Note that since all commands run in the same process, if state wasn't cleared correctly from a previous command call, it may affect the next test case. Make sure to properly reset any global state between test cases when using this method.
57+
58+
## Environment Variables Configuration
59+
60+
E2E tests support loading environment variables from a `.env` file for easier configuration management. The `.env` file is automatically loaded when tests run using the [godotenv autoload feature](https://github.com/joho/godotenv#autoload) from the open source [godotenv library](https://github.com/joho/godotenv). The autoload happens when the test package is imported, so as long as you run tests from the `e2e` directory, the `.env` file in that directory will be automatically loaded.
61+
62+
### Using a `.env` file
63+
64+
1. Copy the sample file to create your `.env` file:
65+
66+
```bash
67+
cd e2e
68+
cp .env.sample .env
69+
```
70+
71+
2. Edit `.env` and set the required values (see `.env.sample` for detailed comments on each variable):
72+
73+
```bash
74+
# Required: Path to the Infisical backend directory
75+
INFISICAL_BACKEND_DIR=/path/to/infisical/backend
76+
77+
# Optional: Other configuration variables
78+
# CLI_E2E_DEFAULT_RUN_METHOD=functionCall
79+
# INFISICAL_CLI_EXECUTABLE=./infisical-merge
80+
```
81+
82+
3. Run your tests - the `.env` file will be automatically loaded:
83+
```bash
84+
cd e2e
85+
go test github.com/infisical/cli/e2e-tests/relay
86+
```
87+
88+
**Note:** The `.env` file is git-ignored, so your local configuration won't be committed to the repository. See `.env.sample` for all available configuration options with detailed explanations.
89+
90+
### Available Environment Variables
91+
92+
The following environment variables can be set either in your `.env` file or as shell environment variables:
93+
94+
#### Required Variables
95+
96+
- **`INFISICAL_BACKEND_DIR`**: Path to the backend folder of the [infisical repository](https://github.com/infisical/infisical). This is required for tests to work.
97+
- Example: `/Users/your-username/workspace/infisical/backend`
98+
99+
#### Optional Variables
100+
101+
- **`INFISICAL_BACKEND_DOCKERFILE`**: Dockerfile to use for building the backend service. Defaults to `"Dockerfile.dev.fips"` if not set.
102+
103+
- **`INFISICAL_CLI_EXECUTABLE`**: Path to the CLI executable to use for testing. If not set, tests will look for `./infisical-merge` in the e2e directory. Only needed when using the "subprocess" run method.
104+
105+
- **`CLI_E2E_DEFAULT_RUN_METHOD`**: Default run method for CLI commands in tests. Valid values:
106+
107+
- `"functionCall"` (default): Calls CLI functions directly - better for IDE debugging, can collect stdout/stderr
108+
- `"subprocess"`: Runs CLI as a separate process - simulates real user interaction, can collect stdout/stderr
109+
110+
- **`CLI_E2E_DISABLE_COMPOSE_CACHE`**: Set to `"1"` to disable the compose container cache. When enabled (default), tests reuse existing containers to speed up development.
111+
112+
- **`CLI_E2E_REMOVE_COMPOSE`**: Set to `"1"` to enable cleanup of compose containers after tests complete. When not set (default), containers will remain running after tests finish, which is useful for debugging. Our cache system will also reuse the existing container if matches, to speed up the development cycle. This controls whether the `t.Cleanup()` function removes the compose stack.
113+
114+
- **`TESTCONTAINERS_RYUK_DISABLED`**: Set to `"true"` to disable Ryuk container cleanup. Useful for debugging backend issues as containers will remain running after tests complete.
115+
116+
For detailed descriptions and examples, see the `.env.sample` file.
50117

51118
## Setting the `INFISICAL_BACKEND_DIR` value
52119

@@ -62,8 +129,7 @@ infisical := NewInfisicalService().
62129
```
63130

64131
Because it runs the actual Infisical API server stack, you need to specify the `INFISICAL_BACKEND_DIR` value and point it to the `backend` folder of the [infisical repository](https://github.com/infisical/infisical) to make it work.
65-
For example, if you have the repo checked out at `/Users/fangpen/workspace/infisical`.
66-
Then you can set the environment variable like this:
132+
The easiest way is to set it in your `.env` file (see above), or you can export it as an environment variable:
67133

68134
```bash
69135
export INFISICAL_BACKEND_DIR=/Users/fangpen/workspace/infisical/backend
@@ -85,7 +151,14 @@ cd e2e
85151
go test github.com/infisical/cli/e2e-tests/relay
86152
```
87153

88-
Combining the exported environment variables, you might end up with running commands like this:
154+
If you're using a `.env` file (recommended), just make sure it's configured and run the tests:
155+
156+
```bash
157+
cd e2e
158+
go test github.com/infisical/cli/e2e-tests/relay
159+
```
160+
161+
Alternatively, you can export environment variables manually:
89162

90163
```bash
91164
export INFISICAL_CLI_EXECUTABLE=/path/to/infisical-merge
@@ -94,7 +167,7 @@ cd e2e
94167
go test github.com/infisical/cli/e2e-tests/relay
95168
```
96169

97-
It's a bit verbose right now, but we will improve the quality of life over time by adding things such as a Makefile to make it much easier.
170+
**Tip:** Using a `.env` file is much more convenient than exporting variables manually. See the [Environment Variables Configuration](#environment-variables-configuration) section above for details.
98171

99172
## Troubleshooting the failing tests due to CLI error
100173

@@ -116,20 +189,26 @@ less /var/folders/wc/g97rf4092_z9wqbp93djvnt00000gn/T/TestRelay_RegistersARelay2
116189

117190
Then you should be able to find out why it fails.
118191
You can also switch the call method to `functionCall` and set up a debugger to trace into the CLI program to find out why it fails.
119-
If you run the command test with `functionCall`, it will not write the stdout / stderr to a file, but instead, it should print it to the console where you run the tests.
192+
With the `functionCall` method, the stdout and stderr logs are also written to temp files, just like with the `subprocess` method, so you can inspect them in the same way.
120193

121194
## Troubleshooting the failing tests due to Infisical backend API errors
122195

123196
If the errors happen in the backend, to find out what's going on, you can open the Docker Desktop app or use `docker ps` and then `docker logs` to find out what the error message is in the Infisical backend API server.
124197
Please note that by default, the [testcontainers library](https://github.com/testcontainers/testcontainers-go) (the library we use to run the docker-compose for the Infisical stack) will start a container called Ryuk for deleting the containers after the test is finished.
125198
Because of that, if you run into an error in the backend reproduced by running the test, the container might already be gone after the test finishes.
126199
Then you won't be able to look inside the container and find out what's going on.
127-
To solve the problem, you can set the `TESTCONTAINERS_RYUK_DISABLED` environment variable to `true` like this to disable the container deleting behavior:
200+
To solve the problem, you can set the `TESTCONTAINERS_RYUK_DISABLED` environment variable to `true` to disable the container deleting behavior. You can do this either in your `.env` file:
128201

129202
```bash
130203
TESTCONTAINERS_RYUK_DISABLED=true
131204
```
132205

206+
Or as an environment variable:
207+
208+
```bash
209+
export TESTCONTAINERS_RYUK_DISABLED=true
210+
```
211+
133212
To learn more about the behavior of Ryuk from testcontainers, please read [their document here](https://golang.testcontainers.org/features/garbage_collector/#ryuk).
134213

135214
## Use compose containers cache to speed up the development cycle
@@ -151,8 +230,57 @@ If you have `TESTCONTAINERS_RYUK_DISABLED` set to `true`, each time the `Up` met
151230
If there's such a container already running, we will reuse it by resetting its database instead of starting a new one.
152231
That way, it's much faster than booting up a new compose stack and waiting for it to get online.
153232

154-
If for any reason the cache system is not working as desired, you can disable it by setting the `CLI_E2E_DISABLE_COMPOSE_CACHE` value to `1` like this:
233+
If for any reason the cache system is not working as desired, you can disable it by setting the `CLI_E2E_DISABLE_COMPOSE_CACHE` value to `1`. You can do this either in your `.env` file:
234+
235+
```bash
236+
CLI_E2E_DISABLE_COMPOSE_CACHE=1
237+
```
238+
239+
Or as an environment variable:
155240

156241
```bash
157242
export CLI_E2E_DISABLE_COMPOSE_CACHE=1
158243
```
244+
245+
## Generate Infisical client code
246+
247+
The e2e tests use generated client code to interact with the Infisical backend API.
248+
The client code is generated from the OpenAPI specification using `go:generate` and the `oapi-codegen` tool.
249+
250+
### How it works
251+
252+
1. **Download the OpenAPI specification**: While the Infisical backend server is running (typically on `http://localhost:4000`), download the OpenAPI JSON specification:
253+
254+
You can use the Makefile target to fetch and format the API docs:
255+
256+
```bash
257+
cd e2e
258+
make api.json
259+
```
260+
261+
This will fetch the OpenAPI spec from `http://localhost:4000/api/docs/json`, format it with `jq`, and save it to `api.json`. If the request fails, the existing `api.json` file will not be overwritten and error messages will be displayed.
262+
263+
Alternatively, you can use curl directly:
264+
265+
```bash
266+
curl http://localhost:4000/api/docs/json -o api.json
267+
```
268+
269+
2. **Important note**: Before downloading the OpenAPI spec, you may need to manually set `hidden: false` for some internal endpoints in the backend code. This step is currently done manually, but a CI job should automate this in the future.
270+
271+
3. **Generate the client code**: Once you have the `api.json` file in the `e2e` folder, you can generate the client code using either:
272+
273+
- `go generate` command:
274+
```bash
275+
cd e2e
276+
go generate
277+
```
278+
- Or the Makefile target:
279+
```bash
280+
cd e2e
281+
make generate-code
282+
```
283+
284+
This will generate `packages/client/client.gen.go` from the OpenAPI specification using the configuration in `openapi-cfg.yaml`.
285+
286+
The `go:generate` directive is defined in `e2e/main.go` and uses the `oapi-codegen` tool to generate type-safe Go client code from the OpenAPI specification.

e2e/allowed-endpoints.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)