Skip to content

Commit

Permalink
WIP: emulator-based tests
Browse files Browse the repository at this point in the history
  • Loading branch information
t184256 committed Jun 13, 2024
1 parent 441d5db commit 3b174e6
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 0 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/emulator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Test nix-on-droid in an emulator
on:
pull_request:
push:
schedule:
- cron: 0 0 * * 1

jobs:
fakedroid-channel:
runs-on: ubuntu-latest

strategy:
matrix:
api-level: [29]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Nix / enable KVM
uses: DeterminateSystems/nix-installer-action@main

- name: Setup cachix
uses: cachix/cachix-action@v14
with:
name: nix-on-droid
signingKey: "${{ secrets.CACHIX_SIGNING_KEY }}"

- name: Initialize fakedroid for channel setup
run: nix run --impure .#fakedroid -- echo INIT

- name: Configure AVD cache
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}

- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."

- name: Run tests
run: |
nix run --impure .#fakedroid -- mkdir -p .cache/nix-on-droid-self-test
nix run --impure .#fakedroid -- touch .cache/nix-on-droid-self-test/confirmation-granted
nix run --impure .#fakedroid -- nix-on-droid on-device-test
- name: Run on-device-tests with api-level=${{ matrix.api-level }}
uses: reactivecircus/android-emulator-runner@v2
with:
target: default
api-level: ${{ matrix.api-level }}
arch: x86_64
script: |
pushd tests/emulator
nix run . -- run bootstrap-channel.py
nix run . -- run on-device-tests.py
popd
# TODO: push to cachix from device
# - name: Push to cachix
# if: always() && github.event_name != 'pull_request'
# run: ...

# TODO: parametrize: channel vs flakes
# TODO: externally-driven test
# TODO: more API levels
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/source.tar.gz
result
result-*
**/__pycache__
29 changes: 29 additions & 0 deletions tests/emulator/bootstrap-channel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from common import wait_for, APK, BOOTSTRAP_URL


def run(d):
nod = d.app('com.termux.nix', url=APK)
nod.permissions.allow_notifications()
nod.launch()

wait_for(d, 'Bootstrap zipball location')
d.ui(className='android.widget.EditText').set_text(BOOTSTRAP_URL)
d.ui(text='OK').click()

wait_for(d, 'Welcome to Nix-on-Droid!')
wait_for(d, 'Do you want to set it up with flakes? (y/N)')
d('input text N') # remove
d.ui.press('enter')
wait_for(d, 'Setting up Nix-on-Droid with channels...')

wait_for(d, 'Installing and updating nix-channels...')
wait_for(d, 'unpacking channels...')
wait_for(d, 'Installing first Nix-on-Droid generation...', timeout=180)
wait_for(d, 'Copying default Nix-on-Droid config...', timeout=180)
wait_for(d, 'Congratulations!')
wait_for(d, 'See config file for further information!')
wait_for(d, 'bash-5.25$')

d('input text "echo smoke-test | base64"') # remove
d.ui.press('enter')
wait_for(d, 'c21va2UtdGVzdAo=')
23 changes: 23 additions & 0 deletions tests/emulator/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import sys
import time

SERVER = 'https://nix-on-droid.unboiled.info'
APK = f'{SERVER}/com.termux.nix_188035-x86_64.apk'
BOOTSTRAP_URL = f'{SERVER}/testing'


def wait_for(d, on_screen_text, timeout=30, critical=True):
start = time.time()
last_displayed_time = None
while (elapsed := time.time() - start) < timeout:
display_time = int(timeout - elapsed)
if display_time != last_displayed_time:
print(f'waiting for `{on_screen_text}`: {display_time}s...')
last_displayed_time = display_time
if on_screen_text in d.ui.dump_hierarchy():
print(f'found: {on_screen_text} after {elapsed:.1f}s')
return
time.sleep(.75)
print(f'NOT FOUND: {on_screen_text} after {timeout}s')
if critical:
sys.exit(1)
23 changes: 23 additions & 0 deletions tests/emulator/on-device-tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from common import wait_for


def run(d):
#wait_for(d, 'bash-5.2$')

#d('input text "nix-on-droid on-device-test"')
#wait_for(d, 'These semi-automated tests are destructive', timeout=180)
#wait_for(d, 'Proceeding will wreck your installation.')
#wait_for(d, 'Do you still wish to proceed?')
#d('input text "I do"')
#d.ui.press('enter')

d.ui.open_notification()
d.ui(text='Nix').right(resourceId='android:id/expand_button').click()
d.ui(text='Acquire wakelock').click()
d.ui(text='Release wakelock').wait()
d.ui.press('back')

if 'Allow' in d.ui.dump_hierarchy():
d.ui.click('Allow')

wait_for(d, 'tests, 0 failures in', timeout=1800)

0 comments on commit 3b174e6

Please sign in to comment.