Introduce pytest unittests to easily implement and test new channel
options. Unlike the QUnit test-http.js test this also allows us to test
UNIX sockets and TLS easily.
Enable strict mode and add the places where complaints popped up.
One not-entirely-mechanical thing: we replace the call to .stop() with a
call to .shutdown(). .stop() is decorated as a D-Bus method (which
unfortunately currently erases type information), which causes
complaints at the call site. But it just calls .shutdown() anyway, so
we may as well just do that directly ourselves.
Use `get_dict` in `Packages.show()` to get typed accessors.
The two `@bus.Interface.Method` decorated methods cause
> Untyped decorator makes function "reload" untyped [misc]
There's no immediate fix for that, ignore these errors for now.
When we landed d53b3e8400 ("pytests: update fixtures to not use
deprecated event_loop") we promised ourselves "this is the last time".
The intensity of hacks required to keep up with being able to run the
same set of tests under modern Python versions and a long-dead version
which isn't getting any new releases of pytest or its plugins is just
too much.
And here we are again. Since fb319e4f43 ("Pin pytest-asyncio version
to unbreak main") we've been avoiding taking a new pytest-asyncio
because it breaks our fragile pile of hacks yet again. It's time.
Drop support for running the pytest unit tests tests under Python 3.6
and remove the massive pile of hacks we had for that. Without any
further effort this has already unbroken the latest pytest-asyncio
version, so we can unpin it.
We still have full coverage of the bridge code on Python 3.6 via
integration testing (beiboot vs container-ws on RHEL 8) and the fact
that we're not as actively hacking on the bridge code anymore means that
any time that was once saved by getting "quick fails" from unit tests is
no longer worth the large and growing amount of effort required to keep
those tests from constantly breaking.
This implements an InteractionHandler from ferny so use the same typing
signature. Also fixes `mypy --strict` complaining about missing
parameters for generic type "Tuple".
sos 4.6.2 changed the tmp dir policy [1] from a static /var/tmp to a
dynamic per-distro policy, which happens to be /tmp on Debian/Ubuntu
right now. This is wrong, and there is no official way to query it [2].
To cope, query the sos policy for the tmp-dir, and only fall back to
static /var/tmp if that fails.
[1] https://github.com/sosreport/sos/pull/4062
[2] https://github.com/sosreport/sos/issues/4074
Tox workflow is missing py3.6 and py3.8. Py3.6 can be installed but
py3.8 is no longer available so I propose we drop it.
As per tox FAQ we need to set `requires = virtualenv<20.22.0` as never
virtualenv version dropped support for version <=py3.6.
https://tox.wiki/en/latest/faq.html#testing-end-of-life-python-versions
Storagelib is shared between projects so useful to have typed. Typing
this mixin requires extending it to MachineCase to have access to the
TestCase functions and browser/machine from MachineCase.
It conceptually fits better there, as it's shared by all external
projects. That makes importing easier as it doesn't have to be
enumerated separately in COCKPIT_REPO_FILES any more.
The Python bridge still used the separate `cockpit-pcp` bridge for
metrics gathering. For us to remove the full C bridge implementation the
separate PCP bridge also has to be rewritten.
This rewrite is a more or less Python copy of the C implementation using
the Python PCP module. Even though the Python PCP module offers a
"higher level" fetchGroup API but preliminary testing has found this has
some issues with changing multi instance values and instances can not be
omitted with a fetch group (but this can be done in our own code)
Co-Authored-By: Allison Karlitskaya <allison.karlitskaya@redhat.com>
Co-Authored-By: Tomas Matus <tomatus777@gmail.com>
You can now do something like this:
$ pytest -k test_browser --js-cov-files='*/fsinfo.ts'
and get results like this:
pkg/lib/cockpit/fsinfo.ts:33:49-33:63 json_merge
▼ from here
33 const updated = is_json_dict(current) ? { ...current } : { };
▲ to here
pkg/lib/cockpit/fsinfo.ts:36:33-38:14 json_merge
▼ from here
36 if (value === null) {
37 delete updated[key];
38 } else {
▲ to here
Since we also use the same approach for collecting data for integration
tests (Profiler.takePreciseCoverage), we could easily add support there
as well.
Unfortunately, `root=` doesn't mean what I thought it did. It does
select the files to be considered for the given overrides, but it also
adds the given directory to the search path.
Having `root="test"` is a problem because it contains a `pytest`
subdirectory, which is what pyright thinks you're talking about if you
say `import pytest`.
Ideally we'd be able to say that all code found in `test/` gets access
to testlib, without adding `test/` itself. I also tried to say that
`src/` doesn't get access to testlib but `.` does, but this resulted in
`testlib` being accessible from files in `src/` as well.
Let's just simplify this to be more like our mypy setup. Really: if
you're importing testlib from the bridge, you're gonna find out about
the problem with that pretty quickly anyway.
Let's turn on strict while we're at it. We don't actually run pyright,
but it gets more messages into the editor, which is nice.
We do this by internalizing some of the code from tap-cdp (which we
delete). The main thing blocking us from doing that before was the
synchronous interface of our CDP module, but our new webdriver_bidi has
a nice async interface for us to use.
There are a few issues with running the Qunit tests under tox, and since
there's not a lot of value in running browser-based tests in tox, just
don't. We might revisit that later, particularly if we move to having
the tests running against a python-based webserver.
We also disable running the Qunit tests during Debian package builds:
there's no qunit bundles in the tarball anyway, but just sourcing
test_browser.py requires aiohttp to be installed (which it isn't).
Doing this at the toplevel lets us drop some hacks for adding those
paths for our verify/ test cases. Plus: we'll soon be using test/common
from outside of verify/, so the logic of wanting to isolate it to that
subdirectory no longer exists.
mypy already knows about it, but for the sake of LSP users, let pyright
know about it too.
This slightly changes the API of `Browser.keys()` with modifiers. We
only use that once inside of testlib.py and twice in
check-system-terminal (and nowhere in external projects), so just adjust
the three callers.
The `Browser.get_js_log()` output format also changes slightly, to be
much more detailed. Adjust tests accordingly.
Skip `TestGrafanaClient` and `TestPages.testAllLanguages` on Chromium
for now. There is a really weird bug where Cockpit/Grafana spontaneously
logs out itself, but *only* in headless Chromium. So run the
test only on Firefox for the time being.
As penance, enable testUpload*() on Firefox, the BiDi API works fine
there. We can enable other tests on Firefox as a follow-up as well (they
need some work unrelated to BiDi though).
This removes excess right/bottom padding from two mobile pixel tests,
update them.
https://issues.redhat.com/browse/COCKPIT-1143
Pillow upstream added a `py.typed` file in their last release, which is
causing us problems because:
- we `from PIL import Image`, which kinda looks like the class `Image`
in the `PIL` module, but is actually a submodule. In particular,
`PIL.Image.open()` is not a static method, but a function call, and
it doesn't return `PIL.Image`, but rather `PIL.Image.Image`. Fix a
couple of annotations.
- our hacks for setting `Image = None` if the import is missing are no
longer working (since the import now has a better type than `Any`).
Let's make the import unconditional. `dnf install python3-pillow`.
- several methods are unannotated in the upstream code, leading to
warnings about "untyped call from typed code". We use an #ignore
for those; cf. https://github.com/python-pillow/Pillow/issues/8029
Move our list of static files out of test/static-code (which is shared
with other projects). Add testlib to that list.
This reduces the cost of running mypy on a warm cache from 20s to ~0.3s,
while expanding checking to every single Python file in the source tree.
A overall `test/static-code` run (minus `node_modules`) decreases from
~24s to ~4s. The majority of that time is now in the json validity
checking rule (since it runs a separate python invocation for each
file).
Now that we gate our ruff updates via the tasks container, we can afford
to be a bit more future-oriented here.
This brings in a nice raft of fix-ups, including my personal favourite:
RUF003 Comment contains ambiguous `µ` (MICRO SIGN). Did you mean `μ` (GREEK SMALL LETTER MU)?
Sure... why not?
The majority of fixes here are from a single rule suggesting to rewrite
a and b or c
as
(a and b) or c
But in most (but not all) cases in our code we actually want to write
that as
b if a else c
I've also added some type annotations to help me make the right choice
in places where it wasn't immediately clear.
Lacking a proper requirements.txt file, we're at the mercy of whatever
got randomly uploaded to pypy last night, and we've been seeing a lot of
breaks lately.
We already run our ruff/mypy/etc. stuff as part of our unit tests
workflow, so let's stop running it in venv. The idea is that we should
pass against the current version of the tasks container (which will
probably shift at some point to being our pinned version of the tasks
container).
While we're at it, drop Python 3.7 (which the world seems to have
collectively decided to stop caring about) and add Python 3.13 (which
has been in Fedora 39 for a while already). Note: we do *not* drop
Python 3.6 — although it is no longer an officially supported release,
it's used in RHEL 7 and RHEL 8 and Fedora intends to keep packaging it.
New ruff warns to stderr that the old way is deprecated. That's enough
to convince test/static-code that an error is being reported.
Let's move this over.