`_testing._sourcetests`: shared repo-kind tests assume the `datafiles` fixture copy is writable, which breaks when package data is installed read-only
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 74/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- python
- 領域
- testing-qa
調査の方向性
Start in buildstream/_testing/_sourcetests/utils.py at add_plugins_conf, then inspect the shared helpers used by the failing tests in build_checkout.py, fetch.py, mirror.py, track.py, and workspace.py. Reproduce with pytest-datafiles 3.x and read-only package data; done means the listed repo-kind tests pass without PermissionError when their copied trees inherit read-only permissions.
索引モデルが issue の本文から書いたものです。
説明
[!NOTE]
This report comes out of my own personal effort to packagebuildstream/
buildstream-pluginsfor nixpkgs (https://github.com/NixOS/nixpkgs/pull/510073) —
it isn't related to or filed on behalf of my employer. Root-causing this and
drafting this report was done with the assistance of an AI coding agent (Claude
Code); I've reviewed the analysis and reproduction myself and stand behind it.
Summary
The shared cross-VCS ("repo kind") test suite in buildstream/_testing/_sourcetests/
(consumed by downstream source plugins via sourcetests_collection_hook, e.g. from
buildstream-plugins) writes new files into the directory tree that pytest's
datafiles fixture (from the pytest-datafiles plugin) copies out for each test.
This assumes the copy is always writable. That assumption broke as a side effect of
an intentional, correct fix in pytest-datafiles 3.0: it now preserves the source
file/directory permission bits on copy (see omarkohl/pytest-datafiles#11, closed with
a regression test to lock in the behaviour). If the source data — i.e. buildstream's
own installed _testing/_sourcetests package data — ends up on disk without the
write bit (for example because it was installed by a package manager that makes
installed files read-only, or, as in our case, because it lives in the Nix store,
where all installed files are always mode 444/dirs 555), every copy datafiles
produces inherits that missing write bit. Any test helper that then tries to write a
new file into that copy fails with PermissionError.
This isn't Nix-specific in principle — it will reproduce in any environment where
buildstream's installed test-data files are non-writable — but Nix's packaging
convention (all store paths are always read-only) makes it 100% reproducible there.
Where we hit it
Packaging buildstream-plugins 2.8.0 for nixpkgs
(https://github.com/apache/buildstream-plugins), whose tests/conftest.py pulls in
the shared suite via:
from buildstream._testing import sourcetests_collection_hook
Running the resulting pytest suite against buildstream 2.8.1 (installed read-only, as
all Nix store paths are) produces 48 errors, all PermissionError, spread across
every parametrized [bzr]/[git] case in:
_sourcetests/build_checkout.py::test_fetch_build_checkout_sourcetests/fetch.py::test_fetch,test_fetch_cross_junction_sourcetests/mirror.py::test_mirror_fetch,test_mirror_fetch_upstream_absent,
test_mirror_from_includes,test_mirror_track_upstream_present,
test_mirror_track_upstream_absent_sourcetests/track.py::test_track,test_track_recurse,
test_track_recurse_except,test_cross_junction,test_track_include,
test_track_include_junction,test_track_junction_included_sourcetests/workspace.py::test_open
Example traceback
request = <SubRequest 'kind' for <Function test_fetch_build_checkout[bzr-strict]>>
datafiles = PosixPath('/build/source/tmp/test_fetch_build_checkout_bzr_0')
@pytest.fixture(params=ALL_REPO_KINDS.keys())
def kind(request, datafiles):
# Register plugins both on the toplevel project and on its junctions
for project_dir in [str(datafiles), os.path.join(str(datafiles), "files", "sub-project")]:
> add_plugins_conf(project_dir, request.param)
.../buildstream/_testing/_sourcetests/utils.py:49:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.../buildstream/_testing/_sourcetests/utils.py:77: in add_plugins_conf
_yaml.roundtrip_dump(project_conf, project_conf_file)
src/buildstream/_yaml.pyx:477: in buildstream._yaml.roundtrip_dump
???
.../lib/python3.14/contextlib.py:141: in __enter__
return next(self.gen)
.../buildstream/utils.py:663: in save_file_atomic
fd, tempname = tempfile.mkstemp(dir=tempdir)
.../lib/python3.14/tempfile.py:354: in mkstemp
return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dir = '/build/source/tmp/test_fetch_build_checkout_bzr_0/files/sub-project'
def _mkstemp_inner(dir, pre, suf, flags, output_type):
...
for seq in range(TMP_MAX):
name = next(names)
file = _os.path.join(dir, pre + name + suf)
_sys.audit("tempfile.mkstemp", file)
try:
> fd = _os.open(file, flags, 0o600)
E PermissionError: [Errno 13] Permission denied: '/build/source/tmp/test_fetch_build_checkout_bzr_0/files/sub-project/tmpb55t9_sb'
.../lib/python3.14/tempfile.py:255: PermissionError
The same shape of failure (write into a datafiles-provided directory that inherited
a non-writable source) recurs across all 48 failing tests listed above — they all
go through add_plugins_conf or an equivalent "write a new file into the copied
project tree" step.
Why this only shows up now
Per omarkohl/pytest-datafiles#11, prior to pytest-datafiles 3.0 the datafiles
fixture did not preserve source permission bits when copying (using py.path),
so a non-writable source always produced a writable copy — masking this bug. 3.0
switched to pathlib/shutil.copy/shutil.copytree, which preserve mode bits by
default, and that change was intentional (a regression test was added specifically
to keep permissions preserved going forward). So pytest-datafiles is behaving
exactly as intended; the bug is in the assumption made on the consuming side, inside
buildstream's own shared test helpers.
Suggested fix
In add_plugins_conf (and any other shared _sourcetests helper that writes into a
datafiles-provided path), don't assume the copy is writable — e.g. chmod the
relevant directory (or just its parent) to be owner-writable before writing into it,
rather than relying on the datafiles copy's permissions matching the installed
package data's permissions.
Environment
buildstream2.8.1buildstream-plugins2.8.0pytest-datafiles3.0.1pytest(via nixpkgs'pytestCheckHook)- Reproduced via
nixpkgs(nix-build -A python314Packages.buildstream-plugins),
where/nix/storepaths are always installed read-only (mode 444 for files, 555
for directories) — https://github.com/NixOS/nixpkgs/pull/510073
- 主要言語
- Python
- スター
- 151
- フォーク
- 49
- 平均マージ
- 3日 19時間
- マージ済み PR(30日)
- 5
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
apache/buildstream のほかの issue
-
logging
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
apache/buildstream#2150 · コメント 3 件 ·
-
question
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
apache/buildstream#2143 · コメント 2 件 · リアクション 1 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
apache/buildstream#2194 ·
-
Modification time of an element with an open workspace propagates into consumer element's sandboxオープンbug
難易度 3/5 1〜2日 初心者へのやさしさ 58/100
apache/buildstream#2186 · コメント 2 件 · リアクション 2 件 ·
-
Find replacement for ujson (ujson is in maintenance-only mode)対応中かも @jjardon が 41 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
apache/buildstream#2184 · コメント 1 件 ·
apache/buildstream の issue をすべて見る
似ている issue
-
bug llm translation
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
Arkansas 2025 tax is $1.70 high above $100,000 net taxable income ($3,809 + 3.9% rule)対応中かも @PavelMakarchuk が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
PolicyEngine/policyengine-us#9828 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
jellyfin/jellyfin-mpv-shim#800 ·
メンテナーはふだん 1 日以内に返信
-
skillfs: one malformed chat-log line aborts the entire skill-usage analysis (skill_usage_from_chat_logs.py)対応中かも @zjncs が今日担当しました。 オープンcomponent:skillfs
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
agentic-os-org/ANOLISA#6116 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
P4: low query
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
jeffknupp/association#336 ·