Skip to content

Commit a4615b5

Browse files
REST: add atime support
Co-authored-by: Junie <junie@jetbrains.com>
1 parent 436e42d commit a4615b5

4 files changed

Lines changed: 26 additions & 10 deletions

File tree

src/borgstore/backends/rest.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,9 @@ def info(self, name: str) -> ItemInfo:
379379
self._handle_response(response, name) # raises!
380380
exists = response.status_code == HTTP.OK
381381
is_dir = response.headers.get("X-BorgStore-Is-Directory") == "true"
382+
atime = float(response.headers.get("X-BorgStore-Atime", 0))
382383
size = int(response.headers.get("Content-Length", 0)) if exists else 0
383-
return ItemInfo(name=name, exists=exists, size=size, directory=is_dir)
384+
return ItemInfo(name=name, exists=exists, size=size, directory=is_dir, atime=atime)
384385

385386
def load(self, name: str, *, size=None, offset=0) -> bytes:
386387
self._assert_open()
@@ -464,4 +465,10 @@ def list(self, name: str) -> Iterator[ItemInfo]:
464465
response = self._request("get", self._url(name) + "/") # trailing "/" needed to get list
465466
self._handle_response(response, name)
466467
for entry in response.json():
467-
yield ItemInfo(name=entry["name"], exists=True, size=entry["size"], directory=entry.get("directory", False))
468+
yield ItemInfo(
469+
name=entry["name"],
470+
exists=True,
471+
size=entry["size"],
472+
directory=entry.get("directory", False),
473+
atime=entry.get("atime", 0),
474+
)

src/borgstore/server/rest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ def do_HEAD(self):
306306
headers={
307307
"Content-Length": str(info.size),
308308
"X-BorgStore-Is-Directory": "true" if info.directory else "false",
309+
"X-BorgStore-Atime": str(info.atime),
309310
},
310311
)
311312
except Exception as e:
@@ -320,7 +321,7 @@ def do_GET(self):
320321
# [{"name": "...", "size": ...}, ...]
321322
with self.server.backend:
322323
items = (
323-
{"name": item.name, "size": item.size, "directory": item.directory}
324+
{"name": item.name, "size": item.size, "directory": item.directory, "atime": item.atime}
324325
for item in self.server.backend.list(self.name)
325326
)
326327
json_data = json.dumps(list(items), indent=2)

tests/test_rest_url.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ def test_rest_url_info(tmp_path):
2222
info = store.info(item_name)
2323
assert info.exists
2424
assert info.size == len(item_data)
25+
assert info.atime > 0
26+
27+
# Test listing
28+
items = list(store.list(""))
29+
assert len(items) == 1
30+
assert items[0].name == item_name
31+
assert items[0].atime > 0
2532

2633
# Test nonexistent item
2734
# This also used to hang if it returned a 404 with a body.

tests/test_server_rest.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -617,31 +617,32 @@ def do_request(method, path, body=b""):
617617
resp_body = b""
618618
if method.upper() != "HEAD" and "Content-Length" in resp_headers:
619619
resp_body = proc.stdout.read(int(resp_headers["Content-Length"]))
620-
return status, resp_body
620+
return status, resp_body, resp_headers
621621

622622
try:
623623
# 1. Create store
624-
status, body = do_request("POST", "/?cmd=create")
624+
status, body, headers = do_request("POST", "/?cmd=create")
625625
assert status == 200
626626

627627
# 2. Store something
628628
item_data = b"stdio data"
629-
status, body = do_request("POST", "/item1", body=item_data)
629+
status, body, headers = do_request("POST", "/item1", body=item_data)
630630
assert status == 200
631631

632632
# 3. List the store
633-
status, body = do_request("GET", "/")
633+
status, body, headers = do_request("GET", "/")
634634
assert status == 200
635635
items = json.loads(body.decode("utf-8"))
636-
assert any(item["name"] == "item1" for item in items)
636+
assert any(item["name"] == "item1" and item.get("atime", 0) > 0 for item in items)
637637

638638
# 4. Info (HEAD)
639-
status, body = do_request("HEAD", "/item1")
639+
status, body, headers = do_request("HEAD", "/item1")
640640
assert status == 200
641641
assert body == b""
642+
assert float(headers.get("X-BorgStore-Atime", 0)) > 0
642643

643644
# 5. Info for nonexistent (HEAD)
644-
status, body = do_request("HEAD", "/nonexistent")
645+
status, body, headers = do_request("HEAD", "/nonexistent")
645646
assert status == 404
646647
assert body == b""
647648

0 commit comments

Comments
 (0)