Skip to content

Add an integration test #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
*.log

# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
Expand All @@ -29,4 +30,4 @@ buildNumber.properties
# Ignore IntelliJ files
.idea
*.iml
.vscode
.vscode
36 changes: 36 additions & 0 deletions it/Dockerfile-auditor
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
ARG SCANNER_VERSION=latest
FROM sonarsource/sonar-scanner-cli:${SCANNER_VERSION} AS builder

FROM eclipse-temurin:21-jre-alpine

ARG SONAR_SCANNER_HOME=/opt/sonar-scanner
ENV HOME=/tmp \
SONAR_SCANNER_HOME=${SONAR_SCANNER_HOME} \
XDG_CONFIG_HOME=/tmp \
SONAR_USER_HOME=${SONAR_SCANNER_HOME}/.sonar \
PATH=${SONAR_SCANNER_HOME}/bin:${PATH} \
SRC_PATH=/usr/src \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
PYTHONUNBUFFERED=1

WORKDIR /usr/src/myapp/it

USER root
# Copy Scanner installation from builder image
COPY --from=builder /opt/sonar-scanner /opt/sonar-scanner


RUN apk update --no-cache && \
apk add --update --no-cache -q curl gcc jq libffi-dev musl-dev openssl-dev python3 py3-requests shellcheck

RUN set -eux && \
addgroup --gid 1000 scanner-cli && \
adduser --uid 1000 --ingroup scanner-cli --disabled-password --no-create-home --gecos "" scanner-cli && \
mkdir -p "${SRC_PATH}" "${SONAR_USER_HOME}" "${SONAR_USER_HOME}/cache" && \
chown -R scanner-cli:scanner-cli "${SONAR_SCANNER_HOME}" "${SRC_PATH}" && \
chmod -R 555 "${SONAR_SCANNER_HOME}" && \
chmod -R 754 "${SRC_PATH}" "${SONAR_USER_HOME}"

USER scanner-cli
COPY --chown=scanner-cli:scanner-cli it /usr/src/myapp/it
90 changes: 90 additions & 0 deletions it/audit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/sh -e

# ----------------------------------
# Colors
# ----------------------------------
NOCOLOR='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'

# Function to get value from a property file
# arg 1 = the property
# arg 2 = the file path
function prop {
grep "${1}" ${2} | cut -d'=' -f2
}

# Configure sonar-scanner
export SONAR_HOST_URL="http://sonarqube:9000"
export SONAR_ADMIN_LOGIN="admin"
export SONAR_ADMIN_PWD="admin"

# Generate Analysis token
echo "Generating analysis token..."
# Use an UUID for token name. It's useful to launch the audit several time on the same SonarQube execution
uuid=$(cat /proc/sys/kernel/random/uuid)
export SONAR_TOKEN=$(curl -su "$SONAR_ADMIN_LOGIN:$SONAR_ADMIN_PWD" -XPOST "$SONAR_HOST_URL/api/user_tokens/generate?name=$uuid&type=GLOBAL_ANALYSIS_TOKEN" | jq -r '.token')
echo $SONAR_TOKEN
# Audit code
echo "Launching scanner..."
cd /usr/src/myapp/it
sonar-scanner -X -Dsonar.qualitygate.wait 2>&1 | tee /tmp/scanner.log

if [ $? -ne 0 ]
then
echo "${RED}Error scanning Shell scripts${NOCOLOR}" >&2
exit 1
fi

# Check for warnings
if grep -q "^WARN: " /tmp/scanner.log
then
echo -e "${ORANGE}Warnings found ${NOCOLOR}" >&2
exit 1
fi

# Sleep a little because SonarQube needs some time to ingest the audit results
sleep 10

export SONAR_PROJECT_KEY=$(prop 'sonar.projectKey' sonar-project.properties)
echo "SONAR_PROJECT_KEY: $SONAR_PROJECT_KEY"

# Check audit result
echo "Checking result..."
python3 << EOF
from __future__ import print_function
import requests
import sys

r = requests.get('http://sonarqube:9000/api/issues/search?componentKeys=$SONAR_PROJECT_KEY:src/clanhb.f&statuses=OPEN', auth=('$SONAR_ADMIN_LOGIN', '$SONAR_ADMIN_PWD'))
if r.status_code != 200:
print('Invalid server response: ' + str(r.status_code), file=sys.stderr)
sys.exit(1)

data = r.json()

if data['total'] != 100:
print('Wrong total number of issues: ' + str(data['total']), file=sys.stderr)
sys.exit(1)

issues = 0
if 'f77-rules' in data['issues'][0]['rule'] and data['issues'][0]['line'] == 1:
issues += 1

r = requests.get('http://sonarqube:9000/api/issues/search?componentKeys=$SONAR_PROJECT_KEY:src/clanhb.f90&statuses=OPEN', auth=('$SONAR_ADMIN_LOGIN', '$SONAR_ADMIN_PWD'))
if r.status_code != 200:
print('Invalid server response: ' + str(r.status_code), file=sys.stderr)
sys.exit(1)

data = r.json()

if data['total'] != 197:
print('Wrong total number of issues: ' + str(data['total']), file=sys.stderr)
sys.exit(1)
if 'f90-rules' in data['issues'][0]['rule'] and data['issues'][0]['line'] == 1:
issues += 1


sys.exit(0 if issues == 2 else 1)
EOF
23 changes: 23 additions & 0 deletions it/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
services:
sonarqube:
image: sonarqube:${SONARQUBE_VERSION:-community}
ports:
- "9000:9000"
environment:
ES_JAVA_OPTS: "-Xms750m -Xmx750m"
SONARQUBE_VERSION: ${SONARQUBE_VERSION:-community}
security_opt:
- seccomp:unconfined
auditor:
image: auditor:${SCANNER_VERSION:-latest}
build:
context: ..
dockerfile: it/Dockerfile-auditor
args:
SCANNER_VERSION: ${SCANNER_VERSION:-latest}
links:
- sonarqube
command: /bin/sh -e /usr/src/myapp/it/audit.sh
environment:
SCANNER_VERSION: ${SCANNER_VERSION:-latest}
93 changes: 93 additions & 0 deletions it/it.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash

usage(){
echo -e "\nUsage: $0 [sSh] \n"
echo "-h : Display help"
echo "-s [SONAR-SCANNER] : Take Sonar-scanner tag image from https://hub.docker.com/r/sonarsource/sonar-scanner-cli"
echo "-S [SONARQUBE] : Take SonarQube tag image from https://hub.docker.com/_/sonarqube"
}

OPTSTRING=":s:S:h"

while getopts ${OPTSTRING} opt; do
case ${opt} in
s)
export SCANNER_VERSION=$OPTARG
;;
S)
export SONARQUBE_VERSION=$OPTARG
;;
h)
usage
exit 0
;;
:)
echo "Option -${OPTARG} requires an argument."
usage
exit 1
;;
?)
echo "Invalid option: -${OPTARG}."
usage
exit 1
;;
esac
done


export SCRIPT_DIR=`dirname $0`

# Clean-up if needed
echo "Cleanup..."
docker-compose -f $SCRIPT_DIR/docker-compose.yml down

# Start containers
echo "Starting SonarQube..."
docker-compose -f $SCRIPT_DIR/docker-compose.yml up -d sonarqube
CONTAINER_NAME=$(docker ps --format "{{.Names}}" | grep 'it-sonarqube-1.*' | head -1)
# Wait for SonarQube to be up
grep -q "SonarQube is operational" <(docker logs --follow --tail 0 $CONTAINER_NAME)
echo "SonarQube started!"

# Copy the plugins
MAVEN_VERSION=$(grep '<version>' $SCRIPT_DIR/../pom.xml | head -1 | sed 's/<\/\?version>//g'| awk '{print $1}')
echo "Installing the plugin Icode version $MAVEN_VERSION"
docker cp $SCRIPT_DIR/../target/sonar-icode-cnes-plugin-$MAVEN_VERSION.jar $CONTAINER_NAME:/opt/sonarqube/extensions/plugins
# Restart SonarQube
docker-compose -f $SCRIPT_DIR/docker-compose.yml restart sonarqube
# Wait for SonarQube to be up
grep -q "SonarQube is operational" <(docker logs --follow --tail 0 $CONTAINER_NAME)
# Check plug-in installation
docker exec -u root $CONTAINER_NAME bash -c "if grep -q Alpine /etc/issue; then apk update && apk add -q curl; fi"
docker exec -u root $CONTAINER_NAME bash -c "if grep -q Ubuntu /etc/issue; then apt-get update && apt-get install -y curl; fi"
if ! docker exec $CONTAINER_NAME curl -su admin:admin http://localhost:9000/api/plugins/installed | python -c '
import sys
import json
plugins_count = 0
plugins_expected = ["icode"]
data = json.loads(sys.stdin.read())
if "plugins" in data:
for plugin in data["plugins"]:
if plugin["key"] in plugins_expected:
plugins_count += 1
if plugins_count == len(plugins_expected):
sys.exit(0)
else:
sys.exit(1)
'
then
echo "Plugin not installed" >&2
exit 1
fi
echo "Plugin successfully installed!"

# Audit code
echo "Audit test scripts..."
docker-compose -f $SCRIPT_DIR/docker-compose.yml up --build --exit-code-from auditor auditor
AUDIT_STATUS=$?

# Delete containers
echo "Cleanup..."
docker-compose -f $SCRIPT_DIR/docker-compose.yml down

exit $AUDIT_STATUS
5 changes: 5 additions & 0 deletions it/sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sonar.projectKey=icode
sonar.projectName=I-Code
sonar.projectVersion=1.0
sonar.sources=src
sonar.scm.disabled=True
Loading