Skip to content

Commit bd677b4

Browse files
committed
tests/emulator: add license, lint with ruff
1 parent 5d88ff2 commit bd677b4

10 files changed

+129
-54
lines changed

.github/workflows/lints.yml

+17-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
schedule:
66
- cron: 0 0 * * 1
77
jobs:
8-
lint:
8+
lint-nix:
99
runs-on: ubuntu-latest
1010

1111
steps:
@@ -17,3 +17,19 @@ jobs:
1717

1818
- name: Run nix-formatter-pack-check
1919
run: nix build .#checks.x86_64-linux.nix-formatter-pack-check
20+
21+
lint-py:
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v4
27+
28+
- name: Install nix
29+
uses: cachix/install-nix-action@v25
30+
31+
- name: Run ruff linter
32+
run: nix run 'nixpkgs#ruff' -- check
33+
34+
- name: Run ruff formatter
35+
run: nix run 'nixpkgs#ruff' -- format --diff

.ruff.toml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
line-length = 79
2+
preview = true
3+
lint.select = [ "ALL" ]
4+
lint.ignore = [
5+
"D203", # one-blank-line-before-class
6+
"D213", # multi-line-summary-second-line
7+
]
8+
lint.per-file-ignores."tests/emulator/**" = [
9+
"ANN", # flake-8 annotations
10+
"D100", # undocumented-public-module
11+
"D103", # undocumented-public-function
12+
"INP001", # implicit-namespace-package
13+
"PLR0915", # too-many-statements
14+
"S101", # assert
15+
"T201", # print
16+
]
17+
lint.per-file-ignores."tests/emulator/common.py" = [
18+
"FBT002", # boolean-default-value-positional-argument
19+
]
20+
lint.per-file-ignores."tests/emulator/android_integration.py" = [
21+
"C901", # complex-structure
22+
]
23+
lint.per-file-ignores."tests/emulator/test_channels_shell.py" = [
24+
"S404", # suspicious-subprocess-import
25+
"S603", # subprocess-without-shell-equals-true
26+
"S607", # start-process-with-partial-path
27+
]
28+
lint.flake8-quotes.inline-quotes = "single"
29+
lint.flake8-quotes.multiline-quotes = "single"
30+
lint.flake8-copyright.notice-rgx = '# Copyright \(c\) 2019-20\d\d, see AUTHORS\. Licensed under MIT License, see LICENSE\n'
31+
format.quote-style = "single"
32+
format.preview = true

tests/emulator/android_integration.py

+19-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
13
import base64
24
import time
35

46
import bootstrap_channels
5-
67
from common import screenshot, wait_for
78

9+
OPENERS = ['termux-open', 'termux-open-url', 'xdg-open']
10+
TOOLS = [
11+
'am',
12+
'termux-setup-storage',
13+
'termux-reload-settings',
14+
'termux-wake-lock',
15+
'termux-wake-unlock',
16+
*OPENERS,
17+
]
818

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

20+
def run(d):
1421
nod = bootstrap_channels.run(d)
1522

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

2330
# Apply a config that enables android-integration tools
24-
cfg = ('/data/local/tmp/n-o-d/unpacked/tests/on-device/'
25-
'config-android-integration.nix')
26-
d(f'input text \'cp {cfg} .config/nixpkgs/nix-on-droid.nix\'')
31+
cfg = (
32+
'/data/local/tmp/n-o-d/unpacked/tests/on-device/'
33+
'config-android-integration.nix'
34+
)
35+
d(f"input text 'cp {cfg} .config/nixpkgs/nix-on-droid.nix'")
2736
d.ui.press('enter')
2837
screenshot(d, 'pre-switch')
2938
d('input text "nix-on-droid switch && echo integration tools installed"')
@@ -135,7 +144,7 @@ def run(d):
135144
d.ui(text='ALLOW').click()
136145
screenshot(d, 'wake-lock-permission-granted')
137146
d.ui.open_notification()
138-
time.sleep(.5)
147+
time.sleep(0.5)
139148
screenshot(d, 'notification-opened')
140149
wait_for(d, '(wake lock held)')
141150
if 'Release wakelock' not in d.ui.dump_hierarchy():
@@ -152,7 +161,7 @@ def run(d):
152161
d.ui.press('enter')
153162
screenshot(d, 'wake-unlock-command')
154163
d.ui.open_notification()
155-
time.sleep(.5)
164+
time.sleep(0.5)
156165
screenshot(d, 'notification-opened')
157166
if 'Acquire wakelock' not in d.ui.dump_hierarchy():
158167
d.ui(text='Nix').right(resourceId='android:id/expand_button').click()

tests/emulator/bootstrap_channels.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1-
from common import screenshot, wait_for, APK, BOOTSTRAP_URL
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
22

33
import time
44

5+
from common import APK, BOOTSTRAP_URL, screenshot, wait_for
6+
57

68
def run(d):
79
nod = d.app('com.termux.nix', url=APK)
810
nod.permissions.allow_notifications()
911
nod.launch()
10-
time.sleep(.5)
12+
time.sleep(0.5)
1113

1214
wait_for(d, 'Bootstrap zipball location')
13-
time.sleep(.5)
15+
time.sleep(0.5)
1416
screenshot(d, 'initial')
1517
d.ui(className='android.widget.EditText').set_text(BOOTSTRAP_URL)
16-
time.sleep(.5)
18+
time.sleep(0.5)
1719
screenshot(d, 'entered-url')
18-
for i in range(2):
20+
for _ in range(2):
1921
if 'text="OK"' not in d.ui.dump_hierarchy():
2022
d.ui.press('back')
21-
time.sleep(.5)
23+
time.sleep(0.5)
2224
else:
2325
break
24-
time.sleep(.5)
26+
time.sleep(0.5)
2527
screenshot(d, 'entered-url-back')
26-
time.sleep(.5)
28+
time.sleep(0.5)
2729
d.ui(text='OK').click()
2830
screenshot(d, 'ok-clicked')
2931

tests/emulator/bootstrap_flakes.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1-
from common import screenshot, wait_for, APK, BOOTSTRAP_URL
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
22

33
import time
44

5+
from common import APK, BOOTSTRAP_URL, screenshot, wait_for
6+
57

68
def run(d):
79
nod = d.app('com.termux.nix', url=APK)
810
nod.permissions.allow_notifications()
911
nod.launch()
10-
time.sleep(.5)
12+
time.sleep(0.5)
1113

1214
wait_for(d, 'Bootstrap zipball location')
13-
time.sleep(.5)
15+
time.sleep(0.5)
1416
screenshot(d, 'initial')
1517
d.ui(className='android.widget.EditText').set_text(BOOTSTRAP_URL)
16-
time.sleep(.5)
18+
time.sleep(0.5)
1719
screenshot(d, 'entered-url')
18-
for i in range(2):
20+
for _ in range(2):
1921
if 'text="OK"' not in d.ui.dump_hierarchy():
2022
d.ui.press('back')
21-
time.sleep(.5)
23+
time.sleep(0.5)
2224
else:
2325
break
24-
time.sleep(.5)
26+
time.sleep(0.5)
2527
screenshot(d, 'entered-url-back')
26-
time.sleep(.5)
28+
time.sleep(0.5)
2729
d.ui(text='OK').click()
2830
screenshot(d, 'ok-clicked')
2931

tests/emulator/common.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import os
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
3+
import pathlib
24
import sys
35
import time
46

@@ -9,11 +11,11 @@
911

1012

1113
def screenshot(d, suffix=''):
12-
os.makedirs('screenshots', exist_ok=True)
13-
fname_base = f'screenshots/{time.time():.3f}-{suffix}'
14-
d.ui.screenshot(f'{fname_base}.png')
15-
with open(f'{fname_base}.xml', 'w') as f:
16-
f.write(d.ui.dump_hierarchy())
14+
screenshots = pathlib.Path('screenshots')
15+
screenshots.mkdir(exist_ok=True)
16+
fname_base = screenshots / f'{time.time():.3f}-{suffix}'
17+
d.ui.screenshot(str(fname_base.with_suffix('.png')))
18+
fname_base.with_suffix('.xml').write_text(d.ui.dump_hierarchy())
1719
print(f'screenshotted: {fname_base}.{{png,xml}}')
1820

1921

@@ -29,7 +31,7 @@ def wait_for(d, on_screen_text, timeout=90, critical=True):
2931
if on_screen_text in d.ui.dump_hierarchy():
3032
print(f'found: {on_screen_text} after {elapsed:.1f}s')
3133
return
32-
time.sleep(.75)
34+
time.sleep(0.75)
3335
print(f'NOT FOUND: {on_screen_text} after {timeout}s')
3436
screenshot(d, suffix='error')
3537
if critical:

tests/emulator/on_device_tests.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
13
from common import screenshot, wait_for
24

35

tests/emulator/poke_around.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import bootstrap_channels
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
3+
import base64
4+
import time
25

6+
import bootstrap_channels
37
from common import screenshot, wait_for
48

59

@@ -54,13 +58,13 @@ def run(d):
5458
screenshot(d, 'zip-is-still-there')
5559

5660
def change_shell_and_relogin(shell, descr):
57-
import base64
58-
import time
59-
config = ('{pkgs, ...}: {user.shell = %SHELL%; ' +
60-
'system.stateVersion = "24.05";}').replace('%SHELL%', shell)
61+
config = (
62+
'{pkgs, ...}: {user.shell = %SHELL%; '
63+
'system.stateVersion = "24.05";}'
64+
).replace('%SHELL%', shell)
6165
config_base64 = base64.b64encode(config.encode()).decode()
62-
d(f'input text "echo {config_base64} | base64 -d > '
63-
'~/.config/nixpkgs/nix-on-droid.nix"')
66+
cfg_file = '~/.config/nixpkgs/nix-on-droid.nix"'
67+
d(f'input text "echo {config_base64} | base64 -d > {cfg_file}')
6468
d.ui.press('enter')
6569
screenshot(d, f'pre-switch-{descr}')
6670
d(f'input text "nix-on-droid switch && echo switched {descr}"')
@@ -85,8 +89,7 @@ def change_shell_and_relogin(shell, descr):
8589
change_shell_and_relogin('"${pkgs.fish}"', 'fish-directory')
8690
wait_for(d, 'Cannot execute shell ')
8791
wait_for(d, 'it is a directory.')
88-
wait_for(d,
89-
"You should point 'user.shell' to the exact binary.")
92+
wait_for(d, "You should point 'user.shell' to the exact binary.")
9093
wait_for(d, 'Falling back to bash.')
9194
wait_for(d, 'bash-5.2$')
9295
screenshot(d, 're-login-done-shell-dir-fallback')

tests/emulator/test_channels_shell.py

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import bootstrap_channels
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
23
import subprocess
34
import sys
45

6+
import bootstrap_channels
57
from common import screenshot, wait_for
68

79
STD = '/data/data/com.termux.nix/files/home/.cache/nix-on-droid-self-test'
@@ -33,18 +35,21 @@ def run(d):
3335
f'touch {STD}/confirmation-granted',
3436
'/data/data/com.termux.nix/files/usr/bin/login echo test',
3537
'/data/data/com.termux.nix/files/usr/bin/login id',
36-
('cd /data/data/com.termux.nix/files/home; '
37-
'pwd; '
38-
'id; '
39-
'env PATH= /data/data/com.termux.nix/files/usr/bin/login '
40-
' nix-on-droid on-device-test'),
38+
(
39+
'cd /data/data/com.termux.nix/files/home; '
40+
'pwd; '
41+
'id; '
42+
'env PATH= /data/data/com.termux.nix/files/usr/bin/login '
43+
' nix-on-droid on-device-test'
44+
),
4145
]:
4246
print(f'running {cmd} as {user} with capture:')
43-
p = subprocess.Popen(['adb', 'shell', 'su', '0', 'su', user,
44-
'sh', '-c', f"'{cmd}'"],
45-
encoding='utf-8',
46-
stdout=subprocess.PIPE,
47-
stderr=subprocess.STDOUT)
47+
p = subprocess.Popen(
48+
['adb', 'shell', 'su', '0', 'su', user, 'sh', '-c', f"'{cmd}'"],
49+
encoding='utf-8',
50+
stdout=subprocess.PIPE,
51+
stderr=subprocess.STDOUT,
52+
)
4853
out = ''
4954
while p.poll() is None:
5055
line = p.stdout.readline()

tests/emulator/test_channels_uiautomator.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Copyright (c) 2019-2024, see AUTHORS. Licensed under MIT License, see LICENSE
2+
13
import bootstrap_channels
24
import on_device_tests
35

0 commit comments

Comments
 (0)