Skip to content

Commit

Permalink
test the virtualfs
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Oct 11, 2023
1 parent f8c5fe7 commit 940b265
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 61 deletions.
71 changes: 68 additions & 3 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def isolated_dir() -> Iterator[Path]:
def config(isolated_dir: Path) -> Config:
cache_dir = isolated_dir / "cache"
cache_dir.mkdir()
cache_database_path = cache_dir / "cache.sqlite3"

cache_database_path = cache_dir / "cache.sqlite3"
with sqlite3.connect(cache_database_path) as conn:
with SCHEMA_PATH.open("r") as fp:
conn.executescript(fp.read())
Expand All @@ -33,14 +33,79 @@ def config(isolated_dir: Path) -> Config:
latest_schema_hash = hashlib.sha256(fp.read()).hexdigest()
conn.execute("INSERT INTO _schema_hash (value) VALUES (?)", (latest_schema_hash,))

music_source_dir = isolated_dir / "source"
music_source_dir.mkdir()

mount_dir = isolated_dir / "mount"
mount_dir.mkdir()

return Config(
music_source_dir=isolated_dir / "source",
fuse_mount_dir=isolated_dir / "mount",
music_source_dir=music_source_dir,
fuse_mount_dir=mount_dir,
cache_dir=cache_dir,
cache_database_path=cache_database_path,
)


@pytest.fixture()
def seeded_cache(config: Config) -> Iterator[None]:
dirpaths = [
config.music_source_dir / "r1",
config.music_source_dir / "r2",
]
filepaths = [
config.music_source_dir / "r1" / "01.m4a",
config.music_source_dir / "r1" / "02.m4a",
config.music_source_dir / "r2" / "01.m4a",
]

with sqlite3.connect(config.cache_database_path) as conn:
conn.executescript(
f"""\
INSERT INTO releases (id, source_path, virtual_dirname, title, release_type, release_year, new)
VALUES ('r1', '{dirpaths[0]}', 'r1', 'Release 1', 'album', 2023, true)
, ('r2', '{dirpaths[1]}', 'r2', 'Release 2', 'album', 2021, false);
INSERT INTO releases_genres (release_id, genre, genre_sanitized)
VALUES ('r1', 'Techno', 'Techno')
, ('r1', 'Deep House', 'Deep House')
, ('r2', 'Classical', 'Classical');
INSERT INTO releases_labels (release_id, label, label_sanitized)
VALUES ('r1', 'Silk Music', 'Silk Music')
, ('r2', 'Native State', 'Native State');
INSERT INTO tracks
(id, source_path, virtual_filename, title, release_id, track_number, disc_number, duration_seconds)
VALUES ('t1', '{filepaths[0]}', '01.m4a', 'Track 1', 'r1', '01', '01', 120)
, ('t2', '{filepaths[1]}', '02.m4a', 'Track 2', 'r1', '02', '01', 240)
, ('t3', '{filepaths[2]}', '01.m4a', 'Track 1', 'r2', '01', '01', 120);
INSERT INTO releases_artists (release_id, artist, artist_sanitized, role)
VALUES ('r1', 'Techno Man', 'Techno Man', 'main')
, ('r1', 'Bass Man', 'Bass Man', 'main')
, ('r2', 'Violin Woman', 'Violin Woman', 'main')
, ('r2', 'Conductor Woman', 'Conductor Woman', 'guest');
INSERT INTO tracks_artists (track_id, artist, artist_sanitized, role)
VALUES ('t1', 'Techno Man', 'Techno Man', 'main')
, ('t1', 'Bass Man', 'Bass Man', 'main')
, ('t2', 'Techno Man', 'Techno Man', 'main')
, ('t2', 'Bass Man', 'Bass Man', 'main')
, ('t3', 'Violin Woman', 'Violin Woman', 'main')
, ('t3', 'Conductor Woman', 'Conductor Woman', 'guest');
"""
)

for d in dirpaths:
d.mkdir()
for f in filepaths:
f.touch()

yield
return None


def freeze_database_time(conn: sqlite3.Connection) -> None:
"""
This function freezes the CURRENT_TIMESTAMP function in SQLite3 to
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ explicit_package_bases = true
module = "fuse"
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = "pytest_cov.embed"
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = "setuptools"
ignore_missing_imports = true

Expand Down
77 changes: 19 additions & 58 deletions rose/cache/read_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pathlib import Path

from rose.cache.database import connect
import pytest

from rose.cache.dataclasses import CachedArtist, CachedRelease, CachedTrack
from rose.cache.read import (
artist_exists,
Expand All @@ -17,53 +18,13 @@
from rose.foundation.conf import Config


def seed_data(c: Config) -> None:
with connect(c) as conn:
conn.executescript(
"""\
INSERT INTO releases (id, source_path, virtual_dirname, title, release_type, release_year, new)
VALUES ('r1', '/tmp/r1', 'r1', 'Release 1', 'album', 2023, true)
, ('r2', '/tmp/r2', 'r2', 'Release 2', 'album', 2021, false);
INSERT INTO releases_genres (release_id, genre, genre_sanitized)
VALUES ('r1', 'Techno', 'Techno')
, ('r1', 'Deep House', 'Deep House')
, ('r2', 'Classical', 'Classical');
INSERT INTO releases_labels (release_id, label, label_sanitized)
VALUES ('r1', 'Silk Music', 'Silk Music')
, ('r2', 'Native State', 'Native State');
INSERT INTO tracks
(id, source_path, virtual_filename, title, release_id, track_number, disc_number, duration_seconds)
VALUES ('t1', '/tmp/r1/01.m4a', '01.m4a', 'Track 1', 'r1', '01', '01', 120)
, ('t2', '/tmp/r1/02.m4a', '02.m4a', 'Track 2', 'r1', '02', '01', 240)
, ('t3', '/tmp/r2/01.m4a', '01.m4a', 'Track 1', 'r2', '01', '01', 120);
INSERT INTO releases_artists (release_id, artist, artist_sanitized, role)
VALUES ('r1', 'Techno Man', 'Techno Man', 'main')
, ('r1', 'Bass Man', 'Bass Man', 'main')
, ('r2', 'Violin Woman', 'Violin Woman', 'main')
, ('r2', 'Conductor Woman', 'Conductor Woman', 'guest');
INSERT INTO tracks_artists (track_id, artist, artist_sanitized, role)
VALUES ('t1', 'Techno Man', 'Techno Man', 'main')
, ('t1', 'Bass Man', 'Bass Man', 'main')
, ('t2', 'Techno Man', 'Techno Man', 'main')
, ('t2', 'Bass Man', 'Bass Man', 'main')
, ('t3', 'Violin Woman', 'Violin Woman', 'main')
, ('t3', 'Conductor Woman', 'Conductor Woman', 'guest');
"""
)


@pytest.mark.usefixtures("seeded_cache")
def test_list_releases(config: Config) -> None:
seed_data(config)
albums = list(list_releases(config))
assert albums == [
CachedRelease(
id="r1",
source_path=Path("/tmp/r1"),
source_path=Path(config.music_source_dir / "r1"),
virtual_dirname="r1",
title="Release 1",
release_type="album",
Expand All @@ -78,7 +39,7 @@ def test_list_releases(config: Config) -> None:
),
CachedRelease(
id="r2",
source_path=Path("/tmp/r2"),
source_path=Path(config.music_source_dir / "r2"),
virtual_dirname="r2",
title="Release 2",
release_type="album",
Expand All @@ -96,7 +57,7 @@ def test_list_releases(config: Config) -> None:
assert list(list_releases(config, sanitized_artist_filter="Techno Man")) == [
CachedRelease(
id="r1",
source_path=Path("/tmp/r1"),
source_path=Path(config.music_source_dir / "r1"),
virtual_dirname="r1",
title="Release 1",
release_type="album",
Expand All @@ -114,7 +75,7 @@ def test_list_releases(config: Config) -> None:
assert list(list_releases(config, sanitized_genre_filter="Techno")) == [
CachedRelease(
id="r1",
source_path=Path("/tmp/r1"),
source_path=Path(config.music_source_dir / "r1"),
virtual_dirname="r1",
title="Release 1",
release_type="album",
Expand All @@ -132,7 +93,7 @@ def test_list_releases(config: Config) -> None:
assert list(list_releases(config, sanitized_label_filter="Silk Music")) == [
CachedRelease(
id="r1",
source_path=Path("/tmp/r1"),
source_path=Path(config.music_source_dir / "r1"),
virtual_dirname="r1",
title="Release 1",
release_type="album",
Expand All @@ -148,13 +109,13 @@ def test_list_releases(config: Config) -> None:
]


@pytest.mark.usefixtures("seeded_cache")
def test_list_tracks(config: Config) -> None:
seed_data(config)
tracks = list(list_tracks(config, "r1"))
assert tracks == [
CachedTrack(
id="t1",
source_path=Path("/tmp/r1/01.m4a"),
source_path=Path(config.music_source_dir / "r1" / "01.m4a"),
virtual_filename="01.m4a",
title="Track 1",
release_id="r1",
Expand All @@ -168,7 +129,7 @@ def test_list_tracks(config: Config) -> None:
),
CachedTrack(
id="t2",
source_path=Path("/tmp/r1/02.m4a"),
source_path=Path(config.music_source_dir / "r1" / "02.m4a"),
virtual_filename="02.m4a",
title="Track 2",
release_id="r1",
Expand All @@ -183,50 +144,50 @@ def test_list_tracks(config: Config) -> None:
]


@pytest.mark.usefixtures("seeded_cache")
def test_list_artists(config: Config) -> None:
seed_data(config)
artists = list(list_artists(config))
assert set(artists) == {"Techno Man", "Bass Man", "Violin Woman", "Conductor Woman"}


@pytest.mark.usefixtures("seeded_cache")
def test_list_genres(config: Config) -> None:
seed_data(config)
genres = list(list_genres(config))
assert set(genres) == {"Techno", "Deep House", "Classical"}


@pytest.mark.usefixtures("seeded_cache")
def test_list_labels(config: Config) -> None:
seed_data(config)
labels = list(list_labels(config))
assert set(labels) == {"Silk Music", "Native State"}


@pytest.mark.usefixtures("seeded_cache")
def test_release_exists(config: Config) -> None:
seed_data(config)
assert release_exists(config, "r1")
assert not release_exists(config, "lalala")


@pytest.mark.usefixtures("seeded_cache")
def test_track_exists(config: Config) -> None:
seed_data(config)
assert track_exists(config, "r1", "01.m4a")
assert not track_exists(config, "lalala", "lalala")
assert not track_exists(config, "r1", "lalala")


@pytest.mark.usefixtures("seeded_cache")
def test_artist_exists(config: Config) -> None:
seed_data(config)
assert artist_exists(config, "Bass Man")
assert not artist_exists(config, "lalala")


@pytest.mark.usefixtures("seeded_cache")
def test_genre_exists(config: Config) -> None:
seed_data(config)
assert genre_exists(config, "Deep House")
assert not genre_exists(config, "lalala")


@pytest.mark.usefixtures("seeded_cache")
def test_label_exists(config: Config) -> None:
seed_data(config)
assert label_exists(config, "Silk Music")
assert not label_exists(config, "Cotton Music")
69 changes: 69 additions & 0 deletions rose/virtualfs/__test__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import time
from contextlib import contextmanager
from multiprocessing import Process
from pathlib import Path
from typing import Iterator

import pytest

from rose.foundation.conf import Config
from rose.virtualfs import mount_virtualfs, unmount_virtualfs


@contextmanager
def startfs(c: Config) -> Iterator[None]:
p = Process(target=mount_virtualfs, args=[c, ["-f"]])
try:
p.start()
time.sleep(0.1)
yield
unmount_virtualfs(c)
p.join(timeout=1)
finally:
if p.exitcode is None: # pragma: no cover
p.terminate()


@pytest.mark.usefixtures("seeded_cache")
def test_virtual_filesystem(config: Config) -> None:
def can_read(p: Path) -> bool:
with p.open("rb") as fp:
return fp.read(256) != b"\x00" * 256

with startfs(config):
root = config.fuse_mount_dir
assert (root / "albums").is_dir()
assert (root / "albums" / "r1").is_dir()
assert not (root / "albums" / "lalala").exists()
assert (root / "albums" / "r1" / "01.m4a").is_file()
assert not (root / "albums" / "r1" / "lala.m4a").exists()
assert can_read(root / "albums" / "r1" / "01.m4a")

assert (root / "artists").is_dir()
assert (root / "artists" / "Bass Man").is_dir()
assert not (root / "artists" / "lalala").exists()
assert (root / "artists" / "Bass Man" / "r1").is_dir()
assert not (root / "artists" / "Bass Man" / "lalala").exists()
assert (root / "artists" / "Bass Man" / "r1" / "01.m4a").is_file()
assert not (root / "artists" / "Bass Man" / "r1" / "lalala.m4a").exists()
assert can_read(root / "artists" / "Bass Man" / "r1" / "01.m4a")

assert (root / "genres").is_dir()
assert (root / "genres" / "Techno").is_dir()
assert not (root / "genres" / "lalala").exists()
assert (root / "genres" / "Techno" / "r1").is_dir()
assert not (root / "genres" / "Techno" / "lalala").exists()
assert (root / "genres" / "Techno" / "r1" / "01.m4a").is_file()
assert not (root / "genres" / "Techno" / "r1" / "lalala.m4a").exists()
assert can_read(root / "genres" / "Techno" / "r1" / "01.m4a")

assert (root / "labels").is_dir()
assert (root / "labels" / "Silk Music").is_dir()
assert not (root / "labels" / "lalala").exists()
assert (root / "labels" / "Silk Music" / "r1").is_dir()
assert not (root / "labels" / "Silk Music" / "lalala").exists()
assert (root / "labels" / "Silk Music" / "r1" / "01.m4a").is_file()
assert not (root / "labels" / "Silk Music" / "r1" / "lalala").exists()
assert can_read(root / "labels" / "Silk Music" / "r1" / "01.m4a")

assert not (root / "lalala").exists()

0 comments on commit 940b265

Please sign in to comment.