diff options
Diffstat (limited to 'tools/testing/kunit/kunit_kernel.py')
| -rw-r--r-- | tools/testing/kunit/kunit_kernel.py | 84 | 
1 files changed, 58 insertions, 26 deletions
diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index d99ae75ef72f..63dbda2d029f 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -10,11 +10,16 @@  import logging  import subprocess  import os +import signal + +from contextlib import ExitStack  import kunit_config +import kunit_parser  KCONFIG_PATH = '.config'  kunitconfig_path = '.kunitconfig' +BROKEN_ALLCONFIG_PATH = 'tools/testing/kunit/configs/broken_on_uml.config'  class ConfigError(Exception):  	"""Represents an error trying to configure the Linux kernel.""" @@ -35,19 +40,40 @@ class LinuxSourceTreeOperations(object):  		except subprocess.CalledProcessError as e:  			raise ConfigError(e.output) -	def make_olddefconfig(self, build_dir): +	def make_olddefconfig(self, build_dir, make_options):  		command = ['make', 'ARCH=um', 'olddefconfig'] +		if make_options: +			command.extend(make_options)  		if build_dir:  			command += ['O=' + build_dir]  		try: -			subprocess.check_output(command) +			subprocess.check_output(command, stderr=subprocess.PIPE)  		except OSError as e:  			raise ConfigError('Could not call make command: ' + e)  		except subprocess.CalledProcessError as e:  			raise ConfigError(e.output) -	def make(self, jobs, build_dir): +	def make_allyesconfig(self): +		kunit_parser.print_with_timestamp( +			'Enabling all CONFIGs for UML...') +		process = subprocess.Popen( +			['make', 'ARCH=um', 'allyesconfig'], +			stdout=subprocess.DEVNULL, +			stderr=subprocess.STDOUT) +		process.wait() +		kunit_parser.print_with_timestamp( +			'Disabling broken configs to run KUnit tests...') +		with ExitStack() as es: +			config = open(KCONFIG_PATH, 'a') +			disable = open(BROKEN_ALLCONFIG_PATH, 'r').read() +			config.write(disable) +		kunit_parser.print_with_timestamp( +			'Starting Kernel with all configs takes a few minutes...') + +	def make(self, jobs, build_dir, make_options):  		command = ['make', 'ARCH=um', '--jobs=' + str(jobs)] +		if make_options: +			command.extend(make_options)  		if build_dir:  			command += ['O=' + build_dir]  		try: @@ -57,18 +83,16 @@ class LinuxSourceTreeOperations(object):  		except subprocess.CalledProcessError as e:  			raise BuildError(e.output) -	def linux_bin(self, params, timeout, build_dir): +	def linux_bin(self, params, timeout, build_dir, outfile):  		"""Runs the Linux UML binary. Must be named 'linux'."""  		linux_bin = './linux'  		if build_dir:  			linux_bin = os.path.join(build_dir, 'linux') -		process = subprocess.Popen( -			[linux_bin] + params, -			stdin=subprocess.PIPE, -			stdout=subprocess.PIPE, -			stderr=subprocess.PIPE) -		process.wait(timeout=timeout) -		return process +		with open(outfile, 'w') as output: +			process = subprocess.Popen([linux_bin] + params, +						   stdout=output, +						   stderr=subprocess.STDOUT) +			process.wait(timeout)  def get_kconfig_path(build_dir): @@ -84,6 +108,7 @@ class LinuxSourceTree(object):  		self._kconfig = kunit_config.Kconfig()  		self._kconfig.read_from_file(kunitconfig_path)  		self._ops = LinuxSourceTreeOperations() +		signal.signal(signal.SIGINT, self.signal_handler)  	def clean(self):  		try: @@ -107,19 +132,19 @@ class LinuxSourceTree(object):  			return False  		return True -	def build_config(self, build_dir): +	def build_config(self, build_dir, make_options):  		kconfig_path = get_kconfig_path(build_dir)  		if build_dir and not os.path.exists(build_dir):  			os.mkdir(build_dir)  		self._kconfig.write_to_file(kconfig_path)  		try: -			self._ops.make_olddefconfig(build_dir) +			self._ops.make_olddefconfig(build_dir, make_options)  		except ConfigError as e:  			logging.error(e)  			return False  		return self.validate_config(build_dir) -	def build_reconfig(self, build_dir): +	def build_reconfig(self, build_dir, make_options):  		"""Creates a new .config if it is not a subset of the .kunitconfig."""  		kconfig_path = get_kconfig_path(build_dir)  		if os.path.exists(kconfig_path): @@ -128,26 +153,33 @@ class LinuxSourceTree(object):  			if not self._kconfig.is_subset_of(existing_kconfig):  				print('Regenerating .config ...')  				os.remove(kconfig_path) -				return self.build_config(build_dir) +				return self.build_config(build_dir, make_options)  			else:  				return True  		else:  			print('Generating .config ...') -			return self.build_config(build_dir) +			return self.build_config(build_dir, make_options) -	def build_um_kernel(self, jobs, build_dir): +	def build_um_kernel(self, alltests, jobs, build_dir, make_options): +		if alltests: +			self._ops.make_allyesconfig()  		try: -			self._ops.make_olddefconfig(build_dir) -			self._ops.make(jobs, build_dir) +			self._ops.make_olddefconfig(build_dir, make_options) +			self._ops.make(jobs, build_dir, make_options)  		except (ConfigError, BuildError) as e:  			logging.error(e)  			return False  		return self.validate_config(build_dir) -	def run_kernel(self, args=[], timeout=None, build_dir=''): -		args.extend(['mem=256M']) -		process = self._ops.linux_bin(args, timeout, build_dir) -		with open(os.path.join(build_dir, 'test.log'), 'w') as f: -			for line in process.stdout: -				f.write(line.rstrip().decode('ascii') + '\n') -				yield line.rstrip().decode('ascii') +	def run_kernel(self, args=[], build_dir='', timeout=None): +		args.extend(['mem=1G']) +		outfile = 'test.log' +		self._ops.linux_bin(args, timeout, build_dir, outfile) +		subprocess.call(['stty', 'sane']) +		with open(outfile, 'r') as file: +			for line in file: +				yield line + +	def signal_handler(self, sig, frame): +		logging.error('Build interruption occurred. Cleaning console.') +		subprocess.call(['stty', 'sane'])  |