0
# Advanced Features
1
2
Advanced functionality including real filesystem mapping, pause/resume operations, OS emulation, and filesystem size tracking. These features enable sophisticated testing scenarios and fine-grained control over the fake filesystem behavior.
3
4
## Capabilities
5
6
### Real Filesystem Mapping
7
8
Map real files and directories into the fake filesystem for hybrid testing scenarios.
9
10
```python { .api }
11
def add_real_file(
12
self,
13
source_path: str,
14
target_path: str = None,
15
read_only: bool = False,
16
encoding: str = None
17
) -> FakeFile:
18
"""
19
Add a real file from the actual filesystem to the fake filesystem.
20
21
Args:
22
source_path: Path to the real file to add
23
target_path: Path in fake filesystem (defaults to source_path)
24
read_only: Whether the file should be read-only in fake filesystem
25
encoding: Text encoding for the file
26
27
Returns:
28
FakeFile object representing the mapped file
29
30
Raises:
31
FileNotFoundError: If source_path doesn't exist in real filesystem
32
"""
33
34
def add_real_directory(
35
self,
36
source_path: str,
37
target_path: str = None,
38
read_only: bool = False,
39
lazy_read: bool = True
40
) -> FakeDirectory:
41
"""
42
Add a real directory tree from actual filesystem to fake filesystem.
43
44
Args:
45
source_path: Path to the real directory to add
46
target_path: Path in fake filesystem (defaults to source_path)
47
read_only: Whether files should be read-only in fake filesystem
48
lazy_read: Whether to read file contents only when accessed
49
50
Returns:
51
FakeDirectory object representing the mapped directory
52
53
Raises:
54
FileNotFoundError: If source_path doesn't exist in real filesystem
55
"""
56
57
def add_real_paths(self, paths: List[str], read_only: bool = False) -> None:
58
"""
59
Add multiple real paths to the fake filesystem.
60
61
Args:
62
paths: List of real filesystem paths to add
63
read_only: Whether added paths should be read-only
64
"""
65
```
66
67
Usage example:
68
69
```python
70
# Map a real configuration file into fake filesystem
71
fs.add_real_file('/etc/hosts', '/etc/hosts', read_only=True)
72
73
# Map a real directory tree
74
fs.add_real_directory('/home/user/config', '/config')
75
76
# Map multiple paths
77
fs.add_real_paths(['/usr/bin/python', '/usr/lib/python3.9'], read_only=True)
78
79
# Now test code can access real files through fake filesystem
80
with open('/etc/hosts', 'r') as f:
81
hosts_content = f.read()
82
```
83
84
### Pause and Resume Operations
85
86
Temporarily disable filesystem patching to access the real filesystem during tests.
87
88
```python { .api }
89
def pause(self) -> None:
90
"""
91
Pause filesystem patching, allowing access to the real filesystem.
92
93
All filesystem operations will use the real filesystem until resume() is called.
94
Useful for operations that need to access real files during test execution.
95
"""
96
97
def resume(self) -> None:
98
"""
99
Resume filesystem patching after a pause() call.
100
101
Restores fake filesystem behavior for all filesystem operations.
102
"""
103
104
def is_paused(self) -> bool:
105
"""
106
Check if filesystem patching is currently paused.
107
108
Returns:
109
True if patching is paused, False if active
110
"""
111
```
112
113
Usage example:
114
115
```python
116
def test_with_pause_resume(fs):
117
# Create fake file
118
fs.create_file('/fake/test.txt', contents='fake content')
119
120
# Pause to access real filesystem
121
fs.pause()
122
123
# This writes to the real filesystem
124
with open('/tmp/real_file.txt', 'w') as f:
125
f.write('real content')
126
127
# Resume fake filesystem
128
fs.resume()
129
130
# Back to fake filesystem
131
assert os.path.exists('/fake/test.txt')
132
assert not os.path.exists('/tmp/real_file.txt') # Not in fake filesystem
133
```
134
135
### Operating System Emulation
136
137
Emulate different operating systems to test cross-platform behavior.
138
139
```python { .api }
140
def set_os_type(self, os_type: OSType) -> None:
141
"""
142
Set the operating system type for path and behavior emulation.
143
144
Args:
145
os_type: Operating system to emulate (OSType.LINUX, OSType.MACOS, OSType.WINDOWS)
146
"""
147
148
def get_os_type(self) -> OSType:
149
"""
150
Get the current operating system type being emulated.
151
152
Returns:
153
Current OSType being emulated
154
"""
155
156
def is_windows_fs(self) -> bool:
157
"""Check if emulating Windows filesystem behavior."""
158
159
def is_macos(self) -> bool:
160
"""Check if emulating MacOS filesystem behavior."""
161
162
def is_case_sensitive(self) -> bool:
163
"""Check if filesystem is case-sensitive (depends on OS type)."""
164
```
165
166
Usage example:
167
168
```python
169
# Test Windows-specific behavior
170
fs.set_os_type(OSType.WINDOWS)
171
fs.create_file('C:\\test\\file.txt', contents='Windows path')
172
173
# Windows paths are case-insensitive
174
assert fs.exists('c:\\test\\FILE.TXT')
175
176
# Test Linux-specific behavior
177
fs.set_os_type(OSType.LINUX)
178
fs.create_file('/test/file.txt', contents='Linux path')
179
180
# Linux paths are case-sensitive
181
assert not fs.exists('/test/FILE.TXT')
182
```
183
184
### Filesystem Size Tracking
185
186
Control and monitor fake filesystem size limits.
187
188
```python { .api }
189
def set_total_size(self, total_size: int) -> None:
190
"""
191
Set the total size limit for the fake filesystem.
192
193
Args:
194
total_size: Maximum filesystem size in bytes (None for unlimited)
195
196
Raises:
197
OSError: If current filesystem usage exceeds the new limit
198
"""
199
200
def get_total_size(self) -> Optional[int]:
201
"""
202
Get the current total size limit.
203
204
Returns:
205
Size limit in bytes, or None if unlimited
206
"""
207
208
def get_disk_usage(self, path: str = None) -> tuple:
209
"""
210
Get disk usage statistics.
211
212
Args:
213
path: Path to check (defaults to filesystem root)
214
215
Returns:
216
Tuple of (total, used, available) bytes
217
"""
218
219
def get_used_size(self) -> int:
220
"""
221
Get the current used size of the filesystem.
222
223
Returns:
224
Used size in bytes
225
"""
226
```
227
228
Usage example:
229
230
```python
231
# Set filesystem size limit to 1MB
232
fs.set_total_size(1024 * 1024)
233
234
# Create files within limit
235
fs.create_file('/small.txt', contents='small file')
236
237
# Check disk usage
238
total, used, available = fs.get_disk_usage()
239
print(f"Used: {used}, Available: {available}")
240
241
# This would raise OSError if it exceeds the limit
242
try:
243
large_content = 'x' * (1024 * 1024) # 1MB of data
244
fs.create_file('/large.txt', contents=large_content)
245
except OSError as e:
246
print(f"Filesystem full: {e}")
247
```
248
249
### User and Permission Emulation
250
251
Emulate different user contexts and permission scenarios.
252
253
```python { .api }
254
def set_uid(self, uid: int) -> None:
255
"""
256
Set the current user ID for filesystem operations.
257
258
Args:
259
uid: User ID to emulate
260
"""
261
262
def set_gid(self, gid: int) -> None:
263
"""
264
Set the current group ID for filesystem operations.
265
266
Args:
267
gid: Group ID to emulate
268
"""
269
270
def is_root_user(self) -> bool:
271
"""Check if currently emulating root user (uid == 0)."""
272
273
def change_root_permission(self, permission: bool) -> None:
274
"""
275
Change whether root permissions are emulated.
276
277
Args:
278
permission: Whether to grant root permissions
279
"""
280
```
281
282
Usage example:
283
284
```python
285
# Test as non-root user
286
fs.set_uid(1000)
287
fs.set_gid(1000)
288
289
# Create file with restricted permissions
290
fs.create_file('/restricted.txt', contents='secret', st_mode=0o600)
291
292
# Test permission checks
293
fs.set_uid(1001) # Different user
294
try:
295
with open('/restricted.txt', 'r') as f:
296
content = f.read() # Should raise PermissionError
297
except PermissionError:
298
print("Access denied as expected")
299
```
300
301
### Symbolic Link Support
302
303
Create and manage symbolic links in the fake filesystem.
304
305
```python { .api }
306
def create_symlink(
307
self,
308
link_path: str,
309
target_path: str,
310
create_missing_dirs: bool = True
311
) -> FakeFile:
312
"""
313
Create a symbolic link in the fake filesystem.
314
315
Args:
316
link_path: Path where the symbolic link will be created
317
target_path: Path that the link points to
318
create_missing_dirs: Create parent directories if needed
319
320
Returns:
321
FakeFile object representing the symbolic link
322
"""
323
324
def readlink(self, link_path: str) -> str:
325
"""
326
Read the target of a symbolic link.
327
328
Args:
329
link_path: Path to the symbolic link
330
331
Returns:
332
Target path of the symbolic link
333
334
Raises:
335
OSError: If path is not a symbolic link
336
"""
337
```
338
339
Usage example:
340
341
```python
342
# Create target file and symbolic link
343
fs.create_file('/target.txt', contents='target content')
344
fs.create_symlink('/link.txt', '/target.txt')
345
346
# Link behaves like the target
347
with open('/link.txt', 'r') as f:
348
content = f.read()
349
assert content == 'target content'
350
351
# Check link properties
352
assert fs.is_link('/link.txt')
353
assert fs.readlink('/link.txt') == '/target.txt'
354
```
355
356
### Filesystem State and Debugging
357
358
Tools for inspecting and debugging the fake filesystem state.
359
360
```python { .api }
361
def reset(self, total_size: int = None) -> None:
362
"""
363
Reset the filesystem to empty state.
364
365
Args:
366
total_size: Optional size limit for the reset filesystem
367
"""
368
369
def clear_cache(self) -> None:
370
"""Clear internal filesystem caches and metadata."""
371
372
def get_filesystem_size(self) -> int:
373
"""Get the total size of all files in the filesystem."""
374
375
def dump_filesystem(self, path: str = '/') -> str:
376
"""
377
Get a string representation of the filesystem tree.
378
379
Args:
380
path: Root path for the dump (defaults to filesystem root)
381
382
Returns:
383
Multi-line string showing filesystem structure
384
"""
385
```
386
387
Usage example:
388
389
```python
390
# Create test filesystem structure
391
fs.create_dir('/app')
392
fs.create_file('/app/config.ini', contents='[settings]\ndebug=true')
393
fs.create_file('/app/main.py', contents='print("Hello World")')
394
395
# Debug filesystem state
396
print(fs.dump_filesystem())
397
# Output:
398
# /
399
# ├── app/
400
# │ ├── config.ini
401
# │ └── main.py
402
403
# Check filesystem size
404
total_size = fs.get_filesystem_size()
405
print(f"Total filesystem size: {total_size} bytes")
406
407
# Reset when done
408
fs.reset()
409
```
410
411
## Advanced Types
412
413
```python { .api }
414
from typing import List, Optional, Tuple, Union
415
from enum import Enum
416
417
class OSType(Enum):
418
"""Operating system types for emulation."""
419
LINUX = "linux"
420
MACOS = "macos"
421
WINDOWS = "windows"
422
423
# Advanced operation types
424
RealPath = str
425
FakePath = str
426
PathMapping = Tuple[RealPath, FakePath]
427
DiskUsage = Tuple[int, int, int] # (total, used, available)
428
FileMode = int
429
UserId = int
430
GroupId = int
431
```