Skip to content

Commit

Permalink
Merge pull request #47 from thin-edge/test-isolated-tests
Browse files Browse the repository at this point in the history
test: use isolated container engines
  • Loading branch information
reubenmiller authored Nov 25, 2024
2 parents 6cd16b4 + 0fa6a3f commit efb92f9
Show file tree
Hide file tree
Showing 19 changed files with 346 additions and 250 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tests/*.tar.gz
45 changes: 18 additions & 27 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,38 @@ jobs:
run: echo "Approved"

test:
name: Test ${{ matrix.job.target }}
name: Test ${{ matrix.job.name }}
runs-on: ubuntu-latest
needs: approve
environment:
name: Test Auto
env:
COMPOSE_PROJECT_NAME: ci_${{ matrix.job.target }}_${{github.run_id}}_${{github.run_attempt || '1'}}
DEVICE_ID: ci_${{ matrix.job.target }}_${{github.run_id}}_${{github.run_attempt || '1'}}
TEST_IMAGE: ${{ matrix.job.image }}

strategy:
fail-fast: false
matrix:
job:
- { target: tedge-container-bundle }
# docker
- { target: tedge-container-bundle, name: "docker v27", image: "docker:27-dind" }
- { target: tedge-container-bundle, name: "docker v26", image: "docker:26-dind" }
- { target: tedge-container-bundle, name: "docker v25", image: "docker:25-dind" }
- { target: tedge-container-bundle, name: "docker v20", image: "docker:20-dind" }
# podman
- { target: tedge-container-bundle, name: "podman", image: debian-systemd-podman-cli }
- { target: tedge-container-bundle, name: "podman v5", image: "podman-v5" }
# - { target: tedge-container-bundle, name: "podman v4", image: "podman-v4" }
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
install: true

- uses: taiki-e/install-action@just

- uses: reubenmiller/setup-go-c8y-cli@main
Expand All @@ -53,20 +65,11 @@ jobs:
run: |
touch .env
echo "DEVICE_ID=$DEVICE_ID" >> .env
echo 'C8Y_BASEURL="${{ secrets.C8Y_BASEURL }}"' >> .env
C8Y_DOMAIN=$(echo "${{ secrets.C8Y_BASEURL }}" | sed 's|.*://||g')
echo 'C8Y_USER="${{ secrets.C8Y_USER }}"' >> .env
echo 'C8Y_PASSWORD="${{ secrets.C8Y_PASSWORD }}"' >> .env
# env variables required by the container
echo "TEDGE_C8Y_URL=$C8Y_DOMAIN" >> .env
cat .env
- name: Bootstrap device
run: |
just init
- uses: actions/setup-python@v5
with:
python-version: '3.11'
Expand All @@ -77,10 +80,7 @@ jobs:
- name: Install dependencies
run: |
just venv
- name: Start demo
run: |
just start -d
just build-test
- name: Run tests
run: just test
Expand All @@ -89,18 +89,9 @@ jobs:
uses: actions/upload-artifact@v4
if: always()
with:
name: reports
name: reports-${{ matrix.job.name }}
path: output

- name: Stop demo
if: always()
run: just stop -v

- name: Cleanup Devices
if: always()
run: |
just cleanup "$DEVICE_ID"
- name: Send report to commit
uses: joonvena/[email protected]
with:
Expand Down
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
.env
device-certs/

# Artifacts
*.tar

# python
.venv/

# Test
output/
*.html
*.xml

# Test artifacts
tests/*.tar.gz
74 changes: 45 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,21 @@ TEDGE_C8Y_OPERATIONS_AUTO_LOG_UPLOAD=always

### Development

#### Starting the container
#### Testing

The following tools are required to run the container:
The system tests are writing using the [RobotFramework](https://robotframework.org/) with some custom thin-edge.io libraries. Generally the test framework will spin up a new container engine environment (defined by the `TEST_IMAGE` variable). In the test itself, a new instance of the **tedge-container-bundle** will be created which the test then uses to check the specified functionality. Using this setup does bring a but if complexity into the setup, however it is necessary to ensure that the **tedge-container-bundle** can be tested against multiple container engine environments (e.g. docker, podman and different versions of each), whilst it also provides a test environment which does not pollute your host's container engine environment.

The following tools are required to run the tests:

* docker
* docker compose
* [docker-buildx-plugin](https://github.com/docker/buildx)
* [go-c8y-cli](https://goc8ycli.netlify.app/)
* Optional: [just](https://github.com/casey/just) - used to run project tasks
* python >= 3.9

After the project pre-requisites have been installed, you can start the container using the following steps:

1. Create a `.env` file containing the environment variables (see the [Providing the device certificate by environment variables](./README.md#providing-the-device-certificate-by-environment-variables) for details on how to provide the device certificate)

```sh
# device id to use for the certificate
DEVICE_ID=demo01

# Which c8y instance you want to connect to
TEDGE_C8Y_URL=example.cumulocity.com

# You can turn specific services on/off via environment variables
SERVICE_TEDGE_MAPPER_AWS=0
SERVICE_TEDGE_MAPPER_AZ=0
SERVICE_TEDGE_MAPPER_C8Y=1

# Other settings
TEDGE_C8Y_OPERATIONS_AUTO_LOG_UPLOAD=always
```

2. Activate your Cumulocity session using go-c8y-cli
1. First run only: Activate your Cumulocity session using [go-c8y-cli](https://goc8ycli.netlify.app/docs/gettingstarted/#creating-a-new-session)

```sh
set-session
Expand All @@ -87,22 +73,32 @@ After the project pre-requisites have been installed, you can start the containe
set-session
```

3. Init the device certificate (stored in a container volume) and upload it to Cumulocity IoT
2. Create a `.env` file containing the environment variables used for testing

```sh
just init
just init-dotenv
```

4. Start the container (using docker compose)
**Note** This will write your current go-c8y-cli's session credentials to the `.env` file, so you don't need to use `set-session` every time.

3. Initialize the docker setup and install the python virtual environment

```sh
# using the justfile task
just start
just build-setup
just venv
```

# Or using docker compose directly
docker compose up --build
4. Build test images

```sh
just build-test
```

5. Run system tests

```sh
just test
```

## Project structure

Expand All @@ -118,3 +114,23 @@ After the project pre-requisites have been installed, you can start the containe
* Both the initialization scripts and services have access to the container's environment variables, which makes it much easier to configure the components.
* Standard Output and Standard Error are redirected to the PID 1 so that the log messages are visible from all services
* Run services under the container `USER`

## Contributions

#### PR Submissions

Contributions are welcomed, but please consider the following

* Does the change make sense for other users? If the answer is no, then maybe you should be just pulling in the `tedge-container-bundle` into your own Dockerfile using `FROM ghcr.io/thin-edge/tedge-container-bundle:<tag>`

* State the motivation of the change

* Write a system test (under `./tests`) and ensure all tests are passing (though the CI will also run this on the PR directly)

Finally, before submitting a PR you should run the following locally to ensure everything is formatted correct and there are no linting errors/warnings!

```sh
just venv
just lint
just format
```
52 changes: 0 additions & 52 deletions docker-compose.yaml

This file was deleted.

4 changes: 2 additions & 2 deletions files/tedge/container-logs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ TMP_FILE="${TMP_LOG_DIR}/${TYPE}_${CONTAINER_NAME}_$(date -Iseconds).log"
echo "dateFrom: $DATE_FROM"
echo "dateTo: $DATE_TO"
echo "maxLines: $MAX_LINES"
echo "command: $DOCKER_CMD logs -n \"$MAX_LINES\" --since \"$DATE_FROM\" --until \"$DATE_TO\" \"$CONTAINER_NAME\""
echo "command: $DOCKER_CMD logs --tail \"$MAX_LINES\" --since \"$DATE_FROM\" --until \"$DATE_TO\" \"$CONTAINER_NAME\""
echo "------------------------------------------------------"
echo
} > "$TMP_FILE"

# Write logs to file (stripping any ansci colour codes)
$DOCKER_CMD logs -n "$MAX_LINES" --since "$DATE_FROM" --until "$DATE_TO" "$CONTAINER_NAME" 2>&1 \
$DOCKER_CMD logs --tail "$MAX_LINES" --since "$DATE_FROM" --until "$DATE_TO" "$CONTAINER_NAME" 2>&1 \
| sed -e 's/\x1b\[[0-9;]*m//g' \
| tee -a "$TMP_FILE"

Expand Down
4 changes: 0 additions & 4 deletions files/tedge/container_run.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
golang template to build the docker run options using `docker inspect <container> --format "container_run.tpl"`
Credit: https://gist.github.com/efrecon/8ce9c75d518b6eb863f667442d7bc679
*/}}
--name {{printf "%q" .Name}} \
{{- with .HostConfig}}
{{- if .Privileged}}
--privileged \
Expand Down Expand Up @@ -45,9 +44,6 @@
{{- if .PublishAllPorts}}
--publish-all \
{{- end}}
{{- if .UTSMode}}
--uts {{printf "%q" .UTSMode}} \
{{- end}}
--restart always \
{{- range $e := .ExtraHosts}}
--add-host {{printf "%q" $e}} \
Expand Down
Loading

6 comments on commit efb92f9

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m11.473984s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.048 s Operations
Service is up 0.164 s Operations
Get Logfile Request 2.344 s Operations
Get Configuration File 4.709 s Operations
Execute Shell Command 2.358 s Operations
Install application using docker compose 17.400 s Operations
Get Container Logs 2.348 s Operations
Trigger self update via local command 18.907 s Self-Update
Self update should only update if there is a new image 15.197 s Self-Update
Self update using software update operation 42.883 s Self-Update
Rollback when trying to install a non-tedge based image 17.192 s Self-Update
Cloud Connection is Online 0.166 s Telemetry
Service status 0.256 s Telemetry
Sends measurements 2.457 s Telemetry

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m12.899343s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.055 s Operations
Service is up 0.148 s Operations
Get Logfile Request 2.346 s Operations
Get Configuration File 4.698 s Operations
Execute Shell Command 2.371 s Operations
Install application using docker compose 15.295 s Operations
Get Container Logs 2.359 s Operations
Trigger self update via local command 19.746 s Self-Update
Self update should only update if there is a new image 15.277 s Self-Update
Self update using software update operation 45.021 s Self-Update
Rollback when trying to install a non-tedge based image 17.631 s Self-Update
Cloud Connection is Online 0.168 s Telemetry
Service status 0.265 s Telemetry
Sends measurements 2.469 s Telemetry

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m17.119118s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.041 s Operations
Service is up 0.188 s Operations
Get Logfile Request 2.423 s Operations
Get Configuration File 4.842 s Operations
Execute Shell Command 2.442 s Operations
Install application using docker compose 17.782 s Operations
Get Container Logs 2.447 s Operations
Trigger self update via local command 19.927 s Self-Update
Self update should only update if there is a new image 17.592 s Self-Update
Self update using software update operation 43.084 s Self-Update
Rollback when trying to install a non-tedge based image 18.255 s Self-Update
Cloud Connection is Online 0.188 s Telemetry
Service status 0.310 s Telemetry
Sends measurements 2.555 s Telemetry

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m22.355695s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.051 s Operations
Service is up 0.159 s Operations
Get Logfile Request 2.410 s Operations
Get Configuration File 4.764 s Operations
Execute Shell Command 2.393 s Operations
Install application using docker compose 17.580 s Operations
Get Container Logs 2.403 s Operations
Trigger self update via local command 20.194 s Self-Update
Self update should only update if there is a new image 15.794 s Self-Update
Self update using software update operation 50.369 s Self-Update
Rollback when trying to install a non-tedge based image 18.106 s Self-Update
Cloud Connection is Online 0.204 s Telemetry
Service status 0.307 s Telemetry
Sends measurements 2.577 s Telemetry

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m37.206624999s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.045 s Operations
Service is up 0.207 s Operations
Get Logfile Request 4.678 s Operations
Get Configuration File 5.017 s Operations
Execute Shell Command 2.539 s Operations
Install application using docker compose 20.323 s Operations
Get Container Logs 4.700 s Operations
Trigger self update via local command 22.515 s Self-Update
Self update should only update if there is a new image 20.229 s Self-Update
Self update using software update operation 43.188 s Self-Update
Rollback when trying to install a non-tedge based image 23.192 s Self-Update
Cloud Connection is Online 0.235 s Telemetry
Service status 2.558 s Telemetry
Sends measurements 2.735 s Telemetry

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
14 0 1 14 100 2m44.590619999s

Passed Tests

Name ⏱️ Duration Suite
Grace period to allow container to startup 5.053 s Operations
Service is up 0.227 s Operations
Get Logfile Request 4.737 s Operations
Get Configuration File 5.115 s Operations
Execute Shell Command 2.597 s Operations
Install application using docker compose 18.372 s Operations
Get Container Logs 4.755 s Operations
Trigger self update via local command 24.052 s Self-Update
Self update should only update if there is a new image 22.697 s Self-Update
Self update using software update operation 48.330 s Self-Update
Rollback when trying to install a non-tedge based image 25.186 s Self-Update
Cloud Connection is Online 0.233 s Telemetry
Service status 0.441 s Telemetry
Sends measurements 2.747 s Telemetry

Please sign in to comment.