From e1d8a23db90838f528aa59a6ace8ff8213e61c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barci=C5=9B?= <232002+github@gmail.com> Date: Sat, 17 Dec 2016 11:06:33 +0100 Subject: [PATCH] atime and ctime (#49) add support and tests for ctime and atime --- libarchive/entry.py | 8 ++++++ libarchive/ffi.py | 2 ++ tests/__init__.py | 2 +- tests/test_atime_ctime.py | 53 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/test_atime_ctime.py diff --git a/libarchive/entry.py b/libarchive/entry.py index cef0b67..57e7ec6 100644 --- a/libarchive/entry.py +++ b/libarchive/entry.py @@ -89,10 +89,18 @@ def issock(self): def isdev(self): return self.ischr or self.isblk or self.isfifo or self.issock + @property + def atime(self): + return ffi.entry_atime(self._entry_p) + @property def mtime(self): return ffi.entry_mtime(self._entry_p) + @property + def ctime(self): + return ffi.entry_ctime(self._entry_p) + def _getpathname(self): return (ffi.entry_pathname_w(self._entry_p) or ffi.entry_pathname(self._entry_p)) diff --git a/libarchive/ffi.py b/libarchive/ffi.py index 1178e4b..d2a62e6 100644 --- a/libarchive/ffi.py +++ b/libarchive/ffi.py @@ -110,7 +110,9 @@ def ffi(name, argtypes, restype, errcheck=None): ffi('entry_new', [], c_archive_entry_p, check_null) ffi('entry_filetype', [c_archive_entry_p], c_int) +ffi('entry_atime', [c_archive_entry_p], c_int) ffi('entry_mtime', [c_archive_entry_p], c_int) +ffi('entry_ctime', [c_archive_entry_p], c_int) ffi('entry_pathname', [c_archive_entry_p], c_char_p) ffi('entry_pathname_w', [c_archive_entry_p], c_wchar_p) ffi('entry_sourcepath', [c_archive_entry_p], c_char_p) diff --git a/tests/__init__.py b/tests/__init__.py index 897e6f4..0d466eb 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -117,7 +117,7 @@ def stat_dict(path): return {k: v for k, v in locals().items() if k in keys} -def treestat(d): +def treestat(d, stat_dict=stat_dict): r = {} for dirpath, dirnames, filenames in walk(d): r[dirpath] = stat_dict(dirpath) diff --git a/tests/test_atime_ctime.py b/tests/test_atime_ctime.py new file mode 100644 index 0000000..0405681 --- /dev/null +++ b/tests/test_atime_ctime.py @@ -0,0 +1,53 @@ +from __future__ import division, print_function, unicode_literals + +from copy import copy +from os import stat + +from libarchive import (file_reader, file_writer, memory_reader, + memory_writer) + +from . import treestat + + +def check_atime_ctime(archive, tree): + tree2 = copy(tree) + for e in archive: + epath = str(e).rstrip('/') + assert epath in tree2 + estat = tree2.pop(epath) + assert e.atime == int(estat['atime']) + assert e.ctime == int(estat['ctime']) + + +def stat_dict(path): + _, _, _, _, _, _, _, atime, _, ctime = stat(path) + return {"atime": atime, "ctime": ctime} + + +def test_memory_atime_ctime(): + # Collect information on what should be in the archive + tree = treestat('libarchive', stat_dict) + + # Create an archive of our libarchive/ directory + buf = bytes(bytearray(1000000)) + with memory_writer(buf, 'zip') as archive1: + archive1.add_files('libarchive/') + + # Check the data + with memory_reader(buf) as archive2: + check_atime_ctime(archive2, tree) + + +def test_file_atime_ctime(tmpdir): + archive_path = tmpdir.strpath+'/test.zip' + + # Collect information on what should be in the archive + tree = treestat('libarchive', stat_dict) + + # Create an archive of our libarchive/ directory + with file_writer(archive_path, 'zip') as archive: + archive.add_files('libarchive/') + + # Read the archive and check that the data is correct + with file_reader(archive_path) as archive: + check_atime_ctime(archive, tree)