Raphaël Gomès <rgomes@octobus.net> [Tue, 05 Nov 2024 15:21:09 +0100] rev 52156
rust-update: make `update_from_null` respect `worker.numcpu` config option
This was overlooked in the original series.
This is important for tests (because we run many at once), and for the
occasional end user that wants to keep their CPU usage in check.
A future series should clean up this `worker` parameter tunelling business by
rewriting the config in Rust, but doing so on stable would be a very bad
idea.
Raphaël Gomès <rgomes@octobus.net> [Tue, 05 Nov 2024 15:18:32 +0100] rev 52155
rust-cpython: add a TODO about repo reuse
This will need to be done soon-ish to prevent any surprises.
Matt Harbison <matt_harbison@yahoo.com> [Mon, 04 Nov 2024 16:43:05 -0500] rev 52154
streamclone: disable the volatile file open handle optimization on Windows
Leaving files open caused new failures like this, since a47f09da8bd1:
diff --git a/tests/test-persistent-nodemap-stream-clone.t b/tests/test-persistent-nodemap-stream-clone.t
--- a/tests/test-persistent-nodemap-stream-clone.t
+++ b/tests/test-persistent-nodemap-stream-clone.t
@@ -115,7 +115,12 @@ Do a mix of clone and commit at the same
$ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | grep -E '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
$ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
$ hg -R test-repo/ commit -m foo
- created new head
+ transaction abort!
+ failed to recover 00changelog.n ([WinError 32] The process cannot access the file because it is being used by another process: b'$STR_REPR_TESTTMP\\test-repo/.hg/store/00changelog.n' -> b'$STR_REPR_TESTTMP\\test-repo/.hg/store/00changelog.n-f418dcd6')
+ rollback failed - please run hg recover
+ (failure reason: [WinError 32] The process cannot access the file because it is being used by another process: b'$STR_REPR_TESTTMP\\test-repo/.hg/store/00changelog.n' -> b'$STR_REPR_TESTTMP\\test-repo/.hg/store/00changelog.n-f418dcd6')
+ abort: The process cannot access the file because it is being used by another process: '$TESTTMP\test-repo\.hg\store\00changelog.n'
+ [255]
$ touch $HG_TEST_STREAM_WALKED_FILE_2
$ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
$ cat clone-output
Since the `VolatileManager` falls back to the old copy method when the open file
threshold is exceeded, this just drops the threshold so that only 1 file is
open. The actual value used (2) is unexpected, and explained inline. I'd like
to have a config option for this so that we can test both ways (in theory, it
could resort to copies on non-Windows systems too), but I don't see a `uimod.ui`
handy.
Alternately, I tried replacing the 3 `open()` calls in the `VolatileManager`
with `util.posixfile()`, but that simply hung the test on Windows for some
reason, I think on the same line that's indicated as failing above. (There was
a `grep` command hanging around, as well as `hg -R test-repo serve --stdio`.)
Matt Harbison <matt_harbison@yahoo.com> [Mon, 04 Nov 2024 17:42:30 -0500] rev 52153
tests: treat `select` as a built-in module on Windows
This fixes:
--- C:/Users/Matt/hg/tests/test-check-module-imports.t
+++ C:/Users/Matt/hg/tests/test-check-module-imports.t.err
@@ -43,3 +43,15 @@
> -X tests/test-verify-repo-operations.py \
> -X tests/test-extension.t \
> | sed 's-\\-/-g' | "$PYTHON" "$import_checker" -
+ hgext/zeroconf/Zeroconf.py:86: stdlib import "socket" follows local import: select\r (esc)
+ hgext/zeroconf/Zeroconf.py:87: stdlib import "struct" follows local import: select\r (esc)
+ hgext/zeroconf/Zeroconf.py:88: stdlib import "threading" follows local import: select\r (esc)
+ hgext/zeroconf/Zeroconf.py:89: stdlib import "time" follows local import: select\r (esc)
+ hgext/zeroconf/Zeroconf.py:90: stdlib import "traceback" follows local import: select\r (esc)
+ mercurial/posix.py:18: stdlib import "stat" follows local import: select\r (esc)
+ mercurial/posix.py:19: stdlib import "sys" follows local import: select\r (esc)
+ mercurial/posix.py:20: stdlib import "tempfile" follows local import: select\r (esc)
+ mercurial/posix.py:21: stdlib import "typing" follows local import: select\r (esc)
+ tests/tinyproxy.py:19: stdlib import "socket" follows local import: select\r (esc)
+ tests/tinyproxy.py:20: stdlib import "sys" follows local import: select\r (esc)
+ [1]
ERROR: test-check-module-imports.t output changed
Matt Harbison <matt_harbison@yahoo.com> [Thu, 31 Oct 2024 17:24:18 -0400] rev 52152
hgweb: skip logging ConnectionAbortedError
Not stacktracing on `ConnectionResetError` was added in 6bbb12cba5a8 (though it
was spelled differently for py2 support), but for some reason Windows
occasionally triggers a `ConnectionAbortedError` here across various *.t files
(notably `test-archive.t` and `test-lfs-serve-access.t`, but there are others).
The payload that fails to send seems to be the html that describes the error to
the client, so I suspect some code is seeing the error status code and closing
the connection before the server gets to write this html. So don't log it, for
test stability- nothing we can do anyway.
FWIW, the CPython implementation of wsgihander specifically ignores these two
errors, plus `BrokenPipeError`, with a comment that "we expect the client to
close the connection abruptly from time to time"[1]. The `BrokenPipeError` is
swallowed a level up in `do_write()`, and avoids writing the response following
this stacktrace. I'm puzzled why a response is being written after these
connection errors are detected- the CPython code referenced doesn't, and the
connection is now broken at this point. Perhaps these errors should both be
handled with the `BrokenPipeError` after the freeze.
(The refactoring away from py2 compat may not be desireable in the freeze, but
this is much easier to read, and obviously correct given the referenced CPython
code.)
I suspect this is what 6bceecb28806 was attempting to fix, but it wasn't
specific about the sporadic errors it was seeing.
[1] https://github.com/python/cpython/blob/b2eaa75b176e07730215d76d8dce4d63fb493391/Lib/wsgiref/handlers.py#L139
Matt Harbison <matt_harbison@yahoo.com> [Fri, 25 Oct 2024 17:15:53 -0400] rev 52151
ci: add a runner for Windows 10
This is currently only manually invoked, and allows for failure because we only
have a single runner that takes over 2h for a full run, and there are a handful
of flakey tests, plus 3 known failing tests.
The system being used here is running MSYS, Python, Visual Studio, etc, as
installed by `install-windows-dependencies.ps1`. This script installs
everything to a specific directory instead of using the defaults, so we adjust
the MinGW shell path to compensate. Additionally, the script doesn't install
the launcher `py.exe`. It is possible to adjust the script to install it, but
it's an option to an existing python install (instead of a standalone installer),
and I've had the whole python install fail and rollback when requested to install
the launcher if it detects a newer one is already installed. In short, it is
a point of failure for a feature we don't (yet?) need.
Unlike other systems where the intepreter name includes the version, everything
here is `python.exe`, so they can't all exist on `PATH` and let the script
choose the desired one. (The `py.exe` launcher would accomplish, using the
registry instead of `PATH`, but that wouldn't allow for venv installs.) Because
of this, switch to the absolute path of the python interpreter to be used (in
this case a venv created from the py39 install, which is old, but what both
pyoxidizer and TortoiseHg currently use).
The `RUNTEST_ARGS` hardcodes `-j8` because this system has 4 cores, and
therefore runs 4 parallel tests by default. However on Windows, using more
parallel tests than cores results in better performance for whatever reason. I
don't have an optimal value yet (ideally the runner itself can make the
adjustment on Windows), but this results in saving ~15m on a full run that
otherwise takes ~2.5h. I'm also not concerned about how it would affect other
Windows machines, because we don't have any at this point, and I have no idea
when we can get more.
As far as system setup goes, the CI is run by a dedicated user that lacks admin
rights. The install script was run by an admin user, and then the standard user
was configured to use it. If I set this up again, I'd probably give the
dedicated user admin rights to run the install script, and reset to standard
user rights when done. The python intepreter failed in weird ways when run by
the standard user until it was manually reinstalled by the standard user:
Fatal Python error: init_fs_encoding: failed to get the Python codec of the
filesystem encoding
Additionally, changing the environment through the Windows UI prompts to
escalate to an admin user, and then setting the user level environment variables
like `TEMP` and `PATH` (to try to avoid exceeding the 260 character path limit)
didn't actually change the user's environment. (Likely it changed the admin
user's environment, but I didn't confirm that.) I ended up having to use the
registry editor for the standard user to make those changes.