Coverage for tests/test_file.py: 22%
91 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-12-02 01:57 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-12-02 01:57 +0000
1# This file is part of lsst-resources.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12import os
13import pathlib
14import unittest
15import unittest.mock
17from lsst.resources import ResourcePath
18from lsst.resources.tests import GenericReadWriteTestCase, GenericTestCase
20TESTDIR = os.path.abspath(os.path.dirname(__file__))
23class FileTestCase(GenericTestCase, unittest.TestCase):
24 scheme = "file"
25 netloc = "localhost"
27 def test_env_var(self):
28 """Test that environment variables are expanded."""
30 with unittest.mock.patch.dict(os.environ, {"MY_TEST_DIR": "/a/b/c"}):
31 uri = ResourcePath("${MY_TEST_DIR}/d.txt")
32 self.assertEqual(uri.path, "/a/b/c/d.txt")
33 self.assertEqual(uri.scheme, "file")
35 # This will not expand
36 uri = ResourcePath("${MY_TEST_DIR}/d.txt", forceAbsolute=False)
37 self.assertEqual(uri.path, "${MY_TEST_DIR}/d.txt")
38 self.assertFalse(uri.scheme)
40 def test_ospath(self):
41 """File URIs have ospath property."""
43 file = ResourcePath(self._make_uri("a/test.txt"))
44 self.assertEqual(file.ospath, "/a/test.txt")
45 self.assertEqual(file.ospath, file.path)
47 # A Schemeless URI can take unquoted files but will be quoted
48 # when it becomes a file URI.
49 something = "/a#/???.txt"
50 file = ResourcePath(something, forceAbsolute=True)
51 self.assertEqual(file.scheme, "file")
52 self.assertEqual(file.ospath, something, "From URI: {file}")
53 self.assertNotIn("???", file.path)
55 def test_path_lib(self):
56 """File URIs can be created from pathlib"""
57 file = ResourcePath(self._make_uri("a/test.txt"))
59 path_file = pathlib.Path(file.ospath)
60 from_path = ResourcePath(path_file)
61 self.assertEqual(from_path.ospath, file.ospath)
63 def test_schemeless_root(self):
64 root = ResourcePath(self._make_uri("/root"))
65 via_root = ResourcePath("b.txt", root=root)
66 self.assertEqual(via_root.ospath, "/root/b.txt")
68 with self.assertRaises(ValueError):
69 # Scheme-less URIs are not allowed to support non-file roots
70 # at the present time. This may change in the future to become
71 # equivalent to ResourcePath.join()
72 ResourcePath("a/b.txt", root=ResourcePath("s3://bucket/a/b/"))
75class FileReadWriteTestCase(GenericReadWriteTestCase, unittest.TestCase):
76 scheme = "file"
77 netloc = "localhost"
78 testdir = TESTDIR
79 transfer_modes = ("move", "copy", "link", "hardlink", "symlink", "relsymlink")
81 def test_transfer_identical(self):
82 """Test overwrite of identical files.
84 Only relevant for local files.
85 """
86 dir1 = self.tmpdir.join("dir1", forceDirectory=True)
87 dir1.mkdir()
88 self.assertTrue(dir1.exists())
89 dir2 = self.tmpdir.join("dir2", forceDirectory=True)
90 # A symlink can't include a trailing slash.
91 dir2_ospath = dir2.ospath
92 if dir2_ospath.endswith("/"):
93 dir2_ospath = dir2_ospath[:-1]
94 os.symlink(dir1.ospath, dir2_ospath)
96 # Write a test file.
97 src_file = dir1.join("test.txt")
98 content = "0123456"
99 src_file.write(content.encode())
101 # Construct URI to destination that should be identical.
102 dest_file = dir2.join("test.txt")
103 self.assertTrue(dest_file.exists())
104 self.assertNotEqual(src_file, dest_file)
106 # Transfer it over itself.
107 dest_file.transfer_from(src_file, transfer="symlink", overwrite=True)
108 new_content = dest_file.read().decode()
109 self.assertEqual(content, new_content)
111 def test_local_temporary(self):
112 """Create temporary local file if no prefix specified."""
113 with ResourcePath.temporary_uri(suffix=".json") as tmp:
114 self.assertEqual(tmp.getExtension(), ".json", f"uri: {tmp}")
115 self.assertTrue(tmp.isabs(), f"uri: {tmp}")
116 self.assertFalse(tmp.exists(), f"uri: {tmp}")
117 tmp.write(b"abcd")
118 self.assertTrue(tmp.exists(), f"uri: {tmp}")
119 self.assertTrue(tmp.isTemporary)
120 self.assertTrue(tmp.isLocal)
122 # If we now ask for a local form of this temporary file
123 # it should still be temporary and it should not be deleted
124 # on exit.
125 with tmp.as_local() as loc:
126 self.assertEqual(tmp, loc)
127 self.assertTrue(loc.isTemporary)
128 self.assertTrue(tmp.exists())
129 self.assertFalse(tmp.exists(), f"uri: {tmp}")
131 def test_transfers_from_local(self):
132 """Extra tests for local transfers."""
134 target = self.tmpdir.join("a/target.txt")
135 with ResourcePath.temporary_uri() as tmp:
136 tmp.write(b"")
137 self.assertTrue(tmp.isTemporary)
139 # Symlink transfers for temporary resources should
140 # trigger a debug message.
141 for transfer in ("symlink", "relsymlink"):
142 with self.assertLogs("lsst.resources", level="DEBUG") as cm:
143 target.transfer_from(tmp, transfer)
144 target.remove()
145 self.assertIn("Using a symlink for a temporary", "".join(cm.output))
147 # Force the target directory to be created.
148 target.transfer_from(tmp, "move")
149 self.assertFalse(tmp.exists())
151 # Temporary file now gone so transfer should not work.
152 with self.assertRaises(FileNotFoundError):
153 target.transfer_from(tmp, "move", overwrite=True)
156if __name__ == "__main__": 156 ↛ 157line 156 didn't jump to line 157, because the condition on line 156 was never true
157 unittest.main()