Files
MusicFS/tests/test_error_handling.py
T
Alexander 81df4790bf Add e2e test suite for beetfs
Tests use real FUSE operations against mounted beetfs filesystem:
- test_smoke: mount/unmount lifecycle
- test_nested_bug: detects critical indentation bug (13 failures)
- test_readdir: directory listing
- test_read: metadata overlay verification
- test_stat: file/directory attributes
- test_write: metadata modification
- test_error_handling: ENOENT, EOPNOTSUPP

Also includes:
- conftest.py with BeetFSTestCase base class and synthetic FLAC generator
- e2e-test-plan.md with Oracle-reviewed test strategy
- flake.nix updated with ffmpeg/flac for test fixtures

Run: cd tests && nix develop ../ --command python -m unittest discover
2026-05-12 14:02:55 +02:00

162 lines
5.0 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import errno
import os
import unittest
from conftest import BeetFSTestCase
class TestENOENT(BeetFSTestCase):
def test_stat_nonexistent_file(self):
self.mount_beetfs()
nonexistent = os.path.join(self.mount_dir, 'does_not_exist.flac')
with self.assertRaises(OSError) as ctx:
os.stat(nonexistent)
self.assertEqual(ctx.exception.errno, errno.ENOENT)
def test_open_nonexistent_file(self):
self.mount_beetfs()
nonexistent = os.path.join(self.mount_dir, 'does_not_exist.flac')
with self.assertRaises(IOError) as ctx:
open(nonexistent, 'rb')
self.assertEqual(ctx.exception.errno, errno.ENOENT)
def test_listdir_nonexistent_directory(self):
self.mount_beetfs()
nonexistent = os.path.join(self.mount_dir, 'Nonexistent Artist')
with self.assertRaises(OSError) as ctx:
os.listdir(nonexistent)
self.assertEqual(ctx.exception.errno, errno.ENOENT)
def test_stat_deeply_nested_nonexistent(self):
self.mount_beetfs()
nonexistent = os.path.join(
self.mount_dir, 'Artist', 'Album', 'Track', 'Nested', 'Path'
)
with self.assertRaises(OSError) as ctx:
os.stat(nonexistent)
self.assertEqual(ctx.exception.errno, errno.ENOENT)
class TestEOPNOTSUPP(BeetFSTestCase):
def test_mkdir_not_supported(self):
self.mount_beetfs()
new_dir = os.path.join(self.mount_dir, 'new_directory')
with self.assertRaises(OSError) as ctx:
os.mkdir(new_dir)
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS])
def test_unlink_not_supported(self):
self.add_test_track(filename='delete_test.flac')
self.mount_beetfs()
tracks = self._find_any_track()
if not tracks:
self.skipTest("No tracks found")
with self.assertRaises(OSError) as ctx:
os.unlink(tracks[0])
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS])
def test_rmdir_not_supported(self):
self.add_test_track(filename='rmdir_test.flac', artist='Rmdir Artist')
self.mount_beetfs()
artist_dir = os.path.join(self.mount_dir, 'Rmdir Artist')
if not os.path.isdir(artist_dir):
self.skipTest("Artist directory not found")
with self.assertRaises(OSError) as ctx:
os.rmdir(artist_dir)
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS, errno.ENOTEMPTY])
def test_rename_not_supported(self):
self.add_test_track(filename='rename_test.flac')
self.mount_beetfs()
tracks = self._find_any_track()
if not tracks:
self.skipTest("No tracks found")
new_path = tracks[0] + '.renamed'
with self.assertRaises(OSError) as ctx:
os.rename(tracks[0], new_path)
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS])
def test_symlink_not_supported(self):
self.mount_beetfs()
link_path = os.path.join(self.mount_dir, 'test_link')
with self.assertRaises(OSError) as ctx:
os.symlink('/tmp', link_path)
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS])
def test_chmod_not_supported(self):
self.add_test_track(filename='chmod_test.flac')
self.mount_beetfs()
tracks = self._find_any_track()
if not tracks:
self.skipTest("No tracks found")
with self.assertRaises(OSError) as ctx:
os.chmod(tracks[0], 0o777)
self.assertIn(ctx.exception.errno, [errno.EOPNOTSUPP, errno.EACCES, errno.EROFS])
def _find_any_track(self):
results = []
for root, dirs, files in os.walk(self.mount_dir):
for f in files:
if f.endswith('.flac'):
results.append(os.path.join(root, f))
return results
class TestEdgeCaseErrors(BeetFSTestCase):
def test_access_empty_path(self):
self.mount_beetfs()
with self.assertRaises((OSError, IOError)):
os.stat(os.path.join(self.mount_dir, ''))
def test_open_directory_as_file(self):
self.add_test_track(filename='test.flac', artist='Dir Artist')
self.mount_beetfs()
artist_dir = os.path.join(self.mount_dir, 'Dir Artist')
if os.path.isdir(artist_dir):
with self.assertRaises((OSError, IOError)):
with open(artist_dir, 'rb') as f:
f.read()
if __name__ == '__main__':
unittest.main()