14
0
forked from pool/python-fuse

- Separate documentation to separate subpackage.

- Add examples subdirectory to that documentation.
- Make the test suite running.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-fuse?expand=0&rev=24
This commit is contained in:
2025-03-17 10:20:32 +00:00
committed by Git OBS Bridge
parent 8b6c96943e
commit 972dad1d65
5 changed files with 119 additions and 5 deletions

4
_multibuild Normal file
View File

@@ -0,0 +1,4 @@
<multibuild>
<package>test</package>
<package>primary</package>
</multibuild>

3
pytest.ini Normal file
View File

@@ -0,0 +1,3 @@
[pytest]
markers =
fstype: Type of filesystem to mount

View File

@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Mon Mar 17 10:20:11 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Separate documentation to separate subpackage.
- Add examples subdirectory to that documentation.
- Make the test suite running.
-------------------------------------------------------------------
Wed Sep 4 08:16:03 UTC 2024 - Frantisek Simorda <frantisek.simorda@suse.com>

View File

@@ -1,7 +1,7 @@
#
# spec file for package python-fuse
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,17 +17,32 @@
%{?sle15_python_module_pythons}
Name: python-fuse
%global flavor @BUILD_FLAVOR@%{nil}
%if "%{flavor}" == "test"
%define psuffix -test
%bcond_without test
%else
%define psuffix %{nil}
%bcond_with test
%endif
Name: python-fuse%{psuffix}
Version: 1.0.8
Release: 0
Summary: Python bindings for FUSE
License: LGPL-2.1-only
URL: https://github.com/libfuse/python-fuse
Source: https://github.com/libfuse/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
Source0: https://github.com/libfuse/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
# From https://raw.githubusercontent.com/libfuse/python-fuse/refs/tags/v%{version}/tests/test_basic.py
Source1: test_basic.py
Source2: pytest.ini
BuildRequires: %{python_module devel}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module wheel}
%if %{with test}
BuildRequires: %{python_module fuse = %{version}}
BuildRequires: %{python_module pytest}
%endif
BuildRequires: fdupes
BuildRequires: fuse-devel
BuildRequires: pkgconfig
@@ -37,26 +52,45 @@ BuildRequires: python-rpm-macros
%description
Python bindings for FUSE (User space File System)
%package -n %{name}-doc
Summary: Documentation files for %name
Group: Documentation/Other
%description -n %{name}-doc
HTML Documentation and examples for %name.
%prep
%autosetup -p1
install -p -D -t tests/ %{SOURCE1}
install -p %{SOURCE2} .
%build
%if %{without test}
export CFLAGS="%{optflags}"
%pyproject_wheel
%endif
%install
%if %{without test}
%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitearch}
%endif
%check
# Can not figured how to do it.
%if %{with test}
%pytest tests
%endif
%if %{without test}
%files %{python_files}
%license COPYING
%doc README.* FAQ AUTHORS
%{python_sitearch}/fuse.py
%pycache_only %{python_sitearch}/__pycache__/fuse*.py*
%{python_sitearch}/fuseparts
%{python_sitearch}/fuse_python-%{version}.dist-info
%files -n %{name}-doc
%doc README.* FAQ AUTHORS example
%endif
%changelog

66
test_basic.py Normal file
View File

@@ -0,0 +1,66 @@
import os
import time
import sys
import struct
import subprocess
import pathlib
import tempfile
import pytest
import fcntl
topdir = pathlib.Path(__file__).parent.parent
@pytest.fixture
def filesystem(request):
fstype = request.node.get_closest_marker("fstype").args[0]
with tempfile.TemporaryDirectory() as tmpdir:
st_dev = os.stat(tmpdir).st_dev
proc = subprocess.Popen([sys.executable, "-d", topdir / "example" / f"{fstype}.py", tmpdir], stdin=subprocess.DEVNULL)
deadline = time.time() + 1
while time.time() < deadline:
new_st_dev = os.stat(tmpdir).st_dev
if new_st_dev != st_dev:
break
time.sleep(.01)
if new_st_dev == st_dev:
proc.terminate()
raise RuntimeError("Filesystem did not mount within 1s")
yield pathlib.Path(tmpdir)
subprocess.call(["fusermount", "-u", "-q", "-z", tmpdir])
deadline = time.time() + 1
while time.time() < deadline:
result = proc.poll()
if result is not None:
if result != 0:
raise RuntimeError("Filesystem exited with an error: {result}")
return
time.sleep(.01)
proc.terminate()
raise RuntimeError("Filesystem failed to exit within 1s after unmount")
@pytest.mark.fstype("hello")
def test_hello(filesystem):
content = (filesystem / "hello").read_text(encoding="utf-8")
assert content == "Hello World!\n"
@pytest.mark.fstype("fioc")
def test_fioc(filesystem):
FIOC_GET_SIZE, FIOC_SET_SIZE = 0x80084500, 0x40084501
with (filesystem / "fioc").open("rb") as f:
b = struct.pack("L", 42)
fcntl.ioctl(f.fileno(), FIOC_SET_SIZE, b)
b = bytearray(struct.calcsize('l'))
fcntl.ioctl(f.fileno(), FIOC_GET_SIZE, b)
assert struct.unpack("L", b)[0] == 42
@pytest.mark.fstype("xattr")
def test_xattr(filesystem):
assert os.getxattr(filesystem / "utf8_attr", "user.xdg.comment").decode("utf-8") == 'ああ、メッセージは切り取られていない'