Skip to content

Commit c5bd4f2

Browse files
committed
ROX-33216: add more test cases for path_rename
In order to validate more of the inode tracking functionality in path_rename more test cases and additional validations are added.
1 parent 7cde780 commit c5bd4f2

1 file changed

Lines changed: 152 additions & 9 deletions

File tree

tests/test_path_rename.py

Lines changed: 152 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,28 @@ def test_rename_dir(monitored_dir, ignored_dir, server):
101101
ignored_dir: Temporary directory path that is not monitored by fact.
102102
server: The server instance to communicate with.
103103
"""
104+
def touch_test_files(directory, process=None) -> list[Event]:
105+
events = []
106+
for i in range(3):
107+
with open(os.path.join(directory, f'{i}.txt'), 'w') as f:
108+
f.write('This is a test')
109+
if process is not None:
110+
events.append(
111+
Event(process=process,
112+
event_type=EventType.OPEN,
113+
file=os.path.join(directory, f'{i}.txt'),
114+
host_path=os.path.join(directory, f'{i}.txt'))
115+
)
116+
return events
117+
104118
# Directory Under Test
105119
dut = os.path.join(monitored_dir, 'some-dir')
106120
new_dut = os.path.join(monitored_dir, 'other-dir')
107121
ignored_dut = os.path.join(ignored_dir, 'some-dir')
108122
new_ignored_dut = os.path.join(ignored_dir, 'other-dir')
109123

110124
os.mkdir(ignored_dut)
111-
for i in range(3):
112-
with open(os.path.join(ignored_dut, f'{i}.txt'), 'w') as f:
113-
f.write('This is a test')
125+
touch_test_files(ignored_dut)
114126

115127
# This rename should generate no events
116128
os.rename(ignored_dut, new_ignored_dut)
@@ -126,16 +138,81 @@ def test_rename_dir(monitored_dir, ignored_dir, server):
126138
host_path=dut, old_file=new_ignored_dut, old_host_path=''),
127139
])
128140

129-
# The following two event should produce full events without scanning the FS.
141+
events = touch_test_files(dut, p)
142+
143+
# The following renames should produce full events without scanning the FS.
130144
os.rename(dut, new_dut)
131-
os.rename(new_dut, ignored_dut)
145+
events.extend([
146+
Event(process=p, event_type=EventType.RENAME, file=new_dut,
147+
host_path=new_dut, old_file=dut, old_host_path=dut),
148+
# Check the renamed subfiles are properly tracked
149+
*touch_test_files(new_dut, p),
150+
])
132151

133-
events = [
134-
Event(process=p, event_type=EventType.RENAME,
135-
file=new_dut, host_path=new_dut, old_file=dut, old_host_path=dut),
152+
os.rename(new_dut, ignored_dut)
153+
events.append(
136154
Event(process=p, event_type=EventType.RENAME,
137155
file=ignored_dut, host_path='', old_file=new_dut, old_host_path=new_dut),
138-
]
156+
)
157+
158+
server.wait_events(events)
159+
160+
161+
@pytest.mark.parametrize('from_monitored,to_monitored', [
162+
pytest.param(True, True, id='both_monitored'),
163+
pytest.param(False, True, id='target_monitored'),
164+
pytest.param(True, False, id='bullet_monitored'),
165+
])
166+
def test_rename_overwrite(from_monitored, to_monitored, monitored_dir, ignored_dir, server):
167+
events = []
168+
p = Process.from_proc()
169+
if from_monitored:
170+
bullet = os.path.join(monitored_dir, 'bullet.txt')
171+
events.append(
172+
Event(process=p,
173+
event_type=EventType.CREATION,
174+
file=bullet,
175+
host_path=bullet,
176+
))
177+
else:
178+
bullet = os.path.join(ignored_dir, 'bullet.txt')
179+
180+
if to_monitored:
181+
target = os.path.join(monitored_dir, 'target.txt')
182+
events.append(
183+
Event(process=p,
184+
event_type=EventType.CREATION,
185+
file=target,
186+
host_path=target,
187+
))
188+
else:
189+
target = os.path.join(ignored_dir, 'target.txt')
190+
191+
# Create both files in the order they are expected in `events`
192+
for path in [bullet, target]:
193+
with open(path, 'w') as f:
194+
f.write('This is a test')
195+
196+
os.rename(bullet, target)
197+
events.append(
198+
Event(process=p,
199+
event_type=EventType.RENAME,
200+
file=target,
201+
host_path=target if to_monitored else '',
202+
old_file=bullet,
203+
old_host_path=bullet if from_monitored else '',
204+
))
205+
206+
if to_monitored:
207+
# One final event to check the mapping is persisted correctly
208+
with open(target, 'w') as f:
209+
f.write('Check mapping')
210+
events.append(
211+
Event(process=p,
212+
event_type=EventType.OPEN,
213+
file=target,
214+
host_path=target,
215+
))
139216

140217
server.wait_events(events)
141218

@@ -203,3 +280,69 @@ def test_mounted_dir(test_container, ignored_dir, server):
203280
]
204281

205282
server.wait_events(events)
283+
284+
285+
def test_cross_mountpoints(test_container, monitored_dir, server):
286+
"""
287+
Attempt to rename files/directories across mountpoints
288+
289+
This test does not necessarily fit here, since it won't trigger the
290+
path_rename LSM hook, but the test ensures that this hook is
291+
defintely not triggered when an inode crosses a mount point, so it
292+
doesn't fit but it kind of does? ¯\\_(ツ)_/¯
293+
"""
294+
mounted_file = '/unmonitored/test.txt'
295+
host_path = os.path.join(monitored_dir, 'test.txt')
296+
ovfs_file = '/container-dir/test.txt'
297+
298+
test_container.exec_run(f'touch {mounted_file}')
299+
# Get owner uid and gid before moving the file
300+
stat = os.stat(host_path)
301+
owner_uid = stat.st_uid
302+
owner_gid = stat.st_gid
303+
mode = stat.st_mode
304+
305+
test_container.exec_run(f'mv {mounted_file} {ovfs_file}')
306+
test_container.exec_run(f'mv {ovfs_file} {mounted_file}')
307+
308+
touch = Process.in_container(
309+
exe_path='/usr/bin/touch',
310+
args=f'touch {mounted_file}',
311+
name='touch',
312+
container_id=test_container.id[:12],
313+
)
314+
first_rename = Process.in_container(
315+
exe_path='/usr/bin/mv',
316+
args=f'mv {mounted_file} {ovfs_file}',
317+
name='mv',
318+
container_id=test_container.id[:12],
319+
)
320+
second_rename = Process.in_container(
321+
exe_path='/usr/bin/mv',
322+
args=f'mv {ovfs_file} {mounted_file}',
323+
name='mv',
324+
container_id=test_container.id[:12],
325+
)
326+
327+
server.wait_events([
328+
Event(process=touch, event_type=EventType.OPEN,
329+
file=mounted_file, host_path=host_path),
330+
Event(process=first_rename, event_type=EventType.CREATION,
331+
file=ovfs_file, host_path=''),
332+
Event(process=first_rename, event_type=EventType.OPEN,
333+
file=ovfs_file, host_path=''),
334+
Event(process=first_rename, event_type=EventType.OWNERSHIP,
335+
file=ovfs_file, host_path='', owner_uid=owner_uid, owner_gid=owner_gid),
336+
Event(process=first_rename, event_type=EventType.PERMISSION,
337+
file=ovfs_file, host_path='', mode=mode),
338+
Event(process=first_rename, event_type=EventType.UNLINK,
339+
file=mounted_file, host_path=host_path),
340+
Event(process=second_rename, event_type=EventType.CREATION,
341+
file=mounted_file, host_path=host_path),
342+
Event(process=second_rename, event_type=EventType.OWNERSHIP,
343+
file=mounted_file, host_path=host_path, owner_uid=owner_uid, owner_gid=owner_gid),
344+
Event(process=second_rename, event_type=EventType.PERMISSION,
345+
file=mounted_file, host_path=host_path, mode=mode),
346+
Event(process=second_rename, event_type=EventType.UNLINK,
347+
file=ovfs_file, host_path=''),
348+
])

0 commit comments

Comments
 (0)