Skip to content

Commit c8f643d

Browse files
committed
tests: add more cache tests
1 parent 02abdbf commit c8f643d

File tree

4 files changed

+102
-7
lines changed

4 files changed

+102
-7
lines changed

pins/boards.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,10 @@ def pin_meta(self, name, version=None):
586586
# special case where we are using http protocol to fetch what may be
587587
# a file. here we need to create a stripped down form of metadata, since
588588
# a metadata file does not exist (and we can't pull files from a version dir).
589-
if self.fs.protocol == "http" and not pin_name.rstrip().endswith("/"):
589+
path_to_pin = self.construct_path([pin_name])
590+
if self.fs.protocol == "http" and not path_to_pin.rstrip().endswith("/"):
590591
# create metadata, rather than read from a file
591-
path_download = self.construct_path([pin_name])
592-
593-
return self.meta_factory.create_raw(path_download, type="file",)
592+
return self.meta_factory.create_raw(path_to_pin, type="file",)
594593

595594
path_meta = self.construct_path([pin_name, meta_name])
596595
f = self.fs.open(path_meta)
@@ -613,6 +612,12 @@ def construct_path(self, elements):
613612
if self.board.strip() == "":
614613
return pin_path
615614

615+
if len(others):
616+
# this is confusing, but R pins url board has a final "/" indicate that
617+
# something is a pin version, rather than a single file. but since other
618+
# boards forbid a final /, we need to strip it off to join elements
619+
pin_path = pin_path.rstrip().rstrip("/")
620+
616621
return super().construct_path([pin_path, *others])
617622

618623

pins/tests/test_boards.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import pytest
2-
import pandas as pd
1+
import fsspec
32
import uuid
3+
import pandas as pd
4+
import pytest
45

56
from pins.tests.helpers import DEFAULT_CREATION_DATE
67
from pins.errors import PinsError
@@ -290,3 +291,53 @@ def test_board_pin_search_admin_user(df, fs_short, fs_admin): # noqa
290291
assert search_res2.shape == (1, 2)
291292
assert search_res2.loc[0, "name"] == "susan/some_df"
292293
assert search_res2.loc[0, "meta"] is None
294+
295+
296+
# Manual Board Specific =======================================================
297+
298+
from pins.boards import BoardManual # noqa
299+
300+
301+
def test_board_manual_http_file_download():
302+
# TODO: change when repo is moved to RStudio
303+
304+
path = "https://raw.githubusercontent.com/machow/pins-python"
305+
license_path = "main/LICENSE"
306+
307+
# use a simple cache, which automatically creates a temporary directory
308+
fs = fsspec.filesystem(
309+
"simplecache", target_protocol="http", target_options={"block_size": 0}
310+
)
311+
312+
# with path ----
313+
board = BoardManual(path, fs, pin_paths={"license": "main/LICENSE"})
314+
315+
assert board.pin_list() == ["license"]
316+
# TODO: better assert
317+
assert len(board.pin_download("license"))
318+
319+
# no base path ----
320+
board2 = BoardManual("", fs, pin_paths={"license": f"{path}/{license_path}"})
321+
322+
assert board2.pin_list() == ["license"]
323+
# TODO better assert
324+
assert len(board2.pin_download("license"))
325+
326+
327+
def test_board_manual_pin_read():
328+
# TODO: block size must be set to 0 to handle gzip encoding from github
329+
# see https://github.com/fsspec/filesystem_spec/issues/389
330+
fs = fsspec.filesystem("http", block_size=0)
331+
board = BoardManual(
332+
"https://raw.githubusercontent.com/machow/pins-python/main/pins/tests/pins-compat",
333+
fs,
334+
pin_paths={
335+
"df_csv": "df_csv/20220214T163718Z-eceac/",
336+
"df_csv2_v2": "df_csv/20220214T163720Z-9bfad/",
337+
},
338+
)
339+
340+
df = board.pin_read("df_csv")
341+
342+
# do a somewhat data-framey check
343+
assert df.shape[0] > 1

pins/tests/test_cache.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,18 @@
22
import shutil
33

44
import pytest
5-
from pins.cache import CachePruner, touch_access_time, cache_prune
5+
from pins.cache import (
6+
CachePruner,
7+
touch_access_time,
8+
cache_prune,
9+
PinsCache,
10+
PinsUrlCache,
11+
)
12+
13+
from fsspec import filesystem
14+
15+
16+
# Utilities ===================================================================
617

718

819
@pytest.fixture
@@ -31,6 +42,31 @@ def test_touch_access_time_auto(some_file):
3142
assert orig_access < new_time
3243

3344

45+
# Cache Classes ===============================================================
46+
47+
# Boards w/ default cache =====================================================
48+
49+
50+
def test_pins_cache_hash_name_preserves():
51+
cache = PinsCache(fs=filesystem("file"))
52+
assert cache.hash_name("a/b/c.txt", True) == "a/b/c.txt"
53+
54+
55+
def test_pins_cache_url_hash_name():
56+
cache = PinsUrlCache(fs=filesystem("file"))
57+
hashed = cache.hash_name("http://example.com/a.txt", True)
58+
59+
# should have form <url_hash>/<version_placeholder>/<filename>
60+
assert hashed.endswith("/a.txt")
61+
assert hashed.count("/") == 2
62+
63+
64+
@pytest.mark.skip("TODO")
65+
def test_pins_cache_open():
66+
# check that opening works and creates the cached file
67+
pass
68+
69+
3470
# Cache pruning ===============================================================
3571

3672

pins/tests/test_constructors.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ def check_dir_writable(p_dir):
3333
assert os.access(p_dir.parent.absolute(), os.W_OK)
3434

3535

36+
# Board particulars ===========================================================
37+
38+
3639
@pytest.mark.skip_on_github
3740
def test_board_constructor_local_default_writable():
3841

0 commit comments

Comments
 (0)