Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run e2e tests on CI #134

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
239 changes: 219 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,13 @@ jobs:
restore-keys: |
${{ runner.os }}-turborepo-android

- name: Check turborepo cache for Android
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:android').cache.status")

if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
fi

- name: Install JDK
if: env.turbo_cache_hit != 1
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Install NDK
if: env.turbo_cache_hit != 1
uses: nttld/setup-ndk@v1
id: setup-ndk
with:
Expand All @@ -108,15 +98,13 @@ jobs:
run: echo "ANDROID_NDK=$ANDROID_HOME/ndk-bundle" >> $GITHUB_ENV

- name: Finalize Android SDK
if: env.turbo_cache_hit != 1
run: |
/bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null"

- name: Install Android SDK
run: echo "sdk.dir=$ANDROID_HOME" > $GITHUB_WORKSPACE/apps/example/android/local.properties

- name: Cache Gradle
if: env.turbo_cache_hit != 1
uses: actions/cache@v3
with:
path: |
Expand All @@ -131,6 +119,225 @@ jobs:
JAVA_OPTS: "-XX:MaxHeapSize=6g"
run: |
yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" --force

- name: Cache apk
uses: actions/cache/save@v3
env:
cache-name: cache-apk
with:
path: apps/example/android/app/build/outputs/apk/debug/app-debug.apk
key: apk-${{ github.sha }}

test-android:
needs: build-android
runs-on: macos-latest-large
env:
TURBO_CACHE_DIR: .turbo/android
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Restore APK
id: cache-apk
uses: actions/cache/restore@v3
with:
path: apps/example/android/app/build/outputs/apk/debug/app-debug.apk
key: apk-${{ github.sha }}

- name: SDKs - download required images
run: $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "system-images;android-30;default;x86_64"

- name: Emulator - Create
run: $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n Pixel_API_30 --device 'Nexus 5X' --package "system-images;android-30;default;x86_64" --sdcard 512M

- name: Emulator - Boot
run: $ANDROID_HOME/emulator/emulator -memory 4096 -avd Pixel_API_30 -wipe-data -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim &

- name: ADB Wait For Device
run: adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'
timeout-minutes: 15

- name: Start Package Manager
working-directory: apps/example
run: CI=true yarn start > yarn_start_output.log 2>&1 &

- name: Check APK existence
uses: andstor/file-existence-action@v2
with:
files: apps/example/android/app/build/outputs/apk/debug/app-debug.apk
fail: true

- name: Install APK
run: adb install -r apps/example/android/app/build/outputs/apk/debug/app-debug.apk

- name: Reverse Port
run: adb devices | grep '\t' | awk '{print $1}' | sed 's/\\s//g' | xargs -I {} adb -s {} reverse tcp:8081 tcp:8081

- name: Launch APK
env:
PACKAGE_NAME: com.microsoft.reacttestapp
run: adb shell monkey -p ${{ env.PACKAGE_NAME }} 1

- name: Run e2e Tests
working-directory: packages/webgpu
run: yarn test

- uses: actions/upload-artifact@v4
if: failure()
with:
path: packages/webgpu/src/__tests__/snapshots/
name: tests-snapshots-screenshots

- name: Display yarn start output
if: always()
run: cat apps/example/yarn_start_output.log

test-android2:
needs: build-android
runs-on: ubuntu-22.04
env:
TURBO_CACHE_DIR: .turbo/android
ANDROID_AVD_HOME: ${{ github.workspace }}/.android/avd
ANDROID_EMULATOR_USE_SYSTEM_LIBS: 'true'
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Install SDK Tools
run: |
sudo apt-get update
sudo apt-get install -y openjdk-11-jdk qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
sudo adduser $USER libvirt
sudo adduser $USER kvm
sdkmanager --update

- name: Adjust KVM permissions
run: sudo chown $USER /dev/kvm

- name: Install system images
run: sdkmanager "system-images;android-30;default;x86_64"

- name: Emulator - Create
run: avdmanager create avd -n Pixel_API_30 --device 'Nexus 5X' --package "system-images;android-30;default;x86_64" --sdcard 512M

- name: Start Emulator
run: |
$ANDROID_HOME/emulator/emulator -avd Pixel_API_30 -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -netdelay none -netspeed full > emulator_output.log 2>&1 &

- name: Wait for emulator to boot
run: |
adb wait-for-device
adb shell 'while [[ $(getprop sys.boot_completed) != "1" ]]; do sleep 1; done;'

- name: Test network connectivity
run: adb shell ping -c 3 www.google.com

- name: Start Package Manager
working-directory: apps/example
run: CI=true yarn start > yarn_start_output.log 2>&1 &

- name: Check APK existence
uses: andstor/file-existence-action@v2
with:
files: apps/example/android/app/build/outputs/apk/debug/app-debug.apk
fail: true

- name: Install APK
run: adb install -r apps/example/android/app/build/outputs/apk/debug/app-debug.apk

- name: Reverse Port
run: adb reverse tcp:8081 tcp:8081

- name: Launch APK
env:
PACKAGE_NAME: com.microsoft.reacttestapp
run: adb shell monkey -p ${{ env.PACKAGE_NAME }} 1

- name: Run e2e Tests
working-directory: packages/webgpu
run: yarn test

- uses: actions/upload-artifact@v4
if: failure()
with:
path: packages/webgpu/src/__tests__/snapshots/
name: tests-snapshots-screenshots

- name: Display yarn start output
if: always()
run: cat apps/example/yarn_start_output.log

- name: Upload emulator logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: emulator-logs
path: emulator_output.log

test-android3:
needs: build-android
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 30
target: default
arch: x86_64
profile: Nexus 5X
emulator-options: '-no-window -noaudio -no-boot-anim -netdelay none -netspeed full'

- name: Start Package Manager
working-directory: apps/example
run: CI=true yarn start > yarn_start_output.log 2>&1 &

- name: Check APK existence
uses: andstor/file-existence-action@v2
with:
files: apps/example/android/app/build/outputs/apk/debug/app-debug.apk
fail: true

- name: Install APK
run: adb install -r apps/example/android/app/build/outputs/apk/debug/app-debug.apk

- name: Reverse Port
run: adb reverse tcp:8081 tcp:8081

- name: Launch APK
env:
PACKAGE_NAME: com.microsoft.reacttestapp
run: adb shell monkey -p ${{ env.PACKAGE_NAME }} 1

- name: Run e2e Tests
working-directory: packages/webgpu
run: yarn test

- uses: actions/upload-artifact@v4
if: failure()
with:
path: packages/webgpu/src/__tests__/snapshots/
name: tests-snapshots-screenshots

- name: Display yarn start output
if: always()
run: cat apps/example/yarn_start_output.log

build-ios:
runs-on: macos-latest
Expand All @@ -153,14 +360,6 @@ jobs:
restore-keys: |
${{ runner.os }}-turborepo-ios-

- name: Check turborepo cache for iOS
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:ios').cache.status")

if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
fi

- name: Build example for iOS
run: |
yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}"
3 changes: 2 additions & 1 deletion apps/example/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
'react-native-reanimated/plugin'
'react-native-reanimated/plugin',
'transform-inline-environment-variables'
],
};
5 changes: 1 addition & 4 deletions apps/example/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/**
* @format
*/

import "react-native-wgpu";
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
Expand Down
4 changes: 2 additions & 2 deletions apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ PODS:
- React-debug
- react-native-safe-area-context (4.11.0):
- React-Core
- react-native-wgpu (0.1.7):
- react-native-wgpu (0.1.8):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1553,7 +1553,7 @@ SPEC CHECKSUMS:
React-logger: 29fa3e048f5f67fe396bc08af7606426d9bd7b5d
React-Mapbuffer: bf56147c9775491e53122a94c423ac201417e326
react-native-safe-area-context: 851c62c48dce80ccaa5637b6aa5991a1bc36eca9
react-native-wgpu: df38193ef32dee670b8be243ade64fb118237a54
react-native-wgpu: 2805714d6764920ef05df7648cdb861d8aa94416
React-nativeconfig: 9f223cd321823afdecf59ed00861ab2d69ee0fc1
React-NativeModulesApple: ff7efaff7098639db5631236cfd91d60abff04c0
React-perflogger: 32ed45d9cee02cf6639acae34251590dccd30994
Expand Down
1 change: 1 addition & 0 deletions apps/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@types/three": "0.168.0",
"@webgpu/types": "^0.1.44",
"babel-jest": "^29.6.3",
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
"eslint": "^8.19.0",
"eslint-config-react-native-wcandillon": "^3.10.2",
"jest": "^29.6.3",
Expand Down
4 changes: 2 additions & 2 deletions apps/example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GestureHandlerRootView } from "react-native-gesture-handler";

import type { Routes } from "./Route";
import { Home } from "./Home";
import { Tests } from "./Tests";
import { CI, Tests } from "./Tests";
import { useAssets } from "./components/useAssets";
import {
Cube,
Expand Down Expand Up @@ -40,7 +40,7 @@ function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Navigator initialRouteName={CI ? "Tests" : "Home"}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="HelloTriangle" component={HelloTriangle} />
<Stack.Screen
Expand Down
4 changes: 2 additions & 2 deletions apps/example/src/Tests.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable no-eval */

import React, { useEffect, useState } from "react";
import { Dimensions, Text, View, Image } from "react-native";
import { GPUOffscreenCanvas } from "react-native-wgpu";
Expand All @@ -12,7 +11,6 @@ import type { AssetProps } from "./components/useAssets";
import { Texture } from "./components/Texture";

export const CI = process.env.CI === "true";

const { width } = Dimensions.get("window");
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();

Expand All @@ -39,7 +37,9 @@ export const Tests = ({ assets: { di3D, saturn, moon } }: AssetProps) => {
const [client, hostname] = useClient();
useEffect(() => {
if (client !== null && adapter !== null && device !== null) {
console.log("ready to listen");
client.onmessage = (e) => {
console.log("GOT A MESSAGE");
const tree = JSON.parse(e.data);
if (tree.code) {
const canvas = new GPUOffscreenCanvas(1024, 1024);
Expand Down
2 changes: 2 additions & 0 deletions packages/webgpu/src/__tests__/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ class RemoteTestingClient implements TestingClient {
private handleResponse<R>(body: string): Promise<R> {
return new Promise((resolve) => {
this.client.once("message", (raw: Buffer) => {
console.log("receive message");
resolve(JSON.parse(raw.toString()));
});
console.log("send message");
this.client.send(body);
});
}
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4248,6 +4248,7 @@ __metadata:
"@types/three": 0.168.0
"@webgpu/types": ^0.1.44
babel-jest: ^29.6.3
babel-plugin-transform-inline-environment-variables: ^0.4.4
eslint: ^8.19.0
eslint-config-react-native-wcandillon: ^3.10.2
fast-text-encoding: ^1.0.6
Expand Down Expand Up @@ -4767,6 +4768,13 @@ __metadata:
languageName: node
linkType: hard

"babel-plugin-transform-inline-environment-variables@npm:^0.4.4":
version: 0.4.4
resolution: "babel-plugin-transform-inline-environment-variables@npm:0.4.4"
checksum: fa361287411301237fd8ce332aff4f8e8ccb8db30e87a2ddc7224c8bf7cd792eda47aca24dc2e09e70bce4c027bc8cbe22f4999056be37a25d2472945df21ef5
languageName: node
linkType: hard

"babel-preset-current-node-syntax@npm:^1.0.0":
version: 1.1.0
resolution: "babel-preset-current-node-syntax@npm:1.1.0"
Expand Down
Loading