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

Convert testbed app to support test mode #6

Merged
merged 34 commits into from Dec 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3aec816
Convert testbed app to a stub app with a pytest test suite.
freakboy3742 Nov 3, 2022
ddfbe78
Add pre-commit (with black, isort and flake8 updates).
freakboy3742 Nov 3, 2022
6c1d727
Correct the naming of the Windows platform stub.
freakboy3742 Nov 3, 2022
2888625
Add a CI configuration.
freakboy3742 Nov 3, 2022
a5ac666
Temporarily use the in-development briefcase branch and templates for…
freakboy3742 Nov 3, 2022
da83b90
no-op tweak to trigger CI.
freakboy3742 Nov 3, 2022
05166cd
Disable fail-fast as a test.
freakboy3742 Nov 3, 2022
8e51688
Re-disable fail-fast.
freakboy3742 Nov 3, 2022
dd1cd80
Use the repo that has the branch.
freakboy3742 Nov 3, 2022
d68a3ed
Correct backend definitions.
freakboy3742 Nov 3, 2022
acd8ae9
Correct pre-command definition.
freakboy3742 Nov 3, 2022
a0fd2ff
Add defaults for all values
freakboy3742 Nov 3, 2022
b58e975
Specify a test device when running on mobile.
freakboy3742 Nov 3, 2022
3a76fee
Diable testing on platforms that don't support it yet.
freakboy3742 Nov 3, 2022
81eabec
Use macOS-12 for iOS; install flatpak dependencies; pin cryptography …
freakboy3742 Nov 4, 2022
267c43e
Exclude platforms where binary packages aren't available.
freakboy3742 Nov 4, 2022
d123b24
Pin cryptography to a version that doesn't need rust
freakboy3742 Nov 4, 2022
db0f3ec
Update project layout to match new testmode format.
freakboy3742 Nov 8, 2022
9be65f2
Use the run --test option.
freakboy3742 Nov 8, 2022
9498f06
Force dependency install (for now)
freakboy3742 Nov 8, 2022
a465762
Test before packaging, and ensure packaged artefact is in production …
freakboy3742 Nov 9, 2022
f2800dd
Use the testcase2 branch for all templates.
freakboy3742 Nov 9, 2022
9f5343f
Merge remote-tracking branch 'origin/dockerfile_extra_content' into t…
freakboy3742 Nov 9, 2022
1f720bf
Run tests on all platforms
freakboy3742 Nov 9, 2022
0d75bd6
Remove the use of the test sentinel, and use an explicit cache folder.
freakboy3742 Nov 17, 2022
8bff0ea
Use an explicitly created emulator for Android tests.
freakboy3742 Nov 17, 2022
4ef3b6b
Add requirements to ensure android emulator can run in CI.
freakboy3742 Nov 17, 2022
d8d4074
Try using macOS to avoid issues with hardware acceleration.
freakboy3742 Nov 18, 2022
b37b89d
Use explicit emulator arguments for Android.
freakboy3742 Nov 22, 2022
61ee42f
Unpack Android sources on test startup.
freakboy3742 Nov 22, 2022
185d798
Disable Linux tests on Android.
freakboy3742 Nov 22, 2022
030b2a7
Use dev branches for templates, and add extra gradle content for Andr…
freakboy3742 Nov 23, 2022
083c7ab
Use the development version of Briefcase.
freakboy3742 Nov 30, 2022
e99738b
Update project to match recent briefcase-template changes.
freakboy3742 Nov 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/dependabot.yml
@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates on Sunday, 8PM UTC
interval: "weekly"
day: "sunday"
time: "20:00"

- package-ecosystem: "pip"
directory: "/"
schedule:
# Check for updates on Sunday, 8PM UTC
interval: "weekly"
day: "sunday"
time: "20:00"
105 changes: 105 additions & 0 deletions .github/workflows/ci.yml
@@ -0,0 +1,105 @@
name: CI
on:
pull_request:
push:
branches:
- main
workflow_call:

defaults:
run:
shell: bash # https://github.com/beeware/briefcase/pull/912

jobs:
pre-commit:
name: Pre-commit code style checks
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3.1.0
- name: Set up Python
uses: actions/setup-python@v4.3.0
with:
python-version: "3.X"
- name: Lint with Pre-commit
uses: pre-commit/action@v3.0.0

unit-tests:
name: Unit tests
needs: [pre-commit]
strategy:
fail-fast: false
matrix:
backend: ["macOS-Xcode", "macOS-app", "linux-appimage", "linux-flatpak", "windows-VisualStudio", "windows-app", "iOS", "android"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
include:
- runs-on: ubuntu-latest
- pre-command:
- briefcase-target:
- briefcase-run-args:

- backend: macOS-Xcode
runs-on: macos-12
briefcase-target: "macOS Xcode"

- backend: macOS-app
runs-on: macos-12
briefcase-target: "macOS app"

- backend: linux-appimage
runs-on: ubuntu-latest
pre-command: "sudo apt-get update -y && sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config"
briefcase-target: "linux appimage"

- backend: linux-flatpak
# Need to use at least 22.04 to get the bugfix in flatpak for handling spaces in filenames.
runs-on: ubuntu-22.04
pre-command: "sudo apt-get update -y && sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config flatpak flatpak-builder"
briefcase-target: "linux flatpak"

- backend: windows-VisualStudio
runs-on: windows-latest
briefcase-target: "windows VisualStudio"

- backend: windows-app
runs-on: windows-latest
briefcase-target: "windows app"

- backend: iOS
runs-on: macos-12
briefcase-target: "iOS"
briefcase-run-args: ' -d "iPhone SE (3rd generation)"'

- backend: android
runs-on: macos-12
briefcase-target: "android"
briefcase-run-args: " -d '{\"avd\":\"beePhone\"}' --Xemulator=-no-window --Xemulator=-no-snapshot --Xemulator=-no-audio --Xemulator=-no-boot-anim --shutdown-on-exit"

exclude:
# Binary packages aren't available for 3.11 on mobile yet
- backend: "android"
python-version: "3.11"

- backend: "iOS"
python-version: "3.11"

runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v3.1.0
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4.3.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
${{ matrix.pre-command }}
# Use the development version of Briefcase
pip install git+https://github.com/beeware/briefcase.git
- name: Test App
run: |
briefcase run ${{ matrix.briefcase-target }} --test ${{ matrix.briefcase-run-args }}
- name: Package
run: |
briefcase package ${{ matrix.briefcase-target }} --update --adhoc-sign
45 changes: 45 additions & 0 deletions .github/workflows/dependabot-changenote.yml
@@ -0,0 +1,45 @@
name: Dependabot Change Note
on:
push:
branches:
- 'dependabot/**'

permissions:
pull-requests: write

jobs:
changenote:
name: Dependabot Change Note
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.actor == 'dependabot[bot]'
steps:

- name: Checkout
uses: actions/checkout@v3.1.0
with:
fetch-depth: 1
token: ${{ secrets.BRUTUS_PAT_TOKEN }}

- name: Configure git
run: |
git config --local user.email "$(git log --pretty='%ae' -1)"
git config --local user.name "Dependabot[bot]"

- name: Commit Change Note
run: |
# Fetch PR number for commit from Github API
API_URL="${{ github.api_url }}/repos/${{ github.repository }}/commits/${{ github.event.head_commit.id }}/pulls"
PR_NUM=$(curl -s -H "Accept: application/vnd.github+json" "${API_URL}" | jq -r '.[].number')

# Create change note from first line of dependabot commit
NEWS=$(printf "${{ github.event.head_commit.message }}" | head -n1 | sed -e 's/Bump/Updated/')
printf "${NEWS}.\n" > "./changes/${PR_NUM}.misc.rst"

# Commit the change note
git add "./changes/${PR_NUM}.misc.rst"
# "dependabot skip" tells Dependabot to continue rebasing this branch despite foreign commits
git commit -m "Add changenote. [dependabot skip]"

- name: Push
run: git push origin
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -5,4 +5,4 @@ iOS
android
windows
linux
briefcase.*.log
briefcase.*.log
38 changes: 38 additions & 0 deletions .pre-commit-config.yaml
@@ -0,0 +1,38 @@
exclude: "^(attic|examples/.template|nursery)/"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-toml
- id: check-yaml
- id: check-case-conflict
- id: check-docstring-first
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/PyCQA/isort
# For split_on_trailing_comma. Should be in the release after 5.10.1
rev: 12cc5fbd67eebf92eb2213b03c07b138ae1fb448
hooks:
- id: isort
additional_dependencies: [toml]
- repo: https://github.com/asottile/pyupgrade
rev: v2.38.2
hooks:
- id: pyupgrade
args: [--py38-plus]
# Docformatter is RST-unaware, and may break markup by inserting or removing newlines
# (see https://github.com/PyCQA/docformatter/issues/124 and linked issues). Until this
# is fixed, it's not safe to run it automatically.
# - repo: https://github.com/myint/docformatter
# rev: v1.5.0
# hooks:
# - id: docformatter
# args: [--in-place]
- repo: https://github.com/psf/black
rev: 22.8.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
hooks:
- id: flake8
1 change: 0 additions & 1 deletion CONTRIBUTING.md
Expand Up @@ -5,4 +5,3 @@ BeeWare <3's contributions!
Please be aware, BeeWare operates under a Code of Conduct.

See [CONTRIBUTING to BeeWare](https://beeware.org/contributing) for details.

20 changes: 18 additions & 2 deletions pyproject.toml
Expand Up @@ -11,14 +11,19 @@ author_email = "russell@beeware.org"
formal_name = "Testbed"
description = "A testbed for the Apple Support packages."
icon = "src/testbed/resources/testbed"
sources = ['src/testbed']
sources = ["src/testbed"]
test_sources = ["tests"]

requires = [
"cryptography",
"lru_dict",
"pillow",
"numpy",
"pandas",
]
test_requires = [
"pytest",
]

[tool.briefcase.app.testbed.macOS]
requires = [
Expand All @@ -30,7 +35,7 @@ requires = [
[tool.briefcase.app.testbed.macOS.app]
# template = "../../templates/briefcase-macOS-app-template"

[tool.briefcase.app.testbed.macOS.xcode]
[tool.briefcase.app.testbed.macOS.Xcode]
# template = "../../templates/briefcase-macOS-Xcode-template"

[tool.briefcase.app.testbed.linux]
Expand Down Expand Up @@ -103,5 +108,16 @@ requires = [
# Android doesn't provide the zoneinfo TZ database; use the Python provided one
"tzdata",
]

# TODO: replace with extractPackages
build_gradle_extra_content = """
android.defaultConfig.python.pyc.src false
"""

# support_package = "../Python-Android-support/dist/Python-3.10-Android-support.custom.zip"
# template = "../../templates/briefcase-Android-gradle-template"

[tool.isort]
profile = "black"
split_on_trailing_comma = true
combine_as_imports = true
5 changes: 5 additions & 0 deletions setup.cfg
@@ -0,0 +1,5 @@

[flake8]
max-complexity = 25
max-line-length = 119
ignore = E203,E266,E501,W503
36 changes: 22 additions & 14 deletions src/testbed/android.py
@@ -1,20 +1,28 @@
###########################################################################
# Android specific tests
###########################################################################
from .utils import assert_
######################################################################
# Android App main loop
#
# The main loop itself is a no-op; however we need a PythonAppDelegate
# to satisfy the app stub.
#######################################################################
from rubicon.java import JavaClass, JavaInterface

# The Android cookiecutter template creates an app whose main Activity is
# called `MainActivity`. The activity assumes that we will store a reference
# to an implementation/subclass of `IPythonApp` in it.
MainActivity = JavaClass("org/beeware/android/MainActivity")

# Don't quit the process at the end of the suite.
def exit(failures):
pass

# The `IPythonApp` interface in Java allows Python code to
# run on Android activity lifecycle hooks such as `onCreate()`.
IPythonApp = JavaInterface("org/beeware/android/IPythonApp")

def test_ctypes():
"The FFI module has been compiled, and ctypes works on Java objects"
from rubicon.java import JavaClass

URL = JavaClass("java/net/URL")
class PythonApp(IPythonApp):
def __init__(self, app):
super().__init__()
self._impl = app
MainActivity.setPythonApp(self)
print("Python app launched & stored in Android Activity class")

sample_url = URL("https://beeware.org/contributing")

assert_(sample_url.getHost() == "beeware.org")
def main_loop():
pass
69 changes: 9 additions & 60 deletions src/testbed/app.py
@@ -1,71 +1,20 @@
"""
A testbed for the Apple Support packages.
"""
import importlib
import platform
import sys
import traceback

from . import common, thirdparty, utils


def discover_tests(module):
"Discover all the test methods in the given module"
return [
(getattr(module, "__name__").split(".")[-1], getattr(module, name))
for name in dir(module)
if name.startswith("test_")
]


def main():
# This should start and launch your app!
print("=" * 80)
print(f"Python {platform.python_version()} Apple Support verification suite")
print(f"Python {platform.python_version()} Verification Suite")
print(f"Running on {platform.platform()}")
print("=" * 80)
# Discover the common test suite
suite = discover_tests(common)

# Discover the platform-specific tests
try:
if hasattr(sys, 'getandroidapilevel'):
module_path = '.android'
else:
module_path = f".{sys.platform}"
platform_module = importlib.import_module(module_path, "testbed")
suite.extend(discover_tests(platform_module))
except ModuleNotFoundError:
print(f"No platform-specific tests for {sys.platform}")
# Load the platform module
if hasattr(sys, "getandroidapilevel"):
module_path = ".android"
else:
module_path = f".{sys.platform}"
platform_module = importlib.import_module(module_path, "testbed")

# Add the tests for third-party modules.
suite.extend(discover_tests(thirdparty))

# Run the suite
failures = 0
tests = 0
skipped = 0
for sys_platform, test in suite:
try:
tests += 1
# If the test has a docstring, use that text;
# otherwise, use the test name
if test.__doc__:
print(f"{sys_platform}: {test.__doc__}", end="...")
else:
print(f"{sys_platform}: {test.__name__}", end="...")
test()
print(" ok")
except utils.SkippedTest as e:
skipped += 1
print(f" skip: {e}")
except Exception as e:
failures += 1
print(" FAILED!")
print("-" * 80)
traceback.print_exc()
print("-" * 80)

print("=" * 80)
print(f"Tests complete; {tests} tests ({skipped} skipped); {failures} failures.")
platform_module.exit(failures)
# Run the main_loop() for the platform
platform_module.main_loop()