def test_live_build_no_cross_build(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) resources.enter_context( patch('ubuntu_image.helpers.get_host_arch', return_value='amd64')) resources.enter_context( patch('ubuntu_image.helpers.find_executable', return_value='/usr/bin/qemu-arm-static')) env = OrderedDict() env['PROJECT'] = 'ubuntu-server' env['SUITE'] = 'xenial' env['ARCH'] = 'armhf' live_build(root_dir, env, enable_cross_build=False) # Make sure that if we explicity disable cross-building, no # cross-build arguments are passed to lb config self.assertEqual(len(mock.call_args_list), 3) self.assertEqual( mock.call_args_list[1], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=armhf', 'lb', 'config'])
def test_state_machine_snap_command_fails(self): # The `snap prepare-image` command fails and main exits with non-zero. # # This tests needs to run the actual snap() helper function, not # the testsuite-wide mock. This is appropriate since we're # mocking it ourselves here. if NosePlugin.snap_mocker is not None: NosePlugin.snap_mocker.patcher.stop() self._resources.callback(NosePlugin.snap_mocker.patcher.start) self._resources.enter_context( patch('ubuntu_image.helpers.subprocess_run', return_value=SimpleNamespace( returncode=1, stdout='command stdout', stderr='command stderr', check_returncode=check_returncode, ))) self._resources.enter_context(LogCapture()) self._resources.enter_context( patch('ubuntu_image.__main__.ModelAssertionBuilder', XXXModelAssertionBuilder)) workdir = self._resources.enter_context(TemporaryDirectory()) imgfile = os.path.join(workdir, 'my-disk.img') code = main( ('--until', 'prepare_filesystems', '--channel', 'edge', '--workdir', workdir, '--output', imgfile, 'model.assertion')) self.assertEqual(code, 1)
def test_live_build_with_full_args(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context(patch('ubuntu_image.helpers.run', mock.run)) resources.enter_context( patch('ubuntu_image.helpers.get_host_arch', return_value='amd64')) env = OrderedDict() env['PROJECT'] = 'ubuntu-cpc' env['SUITE'] = 'xenial' env['ARCH'] = 'amd64' env['SUBPROJECT'] = 'live' env['SUBARCH'] = 'ubuntu-cpc' env['PROPOSED'] = 'true' env['IMAGEFORMAT'] = 'ext4' env['EXTRA_PPAS'] = '******' live_build(root_dir, env) self.assertEqual(len(mock.call_args_list), 3) self.assertEqual(mock.call_args_list[1], [ 'sudo', 'PROJECT=ubuntu-cpc', 'SUITE=xenial', 'ARCH=amd64', 'SUBPROJECT=live', 'SUBARCH=ubuntu-cpc', 'PROPOSED=true', 'IMAGEFORMAT=ext4', 'EXTRA_PPAS=foo1/bar1 foo2', 'lb', 'config' ]) self.assertEqual(mock.call_args_list[2], [ 'sudo', 'PROJECT=ubuntu-cpc', 'SUITE=xenial', 'ARCH=amd64', 'SUBPROJECT=live', 'SUBARCH=ubuntu-cpc', 'PROPOSED=true', 'IMAGEFORMAT=ext4', 'EXTRA_PPAS=foo1/bar1 foo2', 'lb', 'build' ])
def test_live_build_cross_build(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) resources.enter_context( patch('ubuntu_image.helpers.get_host_arch', return_value='amd64')) resources.enter_context( patch('ubuntu_image.helpers.find_executable', return_value='/usr/bin/qemu-arm-static-fake')) env = OrderedDict() env['PROJECT'] = 'ubuntu-server' env['SUITE'] = 'xenial' env['ARCH'] = 'armhf' live_build(root_dir, env) self.assertEqual(len(mock.call_args_list), 3) self.assertEqual( mock.call_args_list[1], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=armhf', 'lb', 'config', '--bootstrap-qemu-arch', 'armhf', '--bootstrap-qemu-static', '/usr/bin/qemu-arm-static-fake', '--architectures', 'armhf']) self.assertEqual( mock.call_args_list[2], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=armhf', 'lb', 'build'])
def test_live_build_env_livecd(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) auto_dir = os.path.join(tmpdir, 'auto') os.mkdir(auto_dir) with open(os.path.join(auto_dir, 'config'), 'w') as fp: fp.write('DUMMY') root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) resources.enter_context( envar('UBUNTU_IMAGE_LIVECD_ROOTFS_AUTO_PATH', auto_dir)) env = OrderedDict() env['PROJECT'] = 'ubuntu-server' env['SUITE'] = 'xenial' env['ARCH'] = 'amd64' live_build(root_dir, env) # Make sure that we had no dpkg -L call made. self.assertEqual(len(mock.call_args_list), 2) self.assertEqual( mock.call_args_list[0], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=amd64', 'lb', 'config']) self.assertEqual( mock.call_args_list[1], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=amd64', 'lb', 'build']) config_path = os.path.join(root_dir, 'auto', 'config') self.assertTrue(os.path.exists(config_path)) with open(os.path.join(config_path), 'r') as fp: self.assertEqual(fp.read(), 'DUMMY')
def test_run_fails_no_output(self): with ExitStack() as resources: log = resources.enter_context(LogCapture()) resources.enter_context( patch('ubuntu_image.helpers.subprocess_run', return_value=FakeProcNoOutput())) run('/bin/false') self.assertEqual(log.logs, [ (logging.ERROR, 'COMMAND FAILED: /bin/false'), ])
def test_bad_gadget_log(self): log = self._resources.enter_context(LogCapture()) workdir = self._resources.enter_context(TemporaryDirectory()) self._resources.enter_context( patch('ubuntu_image.__main__.ModelAssertionBuilder', BadGadgetModelAssertionBuilder)) main(('--channel', 'edge', '--workdir', workdir, self.model_assertion)) self.assertEqual(log.logs, [(logging.ERROR, 'gadget.yaml parse error: ' 'GUID structure type with non-GPT schema'), (logging.ERROR, 'Use --debug for more information')])
def test_snap(self): model = resource_filename('ubuntu_image.tests.data', 'model.assertion') with ExitStack() as resources: resources.enter_context(LogCapture()) mock = resources.enter_context( patch('ubuntu_image.helpers.subprocess_run', return_value=FakeProc())) tmpdir = resources.enter_context(TemporaryDirectory()) snap(model, tmpdir) self.assertEqual(len(mock.call_args_list), 1) args, kws = mock.call_args_list[0] self.assertEqual(args[0], ['snap', 'prepare-image', model, tmpdir])
def test_live_build_command_fails_debug(self): with ExitStack() as resources: workdir = resources.enter_context(TemporaryDirectory()) unpackdir = resources.enter_context(TemporaryDirectory()) # Fast forward a state machine to the method under test. args = SimpleNamespace( cmd='classic', project='ubuntu-cpc', suite='xenial', arch='amd64', image_format='img', unpackdir=unpackdir, workdir=workdir, debug=True, cloud_init=None, output=None, subproject=None, subarch=None, output_dir=None, with_proposed=None, extra_ppas=None, hooks_directory=[], disk_info=None, disable_console_conf=False, gadget_tree=self.gadget_tree, filesystem=None, ) # Jump right to the method under test. state = resources.enter_context(XXXClassicBuilder(args)) state.unpackdir = unpackdir state._next.pop() state._next.append(state.prepare_image) resources.enter_context( patch('ubuntu_image.helpers.subprocess_run', return_value=SimpleNamespace( returncode=1, stdout='command stdout', stderr='command stderr', check_returncode=check_returncode, ))) log_capture = resources.enter_context(LogCapture()) next(state) self.assertEqual(state.exitcode, 1) # Note that there is traceback in the output now. self.assertEqual(log_capture.logs, [ (logging.ERROR, 'COMMAND FAILED: dpkg -L livecd-rootfs | grep "auto$"'), (logging.ERROR, 'command stdout'), (logging.ERROR, 'command stderr'), (logging.ERROR, 'Full debug traceback follows'), ('IMAGINE THE TRACEBACK HERE'), ])
def test_bad_gadget_debug_log(self): log = self._resources.enter_context(LogCapture()) workdir = self._resources.enter_context(TemporaryDirectory()) self._resources.enter_context( patch('ubuntu_image.__main__.ModelAssertionBuilder', BadGadgetModelAssertionBuilder)) main(('snap', '--debug', '--workdir', workdir, '--channel', 'edge', self.model_assertion)) self.assertEqual(log.logs, [ (logging.ERROR, 'uncaught exception in state machine step: ' '[3] load_gadget_yaml'), 'IMAGINE THE TRACEBACK HERE', (logging.ERROR, 'gadget.yaml parse error'), 'IMAGINE THE TRACEBACK HERE', ])
def test_live_build_cross_build_no_static(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context(patch('ubuntu_image.helpers.run', mock.run)) resources.enter_context( patch('ubuntu_image.helpers.get_host_arch', return_value='amd64')) resources.enter_context( patch('ubuntu_image.helpers.find_executable', return_value=None)) env = OrderedDict() env['PROJECT'] = 'ubuntu-server' env['SUITE'] = 'xenial' env['ARCH'] = 'armhf' with self.assertRaises(DependencyError) as cm: live_build(root_dir, env) self.assertEqual(len(mock.call_args_list), 1) self.assertEqual(cm.exception.name, 'qemu-arm-static')
def test_live_build(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) root_dir = os.path.join(tmpdir, 'root_dir') mock = LiveBuildMocker(root_dir) resources.enter_context(LogCapture()) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) env = OrderedDict() env['PROJECT'] = 'ubuntu-server' env['SUITE'] = 'xenial' env['ARCH'] = 'amd64' live_build(root_dir, env) self.assertEqual(len(mock.call_args_list), 3) self.assertEqual( mock.call_args_list[1], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=amd64', 'lb', 'config']) self.assertEqual( mock.call_args_list[2], ['sudo', 'PROJECT=ubuntu-server', 'SUITE=xenial', 'ARCH=amd64', 'lb', 'build'])