Message ID | 20221219144147.31245-3-venkata.pyla@toshiba-tsip.com |
---|---|
State | Accepted, archived |
Headers | show |
Series | Test for verifiying reproducible images | expand |
This was merged into "master", if we did have linter checks like "flake8" on python code this one would certainly fail them. A simple black testsuite/repro-build-test.py already makes it much happier. And the several "imported but unused" could also be checked. venkata pyla please have a look at this if you want run black testsuite/repro-build-test.py and see if you like the result run flake8 testsuite/repro-build-test.py and see if you can fix things it reports possibly do that in "black" and "flake8" loops until both agree And maybe do the same thing for other .py files if you like. The whole repro story is about being pedantic so let us use tools that help us with being very pedantic. Henning Am Mon, 19 Dec 2022 20:11:47 +0530 schrieb venkata.pyla@toshiba-tsip.com: > From: venkata pyla <venkata.pyla@toshiba-tsip.com> > > This test verifies whether the images are reproducible by checking > with in-depth comparision tool `diffoscope` and produces a > comparision output in plain text format for checking the differences. > > Signed-off-by: venkata pyla <venkata.pyla@toshiba-tsip.com> > --- > testsuite/repro-build-test.py | 68 > +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) > create mode 100755 testsuite/repro-build-test.py > > diff --git a/testsuite/repro-build-test.py > b/testsuite/repro-build-test.py new file mode 100755 > index 0000000..e89becf > --- /dev/null > +++ b/testsuite/repro-build-test.py > @@ -0,0 +1,68 @@ > +#!/usr/bin/env python3 > + > +import glob > +import os > +import re > +import tempfile > +import time > + > +from cibuilder import CIBuilder, isar_root > +from avocado.utils import process > + > +class ReproBuild(CIBuilder): > + > + """ > + Test reproducible builds by comparing the artifacts > + > + :avocado: tags=repro-build > + """ > + def test_repro_build(self): > + target = self.params.get('build_target', > default='mc:qemuamd64-bullseye:isar-image-base') > + source_date_epoch = self.params.get('source_date_epoch', > default=self.git_last_commit_timestamp()) > + self.init() > + self.build_repro_image(target, source_date_epoch, > 'image1.tar.gz') > + self.build_repro_image(target, source_date_epoch, > 'image2.tar.gz') > + self.compare_repro_image('image1.tar.gz', 'image2.tar.gz') > + > + def git_last_commit_timestamp(self): > + return process.run('git log -1 --pretty=%ct').stdout > + > + def get_image_path(self, target_name): > + image_dir = "tmp/deploy/images" > + target_params = target_name.split(':') > + machine = target_params[1].split('-')[0] > + distro = 'debian-' + target_params[1].split('-')[1] > + image_type = target_params[2] > + return > f'{image_dir}/{machine}/{image_type}-{distro}-{machine}.tar.gz' + > + def build_repro_image(self, target, source_date_epoch=None > ,image_name='image.tar.gz'): + > + if not source_date_epoch: > + self.error("Reproducible build should configure with > source_date_epoch time") + > + # clean artifacts before build > + self.clean() > + > + # Build > + self.log.info("Started Build " + image_name) > + self.configure(source_date_epoch=source_date_epoch) > + self.bitbake(target) > + > + # copy the artifacts image name with given name > + image_path = self.get_image_path(target) > + self.log.info("Copy image " + image_path + " as " + > image_name) > + self.move_in_build_dir(image_path, image_name) > + > + def clean(self): > + self.delete_from_build_dir('tmp') > + self.delete_from_build_dir('sstate-cache') > + > + def compare_repro_image(self, image1, image2): > + self.log.info("Compare artifacts image1: " + image1 + ", > image2: " + image2) > + result = process.run('diffoscope ' > + '--text ' + self.build_dir + > '/diffoscope-output.txt' > + ' ' + self.build_dir + '/' + image1 + > + ' ' + self.build_dir + '/' + image2 , > + ignore_status = True) > + if result.exit_status > 0: > + self.fail(f'Images {image1} and {image2} are not > reproducible')
diff --git a/testsuite/repro-build-test.py b/testsuite/repro-build-test.py new file mode 100755 index 0000000..e89becf --- /dev/null +++ b/testsuite/repro-build-test.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import glob +import os +import re +import tempfile +import time + +from cibuilder import CIBuilder, isar_root +from avocado.utils import process + +class ReproBuild(CIBuilder): + + """ + Test reproducible builds by comparing the artifacts + + :avocado: tags=repro-build + """ + def test_repro_build(self): + target = self.params.get('build_target', default='mc:qemuamd64-bullseye:isar-image-base') + source_date_epoch = self.params.get('source_date_epoch', default=self.git_last_commit_timestamp()) + self.init() + self.build_repro_image(target, source_date_epoch, 'image1.tar.gz') + self.build_repro_image(target, source_date_epoch, 'image2.tar.gz') + self.compare_repro_image('image1.tar.gz', 'image2.tar.gz') + + def git_last_commit_timestamp(self): + return process.run('git log -1 --pretty=%ct').stdout + + def get_image_path(self, target_name): + image_dir = "tmp/deploy/images" + target_params = target_name.split(':') + machine = target_params[1].split('-')[0] + distro = 'debian-' + target_params[1].split('-')[1] + image_type = target_params[2] + return f'{image_dir}/{machine}/{image_type}-{distro}-{machine}.tar.gz' + + def build_repro_image(self, target, source_date_epoch=None ,image_name='image.tar.gz'): + + if not source_date_epoch: + self.error("Reproducible build should configure with source_date_epoch time") + + # clean artifacts before build + self.clean() + + # Build + self.log.info("Started Build " + image_name) + self.configure(source_date_epoch=source_date_epoch) + self.bitbake(target) + + # copy the artifacts image name with given name + image_path = self.get_image_path(target) + self.log.info("Copy image " + image_path + " as " + image_name) + self.move_in_build_dir(image_path, image_name) + + def clean(self): + self.delete_from_build_dir('tmp') + self.delete_from_build_dir('sstate-cache') + + def compare_repro_image(self, image1, image2): + self.log.info("Compare artifacts image1: " + image1 + ", image2: " + image2) + result = process.run('diffoscope ' + '--text ' + self.build_dir + '/diffoscope-output.txt' + ' ' + self.build_dir + '/' + image1 + + ' ' + self.build_dir + '/' + image2 , + ignore_status = True) + if result.exit_status > 0: + self.fail(f'Images {image1} and {image2} are not reproducible')