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.
This commit is contained in:
@@ -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
|
|||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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")
|
||||||
|
|||||||
@@ -184,11 +184,6 @@ class Containerize():
|
|||||||
self.services = ''
|
self.services = ''
|
||||||
self.deploymentTag = ''
|
self.deploymentTag = ''
|
||||||
|
|
||||||
self.cli = ''
|
|
||||||
self.cliBuildOptions = ''
|
|
||||||
self.dockerfileprefix = ''
|
|
||||||
self.host = ''
|
|
||||||
|
|
||||||
self.num_attempts = 1
|
self.num_attempts = 1
|
||||||
|
|
||||||
self.flexricTag = ''
|
self.flexricTag = ''
|
||||||
@@ -203,18 +198,7 @@ class Containerize():
|
|||||||
cmd = cls_cmd.getConnection(node)
|
cmd = cls_cmd.getConnection(node)
|
||||||
log_files = []
|
log_files = []
|
||||||
|
|
||||||
# Checking the hostname to get adapted on cli and dockerfileprefixes
|
dockerfileprefix = '.ubuntu'
|
||||||
cmd.run('hostnamectl')
|
|
||||||
result = re.search('Ubuntu|Red Hat', cmd.getBefore())
|
|
||||||
self.host = result.group(0)
|
|
||||||
if self.host == 'Ubuntu':
|
|
||||||
self.cli = 'docker'
|
|
||||||
self.dockerfileprefix = '.ubuntu'
|
|
||||||
self.cliBuildOptions = ''
|
|
||||||
elif self.host == 'Red Hat':
|
|
||||||
self.cli = 'sudo podman'
|
|
||||||
self.dockerfileprefix = '.rhel9'
|
|
||||||
self.cliBuildOptions = '--disable-compression'
|
|
||||||
|
|
||||||
# we always build the ran-build image with all targets
|
# we always build the ran-build image with all targets
|
||||||
# Creating a tupple with the imageName, the DockerFile prefix pattern, targetName and sanitized option
|
# Creating a tupple with the imageName, the DockerFile prefix pattern, targetName and sanitized option
|
||||||
@@ -232,23 +216,20 @@ class Containerize():
|
|||||||
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', ''))
|
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', ''))
|
||||||
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue', ''))
|
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue', ''))
|
||||||
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
|
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
|
||||||
if self.host == 'Red Hat':
|
imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', ''))
|
||||||
imageNames.append(('oai-physim', 'phySim', 'oai-physim', ''))
|
# Building again the 5G images with Address Sanitizer
|
||||||
if self.host == 'Ubuntu':
|
imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', ''))
|
imageNames.append(('oai-enb', 'eNB', 'oai-enb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
# Building again the 5G images with Address Sanitizer
|
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
imageNames.append(('oai-enb', 'eNB', 'oai-enb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||||
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('ran-build-fhi72', 'build.fhi72', 'ran-build-fhi72', ''))
|
||||||
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
|
||||||
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
imageNames.append(('oai-nr-oru', 'nrORU.fhi72', 'oai-nr-oru', ''))
|
||||||
imageNames.append(('ran-build-fhi72', 'build.fhi72', 'ran-build-fhi72', ''))
|
|
||||||
imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
|
|
||||||
imageNames.append(('oai-nr-oru', 'nrORU.fhi72', 'oai-nr-oru', ''))
|
|
||||||
result = re.search('build_cross_arm64', self.imageKind)
|
result = re.search('build_cross_arm64', self.imageKind)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
self.dockerfileprefix = '.ubuntu.cross-arm64'
|
dockerfileprefix = '.ubuntu.cross-arm64'
|
||||||
result = re.search('native_armv9', self.imageKind)
|
result = re.search('native_armv9', self.imageKind)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
|
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
|
||||||
@@ -263,10 +244,6 @@ class Containerize():
|
|||||||
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
|
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
|
||||||
|
|
||||||
cmd.cd(lSourcePath)
|
cmd.cd(lSourcePath)
|
||||||
# if asterix, copy the entitlement and subscription manager configurations
|
|
||||||
if self.host == 'Red Hat':
|
|
||||||
cmd.run('mkdir -p ./etc-pki-entitlement')
|
|
||||||
cmd.run('cp /etc/pki/entitlement/*.pem ./etc-pki-entitlement/')
|
|
||||||
|
|
||||||
baseImage = 'ran-base'
|
baseImage = 'ran-base'
|
||||||
baseTag = 'develop'
|
baseTag = 'develop'
|
||||||
@@ -275,7 +252,7 @@ class Containerize():
|
|||||||
if (self.ranAllowMerge):
|
if (self.ranAllowMerge):
|
||||||
imageTag = 'ci-temp'
|
imageTag = 'ci-temp'
|
||||||
if self.ranTargetBranch == 'develop':
|
if self.ranTargetBranch == 'develop':
|
||||||
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
|
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{dockerfileprefix} | grep --colour=never -i INDEX')
|
||||||
result = re.search('index', cmd.getBefore())
|
result = re.search('index', cmd.getBefore())
|
||||||
if result is not None:
|
if result is not None:
|
||||||
forceBaseImageBuild = True
|
forceBaseImageBuild = True
|
||||||
@@ -289,31 +266,30 @@ class Containerize():
|
|||||||
forceBaseImageBuild = True
|
forceBaseImageBuild = True
|
||||||
|
|
||||||
# Let's remove any previous run artifacts if still there
|
# Let's remove any previous run artifacts if still there
|
||||||
cmd.run(f"{self.cli} image prune --force")
|
cmd.run(f"docker image prune --force")
|
||||||
for image,pattern,name,option in imageNames:
|
for image,pattern,name,option in imageNames:
|
||||||
cmd.run(f"{self.cli} image rm {name}:{imageTag}", reportNonZero=False)
|
cmd.run(f"docker image rm {name}:{imageTag}", reportNonZero=False)
|
||||||
|
|
||||||
cmd.run(f'docker login -u oaicicd -p oaicicd {DEFAULT_REGISTRY}')
|
cmd.run(f'docker login -u oaicicd -p oaicicd {DEFAULT_REGISTRY}')
|
||||||
ubuntuImage = "ubuntu:noble"
|
ubuntuImage = "ubuntu:noble"
|
||||||
# Build the base image only on Push Events (not on Merge Requests)
|
# Build the base image only on Push Events (not on Merge Requests)
|
||||||
# On when the base image docker file is being modified.
|
# On when the base image docker file is being modified.
|
||||||
if forceBaseImageBuild:
|
if forceBaseImageBuild:
|
||||||
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
|
cmd.run(f"docker image rm {baseImage}:{baseTag}")
|
||||||
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.docker.log'
|
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.docker.log'
|
||||||
if self.host == 'Ubuntu':
|
option = f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
|
||||||
option = f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
|
cmd.run(f"docker build --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{dockerfileprefix} {option} . &> {logfile}", timeout=1600)
|
||||||
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} {option} . &> {logfile}", timeout=1600)
|
|
||||||
t = ("ran-base", archiveArtifact(cmd, ctx, logfile))
|
t = ("ran-base", archiveArtifact(cmd, ctx, logfile))
|
||||||
log_files.append(t)
|
log_files.append(t)
|
||||||
|
|
||||||
# First verify if the base image was properly created.
|
# First verify if the base image was properly created.
|
||||||
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
|
ret = cmd.run(f"docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
|
||||||
allImagesSize = {}
|
allImagesSize = {}
|
||||||
if ret.returncode != 0:
|
if ret.returncode != 0:
|
||||||
logging.error('\u001B[1m Could not build properly ran-base\u001B[0m')
|
logging.error('\u001B[1m Could not build properly ran-base\u001B[0m')
|
||||||
# Recover the name of the failed container?
|
# Recover the name of the failed container?
|
||||||
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty {self.cli} rm -f")
|
cmd.run(f"docker ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty docker rm -f")
|
||||||
cmd.run(f"{self.cli} image prune --force")
|
cmd.run(f"docker image prune --force")
|
||||||
cmd.close()
|
cmd.close()
|
||||||
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
|
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
|
||||||
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
|
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
|
||||||
@@ -333,32 +309,31 @@ class Containerize():
|
|||||||
for image,pattern,name,option in imageNames:
|
for image,pattern,name,option in imageNames:
|
||||||
# the archived Dockerfiles have "ran-base:latest" as base image
|
# the archived Dockerfiles have "ran-base:latest" as base image
|
||||||
# we need to update them with proper tag
|
# we need to update them with proper tag
|
||||||
cmd.run(f'git checkout -- docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
cmd.run(f'git checkout -- docker/Dockerfile.{pattern}{dockerfileprefix}')
|
||||||
cmd.run(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
cmd.run(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
|
||||||
# target images should use the proper ran-build image
|
# target images should use the proper ran-build image
|
||||||
if image != 'ran-build' and "-asan" in name:
|
if image != 'ran-build' and "-asan" in name:
|
||||||
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
|
||||||
elif "fhi72" in name or name == "oai-nr-oru":
|
elif "fhi72" in name or name == "oai-nr-oru":
|
||||||
cmd.run(f'sed -i -e "s#ran-build-fhi72:latest#ran-build-fhi72:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
cmd.run(f'sed -i -e "s#ran-build-fhi72:latest#ran-build-fhi72:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
|
||||||
elif image != 'ran-build':
|
elif image != 'ran-build':
|
||||||
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
|
||||||
if image == 'oai-gnb-aerial':
|
if image == 'oai-gnb-aerial':
|
||||||
cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2026.01.07.tar.gz .')
|
cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2026.01.07.tar.gz .')
|
||||||
logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log'
|
logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log'
|
||||||
if self.host == 'Ubuntu':
|
option = option + f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
|
||||||
option = option + f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
|
ret = cmd.run(f'docker build --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
|
||||||
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
|
|
||||||
t = (name, archiveArtifact(cmd, ctx, logfile))
|
t = (name, archiveArtifact(cmd, ctx, logfile))
|
||||||
log_files.append(t)
|
log_files.append(t)
|
||||||
if image == 'oai-gnb-aerial':
|
if image == 'oai-gnb-aerial':
|
||||||
cmd.run('rm -f nvipc_src.2026.01.07.tar.gz')
|
cmd.run('rm -f nvipc_src.2026.01.07.tar.gz')
|
||||||
# check the status of the build
|
# check the status of the build
|
||||||
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
|
ret = cmd.run(f"docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
|
||||||
if ret.returncode != 0:
|
if ret.returncode != 0:
|
||||||
logging.error('\u001B[1m Could not build properly ' + name + '\u001B[0m')
|
logging.error('\u001B[1m Could not build properly ' + name + '\u001B[0m')
|
||||||
status = False
|
status = False
|
||||||
# Here we should check if the last container corresponds to a failed command and destroy it
|
# Here we should check if the last container corresponds to a failed command and destroy it
|
||||||
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty {self.cli} rm -f")
|
cmd.run(f"docker ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty docker rm -f")
|
||||||
allImagesSize[name] = 'N/A -- Build Failed'
|
allImagesSize[name] = 'N/A -- Build Failed'
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -372,16 +347,16 @@ class Containerize():
|
|||||||
logging.debug(f'{name} size is unknown')
|
logging.debug(f'{name} size is unknown')
|
||||||
allImagesSize[name] = 'unknown'
|
allImagesSize[name] = 'unknown'
|
||||||
# Now pruning dangling images in between target builds
|
# Now pruning dangling images in between target builds
|
||||||
cmd.run(f"{self.cli} image prune --force")
|
cmd.run(f"docker image prune --force")
|
||||||
cmd.run(f'docker logout {DEFAULT_REGISTRY}')
|
cmd.run(f'docker logout {DEFAULT_REGISTRY}')
|
||||||
# Remove all intermediate build images and clean up
|
# Remove all intermediate build images and clean up
|
||||||
cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true")
|
cmd.run(f"docker image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true")
|
||||||
cmd.run(f"{self.cli} volume prune --force")
|
cmd.run(f"docker volume prune --force")
|
||||||
|
|
||||||
# Remove some cached artifacts to prevent out of diskspace problem
|
# Remove some cached artifacts to prevent out of diskspace problem
|
||||||
logging.debug(cmd.run("df -h").stdout)
|
logging.debug(cmd.run("df -h").stdout)
|
||||||
logging.debug(cmd.run("docker system df").stdout)
|
logging.debug(cmd.run("docker system df").stdout)
|
||||||
cmd.run(f"{self.cli} buildx prune --filter until=1h --force")
|
cmd.run(f"docker buildx prune --filter until=1h --force")
|
||||||
logging.debug(cmd.run("df -h").stdout)
|
logging.debug(cmd.run("df -h").stdout)
|
||||||
logging.debug(cmd.run("docker system df").stdout)
|
logging.debug(cmd.run("docker system df").stdout)
|
||||||
|
|
||||||
@@ -489,20 +464,12 @@ class Containerize():
|
|||||||
cmd = cls_cmd.getConnection(node)
|
cmd = cls_cmd.getConnection(node)
|
||||||
cmd.cd(lSourcePath)
|
cmd.cd(lSourcePath)
|
||||||
|
|
||||||
ret = cmd.run('hostnamectl')
|
|
||||||
result = re.search('Ubuntu', ret.stdout)
|
|
||||||
host = result.group(0)
|
|
||||||
if host != 'Ubuntu':
|
|
||||||
cmd.close()
|
|
||||||
raise Exception("Can build unit tests only on Ubuntu server")
|
|
||||||
logging.debug('running on Ubuntu as expected')
|
|
||||||
|
|
||||||
# check that ran-base image exists as we expect it
|
# check that ran-base image exists as we expect it
|
||||||
baseImage = 'ran-base'
|
baseImage = 'ran-base'
|
||||||
baseTag = 'develop'
|
baseTag = 'develop'
|
||||||
if self.ranAllowMerge:
|
if self.ranAllowMerge:
|
||||||
if self.ranTargetBranch == 'develop':
|
if self.ranTargetBranch == 'develop':
|
||||||
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
|
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.ubuntu | grep --colour=never -i INDEX')
|
||||||
result = re.search('index', cmd.getBefore())
|
result = re.search('index', cmd.getBefore())
|
||||||
if result is not None:
|
if result is not None:
|
||||||
baseTag = 'ci-temp'
|
baseTag = 'ci-temp'
|
||||||
|
|||||||
@@ -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
|
|||||||
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')
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
# 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
|
|
||||||
+3
-8
@@ -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):
|
|||||||
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):
|
|||||||
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()
|
|||||||
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()
|
|||||||
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 @@
|
|||||||
- 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
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<!-- 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.
|
|||||||
- [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.
|
|||||||
- 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)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!-- 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.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# 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"
|
||||||
|
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/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` .
|
||||||
Reference in New Issue
Block a user