Skip to content
Merged
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
234 changes: 95 additions & 139 deletions testcases/OpTestKernelTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ def setUp(self):
if not (self.conf.args.host_ip and self.conf.args.host_user and self.conf.args.host_password):
self.fail(
"Provide host ip user details refer, --host-{ip,user,password}")

def build_kernel(self):
"""
Build and install the Linux kernel.
"""
self.config_path = self.conf.args.git_repoconfigpath

def is_url(path):
'''
param path: path to download
Expand All @@ -94,16 +87,21 @@ def is_url(path):
self.con.run_command("cd {}".format(self.home))
if not self.branch:
self.branch='master'
self.con.run_command("git clone -b {} {} linux".format( self.branch, self.repo),timeout=3000)
self.con.run_command("git clone --depth 1 -b {} {} linux".format(self.branch, self.repo),timeout=3000)
self.con.run_command("cd linux")
self.commit = self.con.run_command(" git log -1 --format=%H | sed -r 's/\x1B\[[0-9:]*[JKsu]//g'")
self.head_commit = self.con.run_command(" git log -1 --format=%H | sed -r 's/\x1B\[[0-9:]*[JKsu]//g'")
self.con.run_command("cd ..")
if self.config_path:
if is_url(self.config_path):
self.con.run_command("wget %s -O linux/.config" % self.config_path)
else:
self.cv_HOST.copy_test_file_to_host(self.config_path, sourcedir="", dstdir=os.path.join(self.linux_path, ".config"))
self.con.run_command("cd linux && make olddefconfig", timeout=60)

def build_kernel(self):
"""
Build and install the Linux kernel.
"""
self.con.run_command("cd {} && make olddefconfig".format(self.linux_path), timeout=60)
# the below part of the code is needed for only first run and will be decided bisect flag false
self.ker_ver = self.con.run_command("make kernelrelease")[-1]
sha = self.con.run_command("git rev-parse HEAD")
Expand All @@ -120,7 +118,7 @@ def is_url(path):
return 0,err
except CommandFailed as e:
log.error("Kernel build failed: {}".format(e))
return 4,e
return 4,e

def Store_loc(self, er) :
"""
Expand Down Expand Up @@ -198,153 +196,111 @@ def boot_kernel(self):
log.error("Kexec failed, booted back to base kernel !")
return True

class KernelBuild(KernelTest):
"""
Does the build for any Linux repo and in case of build failure, calls build bisector
from OpTestUtils to give first bad commit and related information along with email template.
"""

def setUp(self):
"""
Does setup for KernelBUild from parent KernelTest
"""
super(KernelBuild,self).setUp()

def runTest(self):
"""
Clones git repo and builds to check for failure and do bisection
"""
log.info("KERNEL BUILD STARTING")
error = self.build_kernel()
bi_flag = False
exit_code = error[0]
errVal = str(error[1])
log.info("printing the exit code '{}'".format(exit_code))
log.info("Printing the build exit code '{}'".format(exit_code))
entry=[]
err_msg=[]
if exit_code != 0:
entry = self.Store_loc(errVal)[-1]
err_msg= self.util.err_message(error)
badCommit = self.commit[-1]
if self.bisect_flag == '1':
log.info("STARTING BUILD_BISECTION")
log.info("BUILD_BISECTION STARTED")
res = self.util.build_bisector(self.linux_path, self.good_commit, self.repo)
log.info("BUILD_BISECTION ENDED")
emaili=res[0]
commiti=res[1]
log.info("revert commit check is manual for now")
else :
emaili=""
commiti=self.commit[-1]
else :
emaili=""
commiti=self.commit[-1]
with open('output.json','w') as f:
json.dump({"exit_code":exit_code,"email":emaili,"commit": commiti,"error":entry,"err_msg":err_msg,"flag":self.bisect_flag},f)
if exit_code != 0:
self.util.format_email(self.linux_path, self.repo)

def tearDown(self):
self.console_thread.console_terminate()
self.con.close()


class KernelBoot(KernelTest):

def setUp(self):
"""
Does setup for KernelBoot from parent KernelTest
"""
super(KernelBoot,self).setUp()

def runTest(self):
"""
Clones git repo and boots the kernel to check for failure and do bisection
"""
self.con.run_command("if [ -d {} ]; then rm -rf {}; fi".format(self.home,self.home))
self.con.run_command("if [ ! -d {} ]; then mkdir -p {}; fi".format(self.home,self.home))
self.con.run_command("cd {}".format(self.home))
if not self.branch:
self.branch='master'
self.con.run_command("git clone -b {} {} linux".format( self.branch, self.repo),timeout=3000)
self.con.run_command("cd linux")
commit = self.con.run_command(" git log -1 --format=%H | sed -r 's/\x1B\[[0-9:]*[JKsu]//g'")
self.con.run_command("cd ..")
error = self.build_kernel()
exit_code = error[0]
if exit_code != 0:
return "Build Failure in boot, check build bisection Aborting"
log.info("BOOOT STARTING")
boot = False
try :
boot = self.boot_kernel()
except Exception as e:
log.info("EXCEPTION")
if not boot and self.bisect_flag == '1':
count = 0
exit_code = 4
local_path = os.getcwd()
log.info("BOOT BISECTION STARTING")
self.con.run_command("cd {}; make clean".format(self.linux_path), timeout=60)
dmessage = self.con.run_command("dmesg --color=never --level=warn")
subprocess.run(f"if [ -d {self.local_path} ]; then rm -rf {self.local_path}; fi", shell=True, check=True)
subprocess.run("git config --global http.postBuffer 1048576000", shell=True, check=True)
subprocess.run(f"git clone -b {self.branch} {self.repo} linux", shell=True, check=True, timeout=1800)
subprocess.run(f"cd {self.local_path}", shell=True, check=True)
try:
subprocess.run("git bisect start", shell=True, check=True, cwd=self.local_path)
subprocess.run("git bisect bad", shell=True, check=True, cwd=self.local_path)
folder_type=re.split(r'[\/\\.]',str(self.repo))[-2]
if folder_type == 'linux-next':
subprocess.run("git fetch --tags" , shell=True, check=True)
good_tag=subprocess.run("git tag -l 'v[0-9]*' | sort -V | tail -n 1", shell=True, check=True)
subprocess.run(f"git bisect good {good_tag}", shell=True, check=True, cwd=self.local_path)
else:
subprocess.run("pwd")
subprocess.run(f"git bisect good {self.good_commit}", shell=True, check=True, cwd=self.local_path)
while True:
log.info("ENTERED BISECTION LOOP {}".format(count))
subprocess.run("git bisect next", shell=True, check=True, cwd=self.local_path)
commit_to_test = subprocess.check_output("git rev-parse HEAD", shell=True, cwd=self.local_path).decode().strip()
log.info(commit_to_test)
self.con.run_command(" if [ '$(pwd)' != {} ]; then cd {} || exit 1 ; fi ; bind 'set enable-bracketed-paste off'".format(self.linux_path,self.linux_path))
self.con.run_command("git checkout {}; git checkout {};".format(self.branch,commit_to_test))
result = self.boot_kernel()
count += 1
if result == True:
log.info("\n ------ git bisect good {} ------ \n".format(commit_to_test))
subprocess.run("git bisect good", shell=True, check=True, cwd=self.local_path)
AuthEmail=res[0]
NewBadCommit=res[1]
bi_flag = True
log.info("Please manually revert and test the bad commit")
else:
log.info("KERNEL BOOT STARTING")
boot = False
try :
boot = self.boot_kernel()
except Exception as e:
log.info("EXCEPTION")
if not boot and self.bisect_flag == '1':
count = 0
exit_code = 4
log.info("BOOT_BISECTION STARTED")
self.con.run_command("cd {}; make clean".format(self.linux_path), timeout=60)
shallow = self.con.run_command("git rev-parse --is-shallow-repository")
if shallow[-1] in [True,'true']:
self.con.run_command("git fetch --unshallow",timeout=3000)
dmessage = self.con.run_command("dmesg --color=never --level=warn")
subprocess.run(f"if [ -d {self.local_path} ]; then rm -rf {self.local_path}; fi", shell=True, check=True)
subprocess.run("git config --global http.postBuffer 1048576000", shell=True, check=True)
subprocess.run(f"git clone -b {self.branch} {self.repo} linux", shell=True, check=True, timeout=1800)
subprocess.run(f"cd {self.local_path}", shell=True, check=True)
try:
subprocess.run("git bisect start", shell=True, check=True, cwd=self.local_path)
subprocess.run("git bisect bad", shell=True, check=True, cwd=self.local_path)
folder_type=re.split(r'[\/\\.]',str(self.repo))[-2]
if folder_type == 'linux-next':
subprocess.run("git fetch --tags" , shell=True, check=True)
good_tag=subprocess.run("git tag -l 'v[0-9]*' | sort -V | tail -n 1", shell=True, check=True)
subprocess.run(f"git bisect good {good_tag}", shell=True, check=True, cwd=self.local_path)
else:
log.info("\n ------ git bisect bad {} ------ \n".format(commit_to_test))
subprocess.run("git bisect bad", shell=True, check=True, cwd=self.local_path)
bilogs = []
bilogs = subprocess.check_output("git bisect log", shell=True, cwd=self.local_path).decode().split('\n')
biflag = False
for logs in bilogs:
if 'first bad commit' in logs:
badCommit = commit_to_test
biflag = True
if biflag:
break
except subprocess.CalledProcessError as e:
log.info("Error:", e)
finally:
bilogs = subprocess.run("git bisect log", shell=True, check=True, cwd=self.local_path)
log.info(bilogs)
entry = self.con.run_command("dmesg --color=never --level=warn | grep 'WARNING:'")
emaili = subprocess.run("git config --global color.ui true;git show --format=%ce {} | sed -r 's/\x1B\[[0-9:]*[JKsu]//g'".format(badCommit), shell=True, check=True, cwd=self.local_path)
subprocess.run("git bisect reset", shell=True, check=True,cwd=self.local_path)
log.info("Boot Bisection Completed ! Bad Commit: {} Author: {}".format(badCommit,emaili))
# WRITING BOOT BISECTION DATA TO JSON AND FORMAT EMAIL FOR BOOT REPORT IS TODO
#with open('output.json','w') as f:
# json.dump({"exit_code":exit_code,"email":emaili,"commit": badCommit,"error":entry,"err_msg":dmessage,"flag":self.bisect_flag},f)
#self.util.format_email(self.linux_path, self.repo)
elif boot and self.bisect_flag == '1':
exit_code = 0
goodCommit = commit
log.info("Boot Successfull.. Updating the last good commit to json")
subprocess.run("pwd")
subprocess.run(f"git bisect good {self.good_commit}", shell=True, check=True, cwd=self.local_path)
while True:
log.info("ENTERED BISECTION LOOP {}".format(count))
subprocess.run("git bisect next", shell=True, check=True, cwd=self.local_path)
commit_to_test = subprocess.check_output("git rev-parse HEAD", shell=True, cwd=self.local_path).decode().strip()
log.info(commit_to_test)
self.con.run_command(" if [ '$(pwd)' != {} ]; then cd {} || exit 1 ; fi ; bind 'set enable-bracketed-paste off'".format(self.linux_path,self.linux_path))
self.con.run_command("git checkout {}; git checkout {};".format(self.branch,commit_to_test))
res_out = self.build_kernel()
exit_code = res_out[0]
if exit_code != 0:
log.info("Build error in boot bisection consider as good")
result = True
else:
result = self.boot_kernel()
count += 1
if result == True:
log.info("\n ------ git bisect good {} ------ \n".format(commit_to_test))
subprocess.run("git bisect good", shell=True, check=True, cwd=self.local_path)
else:
log.info("\n ------ git bisect bad {} ------ \n".format(commit_to_test))
subprocess.run("git bisect bad", shell=True, check=True, cwd=self.local_path)
bilogs = []
bilogs = subprocess.check_output("git bisect log", shell=True, cwd=self.local_path).decode().split('\n')
for logs in bilogs:
if 'first bad commit' in logs:
NewBadCommit = commit_to_test
bi_flag = True
if bi_flag:
break
except subprocess.CalledProcessError as e:
log.info("Error:", e)
finally:
bilogs = subprocess.run("git bisect log", shell=True, check=True, cwd=self.local_path)
log.info(bilogs)
entry = self.con.run_command("dmesg --color=never --level=warn | grep 'WARNING:'")
AuthEmail = subprocess.run("git config --global color.ui true;git show --format=%ce {} | sed -r 's/\x1B\[[0-9:]*[JKsu]//g'".format(badCommit), shell=True, check=True, cwd=self.local_path)
subprocess.run("git bisect reset", shell=True, check=True,cwd=self.local_path)
log.info("Boot Bisection Completed ! Bad Commit: {} Author: {}".format(NewBadCommit, AuthEmail))
elif boot and self.bisect_flag == '1':
exit_code = 0
self.bisect_flag = 0
NewGoodCommit = self.head_commit[0]
log.info("Boot Successfull.. Updating the last good commit to json")
if bi_flag:
with open('output.json','w') as f:
json.dump({"exit_code":exit_code,"commit": goodCommit,"flag":self.bisect_flag},f)
json.dump({"exit_code":exit_code,"email":AuthEmail,"commit": NewBadCommit,"error":entry,"err_msg":err_msg,"flag":self.bisect_flag},f)
self.util.format_email(self.linux_path, self.repo)
else:
log.info("BOOT FAILED, NO BISECTION SELECTED")
with open('output.json','w') as f:
json.dump({"exit_code":exit_code,"commit": NewGoodCommit, "flag":self.bisect_flag},f)

def tearDown(self):
self.console_thread.console_terminate()
Expand Down