Commit e5c54b59 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/ci-cppcheck-build-cleanup' into integration_2026_w16 (!4011)

CI: remove cppcheck, cleanup in build and license checks

Remove cppcheck. For those who want to use it, it's now in tools/cppcheck/,
and likely easier to use locally.
Clean up some code for CI build and license check. Remove global variable.
parents 463a3ad1 ff97f0de
...@@ -219,28 +219,6 @@ pipeline { ...@@ -219,28 +219,6 @@ pipeline {
} }
} }
} }
stage ("cppcheck") {
steps {
script {
triggerSlaveJob ('RAN-cppcheck', 'cppcheck')
}
}
post {
always {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
cppcheckStatus = finalizeSlaveJob('RAN-cppcheck')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += cppcheckStatus
}
}
}
}
stage ("ARM-Cross-Compile") { stage ("ARM-Cross-Compile") {
steps { steps {
script { script {
......
...@@ -22,7 +22,7 @@ import constants as CONST ...@@ -22,7 +22,7 @@ import constants as CONST
#----------------------------------------------------------- #-----------------------------------------------------------
def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
force_local = False force_local = False
date_fmt = None date_fmt = None
...@@ -53,7 +53,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -53,7 +53,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
RAN.ranRepository=matchReg.group(1) RAN.ranRepository=matchReg.group(1)
HTML.ranRepository=matchReg.group(1) HTML.ranRepository=matchReg.group(1)
CONTAINERS.ranRepository=matchReg.group(1) CONTAINERS.ranRepository=matchReg.group(1)
SCA.ranRepository=matchReg.group(1)
CLUSTER.ranRepository=matchReg.group(1) CLUSTER.ranRepository=matchReg.group(1)
elif re.match(r'^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): if re.match(r'^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
...@@ -66,7 +65,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -66,7 +65,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
RAN.ranAllowMerge=True RAN.ranAllowMerge=True
HTML.ranAllowMerge=True HTML.ranAllowMerge=True
CONTAINERS.ranAllowMerge=True CONTAINERS.ranAllowMerge=True
SCA.ranAllowMerge=True
CLUSTER.ranAllowMerge=True CLUSTER.ranAllowMerge=True
elif re.match(r'^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): if re.match(r'^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
...@@ -77,7 +75,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -77,7 +75,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
RAN.ranBranch=matchReg.group(1) RAN.ranBranch=matchReg.group(1)
HTML.ranBranch=matchReg.group(1) HTML.ranBranch=matchReg.group(1)
CONTAINERS.ranBranch=matchReg.group(1) CONTAINERS.ranBranch=matchReg.group(1)
SCA.ranBranch=matchReg.group(1)
CLUSTER.ranBranch=matchReg.group(1) CLUSTER.ranBranch=matchReg.group(1)
elif re.match(r'^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): if re.match(r'^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
...@@ -88,7 +85,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -88,7 +85,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
RAN.ranCommitID=matchReg.group(1) RAN.ranCommitID=matchReg.group(1)
HTML.ranCommitID=matchReg.group(1) HTML.ranCommitID=matchReg.group(1)
CONTAINERS.ranCommitID=matchReg.group(1) CONTAINERS.ranCommitID=matchReg.group(1)
SCA.ranCommitID=matchReg.group(1)
CLUSTER.ranCommitID=matchReg.group(1) CLUSTER.ranCommitID=matchReg.group(1)
elif re.match(r'^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): if re.match(r'^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
...@@ -99,7 +95,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -99,7 +95,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
RAN.ranTargetBranch=matchReg.group(1) RAN.ranTargetBranch=matchReg.group(1)
HTML.ranTargetBranch=matchReg.group(1) HTML.ranTargetBranch=matchReg.group(1)
CONTAINERS.ranTargetBranch=matchReg.group(1) CONTAINERS.ranTargetBranch=matchReg.group(1)
SCA.ranTargetBranch=matchReg.group(1)
CLUSTER.ranTargetBranch=matchReg.group(1) CLUSTER.ranTargetBranch=matchReg.group(1)
elif re.match(r'^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
print("parameters --eNB*IPAddress ignored") print("parameters --eNB*IPAddress ignored")
...@@ -112,7 +107,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): ...@@ -112,7 +107,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
matchReg = re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBSourceCodePath=matchReg.group(1) RAN.eNBSourceCodePath=matchReg.group(1)
CONTAINERS.eNBSourceCodePath=matchReg.group(1) CONTAINERS.eNBSourceCodePath=matchReg.group(1)
SCA.eNBSourceCodePath=matchReg.group(1)
CLUSTER.eNBSourceCodePath=matchReg.group(1) CLUSTER.eNBSourceCodePath=matchReg.group(1)
elif re.match(r'^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): elif re.match(r'^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
print("parameter --eNB1SourceCodePath ignored") print("parameter --eNB1SourceCodePath ignored")
......
This diff is collapsed.
...@@ -379,90 +379,6 @@ class HTMLManagement(): ...@@ -379,90 +379,6 @@ class HTMLManagement():
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.close() self.htmlFile.close()
def CreateHtmlTestRowCppCheckResults(self, CCR):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return
self.htmlFile = open('test_results.html', 'a')
vId = 0
for version in CCR.versions:
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"><b> Results for cppcheck v ' + version + ' </b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
if CCR.nbErrors[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbErrors[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
if CCR.nbWarnings[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbWarnings[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"> ----------------- </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbUninitVars[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"> </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
vId += 1
def CreateHtmlTestRowPhySimTestResult(self, testSummary, testResult): def CreateHtmlTestRowPhySimTestResult(self, testSummary, testResult):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)): if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return return
......
...@@ -27,160 +27,30 @@ import constants as CONST ...@@ -27,160 +27,30 @@ import constants as CONST
import cls_cmd import cls_cmd
from cls_ci_helper import archiveArtifact from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class CppCheckResults():
def __init__(self):
self.variants = ['bionic', 'focal']
self.versions = ['','']
self.nbErrors = [0,0]
self.nbWarnings = [0,0]
self.nbNullPtrs = [0,0]
self.nbMemLeaks = [0,0]
self.nbUninitVars = [0,0]
self.nbInvalidPrintf = [0,0]
self.nbModuloAlways = [0,0]
self.nbTooManyBitsShift = [0,0]
self.nbIntegerOverflow = [0,0]
self.nbWrongScanfArg = [0,0]
self.nbPtrAddNotNull = [0,0]
self.nbOppoInnerCondition = [0,0]
class StaticCodeAnalysis(): class StaticCodeAnalysis():
def __init__(self): def LicenceAndFormattingCheck(ctx, node, HTML, d, branch, allowMerge, targetBranch):
self.ranRepository = ''
self.ranBranch = ''
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBSourceCodePath = ''
def CppCheckAnalysis(self, ctx, node, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
lSourcePath = self.eNBSourceCodePath
if not lSourcePath or not node:
raise ValueError(f"{lSourcePath=} {node=}")
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
# on RedHat/CentOS .git extension is mandatory
result = re.search(r'([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None:
full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else:
full_ran_repo_name = self.ranRepository + '.git'
cmd.cd(lSourcePath)
logDir = f'{lSourcePath}/cmake_targets/log'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
cmd.run(f'sed -e "s@xenial@bionic@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic')
cmd.run(f'docker build --tag oai-cppcheck:bionic --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic . > {logDir}/cppcheck-bionic.txt 2>&1')
cmd.run(f'sed -e "s@xenial@focal@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal')
cmd.run(f'docker build --tag oai-cppcheck:focal --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal . > {logDir}/cppcheck-focal.txt 2>&1')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
bionic = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-bionic.txt')
focal = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-focal.txt')
cmd.close()
CCR = CppCheckResults()
CCR_ref = CppCheckResults()
vId = 0
for variant in CCR.variants:
filename = ctx.baseFilename() + '-cppcheck-'+ variant + '.txt'
logging.info(f"will check file '{filename}'")
if not os.path.isfile(filename):
raise FileNotFoundError(f"{filename} is not a file")
else:
xmlStart = False
with open(filename, 'r') as logfile:
for line in logfile:
ret = re.search(r'cppcheck version="(?P<version>[0-9\.]+)"', str(line))
if ret is not None:
CCR.versions[vId] = ret.group('version')
if re.search('RUN cat cmake_targets/log/cppcheck.xml', str(line)) is not None:
xmlStart = True
if xmlStart:
if re.search('severity="error"', str(line)) is not None:
CCR.nbErrors[vId] += 1
if re.search('severity="warning"', str(line)) is not None:
CCR.nbWarnings[vId] += 1
if re.search('id="memleak"', str(line)) is not None:
CCR.nbMemLeaks[vId] += 1
if re.search('id="nullPointer"', str(line)) is not None:
CCR.nbNullPtrs[vId] += 1
if re.search('id="uninitvar"', str(line)) is not None:
CCR.nbUninitVars[vId] += 1
if re.search('id="invalidPrintfArgType_sint"|id="invalidPrintfArgType_uint"', str(line)) is not None:
CCR.nbInvalidPrintf[vId] += 1
if re.search('id="moduloAlwaysTrueFalse"', str(line)) is not None:
CCR.nbModuloAlways[vId] += 1
if re.search('id="shiftTooManyBitsSigned"', str(line)) is not None:
CCR.nbTooManyBitsShift[vId] += 1
if re.search('id="integerOverflow"', str(line)) is not None:
CCR.nbIntegerOverflow[vId] += 1
if re.search('id="wrongPrintfScanfArgNum"|id="invalidScanfArgType_int"', str(line)) is not None:
CCR.nbWrongScanfArg[vId] += 1
if re.search('id="pointerAdditionResultNotNull"', str(line)) is not None:
CCR.nbPtrAddNotNull[vId] += 1
if re.search('id="oppositeInnerCondition"', str(line)) is not None:
CCR.nbOppoInnerCondition[vId] += 1
vMsg = ''
vMsg += '======== Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========\n'
vMsg += ' ' + str(CCR.nbErrors[vId]) + ' errors\n'
vMsg += ' ' + str(CCR.nbWarnings[vId]) + ' warnings\n'
vMsg += ' -- Details --\n'
vMsg += ' Memory leak: ' + str(CCR.nbMemLeaks[vId]) + '\n'
vMsg += ' Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]) + '\n'
vMsg += ' Uninitialized variable: ' + str(CCR.nbUninitVars[vId]) + '\n'
vMsg += ' Undefined behaviour shifting: ' + str(CCR.nbTooManyBitsShift[vId]) + '\n'
vMsg += ' Signed integer overflow: ' + str(CCR.nbIntegerOverflow[vId]) + '\n'
vMsg += '\n'
vMsg += ' Printf formatting issue: ' + str(CCR.nbInvalidPrintf[vId]) + '\n'
vMsg += ' Modulo result is predetermined: ' + str(CCR.nbModuloAlways[vId]) + '\n'
vMsg += ' Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]) + '\n'
vMsg += ' Wrong Scanf Nb Args: ' + str(CCR.nbWrongScanfArg[vId]) + '\n'
for vLine in vMsg.split('\n'):
logging.debug(vLine)
vId += 1
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTestRowCppCheckResults(CCR)
logging.info('\u001B[1m Static Code Analysis Pass\u001B[0m')
return True
def LicenceAndFormattingCheck(self, ctx, node, HTML):
# Workspace is no longer recreated from scratch. # Workspace is no longer recreated from scratch.
# It implies that this method shall be called last within a build pipeline # It implies that this method shall be called last within a build pipeline
# where workspace is already created # where workspace is already created
lSourcePath = self.eNBSourceCodePath
if not node or not lSourcePath: if not node or not d:
raise ValueError(f"{lSourcePath=} {node=}") raise ValueError(f"{d=} {node=}")
logging.debug('Building on server: ' + node) logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node) cmd = cls_cmd.getConnection(node)
check_options = '' check_options = ''
if self.ranAllowMerge: if allowMerge:
check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={self.ranBranch}' check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={branch}'
if self.ranTargetBranch == '': if targetBranch == '':
if self.ranBranch != 'develop' and self.ranBranch != 'origin/develop': if branch != 'develop' and branch != 'origin/develop':
check_options += ' --build-arg TARGET_BRANCH=develop' check_options += ' --build-arg TARGET_BRANCH=develop'
else: else:
check_options += f' --build-arg TARGET_BRANCH={self.ranTargetBranch}' check_options += f' --build-arg TARGET_BRANCH={targetBranch}'
logDir = f'{lSourcePath}/cmake_targets/log/' logDir = f'{d}/cmake_targets/log/'
cmd.run(f'mkdir -p {logDir}') cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-formatting-check:latest') cmd.run('docker image rm oai-formatting-check:latest')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.ubuntu {lSourcePath} > {logDir}/oai-formatting-check.txt 2>&1') cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {d}/ci-scripts/docker/Dockerfile.formatting.ubuntu {d} > {logDir}/oai-formatting-check.txt 2>&1')
cmd.run('docker image rm oai-formatting-check:latest') cmd.run('docker image rm oai-formatting-check:latest')
cmd.run('docker image prune --force') cmd.run('docker image prune --force')
......
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
#
#---------------------------------------------------------------------
FROM ubuntu:xenial AS oai-cppcheck
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get upgrade --yes && \
apt-get install --yes \
build-essential \
vim \
cppcheck
WORKDIR /oai-ran
COPY . .
WORKDIR /oai-ran/common/utils/T
RUN make
WORKDIR /oai-ran
RUN mkdir -p cmake_targets/log && \
cppcheck --enable=warning --force --xml --xml-version=2 \
--inline-suppr \
-i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c \
--suppressions-list=ci-scripts/cppcheck_suppressions.list \
-I common/utils \
-I openair3/NAS/COMMON/UTIL \
-j`nproc` . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt
RUN grep -E -c 'severity="error' cmake_targets/log/cppcheck.xml
RUN grep -E -c 'severity="warning' cmake_targets/log/cppcheck.xml
RUN cat cmake_targets/log/cppcheck.xml
...@@ -22,7 +22,7 @@ import constants as CONST ...@@ -22,7 +22,7 @@ import constants as CONST
import cls_oaicitest #main class for OAI CI test framework import cls_oaicitest #main class for OAI CI test framework
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_static_code_analysis #class for static code analysis import cls_static_code_analysis as SCA
import cls_cluster # class for building/deploying on cluster import cls_cluster # class for building/deploying on cluster
import cls_native # class for all native/source-based operations import cls_native # class for all native/source-based operations
from cls_ci_helper import TestCaseCtx from cls_ci_helper import TestCaseCtx
...@@ -64,7 +64,6 @@ def ExecuteActionWithParam(action, ctx, node): ...@@ -64,7 +64,6 @@ def ExecuteActionWithParam(action, ctx, node):
global RAN global RAN
global HTML global HTML
global CONTAINERS global CONTAINERS
global SCA
global CLUSTER global CLUSTER
if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy' or action == "Build_Cluster_Image" or action == "Build_Run_Tests": if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy' or action == "Build_Cluster_Image" or action == "Build_Run_Tests":
RAN.Build_eNB_args=test.findtext('Build_eNB_args') RAN.Build_eNB_args=test.findtext('Build_eNB_args')
...@@ -196,10 +195,7 @@ def ExecuteActionWithParam(action, ctx, node): ...@@ -196,10 +195,7 @@ def ExecuteActionWithParam(action, ctx, node):
success = CONTAINERS.Create_Workspace(node, HTML) success = CONTAINERS.Create_Workspace(node, HTML)
elif action == 'LicenceAndFormattingCheck': elif action == 'LicenceAndFormattingCheck':
success = SCA.LicenceAndFormattingCheck(ctx, node, HTML) success = SCA.StaticCodeAnalysis.LicenceAndFormattingCheck(ctx, node, HTML, RAN.eNBSourceCodePath, RAN.ranBranch, RAN.ranAllowMerge, RAN.ranTargetBranch)
elif action == 'Cppcheck_Analysis':
success = SCA.CppCheckAnalysis(ctx, node, HTML)
elif action == 'Push_Local_Registry': elif action == 'Push_Local_Registry':
tag_prefix = test.findtext('tag_prefix') or "" tag_prefix = test.findtext('tag_prefix') or ""
...@@ -297,7 +293,6 @@ CiTestObj = cls_oaicitest.OaiCiTest() ...@@ -297,7 +293,6 @@ CiTestObj = cls_oaicitest.OaiCiTest()
RAN = ran.RANManagement() RAN = ran.RANManagement()
HTML = cls_oai_html.HTMLManagement() HTML = cls_oai_html.HTMLManagement()
CONTAINERS = cls_containerize.Containerize() CONTAINERS = cls_containerize.Containerize()
SCA = cls_static_code_analysis.StaticCodeAnalysis()
CLUSTER = cls_cluster.Cluster() CLUSTER = cls_cluster.Cluster()
#----------------------------------------------------------- #-----------------------------------------------------------
...@@ -307,7 +302,7 @@ CLUSTER = cls_cluster.Cluster() ...@@ -307,7 +302,7 @@ CLUSTER = cls_cluster.Cluster()
import args_parse import args_parse
# Force local execution, move all execution targets to localhost # Force local execution, move all execution targets to localhost
force_local = False force_local = False
mode, force_local, date_fmt = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER) mode, force_local, date_fmt = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER)
fmt = "%(levelname)8s: %(message)s" fmt = "%(levelname)8s: %(message)s"
if date_fmt: if date_fmt:
fmt = "[%(asctime)s] %(levelname)s %(message)s" fmt = "[%(asctime)s] %(levelname)s %(message)s"
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
- Deploy_Object - Deploy_Object
- Stop_Object - Stop_Object
- Undeploy_Object - Undeploy_Object
- Cppcheck_Analysis
- Deploy_Run_OC_PhySim - Deploy_Run_OC_PhySim
- Build_Deploy_PhySim - Build_Deploy_PhySim
- LicenceAndFormattingCheck - LicenceAndFormattingCheck
......
<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>CPPCHECK Analysis</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<testCase>
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>carabe</node>
</testCase>
<testCase>
<class>Cppcheck_Analysis</class>
<desc>Static Code Analysis with cppcheck</desc>
<node>carabe</node>
</testCase>
</testCaseList>
...@@ -135,6 +135,7 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs. ...@@ -135,6 +135,7 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
- [clang-format.md](./clang-format.md): how to format the code. See also the - [clang-format.md](./clang-format.md): how to format the code. See also the
next entry for an error detection tool. next entry for an error detection tool.
- [formatting](../tools/formatting/README.md) is a clang-format error detection tool - [formatting](../tools/formatting/README.md) is a clang-format error detection tool
- [cppcheck](../tools/cppcheck/README.md) for static code analysis
- [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan - [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan
- [iwyu](../tools/iwyu/README.md) is a tool to detect `#include` errors - [iwyu](../tools/iwyu/README.md) is a tool to detect `#include` errors
- [docker-dev-env](../tools/docker-dev-env/README.md) is a ubuntu24 docker development environment - [docker-dev-env](../tools/docker-dev-env/README.md) is a ubuntu24 docker development environment
......
...@@ -96,10 +96,6 @@ information on how the images are built. ...@@ -96,10 +96,6 @@ information on how the images are built.
- orion: Cross-compilation from Intel to ARM - orion: Cross-compilation from Intel to ARM
- base image from `Dockerfile.base.ubuntu.cross-arm64` - base image from `Dockerfile.base.ubuntu.cross-arm64`
- build image from `Dockerfile.build.ubuntu.cross-arm64` (no target images) - build image from `Dockerfile.build.ubuntu.cross-arm64` (no target images)
- [RAN-cppcheck](https://jenkins-oai.eurecom.fr/job/RAN-cppcheck/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- bellatrix
- performs static code analysis, currently not actively enforced
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/) - [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE ~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL image build using the OpenShift Cluster (using gcc/clang) - cluster (`Asterix-OC-oaicicd-session` resource): RHEL image build using the OpenShift Cluster (using gcc/clang)
......
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# Static code analysis
How to run static code analysis tool(s).
[[_TOC_]]
## cppcheck Overview
This can run a (dockerized) cppcheck static code analysis. The docker-compose
file represents the status as run as in the CI until it's removal (because it
was not enforced). It is now here so that people could use it to find bugs (and
use the tool more easily).
## cppcheck Usage
From the openairinterface5g root, simply run
./tools/cppcheck/run-cppcheck.sh
This will run cppcheck with options listed in this file, assuming you have it
installed. Alternatively, you can run the CI version as of Ubuntu 20 with
cd tools/cppcheck && docker compose up --no-log-prefix
You can upgrade to a newer version by modifying the `FROM` line in the
docker-compose file.
# SPDX-License-Identifier: MIT
services:
cppcheck:
image: cppcheck
build:
dockerfile_inline: |
FROM ubuntu:focal
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y cppcheck
volumes:
- ../../:/code/
command:
bash -c "cd /code/ && ./tools/cppcheck/run-cppcheck.sh"
#!/bin/bash
# SPDX-License-Identifier: MIT
cppcheck --enable=warning --force \
--inline-suppr \
--quiet \
-i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c \
--suppressions-list=tools/cppcheck/suppressions.list \
-I common/utils \
-I openair3/NAS/COMMON/UTIL \
-j`nproc` .
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment