Skip to content

Run tests, then collect result and coverage #24

Run tests, then collect result and coverage

Run tests, then collect result and coverage #24

name: Run tests, then collect result and coverage
#on: { push: { paths-ignore: [ 'README.md', 'LICENSE', '**/requirements.txt' ] }, workflow_dispatch }
on: { workflow_dispatch }
# Configuration
env:
strPlatform: x86 # or x64
strConfiguration: Debug # or Release
strNameOccSetupFile: OpenCppCoverageSetup-x86-0.9.9.0.exe
strGhTagOccSetupFile: release-0.9.9.0 # from https://github.com/OpenCppCoverage/OpenCppCoverage/tags
strNameCppcheckSetupFile: cppcheck-2.11-x64-Setup.msi
strGhTagCppcheckSetupFile: 2.11 # from https://github.com/danmar/cppcheck/releases/tag/
strOccExecutable: OpenCppCoverage.exe
relHtmlReport: HtmlReportOcc
strCoberturaReport: CoberturaReportOcc.xml
relGtestOutput: GtestOutput
module0: GTest1.exe
module1: GTestDefWindowProc.exe
module2: GTestEmptyWorkingSet.exe
module3: GTestMem.exe
jobs:
collect-tests-code-coverage:
runs-on: windows-latest
permissions:
actions: read # for "dawidd6/action-download-artifact@v2"
contents: read # for "actions/checkout@v3" when GITHUB_TOKEN
steps:
- uses: actions/checkout@v3
- name: Set values (windows-latest)
run: | # build from *.sln, all tests
echo "dirTestExecutables=${{github.workspace}}\qa\UnitTest\bin\${{env.strPlatform}}\${{env.strConfiguration}}" >> $env:GITHUB_ENV
echo "strCfg=${{env.strPlatform}}-${{env.strConfiguration}}" >> $env:GITHUB_ENV
echo "dirSetupOcc=${env:Programfiles}\Occ" >> $env:GITHUB_ENV
echo "dirSetupCppcheck=${env:Programfiles}\cppcheck" >> $env:GITHUB_ENV
- name: Download artifact
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-tests-gtest-debug-x86.yml
name: artifact-build-tests-gtest-${{env.strCfg}}
path: ${{env.dirTestExecutables}}
search_artifacts: true
- name: Cache tool Occ
uses: actions/cache@v3
with:
path: ${{env.dirSetupOcc}}
key: cache-key-tool-occ-${{env.strNameOccSetupFile}}
id: cache-tool-occ
- name: Download tool Occ
if: steps.cache-tool-occ.outputs.cache-hit != 'true'
uses: robinraju/release-downloader@v1.8
with:
repository: OpenCppCoverage/OpenCppCoverage
fileName: ${{env.strNameOccSetupFile}}
tag: ${{env.strGhTagOccSetupFile}}
- name: Install tool Occ
if: steps.cache-tool-occ.outputs.cache-hit != 'true'
run: |
$arglist="/VERYSILENT /SUPPRESSMSGBOXES /DIR=""${{env.dirSetupOcc}}"" /LOG=""${{runner.temp}}\${{env.strNameOccSetupFile}}.log"""
Start-Process "${{env.strNameOccSetupFile}}" -ArgumentList $arglist -Wait
#type "${{runner.temp}}\${{env.strNameOccSetupFile}}.log"
- name: Run tool Occ
continue-on-error: true
run: | # double launching because windows system hooks from AppCompat conflicts with gmock-win32 hooks
@(
"${{env.module0}}"
, "${{env.module1}}"
, "${{env.module2}}"
, "${{env.module3}}"
).ForEach{ Start-Process "${{env.dirTestExecutables}}\$_" -ArgumentList '--gtest_repeat=0' -NoNewWindow; }
$common_args='-q --working_dir "src"'
$modules="--modules ${{env.dirTestExecutables}}"
$sep = ' --excluded_sources '; $excluded_sources = $sep + ( '"{0}"' -f ( @(
'src\Main.h'
, 'src\Legacy'
, 'qa\UnitTest'
, 'D:\a\_work'
, 'C:\Program Files'
) -join '"'+$sep+'"') );
$excluded_line_regex='--excluded_line_regex .*@NOCOVERAGE.*'
Function runnerOcc_ ( $arg_program ) {
$export_type="--export_type binary:${{runner.temp}}\${arg_program}.cov"
$program_to_run="${{env.dirTestExecutables}}\$arg_program --gtest_brief=1 --gtest_output=xml:${{runner.temp}}\${{env.relGtestOutput}}\$arg_program.xml"
Start-Process -Wait -NoNewWindow "${{env.dirSetupOcc}}\${{env.strOccExecutable}}" -ArgumentList "$common_args $modules $excluded_sources $excluded_line_regex $export_type -- $program_to_run"
}
runnerOcc_ ${{env.module0}}
runnerOcc_ ${{env.module1}}
runnerOcc_ ${{env.module2}}
runnerOcc_ ${{env.module3}}
# Change html template
$ffnOccTemplate="${{env.dirSetupOcc}}\Template\MainTemplate.html"
(Get-Content $ffnOccTemplate).replace('{{TITLE}}', 'Merged from all tests') | Set-Content $ffnOccTemplate
$export_type="--export_type html:${{runner.temp}}\${{env.relHtmlReport}} --export_type cobertura:${{runner.temp}}\${{env.strCoberturaReport}}"
$sep = " --input_coverage ${{runner.temp}}\";
$input_coverage = $sep + ( @(
"${{env.module0}}.cov"
, "${{env.module1}}.cov"
, "${{env.module2}}.cov"
, "${{env.module3}}.cov"
) -join $sep );
Start-Process -Wait -NoNewWindow "${{env.dirSetupOcc}}\${{env.strOccExecutable}}" -ArgumentList "$input_coverage $export_type"
[xml]$oSystem_Xml_XmlDocument = Get-Content ${{runner.temp}}\${{env.strCoberturaReport}};
$oSystem_Xml_XmlElement = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'coverage' ).Item( 0 );
$uLinesCovered = $oSystem_Xml_XmlElement.GetAttribute( 'lines-covered' );
$uLinesValid = $oSystem_Xml_XmlElement.GetAttribute( 'lines-valid' );
$dCoveredPercent = ( 100 * ( $uLinesCovered / $uLinesValid ) );
$strCoveredPercent = [math]::Round( $dCoveredPercent, 2 );
echo "strCoverageValue=$strCoveredPercent" >> $env:GITHUB_ENV
- name: Generate *.svg file for badge TestsCoverage if success
if: ${{ success( ) }}
uses: emibcn/badge-action@v2.0.2
with:
label: Tests coverage
status: ${{env.strCoverageValue}}%
color: ${{ false
|| env.strCoverageValue > 90 && 'green'
|| env.strCoverageValue > 80 && 'yellow,green'
|| env.strCoverageValue > 70 && 'yellow'
|| env.strCoverageValue > 60 && 'orange,yellow'
|| env.strCoverageValue > 50 && 'orange'
|| env.strCoverageValue > 40 && 'red,orange'
|| env.strCoverageValue > 30 && 'red,red,orange'
|| env.strCoverageValue > 20 && 'red,red,red,orange'
|| 'red' }}
path: TestsCoverage-Occ-${{runner.os}}-${{env.strCfg}}.svg
# env-s not pass between steps when failure
- name: Generate *.svg file for badge TestsCoverage if failure
if: ${{ failure( ) }}
uses: emibcn/badge-action@v2.0.2
with:
label: Tests coverage
status: failing
color: red
path: TestsCoverage-Occ-${{runner.os}}-${{env.strCfg}}.svg
- name: Put *.svg file to Gists for badge TestsCoverage
if: ${{ success( ) || failure( ) }} # yes, not 'always( )' because 'cancelled( )'
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: TestsCoverage-Occ-${{runner.os}}-${{env.strCfg}}.svg
- uses: actions/setup-python@v4
with:
python-version: 3.10 # need for metrixpp/metrix++ because "python ValueError: invalid mode: 'rU'"
cache: pip
- name: Install xml merger
run: pip install junitparser
- name: Merge xml reports
run: junitparser merge --suite-name AllTests --glob "${{runner.temp}}\${{env.relGtestOutput}}\*.xml" "${{env.strCfg}}.xml"
- name: Install gtest xml to html converter
run: git clone https://github.com/Alex0vSky/gtest_report
- name: Convert xml to html
working-directory: ./gtest_report # directory html_resources must be in current dir
run: |
py scripts\genHtmlReportFromGtest.py "out\GoogleTestCombinedOutput.html" "..\${{env.strCfg}}.xml"
mv -v "out" ${{runner.temp}}\GoogleTestCombinedOutput
[xml]$oSystem_Xml_XmlDocument = Get-Content ..\${{env.strCfg}}.xml
$oSystem_Xml_XmlElement = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'testsuites' ).Item( 0 );
$uTests = $oSystem_Xml_XmlElement.GetAttribute( 'tests' );
echo "uTests=$uTests" >> $env:GITHUB_ENV
- name: Generate *.svg file for badge GoogleTest
uses: emibcn/badge-action@v2.0.2
with:
label: GoogleTest
status: ${{env.uTests}} testsuites
path: GoogleTest-testsuites-${{runner.os}}-${{env.strCfg}}.svg
- name: Put *.svg file to Gists for badge GoogleTest
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: GoogleTest-testsuites-${{runner.os}}-${{env.strCfg}}.svg
- name: Install metrics code
run: pip install metrixpp
- name: Run metrics code
run: |
$strVersionMetrixpp=( pip show metrixpp |findstr Version ) -replace 'Version: ',''
"Version: $strVersionMetrixpp" > ${{runner.temp}}\metrixpp.txt
metrix++ collect --log-level=ERROR --std.code.lines.code --std.code.lines.comments --std.code.complexity.cyclomatic --db-file=${{runner.temp}}\metrixpp.db -- ${{github.workspace}}\src
metrix++ view --log-level=ERROR --db-file=${{runner.temp}}\metrixpp.db -- ${{github.workspace}}\src >> ${{runner.temp}}\metrixpp.txt
metrix++ view --log-level=ERROR --format=xml --db-file=${{runner.temp}}\metrixpp.db -- ${{github.workspace}}\src > ${{runner.temp}}\metrixpp.xml
[xml]$oSystem_Xml_XmlDocument = Get-Content ${{runner.temp}}\metrixpp.xml
$uLocTotalCode = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'std.code.lines' ).GetElementsByTagName( 'code' ).GetAttribute( 'total' );
$uLocTotalComments = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'std.code.lines' ).GetElementsByTagName( 'comments' ).GetAttribute( 'total' );
$child = $oSystem_Xml_XmlDocument.CreateElement( 'Version' )
$child.InnerText = $strVersionMetrixpp;
$oSystem_Xml_XmlDocument.DocumentElement.AppendChild( $child );
$oSystem_Xml_XmlDocument.Save( "${{runner.temp}}\metrixpp.xml" )
$uLocTotalCode = [math]::Round( $uLocTotalCode, 0 );
$uLocTotalComments = [math]::Round( $uLocTotalComments, 0 );
echo "metrixpp_uLocTotalCode=$uLocTotalCode" >> $env:GITHUB_ENV
echo "metrixpp_uLocTotalComments=$uLocTotalComments" >> $env:GITHUB_ENV
- name: Generate *.svg file for badge LinesOfСode
uses: emibcn/badge-action@v2.0.2
with:
label: LinesOfСode
status: ${{env.metrixpp_uLocTotalCode}}
color: a9a9a9 # darkgrey=a9a9a9, lightgrey=d3d3d3
path: Metrixpp-LinesOfСode.svg
- name: Put *.svg file to Gists for badge LinesOfСode
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: Metrixpp-LinesOfСode.svg
- name: Generate *.svg file for badge Comments
uses: emibcn/badge-action@v2.0.2
with:
label: Comments
status: ${{env.metrixpp_uLocTotalComments}}
color: a9a9a9 # darkgrey=a9a9a9, lightgrey=d3d3d3
path: Metrixpp-Comments.svg
- name: Put *.svg file to Gists for badge Comments
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: Metrixpp-Comments.svg
- name: Install GoogleStyle cpplint
run: pip install cpplint
- name: Run GoogleStyle cpplint
id: RunToolGoogleStyleCpplint
continue-on-error: true # when cpplint return error
run: |
$strVersionCpplint=(pip show cpplint |findstr Version) -replace 'Version: ',''
$arrFilter = @(
'whitespace/tab',
'whitespace/end_of_line',
'whitespace/parens',
'readability/namespace',
'whitespace/comments'
);
$filter = '-' + ( $arrFilter -join ',-' );
$linelength=120
$cpplint_args="--linelength=$linelength --filter=$filter --exclude=src\MsvcGenerated\* --exclude=src\Legacy\* --recursive --output=junit src";
Start-Process -Wait -NoNewWindow cpplint -ArgumentList $cpplint_args -RedirectStandardError ${{runner.temp}}\cpplint.xml
[xml]$oSystem_Xml_XmlDocument = Get-Content ${{runner.temp}}\cpplint.xml
$cpplint_failures = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'testsuite' ).GetAttribute( 'failures' );
$child = $oSystem_Xml_XmlDocument.CreateElement( 'Arguments' )
$child.InnerText = $cpplint_args;
$oSystem_Xml_XmlDocument.DocumentElement.AppendChild( $child );
$child = $oSystem_Xml_XmlDocument.CreateElement( 'Version' )
$child.InnerText = $strVersionCpplint;
$oSystem_Xml_XmlDocument.DocumentElement.AppendChild( $child );
$oSystem_Xml_XmlDocument.Save( "${{runner.temp}}\cpplint.xml" )
echo "cpplint_failures=$cpplint_failures" >> $env:GITHUB_ENV
echo "cpplint_arrFilter_Count=$($arrFilter.Count)" >> $env:GITHUB_ENV
echo "cpplint_linelength=$linelength" >> $env:GITHUB_ENV
- name: Generate *.svg file for badge GoogleStyle cpplint if success
if: steps.RunToolGoogleStyleCpplint.outcome == 'success' && env.cpplint_failures == '0'
uses: emibcn/badge-action@v2.0.2
with:
label: cpplint
status: ${{env.cpplint_arrFilter_Count}} filters, linelength=${{env.cpplint_linelength}}
path: GoogleStyle_cpplint.svg
- name: Generate *.svg file for badge GoogleStyle cpplint if failure
if: env.cpplint_failures > 0 || env.cpplint_failures == ''
uses: emibcn/badge-action@v2.0.2
with:
label: cpplint
status: failing
color: red
path: GoogleStyle_cpplint.svg
- name: Put *.svg file to Gists for badge GoogleStyle cpplint
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: GoogleStyle_cpplint.svg
- name: Cache tool cppcheck
uses: actions/cache@v3
with:
path: ${{env.dirSetupCppcheck}}
key: cache-key-tool-cppcheck-${{env.strNameCppcheckSetupFile}}
id: cache-tool-cppcheck
- name: Download tool cppcheck
if: steps.cache-tool-cppcheck.outputs.cache-hit != 'true'
uses: robinraju/release-downloader@v1.8
with:
repository: danmar/cppcheck
fileName: ${{env.strNameCppcheckSetupFile}}
tag: ${{env.strGhTagCppcheckSetupFile}}
- name: Install tool cppcheck
if: steps.cache-tool-cppcheck.outputs.cache-hit != 'true'
run: |
$arglist = "/i ""${{github.workspace}}\${{env.strNameCppcheckSetupFile}}"" INSTALLDIR=""${{env.dirSetupCppcheck}}"" TARGETDIR=""${{env.dirSetupCppcheck}}"" ALLUSERS=2 MSIINSTALLPERUSER=1 /quiet /norestart /log ""${{runner.temp}}\${{env.strNameCppcheckSetupFile}}.log"" "
$uWait_seconds = 60;
$ps = new-object System.Diagnostics.Process; $ps.StartInfo.UseShellExecute = $false; $ps.StartInfo.WorkingDirectory = Get-Location;
$ps.StartInfo.Filename = "msiexec"
$ps.StartInfo.Arguments = $arglist
$uWait_milliseconds = $uWait_seconds *1000;
$ps.start( ); $ps.WaitForExit( $uWait_milliseconds );
type "${{runner.temp}}\${{env.strNameCppcheckSetupFile}}.log"
- name: Run tool cppcheck
id: RunToolCppcheck
continue-on-error: true
run: |
$common = ' --std=c++14 --platform=win32A --library=microsoft_sal --library=windows --enable=all -q --xml ';
$include = '';
$include += ' -I "resource"'
$include += ' -I "src"'
$include += ' -I "ThirdParty\SynCOMAPIv1_0\Include"'
$defines = ''
$defines += ' -DDECLSPEC_IMPORT=__declspec(import)'
$defines += ' -D_X86_=1'
$defines += ' -D_M_HYBRID_X86_ARM64=1'
$suppress = ' --suppress=missingIncludeSystem --suppress=missingInclude:*\SynCtrl.h --suppress=preprocessorErrorDirective:*\SynCtrl.h'
$cppcheck_exe = "${{env.dirSetupCppcheck}}\cppcheck.exe"
$cppcheck_args = $common + $include + $defines + $suppress + ' ' + 'src';
Start-Process -Wait -NoNewWindow $cppcheck_exe -ArgumentList $cppcheck_args -RedirectStandardError ${{runner.temp}}\cppcheck.xml
[xml]$oSystem_Xml_XmlDocument = Get-Content ${{runner.temp}}\cppcheck.xml
$uCountError = $oSystem_Xml_XmlDocument.GetElementsByTagName( 'results' ).GetElementsByTagName( 'errors' ).GetElementsByTagName( 'error' ).Count;
[xml]$oSystem_Xml_XmlDocument = Get-Content ${{runner.temp}}\cppcheck.xml
$child = $oSystem_Xml_XmlDocument.CreateElement( 'Arguments' )
$child.InnerText = $cppcheck_args;
$oSystem_Xml_XmlDocument.DocumentElement.AppendChild( $child );
$oSystem_Xml_XmlDocument.Save( "${{runner.temp}}\cppcheck.xml" )
echo "cppcheck_uCountError=$uCountError" >> $env:GITHUB_ENV
- name: Generate *.svg file for badge cppcheck if success
if: steps.RunToolCppcheck.outcome == 'success' && env.cppcheck_uCountError == '0'
uses: emibcn/badge-action@v2.0.2
with:
label: cppcheck
status: enable=all
color: green
path: StaticAnalysis_cppcheck.svg
- name: Generate *.svg file for badge cppcheck if failure
if: env.cppcheck_uCountError > 0 || env.cppcheck_uCountError == ''
uses: emibcn/badge-action@v2.0.2
with:
label: cppcheck
status: ${{env.cppcheck_uCountError}} errors
color: red
path: StaticAnalysis_cppcheck.svg
- name: Put *.svg file to Gists for badge cppcheck
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.ACCESS_TO_GIST }}
gist_id: 2af621bdd237231125e907ea81b1f8a8
file_path: StaticAnalysis_cppcheck.svg
- uses: actions/upload-artifact@v3
with:
name: artifact-coverage-tests-OpenCppCoverage-${{env.strCfg}}
path: |
${{ runner.temp }}\${{ env.relHtmlReport }}
${{ runner.temp }}\GoogleTestCombinedOutput
${{ runner.temp }}\metrixpp.txt
${{ runner.temp }}\cpplint.xml
${{ runner.temp }}\cppcheck.xml
${{ runner.temp }}\${{ env.strCoberturaReport }}