From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web11.1156.1664502959898933557 for ; Thu, 29 Sep 2022 18:56:02 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=QpmNNSkW; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: gua.guo@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1664502962; x=1696038962; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qBXmQbGBruUWvDZbBtqQCCC7VBg/XVzxv8ZebASNc9I=; b=QpmNNSkWbGt23aug5kL8+pIVJWQpj4MKwyBn8U1RoE1nL2bEg0xgriow PfTy5x8iIt9K0AXTLWrQXqVaHavJMosXo8E0hlg+rYgxgY+oFc6bWPhoa gzPTehT+v0UecT8WzbebM0bT2ayXY46+XPwLXurLsw8yNWDeg+vlBethZ Gwxb2+kzL280b+c1BApTX+XqLformARPxUuV00Ij9gBm/wbQFpxKqX14l ZOJnWg5/frzyVluBjcnl89DIMD/lhrlZp4OQ+74OLG6oeQ0WRsDRx6jKy vcTlADXW4liJS6NXoRbUE4ppHtDdpHBtVep9PxbhGZRQPxW268Kmxr6qP A==; X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="281788309" X-IronPort-AV: E=Sophos;i="5.93,357,1654585200"; d="scan'208";a="281788309" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Sep 2022 18:56:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="726671317" X-IronPort-AV: E=Sophos;i="5.93,357,1654585200"; d="scan'208";a="726671317" Received: from gguo-desk.gar.corp.intel.com ([10.5.215.23]) by fmsmga002.fm.intel.com with ESMTP; 29 Sep 2022 18:56:00 -0700 From: "Guo, Gua" To: devel@edk2.groups.io Cc: Gua Guo , Bob Feng , Bret Barkelew , Liming Gao , Michael D Kinney , Sean Brogan Subject: [PATCH v5 2/3] BaseTools/Plugin: Add coverage support for Unit Test Date: Fri, 30 Sep 2022 09:55:55 +0800 Message-Id: <487d272749228714039d4da8b4f48d66533383ec.1664502910.git.gua.guo@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Gua Guo For GCC, use lcov to generate Unit Test code coverage report For VS2019, use OpenCppCoverage to generate code coverage report Cc: Bob Feng Cc: Bret Barkelew Cc: Liming Gao Cc: Michael D Kinney Cc: Sean Brogan Signed-off-by: Gua Guo --- .../HostBasedUnitTestRunner.py | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunn= er.py b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py index c1eeaf2625..d92de236dc 100644 --- a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py +++ b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py @@ -112,4 +112,123 @@ class HostBasedUnitTestRunner(IUefiBuildPlugin): " %s - %s" % (case.attrib['na= me'], result.text))=0D failure_count +=3D 1=0D =0D + if thebuilder.env.GetValue("TOOL_CHAIN_TAG") =3D=3D "GCC5":=0D + self.gen_code_coverage_gcc(thebuilder)=0D + elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") =3D=3D "VS2019"= :=0D + self.gen_code_coverage_msvc(thebuilder)=0D + else:=0D + logging.info("Skipping code coverage. Only supported on GC= C.")=0D +=0D return failure_count=0D +=0D + def gen_code_coverage_gcc(self, thebuilder):=0D + logging.info("Generating UnitTest code coverage")=0D +=0D + buildOutputBase =3D thebuilder.env.GetValue("BUILD_OUTPUT_BASE")=0D + workspace =3D thebuilder.env.GetValue("WORKSPACE")=0D +=0D + # Generate base code coverage for all source files=0D + ret =3D RunCmd("lcov", f"--no-external --capture --initial --direc= tory {buildOutputBase} --output-file {buildOutputBase}/cov-base.info --rc l= cov_branch_coverage=3D1")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to build initial cove= rage data.")=0D + return 1=0D +=0D + # Coverage data for tested files only=0D + ret =3D RunCmd("lcov", f"--capture --directory {buildOutputBase}/ = --output-file {buildOutputBase}/coverage-test.info --rc lcov_branch_coverag= e=3D1")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to build coverage dat= a for tested files.")=0D + return 1=0D +=0D + # Aggregate all coverage data=0D + ret =3D RunCmd("lcov", f"--add-tracefile {buildOutputBase}/cov-bas= e.info --add-tracefile {buildOutputBase}/coverage-test.info --output-file {= buildOutputBase}/total-coverage.info --rc lcov_branch_coverage=3D1")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to aggregate coverage= data.")=0D + return 1=0D +=0D + # Generate coverage XML=0D + ret =3D RunCmd("lcov_cobertura",f"{buildOutputBase}/total-coverage= .info -o {buildOutputBase}/compare.xml")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate coverage = XML.")=0D + return 1=0D +=0D + # Filter out auto-generated and test code=0D + ret =3D RunCmd("lcov_cobertura",f"{buildOutputBase}/total-coverage= .info --excludes ^.*UnitTest\|^.*MU\|^.*Mock\|^.*DEBUG -o {buildOutputBase}= /coverage.xml")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed generate filtered cov= erage XML.")=0D + return 1=0D +=0D + # Generate all coverage file=0D + testCoverageList =3D glob.glob (f"{workspace}/Build/**/total-cover= age.info", recursive=3DTrue)=0D +=0D + coverageFile =3D ""=0D + for testCoverage in testCoverageList:=0D + coverageFile +=3D " --add-tracefile " + testCoverage=0D + ret =3D RunCmd("lcov", f"{coverageFile} --output-file {workspace}/= Build/all-coverage.info --rc lcov_branch_coverage=3D1")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed generate all coverage= file.")=0D + return 1=0D +=0D + # Generate and HTML file if requested.by each package=0D + ret =3D RunCmd("pycobertura", f"show --format html --output {build= OutputBase}/coverage.html {buildOutputBase}/coverage.xml --source {workspac= e}")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate HTML in s= ingle package..")=0D +=0D + # Generate and HTML file if requested.for all package=0D + if os.path.isfile(f"{workspace}/Build/coverage.xml"):=0D + os.remove(f"{workspace}/Build/coverage.xml")=0D + ret =3D RunCmd("lcov_cobertura",f"{workspace}/Build/all-coverage.i= nfo --excludes ^.*UnitTest\|^.*MU\|^.*Mock\|^.*DEBUG -o {workspace}/Build/c= overage.xml")=0D +=0D + if os.path.isfile(f"{workspace}/Build/coverage.html"):=0D + os.remove(f"{workspace}/Build/coverage.html")=0D + ret =3D RunCmd("pycobertura", f"show --format html --output {works= pace}/Build/coverage.html {workspace}/Build/coverage.xml --source {workspac= e}")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate HTML.")=0D +=0D + return 0=0D +=0D +=0D + def gen_code_coverage_msvc(self, thebuilder):=0D + logging.info("Generating UnitTest code coverage")=0D +=0D +=0D + buildOutputBase =3D thebuilder.env.GetValue("BUILD_OUTPUT_BASE")=0D + testList =3D glob.glob(os.path.join(buildOutputBase, "**","*Test*.= exe"), recursive=3DTrue)=0D + workspace =3D thebuilder.env.GetValue("WORKSPACE")=0D +=0D + # Generate coverage file=0D + coverageFile =3D ""=0D + for testFile in testList:=0D + ret =3D RunCmd("OpenCppCoverage", f"--source {workspace} --exp= ort_type binary:{testFile}.cov -- {testFile}")=0D + coverageFile +=3D " --input_coverage=3D" + testFile + ".cov"=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to collect covera= ge data.")=0D + return 1=0D +=0D + # Generate and HTML file if requested.by each package=0D + ret =3D RunCmd("OpenCppCoverage", f"--export_type cobertura:{build= OutputBase}/coverage.xml --working_dir=3D{workspace}/Build {coverageFile}")= =0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate cobertura= format xml in single package.")=0D + return 1=0D +=0D + ret =3D RunCmd("pycobertura", f"show --format html --output {build= OutputBase}/cverage.html {buildOutputBase}/coverage.xml --source {workspace= }")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate HTML in s= ingle package.")=0D + return 1=0D +=0D + # Generate total report HTML file for all package=0D + testCoverageList =3D glob.glob(os.path.join(workspace, "Build", "*= *","*Test*.exe.cov"), recursive=3DTrue)=0D + coverageFile =3D ""=0D + for testCoverage in testCoverageList:=0D + coverageFile +=3D " --input_coverage=3D" + testCoverage=0D +=0D + ret =3D RunCmd("OpenCppCoverage", f"--export_type cobertura:{works= pace}/Build/coverage.xml --working_dir=3D{workspace}/Build {coverageFile}")= =0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate cobertura= format xml.")=0D + return 1=0D +=0D + ret =3D RunCmd("pycobertura", f"show --format html --output {works= pace}/Build/coverage.html {workspace}/Build/coverage.xml --source {workspac= e}")=0D + if(ret !=3D 0):=0D + logging.error("UnitTest Coverage: Failed to generate HTML.")=0D + return 1=0D +=0D + return 0=0D --=20 2.31.1.windows.1