238 lines
7.5 KiB
Python
238 lines
7.5 KiB
Python
from collections import defaultdict
|
|
from contextlib import ExitStack
|
|
from pathlib import Path
|
|
from unittest import TestCase
|
|
from unittest import mock
|
|
|
|
import json
|
|
import os
|
|
import shutil
|
|
|
|
from parameterized import parameterized, parameterized_class # type: ignore
|
|
|
|
import yaml
|
|
|
|
from cloud_build import CB
|
|
from tests.call import Call
|
|
|
|
|
|
def change(origin, new, key, value):
|
|
with open(origin) as f:
|
|
cfg = yaml.safe_load(f)
|
|
|
|
with open(new, 'w') as f:
|
|
yaml.safe_dump(cfg | {key: value}, f)
|
|
|
|
|
|
def get_class_name(cls, num, params_dict):
|
|
result = cls.__name__
|
|
if branch := params_dict['branch']:
|
|
result = f'{result}_{parameterized.to_safe_name(branch)}'
|
|
if arch := params_dict['arch']:
|
|
result = f'{result}_{parameterized.to_safe_name(arch)}'
|
|
return f'{result}_{num}'
|
|
|
|
|
|
@parameterized_class([
|
|
{'branch': 'branch', 'arch': ''},
|
|
{'branch': 'branch', 'arch': 'arch'},
|
|
{'branch': '', 'arch': 'arch'},
|
|
{'branch': '', 'arch': ''},
|
|
], class_name_func=get_class_name)
|
|
class TestIntegrationImages(TestCase):
|
|
def setUp(self):
|
|
self._images = self.__class__._images
|
|
self.images_dir = self.__class__.images_dir
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.work_dir = Path('/tmp/cloud-build')
|
|
shutil.rmtree(cls.work_dir, ignore_errors=True)
|
|
os.makedirs(cls.work_dir / 'external_files/p9/x86_64', exist_ok=True)
|
|
readme = cls.work_dir / 'external_files/p9/x86_64/README'
|
|
readme.write_text('README')
|
|
os.symlink(readme, readme.with_suffix(".txt"))
|
|
config = cls.work_dir / 'config.yaml'
|
|
branch = cls.branch
|
|
arch = cls.arch
|
|
remote = Path('/tmp/cloud-build/images')
|
|
if branch:
|
|
remote = remote / '{branch}'
|
|
if arch:
|
|
remote = remote / '{arch}'
|
|
remote = (remote / 'cloud').as_posix()
|
|
change(
|
|
'tests/test_integration_images.yaml',
|
|
config,
|
|
'remote',
|
|
remote,
|
|
)
|
|
|
|
with ExitStack() as stack:
|
|
stack.enter_context(mock.patch('subprocess.call', Call()))
|
|
|
|
cloud_build = CB(
|
|
config=config,
|
|
data_dir=(cls.work_dir / 'cloud_build').as_posix(),
|
|
)
|
|
cloud_build.create_images(no_tests=True)
|
|
cloud_build.copy_external_files()
|
|
cloud_build.sign()
|
|
cloud_build.sync(create_remote_dirs=True)
|
|
|
|
images_dir = cls.work_dir / 'images'
|
|
cls.images_dir = images_dir
|
|
images = defaultdict(lambda: defaultdict(list))
|
|
|
|
if branch:
|
|
for branch in os.listdir(images_dir):
|
|
if arch:
|
|
for arch in os.listdir(images_dir / branch):
|
|
images[branch][arch] = os.listdir(
|
|
images_dir / branch / arch / 'cloud'
|
|
)
|
|
else:
|
|
images[branch]['arch'] = os.listdir(
|
|
images_dir / branch / 'cloud'
|
|
)
|
|
elif arch:
|
|
for arch in os.listdir(images_dir):
|
|
images['branch'][arch] = os.listdir(
|
|
images_dir / arch / 'cloud'
|
|
)
|
|
else:
|
|
images['branch']['arch'] = os.listdir(
|
|
images_dir / 'cloud'
|
|
)
|
|
cls._images = images
|
|
|
|
def image_path(self, branch, arch, image) -> Path:
|
|
images_dir = self.images_dir
|
|
if self.branch: # type: ignore
|
|
images_dir = images_dir / branch
|
|
if self.arch: # type: ignore
|
|
images_dir = images_dir / arch
|
|
|
|
return images_dir / 'cloud' / image
|
|
|
|
def images(self, branch, arch) -> list:
|
|
if not self.branch: # type: ignore
|
|
branch = 'branch'
|
|
if not self.arch: # type: ignore
|
|
arch = 'arch'
|
|
|
|
return self._images[branch][arch]
|
|
|
|
def images_lists(self) -> list:
|
|
result = []
|
|
for branch_value in self._images.values():
|
|
for arch_value in branch_value.values():
|
|
result.append(arch_value)
|
|
return result
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
shutil.rmtree(cls.work_dir, ignore_errors=True)
|
|
|
|
def test_arch_ppc64le(self):
|
|
self.assertIn('alt-p9-rootfs-minimal-ppc64le.tar.xz',
|
|
self.images('p9', 'ppc64le'))
|
|
|
|
def test_branches(self):
|
|
if self.branch:
|
|
self.assertCountEqual(self._images.keys(),
|
|
['Sisyphus', 'p9', 'p8'])
|
|
else:
|
|
self.assertCountEqual(self._images.keys(), ['branch'])
|
|
|
|
def test_build_cloud_img(self):
|
|
self.assertIn('alt-p9-cloud-x86_64.img', self.images('p9', 'x86_64'))
|
|
|
|
def test_rename_regex_cloud(self):
|
|
self.assertIn('alt-p9-cloud-x86_64.qcow2', self.images('p9', 'x86_64'))
|
|
|
|
def test_exclude_arches(self):
|
|
self.assertNotIn('alt-p8-cloud-x86_64.qcow2',
|
|
self.images('p8', 'x86_64'))
|
|
|
|
def test_exclude_branches(self):
|
|
self.assertNotIn('alt-p9-cloud-ppc64le.qcow2',
|
|
self.images('p9', 'ppc64le'))
|
|
|
|
def get_make_args(self, branch, arch, image):
|
|
image = self.image_path(branch, arch, image)
|
|
return json.loads(image.read_text())
|
|
|
|
def test_branch_sisyphus_cloud(self):
|
|
self.assertIn(
|
|
"BRANCH=sisyphus",
|
|
self.get_make_args(
|
|
'Sisyphus',
|
|
'x86_64',
|
|
'alt-sisyphus-cloud-x86_64.qcow2',
|
|
),
|
|
)
|
|
|
|
def test_branding_present_p9_rootfs_minimal(self):
|
|
self.assertIn(
|
|
"BRANDING=alt-starterkit",
|
|
self.get_make_args(
|
|
'p9',
|
|
'x86_64',
|
|
'alt-p9-rootfs-minimal-x86_64.tar.xz',
|
|
),
|
|
)
|
|
|
|
def test_branding_present_p9_cloud(self):
|
|
self.assertIn(
|
|
"BRANDING=alt-starterkit",
|
|
self.get_make_args('p9', 'x86_64', 'alt-p9-cloud-x86_64.qcow2'),
|
|
)
|
|
|
|
def test_branding_absent_p9_workstation_cloud(self):
|
|
self.assertNotRegex(
|
|
' '.join(self.get_make_args(
|
|
'p9',
|
|
'x86_64',
|
|
'alt-p9-workstation-cloud-x86_64.qcow2',
|
|
)),
|
|
'BRANDING'
|
|
)
|
|
|
|
def test_branding_absent_sisyphus_cloud(self):
|
|
self.assertNotRegex(
|
|
' '.join(self.get_make_args(
|
|
'Sisyphus',
|
|
'x86_64',
|
|
'alt-sisyphus-cloud-x86_64.qcow2',
|
|
)),
|
|
'BRANDING'
|
|
)
|
|
|
|
def test_external_files(self):
|
|
self.assertIn('README', self.images('p9', 'x86_64'))
|
|
|
|
def test_external_symlinks(self):
|
|
readme_txt = self.image_path('p9', 'x86_64', 'README.txt')
|
|
self.assertTrue(readme_txt.is_symlink())
|
|
|
|
def test_verification_files(self):
|
|
for images_list in self.images_lists():
|
|
self.assertIn('SHA256SUMS', images_list)
|
|
self.assertIn('SHA256SUMS.gpg', images_list)
|
|
|
|
number_of_images = len(self.image_path(
|
|
'p9',
|
|
'x86_64',
|
|
'SHA256SUMS',
|
|
).read_text().splitlines())
|
|
index = bool(self.branch) * 2 + bool(self.arch)
|
|
expected_numbers = [59, 20, 25, 9]
|
|
self.assertEqual(number_of_images, expected_numbers[index])
|
|
|
|
def test_number_of_images(self):
|
|
number_of_images = sum(len(lst) for lst in self.images_lists())
|
|
index = bool(self.branch) * 2 + bool(self.arch)
|
|
expected_numbers = [63, 79, 71, 103]
|
|
self.assertEqual(number_of_images, expected_numbers[index])
|