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