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

tests/emulator: add license, lint with ruff #412

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

Choose a reason for hiding this comment

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

in the interest of running the version of ruff we expect to run, shouldn't this point to something in flake.nix? Unfortunately I don't think nix run .#nixpkgs.legacyPackages.x86_64.ruff works but we could expose ruff in the flake and run that.


- 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
Loading