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

Initial run of a py.test collector for the existing klippy .test format, rework CI to do more validation #503

Merged
merged 6 commits into from
Feb 1, 2025
Merged
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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
ci_build/
ci_cache/

.venv/
dict/
scripts/Dockerfile*
out/
.pytest_cache/
.ruff_cache/
51 changes: 40 additions & 11 deletions .github/workflows/ci-build_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,48 @@ jobs:
id: changes
with:
filters: |
klippy:
- 'klippy/**'
- 'test/**'
- 'scripts/**'
dependencies:
- 'pyproject.toml'
- 'scripts/klippy-requirements.txt'
- 'scripts/requirements_dev.txt'
klipper:
- 'pyproject.toml'
- 'Makefile'
- 'src/**'
- 'lib/**'
- 'test/**'
- 'test/configs/**'
- 'scripts/Dockerfile-build'
- 'scripts/buildcommands.py'
- 'scripts/check-gcc.sh'

- name: Test Klippy Only
if: steps.changes.outputs.klippy == 'true' && steps.changes.outputs.klipper == 'false'
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest "./scripts/ci-build.sh" 2>&1
# Always pull the latest image to take advantage of layer caching
- name: Pull docker image
run: docker pull dangerklippers/klipper-build:latest

- name: Test Klipper Full
if: steps.changes.outputs.klippy == 'true' && steps.changes.outputs.klipper == 'true'
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest "./scripts/ci-build.sh" compile 2>&1
- name: Test Klipper build (changes to the firmware)
if: steps.changes.outputs.klipper == 'true'
run: docker build -f scripts/Dockerfile-build -t dangerklippers/klipper-build:latest .

- name: Ensure scripts/klippy-dependencies.txt is up to date
if: steps.changes.outputs.dependencies == 'true'
uses: nickcharlton/diff-check@main
with:
command: |
docker run -v $PWD:/klipper dangerklippers/klipper-build:latest uv export --frozen -o scripts/klippy-requirements.txt --no-dev --no-hashes
docker run -v $PWD:/klipper dangerklippers/klipper-build:latest uv export --frozen -o scripts/requirements_dev.txt --only-dev --no-hashes

# This *could* be done with a matrix, but then we would have to figure out sharing the docker image between builds
- name: Test Klippy (Python 3.9)
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest --python 3.9 py.test -n auto

- name: Test Klippy (Python 3.10)
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest --python 3.10 py.test -n auto

- name: Test Klippy (Python 3.11)
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest --python 3.11 py.test -n auto

- name: Test Klippy (Python 3.12)
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest --python 3.12 py.test -n auto

- name: Test Klippy (Python 3.13)
run: docker run -v $PWD:/klipper dangerklippers/klipper-build:latest --python 3.13 py.test -n auto
17 changes: 15 additions & 2 deletions .github/workflows/ci-builder.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,21 @@ name: Klipper Container Build and Push

on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 0" # at 00.00 on Sunday
push:
branches:
- main
# This should mirror the klipper paths-filter in ci-build_test.yaml
paths:
- "Makefile"
- "pyproject.toml"
- "src/**"
- "lib/**"
- "test/configs/**"
- "scripts/Dockerfile-build"
- "scripts/buildcommands.py"
- "scripts/check-gcc.sh"
- "scripts/ci-build.sh"
- ".github/workflows/ci-builder.yaml"

jobs:
login:
Expand Down
1 change: 1 addition & 0 deletions klippy/gcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ def cmd_default(self, gcmd):
# Don't warn about requests to turn off fan when fan not present
return
gcmd.respond_info('Unknown command:"%s"' % (cmd,))
self.printer.send_event("gcode:unknown_command", cmd)

def _cmd_mux(self, command, gcmd):
key, values = self.mux_commands[command]
Expand Down
2 changes: 2 additions & 0 deletions klippy/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ def _read_config(self):
"telemetry",
]:
self.load_object(config, section_config, None)
if self.get_start_args().get("debuginput") is not None:
self.load_object(config, "testing", None)
for m in [toolhead]:
m.add_printer_objects(config)
# Validate that there are no undefined parameters in the config file
Expand Down
22 changes: 16 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ dependencies = [
"python-can==3.3.4",
]

[tool.uv]
dev-dependencies = [
"ruff>=0.9.3",
"pre-commit>=4.0.1",
"pytest-xdist>=3.6.1",
"pytest>=8.3.4",
]

[project.urls]
homepage = "https://kalico.gg/"
source = "https://github.com/KalicoCrew/kalico"
Expand All @@ -29,7 +37,11 @@ indent-width = 4
exclude = [".github", ".history", "config", "docs", "lib", "src"]

[tool.ruff.lint]
extend-select = ["B006"]
extend-select = [
"B006", # Checks for uses of mutable objects as function argument defaults
"FA100", # Detect when type annotations could be made better with PEP563
"FA102", # Detect type annotations that would require `from __future__ import annotations`
]
ignore = [
"E401", # Multiple imports on one line
"C901", # Function is too complex
Expand All @@ -41,8 +53,6 @@ ignore = [
"E721", # Do not compare types, use 'isinstance()'
]

[dependency-groups]
dev = [
"ruff>=0.9.3",
"pre-commit>=4.0.1",
]
[tool.pytest.ini_options]
pythonpath = ["."]
testpaths = ["test"]
29 changes: 24 additions & 5 deletions scripts/Dockerfile-build
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,31 @@ ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt update && apt install -y sudo git curl
RUN mkdir /ci_build

# Install dependencies
RUN apt update \
&& apt install -y sudo git curl \
python3 python3-dev python3-venv libffi-dev build-essential \
gcc-avr avr-libc \
libnewlib-arm-none-eabi gcc-arm-none-eabi binutils-arm-none-eabi \
pv libmpfr-dev libgmp-dev libmpc-dev texinfo bison flex \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Install or1k-linux-musl toolchain
RUN --mount=type=cache,target=/ci_cache \
curl https://more.musl.cc/10/x86_64-linux-musl/or1k-linux-musl-cross.tgz -o /ci_cache/or1k-linux-musl-cross-10.tgz && \
tar -x -C /ci_build -f /ci_cache/or1k-linux-musl-cross-10.tgz

# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

COPY . /klipper
WORKDIR /klipper

RUN ./scripts/ci-install.sh
RUN ./scripts/ci-build.sh
ENV PATH="/ci_build/python-env/bin:$PATH"
RUN pip install -r ./scripts/requirements_dev.txt
ENV DICTDIR=/ci_build/dict
RUN uv run ./scripts/ci-build.sh

ENTRYPOINT [ "/bin/uv", "run" ]
CMD [ "py.test" ]
15 changes: 6 additions & 9 deletions scripts/ci-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ compile()
finish_test mcu_compile "$TARGET"
cp out/klipper.dict ${1}/$(basename ${TARGET} .config).dict
done
make clean
make distclean
}

DICTDIR=${BUILD_DIR}/dict
export DICTDIR=${DICTDIR:-${BUILD_DIR}/dict}

if [ ! -d "${DICTDIR}" ]; then
mkdir -p ${DICTDIR}
Expand All @@ -62,11 +64,6 @@ fi
# Verify klippy host software
######################################################################

start_test klippy "Test klippy import (Python3)"
# I'm leaving this with klippy/klippy.py so we test that compatibility
$PYTHON klippy/klippy.py --import-test
finish_test klippy "Test klippy import (Python3)"

start_test klippy "Test invoke klippy (Python3)"
$PYTHON scripts/test_klippy.py -d ${DICTDIR} test/klippy/*.test
finish_test klippy "Test invoke klippy (Python3)"
start_test klippy "py.test suite"
py.test
finish_test klippy "py.test suite"
50 changes: 0 additions & 50 deletions scripts/ci-install.sh

This file was deleted.

10 changes: 5 additions & 5 deletions scripts/klippy-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file was autogenerated by uv via the following command:
# uv export -o scripts/klippy-requirements.txt --no-dev --no-hashes
# uv export --frozen -o scripts/klippy-requirements.txt --no-dev --no-hashes
aenum==3.1.15
cffi==1.15.1 ; python_full_version < '3.13'
cffi==1.17.1 ; python_full_version >= '3.13'
Expand All @@ -9,9 +9,9 @@ greenlet==3.1.0 ; python_full_version >= '3.13'
jinja2==3.1.5
markupsafe==2.1.5
numpy==2.0.2 ; python_full_version < '3.10'
numpy==2.2.0 ; python_full_version >= '3.10'
pycparser==2.21
numpy==2.2.2 ; python_full_version >= '3.10'
pycparser==2.22
pyserial==3.4
python-can==3.3.4
windows-curses==2.4.0 ; sys_platform == 'win32'
wrapt==1.16.0
windows-curses==2.4.1 ; sys_platform == 'win32'
wrapt==1.17.2
21 changes: 15 additions & 6 deletions scripts/requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# This file was autogenerated by uv via the following command:
# uv export -o scripts/requirements_dev.txt --only-dev --no-hashes
# uv export --frozen -o scripts/requirements_dev.txt --only-dev --no-hashes
cfgv==3.4.0
colorama==0.4.6 ; sys_platform == 'win32'
distlib==0.3.9
filelock==3.16.1
identify==2.6.5
exceptiongroup==1.2.2 ; python_full_version < '3.11'
execnet==2.1.1
filelock==3.17.0
identify==2.6.6
iniconfig==2.0.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.6
pre-commit==4.0.1
pluggy==1.5.0
pre-commit==4.1.0
pytest==8.3.4
pytest-xdist==3.6.1
pyyaml==6.0.2
ruff==0.8.4
virtualenv==20.28.1
ruff==0.9.3
tomli==2.2.1 ; python_full_version < '3.11'
virtualenv==20.29.1
34 changes: 34 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from __future__ import annotations

import klippy.chelper
import pathlib
import os

# Ensure chelper is built
klippy.chelper.get_ffi()


ROOT = pathlib.Path(__file__).parent.parent
KLIPPY_PLUGINS = ROOT / "klippy" / "plugins"
TESTING_PLUGIN = ROOT / "test" / "klippy_testing_plugin.py"


def pytest_addoption(parser):
parser.addoption(
"--dictdir",
action="store",
default=os.environ.get("DICTDIR", "dict"),
help="Klipper build dictionary path",
)


def pytest_sessionstart(session):
link_path = KLIPPY_PLUGINS / "testing.py"
if link_path.exists():
return

os.symlink(TESTING_PLUGIN, link_path)

@session.config.add_cleanup
def clean_symlink():
os.unlink(link_path)
2 changes: 0 additions & 2 deletions test/klippy/bed_screws.test
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ ACCEPT
ACCEPT
ACCEPT

ACCEPT
ACCEPT
ACCEPT

# Start helper script and run with two readjusts
Expand Down
9 changes: 3 additions & 6 deletions test/klippy/commands.test
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ RESTORE_GCODE_STATE MOVE=1

# Update commands
SET_GCODE_OFFSET Z=.1
M206 Z-.2
SET_GCODE_OFFSET Z_ADJUST=-.1

SET_VELOCITY_LIMIT ACCEL=100 VELOCITY=20 SQUARE_CORNER_VELOCITY=1 ACCEL_TO_DECEL=200
Expand All @@ -45,8 +44,6 @@ SET_PRESSURE_ADVANCE EXTRUDER=extruder ADVANCE=.001
SET_PRESSURE_ADVANCE ADVANCE=.002 ADVANCE_LOOKAHEAD_TIME=.001

# test telemetry
TELEMETRY_ENABLE
TELEMETRY_EXAMPLE

# Restart command (must be last in test)
RESTART
ASSERT TEST='{"telemetry" not in printer.configfile.save_config_pending_items}'
ENABLE_TELEMETRY
ASSERT TEST='{printer.configfile.save_config_pending_items.telemetry.enabled}'
Loading