Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions iib/workers/tasks/fbc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,35 @@ def extract_fbc_fragment(
# store the fbc_fragment at /tmp/iib-**/fbc-fragment-{index} to prevent
# cross-contamination
conf = get_worker_config()
fbc_fragment_path = os.path.join(temp_dir, f"{conf['temp_fbc_fragment_path']}-{fragment_index}")
fbc_fragment_base_path = os.path.join(
temp_dir, f"{conf['temp_fbc_fragment_path']}-{fragment_index}"
)
# Copy fbc_fragment's catalog to /tmp/iib-**/fbc-fragment-{index}
extract_directory_from_image_non_privileged(
image=fbc_fragment, src_path=conf['fbc_fragment_catalog_path'], dest_path=fbc_fragment_path
image=fbc_fragment,
src_path=conf['fbc_fragment_catalog_path'],
dest_path=fbc_fragment_base_path,
)

# extract_directory_from_image_non_privileged creates dest_path/<basename(src_path)>/,
# e.g. /tmp/iib-**/fbc-fragment-0/configs/example-operator. Match get_catalog_dir().
fbc_fragment_catalog_dir = os.path.join(
fbc_fragment_base_path,
os.path.basename(conf['fbc_fragment_catalog_path'].rstrip('/')),
)
if not os.path.isdir(fbc_fragment_catalog_dir):
raise IIBError(
f"FBC fragment catalog directory not found at {fbc_fragment_catalog_dir} "
f"after extracting {fbc_fragment}"
)

log.info("fbc_fragment extracted at %s", fbc_fragment_path)
operator_packages = os.listdir(fbc_fragment_path)
log.info("fbc_fragment extracted at %s", fbc_fragment_catalog_dir)
operator_packages = os.listdir(fbc_fragment_catalog_dir)
log.info("fbc_fragment contains packages %s", operator_packages)
if not operator_packages:
raise IIBError("No operator packages in fbc_fragment %s", fbc_fragment)

return fbc_fragment_path, operator_packages
return fbc_fragment_catalog_dir, operator_packages


def _serialize_datetime(obj: datetime) -> str:
Expand Down
59 changes: 45 additions & 14 deletions tests/test_workers/test_tasks/test_fbc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,27 @@ def test_extract_fbc_fragment(mock_extract_dir, mock_osldr, ldr_output, tmpdir):
test_fbc_fragment = "example.com/test/fbc_fragment:latest"
mock_osldr.return_value = ldr_output
# The function now adds -0 suffix by default when fragment_index is not provided
fbc_fragment_path = os.path.join(tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0")
fbc_fragment_base_path = os.path.join(
tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0"
)
fbc_fragment_catalog_dir = os.path.join(
fbc_fragment_base_path, os.path.basename(get_worker_config()['fbc_fragment_catalog_path'])
)
os.makedirs(fbc_fragment_catalog_dir)

if not ldr_output:
with pytest.raises(IIBError):
extract_fbc_fragment(tmpdir, test_fbc_fragment)
else:
extract_fbc_fragment(tmpdir, test_fbc_fragment)
result_path, result_operators = extract_fbc_fragment(tmpdir, test_fbc_fragment)
assert result_path == fbc_fragment_catalog_dir
assert result_operators == ldr_output
mock_extract_dir.assert_called_once_with(
image=test_fbc_fragment,
src_path=get_worker_config()['fbc_fragment_catalog_path'],
dest_path=fbc_fragment_path,
dest_path=fbc_fragment_base_path,
)
mock_osldr.assert_called_once_with(fbc_fragment_path)
mock_osldr.assert_called_once_with(fbc_fragment_catalog_dir)


@pytest.mark.parametrize('ldr_output', [['testoperator'], ['test1', 'test2']])
Expand All @@ -240,26 +248,30 @@ def test_extract_fbc_fragment_with_index(mock_extract_dir, mock_osldr, ldr_outpu

# Test with fragment_index = 2
fragment_index = 2
fbc_fragment_path = os.path.join(
fbc_fragment_base_path = os.path.join(
tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-{fragment_index}"
)
fbc_fragment_catalog_dir = os.path.join(
fbc_fragment_base_path, os.path.basename(get_worker_config()['fbc_fragment_catalog_path'])
)
os.makedirs(fbc_fragment_catalog_dir)

result_path, result_operators = extract_fbc_fragment(
tmpdir, test_fbc_fragment, fragment_index=fragment_index
)

# Verify the path includes the correct index
assert result_path == fbc_fragment_path
assert result_path.endswith(f"-{fragment_index}")
# Verify the path includes the correct index and catalog directory
assert result_path == fbc_fragment_catalog_dir
assert result_path.endswith(f"fbc-fragment-{fragment_index}/configs")
assert result_operators == ldr_output

# Verify the function was called with the correct path
mock_extract_dir.assert_called_once_with(
image=test_fbc_fragment,
src_path=get_worker_config()['fbc_fragment_catalog_path'],
dest_path=fbc_fragment_path,
dest_path=fbc_fragment_base_path,
)
mock_osldr.assert_called_once_with(fbc_fragment_path)
mock_osldr.assert_called_once_with(fbc_fragment_catalog_dir)


@mock.patch('os.listdir')
Expand All @@ -272,6 +284,25 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir):
# Mock different outputs for each fragment
mock_osldr.side_effect = [['operator1'], ['operator2']]

fbc_fragment_base_path_0 = os.path.join(
tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0"
)
fbc_fragment_base_path_1 = os.path.join(
tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-1"
)
os.makedirs(
os.path.join(
fbc_fragment_base_path_0,
os.path.basename(get_worker_config()['fbc_fragment_catalog_path']),
)
)
os.makedirs(
os.path.join(
fbc_fragment_base_path_1,
os.path.basename(get_worker_config()['fbc_fragment_catalog_path']),
)
)

# Extract first fragment with index 0
path1, operators1 = extract_fbc_fragment(tmpdir, test_fbc_fragment1, fragment_index=0)

Expand All @@ -280,8 +311,8 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir):

# Verify paths are different and include correct indices
assert path1 != path2
assert path1.endswith("-0")
assert path2.endswith("-1")
assert path1.endswith("fbc-fragment-0/configs")
assert path2.endswith("fbc-fragment-1/configs")

# Verify operators are different (no cross-contamination)
assert operators1 == ['operator1']
Expand All @@ -292,12 +323,12 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir):
mock.call(
image=test_fbc_fragment1,
src_path=get_worker_config()['fbc_fragment_catalog_path'],
dest_path=path1,
dest_path=fbc_fragment_base_path_0,
),
mock.call(
image=test_fbc_fragment2,
src_path=get_worker_config()['fbc_fragment_catalog_path'],
dest_path=path2,
dest_path=fbc_fragment_base_path_1,
),
]
mock_extract_dir.assert_has_calls(expected_calls, any_order=True)
Expand Down