Skip to content

Commit

Permalink
Fix regression in windows file creation/modification times (#5752)
Browse files Browse the repository at this point in the history
* Reproduce issue #5693

* Fix regression in windows file creation/modification times

* Add newsfragement
  • Loading branch information
vxgmichel authored Nov 10, 2023
1 parent 696da4f commit 3717067
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
1 change: 1 addition & 0 deletions newsfragments/5693.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix file creation/modification times as shown in the file explorer on Windows
6 changes: 3 additions & 3 deletions parsec/core/mountpoint/winfsp_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import json
from contextlib import contextmanager
from datetime import datetime
from datetime import datetime, timezone
from functools import partial, wraps
from pathlib import PurePath
from typing import Any, Callable, Iterator, List, Tuple, TypeVar, Union, cast
Expand Down Expand Up @@ -220,8 +220,8 @@ def stat_to_file_attributes(stat: dict[str, str]) -> FILE_ATTRIBUTE:


def stat_to_winfsp_attributes(stat: dict[str, Any]) -> dict[str, Any]:
created = dt_to_filetime(datetime.fromtimestamp(stat["created"].timestamp()))
updated = dt_to_filetime(datetime.fromtimestamp(stat["updated"].timestamp()))
created = dt_to_filetime(datetime.fromtimestamp(stat["created"].timestamp(), tz=timezone.utc))
updated = dt_to_filetime(datetime.fromtimestamp(stat["updated"].timestamp(), tz=timezone.utc))
attributes = {
"creation_time": created,
"last_access_time": updated,
Expand Down
47 changes: 46 additions & 1 deletion tests/core/mountpoint/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from parsec._parsec import CoreEvent, DateTime
from parsec.api.data import EntryID, EntryName
from parsec.core import logged_core_factory
from parsec.core.fs import FsPath
from parsec.core.fs import FsPath, UserFS
from parsec.core.mountpoint import (
MountpointAlreadyMounted,
MountpointConfigurationError,
Expand Down Expand Up @@ -816,3 +816,48 @@ def check_mountpoint_paths(standard_mountpoint_path, personal_mountpoint_path):
await mountpoint_manager.mount_workspace(wid_standard),
await mountpoint_manager.mount_workspace(wid_personal),
)


@pytest.mark.trio
@pytest.mark.mountpoint
async def test_file_creation_and_modification_time(
base_mountpoint,
alice_user_fs: UserFS,
event_bus,
running_backend,
):
# Populate a bit the fs first...

wid = await alice_user_fs.workspace_create(EntryName("w"))
workspace = alice_user_fs.get_workspace(wid)

before_creation = alice_user_fs.device.time_provider.now().timestamp()
await workspace.write_bytes("/foo.txt", b"Hello world !")
after_creation = alice_user_fs.device.time_provider.now().timestamp()

# Now we can start fuse

async with mountpoint_manager_factory(
alice_user_fs, event_bus, base_mountpoint
) as mountpoint_manager:
path = trio.Path(await mountpoint_manager.mount_workspace(wid)) / "foo.txt"
stat = await path.stat()

assert before_creation <= stat.st_ctime <= stat.st_mtime <= stat.st_atime <= after_creation

before_modification = alice_user_fs.device.time_provider.now().timestamp()
assert await path.read_text() == "Hello world !"
await path.write_text("New content")
assert await path.read_text() == "New content"
after_modification = alice_user_fs.device.time_provider.now().timestamp()

stat = await path.stat()
assert (
before_creation
<= stat.st_ctime
<= after_creation
<= before_modification
<= stat.st_mtime
<= stat.st_atime
<= after_modification
)

0 comments on commit 3717067

Please sign in to comment.