feat(ci): Add e2e test bed (#3135)

- [x] Launch control plane via docker compose
- [x] Ensure all clients build
This commit is contained in:
Jamil
2024-01-15 17:57:41 -08:00
committed by GitHub
parent b8e2a59570
commit b1738bdd46
16 changed files with 3215 additions and 93 deletions

View File

@@ -1,3 +1,3 @@
[codespell]
skip = ./website/.next,./website/pnpm-lock.yaml,./rust/target,Cargo.lock,./website/docs/reference/api/*.mdx,./erl_crash.dump,./apps/*/erl_crash.dump,./cover,./vendor,*.json,seeds.exs,./**/node_modules,./deps,./priv/static,./priv/plts,./**/priv/static,./.git,./_build
skip = ./e2e/pnpm-lock.yaml,./website/.next,./website/pnpm-lock.yaml,./rust/target,Cargo.lock,./website/docs/reference/api/*.mdx,./erl_crash.dump,./apps/*/erl_crash.dump,./cover,./vendor,*.json,seeds.exs,./**/node_modules,./deps,./priv/static,./priv/plts,./**/priv/static,./.git,./_build
ignore-words-list = optin,crate,keypair,keypairs,iif,statics,wee,anull,commitish,inout,fo,superceded

16
.github/actions/setup-node/action.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: "Setup Node"
description: "Sets up the correct Node version and installs pnpm"
inputs:
node-version:
description: "Version of nodejs to install"
required: false
default: '18'
runs:
using: "composite"
steps:
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}

View File

@@ -1,6 +1,10 @@
name: "Setup Rust"
description: "Sets up the correct Rust version and caching via sccache and a GCP backend"
inputs:
sccache_enabled:
description: "Enable or disable the sccache service"
required: false
default: 'true'
targets:
description: "Additional targets to install"
required: false
@@ -8,19 +12,23 @@ inputs:
runs:
using: "composite"
steps:
- id: auth
- if: ${{ inputs.sccache_enabled == 'true' }}
id: auth
uses: google-github-actions/auth@v1
with:
workload_identity_provider: "projects/397012414171/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions"
service_account: "github-actions@github-iam-387915.iam.gserviceaccount.com"
export_environment_variables: true
create_credentials_file: true
- run: |
- if: ${{ inputs.sccache_enabled == 'true' }}
run: |
echo "SCCACHE_GCS_BUCKET=firezone-staging-sccache" >> $GITHUB_ENV
echo "SCCACHE_GCS_RW_MODE=READ_WRITE" >> $GITHUB_ENV
shell: bash
- uses: mozilla-actions/sccache-action@v0.0.3
- run: echo "RUSTC_WRAPPER=$SCCACHE_PATH" >> $GITHUB_ENV
- if: ${{ inputs.sccache_enabled == 'true' }}
uses: mozilla-actions/sccache-action@v0.0.3
- if: ${{ inputs.sccache_enabled }}
run: echo "RUSTC_WRAPPER=$SCCACHE_PATH" >> $GITHUB_ENV
shell: bash
- name: Extract Rust version
run: |
@@ -32,9 +40,10 @@ runs:
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
components: rustfmt,clippy
- run: rustup target add ${{ inputs.targets }}
if: inputs.targets != ''
- if: inputs.targets != ''
run: rustup target add ${{ inputs.targets }}
shell: bash
- name: Start sccache
- if: ${{ inputs.sccache_enabled == 'true' }}
name: Start sccache
run: $SCCACHE_PATH --start-server
shell: bash

View File

@@ -391,12 +391,9 @@ jobs:
with:
otp-version: ${{ steps.versions.outputs.erlang }}
elixir-version: ${{ steps.versions.outputs.elixir }}
- uses: actions/setup-node@v4
- uses: ./.github/actions/setup-node
with:
node-version: ${{ steps.versions.outputs.nodejs }}
- uses: pnpm/action-setup@v2
with:
version: 8
# Elixir cache
- uses: actions/cache/restore@v3
name: Restore Elixir Deps Cache

View File

@@ -82,14 +82,15 @@ jobs:
BINARY_DEST_PATH: ${{ matrix.name.artifact }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-node
- uses: ./.github/actions/setup-rust
with:
targets: x86_64-pc-windows-msvc
- name: Build release binaries
run: |
npm install -g @tauri-apps/cli
pnpm install -g @tauri-apps/cli
# NPM installs tauri-cli to somewhere in $PATH
# PNPM installs tauri-cli to somewhere in $PATH
tauri build
# Used for release artifact

View File

@@ -20,18 +20,6 @@ jobs:
platform: iOS
destination: generic/platform=iOS
xcode: "15.0"
# TODO: Enable when GH Actions has macos-14 runners. Until this, this depends
# on self-hosted runners which can be less reliable and have issues with things
# like sccache.
# See https://github.com/firezone/firezone/actions/runs/6608338431/job/17946908445
# - sdk: macosx
# runs-on: macos-14
# platform: macOS
# destination: platform=macOS
# - sdk: iphoneos
# runs-on: macos-14
# platform: iOS
# destination: generic/platform=iOS
permissions:
contents: read
id-token: 'write'

View File

@@ -1,3 +1,9 @@
# This workflow file contains end-to-end tests for running client apps on
# our baremetal testbed. Artifacts are intentionally built in debug mode
# so that debug assert and other test-related macros can be triggered.
#
# This workflow does not replace the need to sanity check the QA builds manually,
# but should reduce (and some day) eliminate the need for a full manual QA runbook.
name: End to end tests
on:
# TODO
@@ -5,81 +11,199 @@ on:
# branches:
# - main
workflow_dispatch:
defaults:
working-directory: ./e2e
pull_request:
concurrency:
group: "e2e-${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
setup-e2e:
setup:
runs-on: ubuntu-22.04-firezone
env:
# mark:automatic-version
VERSION: "1.0.0"
steps:
- uses: actions/checkout@v4
- run: echo "Spin up docker test environment"
- run: docker compose up -d postgres
- run: docker compose run elixir /bin/sh -c 'cd apps/domain && mix do ecto.create, ecto.migrate, ecto.seed'
- name: Build images
run: |
docker compose build
- name: Start docker compose in the background
run: |
docker compose up -d \
api \
web \
client \
relay \
gateway \
iperf3
- name: Wait for client to ping resource
run: |
docker compose exec -it client timeout 60 \
sh -c 'until ping -W 1 -c 1 172.20.0.100 &>/dev/null; do true; done'
macos:
needs: setup-e2e
needs: setup
runs-on: macos-14-firezone
permissions:
contents: read
id-token: 'write'
defaults:
run:
working-directory: ./swift/apple
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
- uses: ./.github/actions/setup-rust
with:
sccache_enabled: false
targets: aarch64-apple-darwin
- name: build macos app
run: |
# Copy xcconfig
cp Firezone/xcconfig/debug.xcconfig Firezone/xcconfig/config.xcconfig
windows:
needs: setup-e2e
runs-on: windows-11-firezone
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
# Unlock keychain; simulates a user logged into the GUI
security unlock-keychain -p '${{ secrets.MACOS_SELF_HOSTED_USER_PASSWORD }}'
linux:
needs: setup-e2e
runs-on: ubuntu-22.04-firezone
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
android:
needs: setup-e2e
runs-on: ubuntu-22.04-firezone
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
chromeos:
needs: setup-e2e
runs-on: ubuntu-22.04-firezone
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
# Build app bundle
# If this results in codesign errors saying errSecInternalComponent, see
# https://forums.developer.apple.com/forums/thread/712005
xcodebuild build \
-allowProvisioningUpdates \
-configuration Debug \
-scheme Firezone \
-sdk macosx \
-destination 'platform=macOS'
ios:
needs: setup-e2e
strategy:
fail-fast: false
matrix:
destination:
- iphone
- ipad
needs: setup
runs-on: macos-14-firezone
permissions:
contents: read
id-token: 'write'
defaults:
run:
working-directory: ./swift/apple
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
- uses: ./.github/actions/setup-rust
with:
sccache_enabled: false
targets: aarch64-apple-ios
- name: build ios app
run: |
# Copy xcconfig
cp Firezone/xcconfig/debug.xcconfig Firezone/xcconfig/config.xcconfig
ipados:
needs: setup-e2e
runs-on: macos-14-firezone
# Unlock keychain; simulates a user logged into the GUI
security unlock-keychain -p '${{ secrets.MACOS_SELF_HOSTED_USER_PASSWORD }}'
# Build archive
xcodebuild build \
-allowProvisioningUpdates \
-configuration Debug \
-scheme Firezone \
-sdk iphoneos \
-destination "platform=iOS,name=${{ matrix.destination }}"
windows:
needs: setup
runs-on: windows-11-firezone
permissions:
contents: read
id-token: 'write'
defaults:
run:
working-directory: ./rust
steps:
- uses: actions/checkout@v4
- run: echo 'Noop'
- uses: ./.github/actions/setup-node
- uses: ./.github/actions/setup-rust
with:
sccache_enabled: false
targets: x86_64-pc-windows-msvc
- name: Build binaries
run: |
pnpm add -g @tauri-apps/cli
tauri build --verbose --debug
teardown-e2e:
linux:
needs: setup
runs-on: ubuntu-22.04-firezone
permissions:
contents: read
id-token: 'write'
defaults:
run:
working-directory: ./rust
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
with:
sccache_enabled: false
targets: x86_64-unknown-linux-musl
- run: |
cargo build --package firezone-linux-client
# TODO Run tests
# ./target/debug/firezone-linux-client
android:
needs: setup
runs-on: ubuntu-22.04-firezone
permissions:
contents: read
id-token: 'write'
defaults:
run:
working-directory: ./kotlin/android
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust
with:
sccache_enabled: false
targets: armv7-linux-androideabi aarch64-linux-android x86_64-linux-android i686-linux-android
- uses: actions/setup-java@v4
with:
distribution: oracle
java-version: 17
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
build-root-directory: ./kotlin/android
- run: |
echo 'sdk.dir=/home/firezone/Android/Sdk' > local.properties
./gradlew --info bundleDebug
teardown:
needs:
- macos
- windows
- linux
- android
- chromeos
- ios
- ipados
if: 'always()'
runs-on: ubuntu-22.04-firezone
steps:
- uses: actions/checkout@v4
- run: echo 'Teardown e2e environment'
- run: docker compose logs postgres
- run: docker compose logs vault
- run: docker compose logs web
- run: docker compose logs client
- run: docker compose logs gateway
- run: docker compose logs relay
- run: docker compose logs elixir
- run: docker compose logs api
- run: |
docker compose down -v
# TODO: Granularly prune to preserve build cache
# docker system prune --force --all --volumes

View File

@@ -374,14 +374,16 @@ networks:
enable_ipv6: true
ipam:
config:
- subnet: 172.20.0.0/16
- subnet: 2001:db8:1::/64
- subnet: 172.20.0.0/24
- subnet: fc00:ff:1::/48
app:
enable_ipv6: true
# Currently not working on testbed
# enable_ipv6: true
ipam:
config:
- subnet: 172.28.0.0/16
- subnet: 2001:db8:2::/64
- subnet: 172.28.0.0/24
# Currently not working on testbed
# - subnet: fc00:ff:2::/48
volumes:
postgres-data:

1
e2e/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/node_modules

View File

@@ -50,16 +50,16 @@ access.
### Addressing
| Host | Interface | IPv4 Address | IPv6 Address |
| ----------------------- | ---------------- | --------------- | ------------ |
| `linux.firezone.test` | egress | `192.168.1.222` | TODO |
| `linux.firezone.test` | testnet ethernet | `10.0.0.1` | TODO |
| `gateway.firezone.test` | testnet ethernet | `10.0.0.254` | TODO |
| `linux.firezone.test` | testnet WiFi | `10.0.1.1` | TODO |
| `macos.firezone.test` | testnet ethernet | `10.0.0.2` | TODO |
| `windows.firezone.test` | testnet ethernet | `10.0.0.3` | TODO |
| `macos.firezone.test` | testnet WiFi | `10.0.1.2` | TODO |
| `windows.firezone.test` | testnet WiFi | `10.0.1.3` | TODO |
| `ios.firezone.test` | testnet WiFi | `10.0.1.4` | TODO |
| `ipados.firezone.test` | testnet WiFi | `10.0.1.5` | TODO |
| `android.firezone.test` | testnet WiFi | `10.0.1.6` | TODO |
| Host | Interface | IPv4 Address | IPv6 Address |
| ----------------------- | ---------------- | --------------- | ----------------------------------------- |
| `linux.firezone.test` | egress | `192.168.1.249` | `2600:1700:3ecb:2410::/64` (DHCP address) |
| `linux.firezone.test` | testnet ethernet | `10.0.0.1` | `fc01:2345:6789:abcd::/64` (DHCP address) |
| `macos.firezone.test` | testnet ethernet | `10.0.0.2` | `fc01:2345:6789:abcd::/64` (DHCP address) |
| `windows.firezone.test` | testnet ethernet | `10.0.0.3` | `fc01:2345:6789:abcd::/64` (DHCP address) |
| `linux.firezone.test` | testnet WiFi | `10.0.1.1` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `macos.firezone.test` | testnet WiFi | `10.0.1.2` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `windows.firezone.test` | testnet WiFi | `10.0.1.3` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `ios.firezone.test` | testnet WiFi | `10.0.1.4` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `ipados.firezone.test` | testnet WiFi | `10.0.1.5` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `android.firezone.test` | testnet WiFi | `10.0.1.6` | `fc01:2345:6789:abce::/64` (DHCP address) |
| `gateway.firezone.test` | testnet ethernet | `10.0.0.254` | `fc01:2345:6789:abcd::/64` (DHCP address) |

5
e2e/package.json Normal file
View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"appium": "^2.4.1"
}
}

2974
e2e/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,8 @@ locally.
PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin
```
1. Make sure the following Rust targets are installed in your current toolchain:
1. Make sure the following Rust targets are installed into the correct
toolchain.
```
aarch64-linux-android
@@ -52,13 +53,15 @@ locally.
x86_64-linux-android
```
If using `rustup` you can run:
Ensure you've activated the correct toolchain version for your local
environment with `rustup default <toolchain>` (find this from the root
`/rust/rust-toolchain.toml` file), then run:
```
rustup target add aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android x86_64-linux-android
```
1. Perform a test build: `./gradlew assembleDebug`
1. Perform a test build: `./gradlew assembleDebug`.
1. Add your debug signing key's SHA256 fingerprint to the portal's
[`assetlinks.json`](../../elixir/apps/web/priv/static/.well-known/assetlinks.json)

View File

@@ -208,6 +208,8 @@ cargo {
} else {
profile = "debug"
}
// Needed for Ubuntu 22.04
pythonCommand = "python3"
prebuiltToolchains = true
verbose = true
module = "../../../rust/connlib/clients/android"

View File

@@ -97,5 +97,5 @@ networks:
enable_ipv6: true
ipam:
config:
- subnet: 172.28.0.0/16
- subnet: 2001:db8:2::/64
- subnet: 172.28.0.0/24
- subnet: fc00:ff:2::/48

View File

@@ -1,2 +1,2 @@
[toolchain]
channel = "1.73.0"
channel = "1.75.0"