Skip to content

Commit

Permalink
tests/emulator: add license, lint with ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
t184256 committed Sep 10, 2024
1 parent 5d88ff2 commit bd677b4
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 54 deletions.
18 changes: 17 additions & 1 deletion .github/workflows/lints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
schedule:
- cron: 0 0 * * 1
jobs:
lint:
lint-nix:
runs-on: ubuntu-latest

steps:
Expand All @@ -17,3 +17,19 @@ jobs:

- name: Run nix-formatter-pack-check
run: nix build .#checks.x86_64-linux.nix-formatter-pack-check

lint-py:
runs-on: ubuntu-latest

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

- name: Install nix
uses: cachix/install-nix-action@v25

- name: Run ruff linter
run: nix run 'nixpkgs#ruff' -- check

- name: Run ruff formatter
run: nix run 'nixpkgs#ruff' -- format --diff
32 changes: 32 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
line-length = 79
preview = true
lint.select = [ "ALL" ]
lint.ignore = [
"D203", # one-blank-line-before-class
"D213", # multi-line-summary-second-line
]
lint.per-file-ignores."tests/emulator/**" = [
"ANN", # flake-8 annotations
"D100", # undocumented-public-module
"D103", # undocumented-public-function
"INP001", # implicit-namespace-package
"PLR0915", # too-many-statements
"S101", # assert
"T201", # print
]
lint.per-file-ignores."tests/emulator/common.py" = [
"FBT002", # boolean-default-value-positional-argument
]
lint.per-file-ignores."tests/emulator/android_integration.py" = [
"C901", # complex-structure
]
lint.per-file-ignores."tests/emulator/test_channels_shell.py" = [
"S404", # suspicious-subprocess-import
"S603", # subprocess-without-shell-equals-true
"S607", # start-process-with-partial-path
]
lint.flake8-quotes.inline-quotes = "single"
lint.flake8-quotes.multiline-quotes = "single"
lint.flake8-copyright.notice-rgx = '# Copyright \(c\) 2019-20\d\d, see AUTHORS\. Licensed under MIT License, see LICENSE\n'
format.quote-style = "single"
format.preview = true
29 changes: 19 additions & 10 deletions tests/emulator/android_integration.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import base64
import time

import bootstrap_channels

from common import screenshot, wait_for

OPENERS = ['termux-open', 'termux-open-url', 'xdg-open']
TOOLS = [
'am',
'termux-setup-storage',
'termux-reload-settings',
'termux-wake-lock',
'termux-wake-unlock',
*OPENERS,
]

def run(d):
OPENERS = ['termux-open', 'termux-open-url', 'xdg-open']
TOOLS = ['am', 'termux-setup-storage', 'termux-reload-settings',
'termux-wake-lock', 'termux-wake-unlock'] + OPENERS

def run(d):
nod = bootstrap_channels.run(d)

# Verify that android-integration tools aren't installed by default
Expand All @@ -21,9 +28,11 @@ def run(d):
screenshot(d, f'no-{toolname}')

# Apply a config that enables android-integration tools
cfg = ('/data/local/tmp/n-o-d/unpacked/tests/on-device/'
'config-android-integration.nix')
d(f'input text \'cp {cfg} .config/nixpkgs/nix-on-droid.nix\'')
cfg = (
'/data/local/tmp/n-o-d/unpacked/tests/on-device/'
'config-android-integration.nix'
)
d(f"input text 'cp {cfg} .config/nixpkgs/nix-on-droid.nix'")
d.ui.press('enter')
screenshot(d, 'pre-switch')
d('input text "nix-on-droid switch && echo integration tools installed"')
Expand Down Expand Up @@ -135,7 +144,7 @@ def run(d):
d.ui(text='ALLOW').click()
screenshot(d, 'wake-lock-permission-granted')
d.ui.open_notification()
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'notification-opened')
wait_for(d, '(wake lock held)')
if 'Release wakelock' not in d.ui.dump_hierarchy():
Expand All @@ -152,7 +161,7 @@ def run(d):
d.ui.press('enter')
screenshot(d, 'wake-unlock-command')
d.ui.open_notification()
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'notification-opened')
if 'Acquire wakelock' not in d.ui.dump_hierarchy():
d.ui(text='Nix').right(resourceId='android:id/expand_button').click()
Expand Down
18 changes: 10 additions & 8 deletions tests/emulator/bootstrap_channels.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
from common import screenshot, wait_for, APK, BOOTSTRAP_URL
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import time

from common import APK, BOOTSTRAP_URL, screenshot, wait_for


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

wait_for(d, 'Bootstrap zipball location')
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'initial')
d.ui(className='android.widget.EditText').set_text(BOOTSTRAP_URL)
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'entered-url')
for i in range(2):
for _ in range(2):
if 'text="OK"' not in d.ui.dump_hierarchy():
d.ui.press('back')
time.sleep(.5)
time.sleep(0.5)
else:
break
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'entered-url-back')
time.sleep(.5)
time.sleep(0.5)
d.ui(text='OK').click()
screenshot(d, 'ok-clicked')

Expand Down
18 changes: 10 additions & 8 deletions tests/emulator/bootstrap_flakes.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
from common import screenshot, wait_for, APK, BOOTSTRAP_URL
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import time

from common import APK, BOOTSTRAP_URL, screenshot, wait_for


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

wait_for(d, 'Bootstrap zipball location')
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'initial')
d.ui(className='android.widget.EditText').set_text(BOOTSTRAP_URL)
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'entered-url')
for i in range(2):
for _ in range(2):
if 'text="OK"' not in d.ui.dump_hierarchy():
d.ui.press('back')
time.sleep(.5)
time.sleep(0.5)
else:
break
time.sleep(.5)
time.sleep(0.5)
screenshot(d, 'entered-url-back')
time.sleep(.5)
time.sleep(0.5)
d.ui(text='OK').click()
screenshot(d, 'ok-clicked')

Expand Down
16 changes: 9 additions & 7 deletions tests/emulator/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import pathlib
import sys
import time

Expand All @@ -9,11 +11,11 @@


def screenshot(d, suffix=''):
os.makedirs('screenshots', exist_ok=True)
fname_base = f'screenshots/{time.time():.3f}-{suffix}'
d.ui.screenshot(f'{fname_base}.png')
with open(f'{fname_base}.xml', 'w') as f:
f.write(d.ui.dump_hierarchy())
screenshots = pathlib.Path('screenshots')
screenshots.mkdir(exist_ok=True)
fname_base = screenshots / f'{time.time():.3f}-{suffix}'
d.ui.screenshot(str(fname_base.with_suffix('.png')))
fname_base.with_suffix('.xml').write_text(d.ui.dump_hierarchy())
print(f'screenshotted: {fname_base}.{{png,xml}}')


Expand All @@ -29,7 +31,7 @@ def wait_for(d, on_screen_text, timeout=90, critical=True):
if on_screen_text in d.ui.dump_hierarchy():
print(f'found: {on_screen_text} after {elapsed:.1f}s')
return
time.sleep(.75)
time.sleep(0.75)
print(f'NOT FOUND: {on_screen_text} after {timeout}s')
screenshot(d, suffix='error')
if critical:
Expand Down
2 changes: 2 additions & 0 deletions tests/emulator/on_device_tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

from common import screenshot, wait_for


Expand Down
21 changes: 12 additions & 9 deletions tests/emulator/poke_around.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import bootstrap_channels
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import base64
import time

import bootstrap_channels
from common import screenshot, wait_for


Expand Down Expand Up @@ -54,13 +58,13 @@ def run(d):
screenshot(d, 'zip-is-still-there')

def change_shell_and_relogin(shell, descr):
import base64
import time
config = ('{pkgs, ...}: {user.shell = %SHELL%; ' +
'system.stateVersion = "24.05";}').replace('%SHELL%', shell)
config = (
'{pkgs, ...}: {user.shell = %SHELL%; '
'system.stateVersion = "24.05";}'
).replace('%SHELL%', shell)
config_base64 = base64.b64encode(config.encode()).decode()
d(f'input text "echo {config_base64} | base64 -d > '
'~/.config/nixpkgs/nix-on-droid.nix"')
cfg_file = '~/.config/nixpkgs/nix-on-droid.nix"'
d(f'input text "echo {config_base64} | base64 -d > {cfg_file}')
d.ui.press('enter')
screenshot(d, f'pre-switch-{descr}')
d(f'input text "nix-on-droid switch && echo switched {descr}"')
Expand All @@ -85,8 +89,7 @@ def change_shell_and_relogin(shell, descr):
change_shell_and_relogin('"${pkgs.fish}"', 'fish-directory')
wait_for(d, 'Cannot execute shell ')
wait_for(d, 'it is a directory.')
wait_for(d,
"You should point 'user.shell' to the exact binary.")
wait_for(d, "You should point 'user.shell' to the exact binary.")
wait_for(d, 'Falling back to bash.')
wait_for(d, 'bash-5.2$')
screenshot(d, 're-login-done-shell-dir-fallback')
Expand Down
27 changes: 16 additions & 11 deletions tests/emulator/test_channels_shell.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import bootstrap_channels
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import subprocess
import sys

import bootstrap_channels
from common import screenshot, wait_for

STD = '/data/data/com.termux.nix/files/home/.cache/nix-on-droid-self-test'
Expand Down Expand Up @@ -33,18 +35,21 @@ def run(d):
f'touch {STD}/confirmation-granted',
'/data/data/com.termux.nix/files/usr/bin/login echo test',
'/data/data/com.termux.nix/files/usr/bin/login id',
('cd /data/data/com.termux.nix/files/home; '
'pwd; '
'id; '
'env PATH= /data/data/com.termux.nix/files/usr/bin/login '
' nix-on-droid on-device-test'),
(
'cd /data/data/com.termux.nix/files/home; '
'pwd; '
'id; '
'env PATH= /data/data/com.termux.nix/files/usr/bin/login '
' nix-on-droid on-device-test'
),
]:
print(f'running {cmd} as {user} with capture:')
p = subprocess.Popen(['adb', 'shell', 'su', '0', 'su', user,
'sh', '-c', f"'{cmd}'"],
encoding='utf-8',
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
p = subprocess.Popen(
['adb', 'shell', 'su', '0', 'su', user, 'sh', '-c', f"'{cmd}'"],
encoding='utf-8',
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
out = ''
while p.poll() is None:
line = p.stdout.readline()
Expand Down
2 changes: 2 additions & 0 deletions tests/emulator/test_channels_uiautomator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE

import bootstrap_channels
import on_device_tests

Expand Down

0 comments on commit bd677b4

Please sign in to comment.