1
+ # Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
+ #
4
+ # The Universal Permissive License (UPL), Version 1.0
5
+ #
6
+ # Subject to the condition set forth below, permission is hereby granted to any
7
+ # person obtaining a copy of this software, associated documentation and/or
8
+ # data (collectively the "Software"), free of charge and under any and all
9
+ # copyright rights in the Software, and any and all patent rights owned or
10
+ # freely licensable by each licensor hereunder covering either (i) the
11
+ # unmodified Software as contributed to or provided by such licensor, or (ii)
12
+ # the Larger Works (as defined below), to deal in both
13
+ #
14
+ # (a) the Software, and
15
+ #
16
+ # (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17
+ # one is included with the Software each a "Larger Work" to which the Software
18
+ # is contributed by such licensors),
19
+ #
20
+ # without restriction, including without limitation the rights to copy, create
21
+ # derivative works of, display, perform, and distribute the Software and make,
22
+ # use, sell, offer for sale, import, export, have made, and have sold the
23
+ # Software and the Larger Work(s), and to sublicense the foregoing rights on
24
+ # either these or other terms.
25
+ #
26
+ # This license is subject to the following condition:
27
+ #
28
+ # The above copyright notice and either this complete permission notice or at a
29
+ # minimum a reference to the UPL must be included in all copies or substantial
30
+ # portions of the Software.
31
+ #
32
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38
+ # SOFTWARE.
39
+
40
+ import unittest
41
+ import shutil
42
+ import io
43
+ import os
44
+ import pathlib
45
+ import re
46
+
47
+
48
+ class TestShUtil (unittest .TestCase ):
49
+
50
+ def test_disk_usage_returns_a_tuple (self ):
51
+ usage = shutil .disk_usage (__file__ )
52
+ self .assertIsInstance (usage , tuple )
53
+ self .assertGreater (usage .total , 0 )
54
+ self .assertGreater (usage .used , 0 )
55
+ self .assertGreater (usage .free , 0 )
56
+ self .assertGreater (usage .total , usage .used )
57
+ self .assertGreater (usage .total , usage .free )
58
+
59
+ def test_disk_usage_accepts_path_as_a_string (self ):
60
+ usage = shutil .disk_usage (__file__ )
61
+ self .assertIsInstance (usage , tuple )
62
+
63
+ def test_disk_usage_accepts_path_as_bytes (self ):
64
+ usage = shutil .disk_usage (__file__ .encode ("utf-8" ))
65
+ self .assertIsInstance (usage , tuple )
66
+
67
+ def test_disk_usage_accepts_path_as_a_pathlike (self ):
68
+ usage = shutil .disk_usage (pathlib .PurePath (__file__ ))
69
+ self .assertIsInstance (usage , tuple )
70
+
71
+ def test_disk_usage_accepts_file_descriptor (self ):
72
+ with io .open (__file__ ) as file :
73
+ fd = file .fileno ()
74
+ usage = shutil .disk_usage (fd )
75
+ self .assertIsInstance (usage , tuple )
76
+
77
+ def test_disk_usage_supports_path_to_file (self ):
78
+ usage = shutil .disk_usage (__file__ )
79
+ self .assertIsInstance (usage , tuple )
80
+
81
+ def test_disk_usage_supports_path_to_directory (self ):
82
+ usage = shutil .disk_usage (os .path .dirname (__file__ ))
83
+ self .assertIsInstance (usage , tuple )
84
+
85
+ def test_disk_usage_raises_exception_when_given_path_type_is_not_supported (self ):
86
+ with self .assertRaisesRegex (TypeError , r'path should be string, bytes, os.PathLike or integer, not list' ):
87
+ shutil .disk_usage ([])
88
+
89
+ def test_disk_usage_raises_exception_when_given_path_does_not_exist (self ):
90
+ not_existing_path = __file__ + '.not-existing'
91
+ not_existing_file_name = os .path .basename (not_existing_path )
92
+
93
+ with self .assertRaisesRegex (FileNotFoundError , rf"No such file or directory: '.+{ not_existing_file_name } '" ):
94
+ shutil .disk_usage (not_existing_path )
95
+
96
+ def test_disk_usage_raises_exception_when_there_is_no_open_file_with_given_file_descriptor (self ):
97
+ not_existing_file_descriptor = 1_000_000 # expect the current process to not open 1M files
98
+
99
+ with self .assertRaisesRegex (OSError , r'(B|b)ad file descriptor: 1000000' ):
100
+ shutil .disk_usage (not_existing_file_descriptor )
0 commit comments