Skip to content
Snippets Groups Projects
Commit 6a61ee9d authored by Alexander Lussier-Cullen's avatar Alexander Lussier-Cullen Committed by Pierre Nicolas
Browse files

tests: implement automatic testing pipeline

- Create docker with android emulator inside
- Compile, then test the app.

GitLab: #1224
Change-Id: Ifdce6b589715d56d1c1fad518c6a8fb74c13e4eb
parent 8635f407
No related branches found
No related tags found
No related merge requests found
......@@ -15,16 +15,16 @@
* License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
pipeline {
pipeline {
agent {
node {
label 'jami-buildmachine-04.mtl.sfl'
}
}
triggers {
gerrit customUrl: '',
gerrit customUrl: '',
gerritProjects: [
[branches: [[compareType: 'PLAIN', pattern: 'master']],
compareType: 'PLAIN',
......@@ -42,37 +42,94 @@
parameters {
string(name: 'GERRIT_REFSPEC',
defaultValue: 'refs/heads/master',
description: 'The Gerrit refspec to fetch.')
defaultValue: 'refs/heads/master',
description: 'The Gerrit refspec to fetch.')
}
stages {
stage('SCM Checkout') {
steps {
// Wipe workspace and fetch jami-daemon
checkout changelog: true, poll: false,
scm: [$class: 'GitSCM',
branches: [[name: 'FETCH_HEAD']],
doGenerateSubmoduleConfigurations: false,
extensions: [
[$class: 'CloneOption', noTags: true, reference: '', shallow: true],
[$class: 'WipeWorkspace']],
submoduleCfg: [],
userRemoteConfigs: [[refspec: '${GERRIT_REFSPEC}', url: 'https://${JAMI_GERRIT_URL}/jami-client-android']]]
}
}
stage('SCM Checkout') {
steps {
// Wipe workspace and fetch jami-daemon
checkout changelog: true, poll: false,
scm: [$class: 'GitSCM',
branches: [[name: 'FETCH_HEAD']],
doGenerateSubmoduleConfigurations: false,
extensions: [
[$class: 'CloneOption', noTags: true, reference: '', shallow: true],
[$class: 'WipeWorkspace']],
submoduleCfg: [],
userRemoteConfigs: [[refspec: '${GERRIT_REFSPEC}', url: 'https://${JAMI_GERRIT_URL}/jami-client-android']]]
}
}
stage('Init repository') {
steps {
script {
sh """
git rev-parse HEAD
git submodule update --init --recursive
"""
}
}
}
}
stage('Init repository') {
steps {
script {
sh """
git rev-parse HEAD
git submodule update --init --recursive
"""
}
}
}
}
stage('Install pre-fetched tarballs') {
environment {
RING_CONTRIB_TARBALLS = '/opt/ring-contrib'
RING_EXTRATOOLS_TARBALLS = '/opt/ring-extras-tools'
}
steps {
script {
def daemonDir = pwd() + '/daemon'
if (fileExists(RING_EXTRATOOLS_TARBALLS)) {
sh "cp ${RING_EXTRATOOLS_TARBALLS}/* ${daemonDir}/extras/tools/ || echo 'No extras-tools tarballs cache'"
}
if (fileExists(RING_CONTRIB_TARBALLS)) {
sh "cp ${RING_CONTRIB_TARBALLS}/* ${daemonDir}/contrib/tarballs/ || echo 'No contribs tarballs cache'"
}
}
}
}
stage('Build and test client') {
environment {
ANDROID_ABI = "x86_64"
BATCH_MODE = '1'
}
agent {
dockerfile {
reuseNode true
dir 'ci'
filename '../docker/Dockerfile'
args "-u root --privileged -v ${pwd()}/:/jami-client-android -w /jami-client-android"
additionalBuildArgs '--build-arg HOST_UID=1001 --build-arg HOST_GID=1001 --build-arg ANDROID_ABI=x86_64 --build-arg BATCH_MODE=1'
}
}
steps {
script {
sh 'su jenkins -c "cd /jami-client-android && ./compile.sh --test"'
sh 'cd /jami-client-android/ci && ./start_emu_headless.sh'
sh 'su jenkins -c "cd /jami-client-android/ci && ./jami_test.sh"'
}
}
}
stage('Update pre-fetched tarballs directory') {
environment {
RING_CONTRIB_TARBALLS = '/opt/ring-contrib'
RING_EXTRATOOLS_TARBALLS = '/opt/ring-extras-tools'
}
steps {
script {
def daemonDir = pwd() + '/daemon'
if (fileExists(RING_CONTRIB_TARBALLS)) {
sh "rsync -u ${daemonDir}/contrib/tarballs/* ${RING_CONTRIB_TARBALLS}/ || echo 'contribs tarballs cache backup failed'"
}
if (fileExists(RING_EXTRATOOLS_TARBALLS)) {
sh "rsync -u ${daemonDir}/extras/tools/*.tar.* ${RING_EXTRATOOLS_TARBALLS}/ || echo 'extras-tools tarballs cache backup failed'"
}
}
}
}
}
}
#!/bin/bash
# Before using this script, ensure the following:
# 1. Set the JAVA_HOME environment variable to the path where Java is installed.
# 2. Set the SPOON_RUNNER_PATH environment variable to the path of the Spoon runner JAR file.
# 3. Set the ANDROID_SDK_ROOT environment variable to the path where Android SDK is installed.
# 4. Compile Jami using the following Gradle command: ./gradlew assembleAndroidTest assembleDebug
# Check the JAVA_HOME environment variable
if [ -z "$JAVA_HOME" ]; then
echo "Error: JAVA_HOME environment variable is not set."
exit 1
fi
# Check the SPOON_RUNNER_PATH environment variable
if [ -z "$SPOON_RUNNER_PATH" ]; then
echo "Error: SPOON_RUNNER_PATH environment variable is not set."
exit 1
fi
# Check the ANDROID_SDK_ROOT environment variable
if [ -z "$ANDROID_SDK_ROOT" ]; then
echo "Error: ANDROID_SDK_ROOT environment variable is not set."
exit 1
fi
SCRIPT_DIRECTORY=$(dirname "$0")
APK_PATH=$SCRIPT_DIRECTORY/../jami-android/app/build/outputs/apk/noPush/debug/app-noPush-debug.apk
TEST_APK_PATH=$SCRIPT_DIRECTORY/../jami-android/app/build/outputs/apk/androidTest/noPush/debug/app-noPush-debug-androidTest.apk
# Check the existence of the APK_PATH file
if [ ! -f "$APK_PATH" ]; then
echo "Error: APK file does not exist at the specified location: $APK_PATH"
exit 1
fi
# Check the existence of the TEST_APK_PATH file
if [ ! -f "$TEST_APK_PATH" ]; then
echo "Error: Test APK file does not exist at the specified location: $TEST_APK_PATH"
exit 1
fi
"$JAVA_HOME"/bin/java -jar "$SPOON_RUNNER_PATH" --apk "$APK_PATH" --test-apk "$TEST_APK_PATH" --sdk "$ANDROID_SDK_ROOT" --fail-on-failure
# Capture the exit code
exit_code=$?
# Check the exit code and display appropriate logs
if [ $exit_code -eq 0 ]; then
echo "Jami UI test success. More info on 'spoon-output' directory."
else
echo "Jami UI test failure ($exit_code). More info on 'spoon-output' directory."
exit $exit_code
fi
#!/bin/bash
# File origin : https://github.com/amrsa1/Android-Emulator-image/blob/main/start_emu_headless.sh
BL='\033[0;34m'
G='\033[0;32m'
RED='\033[0;31m'
YE='\033[1;33m'
NC='\033[0m' # No Color
emulator_name="${EMULATOR_NAME}"
set -x
function check_hardware_acceleration () {
if [[ "$HW_ACCEL_OVERRIDE" != "" ]]; then
hw_accel_flag="$HW_ACCEL_OVERRIDE"
else
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS-specific hardware acceleration check
HW_ACCEL_SUPPORT=$(sysctl -a | grep -E -c '(vmx|svm)')
else
# generic Linux hardware acceleration check
HW_ACCEL_SUPPORT=$(grep -E -c '(vmx|svm)' /proc/cpuinfo)
fi
if [[ $HW_ACCEL_SUPPORT == 0 ]]; then
hw_accel_flag="-accel off"
else
hw_accel_flag="-accel on"
fi
fi
echo "$hw_accel_flag"
}
hw_accel_flag=$(check_hardware_acceleration)
function launch_emulator () {
adb devices | grep emulator | cut -f1 | xargs -I {} adb -s "{}" emu kill
options="@${emulator_name} -no-window -no-snapshot -noaudio -no-boot-anim -memory 2048 ${hw_accel_flag} -camera-back none"
if [[ "$OSTYPE" == *linux* ]]; then
echo "${OSTYPE}: emulator ${options} -gpu off"
nohup emulator $options -gpu off &
fi
if [[ "$OSTYPE" == *darwin* ]] || [[ "$OSTYPE" == *macos* ]]; then
echo "${OSTYPE}: emulator ${options} -gpu swiftshader_indirect"
nohup emulator $options -gpu swiftshader_indirect &
fi
if [ $? -ne 0 ]; then
echo "Error launching emulator"
return 1
fi
}
function check_emulator_status () {
printf "${G}==> ${BL}Checking emulator booting up status 🧐${NC}\n"
start_time=$(date +%s)
spinner=( "⠹" "⠺" "⠼" "⠶" "⠦" "⠧" "⠇" "⠏" )
i=0
# Get the timeout value from the environment variable or use the default value of 300 seconds (5 minutes)
timeout=${EMULATOR_TIMEOUT:-300}
while true; do
result=$(adb shell getprop sys.boot_completed 2>&1)
if [ "$result" == "1" ]; then
printf "\e[K${G}==> \u2713 Emulator is ready : '$result' ${NC}\n"
adb devices -l
adb shell input keyevent 82
break
elif [ "$result" == "" ]; then
printf "${YE}==> Emulator is partially Booted! 😕 ${spinner[$i]} ${NC}\r"
else
printf "${RED}==> $result, please wait ${spinner[$i]} ${NC}\r"
i=$(( (i+1) % 8 ))
fi
current_time=$(date +%s)
elapsed_time=$((current_time - start_time))
if [ $elapsed_time -gt $timeout ]; then
printf "${RED}==> Timeout after ${timeout} seconds elapsed 🕛.. ${NC}\n"
break
fi
sleep 4
done
};
function disable_animation() {
adb shell "settings put global window_animation_scale 0.0"
adb shell "settings put global transition_animation_scale 0.0"
adb shell "settings put global animator_duration_scale 0.0"
};
function hidden_policy() {
adb shell "settings put global hidden_api_policy_pre_p_apps 1;settings put global hidden_api_policy_p_apps 1;settings put global hidden_api_policy 1"
};
launch_emulator
check_emulator_status
disable_animation
hidden_policy
#! /bin/bash
# Build Jami daemon and client APK for Android
# Flags:
# --test: build in test mode
# --release: build in release mode
# --daemon: Only build the daemon for the selected archs
TEST=0
RELEASE=0
DAEMON_ONLY=0
for i in ${@}; do
for i in "${@}"; do
case "$i" in
test|--test)
TEST=1
;;
release|--release)
RELEASE=1
;;
......@@ -19,6 +24,7 @@ for i in ${@}; do
;;
esac
done
export RELEASE
if [ -z "$DAEMON_DIR" ]; then
......@@ -35,15 +41,15 @@ fi
export DAEMON_DIR
JNIDIR=$DAEMON_DIR/bin/jni
ANDROID_TOPLEVEL_DIR="`pwd`"
ANDROID_TOPLEVEL_DIR="$(pwd)"
ANDROID_APP_DIR="${ANDROID_TOPLEVEL_DIR}/jami-android"
GRADLE_PROPERTIES=
if [ ! -z "$ANDROID_ABI" ]; then
if [ -n "$ANDROID_ABI" ]; then
GRADLE_PROPERTIES="-Parchs=${ANDROID_ABI}"
fi
# Generate JNI interface
cd $JNIDIR
cd "$JNIDIR" || exit 1
PACKAGEDIR=$ANDROID_APP_DIR/libjamiclient/src/main/java ./make-swig.sh
if [[ $DAEMON_ONLY -eq 0 ]]; then
......@@ -54,11 +60,17 @@ if [[ $DAEMON_ONLY -eq 0 ]]; then
echo "Building with Firebase support"
fi
if [[ $RELEASE -eq 1 ]]; then
cd $ANDROID_APP_DIR && ./gradlew $GRADLE_PROPERTIES assembleRelease bundleRelease
echo "Building in release mode"
cd "$ANDROID_APP_DIR" && ./gradlew $GRADLE_PROPERTIES assembleRelease bundleRelease
elif [[ $TEST -eq 1 ]]; then
echo "Building in test mode"
cd "$ANDROID_APP_DIR" && ./gradlew $GRADLE_PROPERTIES assembleDebug assembleAndroidTest
else
cd $ANDROID_APP_DIR && ./gradlew $GRADLE_PROPERTIES assembleDebug
echo "Building in debug mode"
echo "$GRADLE_PROPERTIES" assembleDebug
cd "$ANDROID_APP_DIR" && ./gradlew $GRADLE_PROPERTIES assembleDebug
fi
else
echo "Building daemon only"
cd $ANDROID_APP_DIR && ./gradlew $GRADLE_PROPERTIES buildCMakeDebug
cd "$ANDROID_APP_DIR" && ./gradlew $GRADLE_PROPERTIES buildCMakeDebug
fi
FROM gradle:jdk17
FROM gradle:jdk17-jammy as build
ENV LANG en_US.utf8
ENV LC_ALL en_US.utf8
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
gnupg \
software-properties-common \
wget
#RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null && \
# apt-add-repository 'deb https://apt.kitware.com/ubuntu/ jammy main'
# Script dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
gnupg \
software-properties-common \
wget
# Jami build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
asciidoc \
autogen \
automake \
autoconf \
autopoint \
gettext \
ca-certificates \
cmake \
bc \
bison \
build-essential \
ninja-build \
bzip2 \
doxygen \
git \
lib32stdc++6 \
lib32z1 \
libtool \
locales \
m4 \
pkg-config \
python-is-python3 \
ssh \
unzip \
wget \
curl \
yasm \
nasm \
zip \
libpcre2-dev \
libpcre3 \
libpcre3-dev \
ruby ruby-dev \
&& locale-gen $LANG $LC_ALL && update-locale $LANG $LC_ALL
# Android SDK tools
RUN echo "prefer-family = IPv6" >> /etc/wgetrc
ENV ANDROID_HOME=/opt/android-sdk
ENV ANDROID_SDK_ROOT=${ANDROID_HOME}
RUN wget -O /tmp/android-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip && \
mkdir -p ${ANDROID_HOME} && \
unzip -q -d ${ANDROID_HOME} /tmp/android-tools.zip && \
rm -f /tmp/android-tools.zip && \
chown -R root:root ${ANDROID_HOME}
ENV PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/bin
# Swig 4.1.1
asciidoc \
autoconf \
autogen \
automake \
autopoint \
bc \
bison \
build-essential \
bzip2 \
cmake \
curl \
doxygen \
gettext \
git \
lib32stdc++6 \
lib32z1 \
libpcre2-dev \
libpcre3 \
libpcre3-dev \
libtool \
locales \
m4 \
nasm \
ninja-build \
pkg-config \
python-is-python3 \
ruby \
ruby-dev \
ssh \
unzip \
yasm \
zip \
&& locale-gen $LANG $LC_ALL && update-locale $LANG $LC_ALL
# Install Swig 4.1.1
RUN wget -O /tmp/swig.tar.gz https://github.com/swig/swig/archive/v4.1.1.tar.gz && \
tar xzf /tmp/swig.tar.gz -C /opt && \
cd /opt/swig-4.1.1/ && ./autogen.sh && ./configure && make && make install && \
cd .. && rm -rf /opt/swig-4.1.1 /tmp/swig.tar.gz
# Android SDK libraries, NDK
RUN sdkmanager --sdk_root=${ANDROID_HOME} --update
RUN (while sleep 1; do echo "y"; done) | sdkmanager --channel=1 --sdk_root=${ANDROID_HOME} 'build-tools;34.0.0' \
'platforms;android-34'\
'extras;android;m2repository'\
'extras;google;m2repository'\
'ndk;26.2.11394342'
ENV ANDROID_SDK=${ANDROID_HOME}
ENV ANDROID_NDK=${ANDROID_HOME}/ndk/26.2.11394342
# Fastlane
tar xzf /tmp/swig.tar.gz -C /opt && \
cd /opt/swig-4.1.1/ && ./autogen.sh && ./configure && make && make install && \
cd .. && rm -rf /opt/swig-4.1.1 /tmp/swig.tar.gz
# Install Fastlane
RUN gem install fastlane -NV
ENV HOME=/tmp
# Install Commandlinetools.
ENV ANDROID_SDK_ROOT=/opt/android
ARG ANDROID_CMD="commandlinetools-linux-11076708_latest.zip"
RUN wget https://dl.google.com/android/repository/${ANDROID_CMD} -P /tmp && \
unzip -d $ANDROID_SDK_ROOT /tmp/$ANDROID_CMD && \
mkdir -p $ANDROID_SDK_ROOT/cmdline-tools/tools && cd $ANDROID_SDK_ROOT/cmdline-tools && mv NOTICE.txt source.properties bin lib tools/ && \
cd $ANDROID_SDK_ROOT/cmdline-tools/tools && ls
ENV PATH "$PATH:$ANDROID_SDK_ROOT/cmdline-tools/tools:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/build-tools/${BUILD_TOOLS}"
# Install android SDK libraries, NDK.
ARG API_LEVEL="34"
ARG BUILD_TOOLS="34.0.0"
RUN sdkmanager --update
RUN yes Y | sdkmanager --licenses
RUN sdkmanager --channel=1 --no_https "platforms;android-${API_LEVEL}" \
'extras;android;m2repository' \
'extras;google;m2repository' \
'ndk;26.3.11579264' \
"build-tools;${BUILD_TOOLS}"
ENV ANDROID_SDK=${ANDROID_SDK_ROOT}
ENV ANDROID_NDK=${ANDROID_SDK_ROOT}/ndk/26.3.11579264
FROM build as test
# Jami build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
libx11-6
# Install Spoon (test manager).
ENV SPOON_RUNNER_PATH=/spoon-runner.jar
RUN wget -O /spoon-runner.jar "https://search.maven.org/remote_content?g=com.squareup.spoon&a=spoon-runner&v=LATEST&c=jar-with-dependencies"
# Install android SDK libraries for emulation.
ARG API_LEVEL="34"
ARG TARGET="google_apis_playstore"
ARG ARCH="x86_64"
ARG EMULATOR_PACKAGE="system-images;android-${API_LEVEL};${TARGET};${ARCH}"
ARG BUILD_TOOLS="34.0.0"
RUN sdkmanager --update
RUN yes Y | sdkmanager --licenses
RUN sdkmanager --channel=1 --no_https "${EMULATOR_PACKAGE}" "emulator" "platform-tools"
# Create emulator.
ARG EMULATOR_NAME="nexus"
ARG EMULATOR_DEVICE="Nexus 6"
ENV EMULATOR_NAME=$EMULATOR_NAME
ENV DEVICE_NAME=$EMULATOR_DEVICE
RUN echo "no" | avdmanager --verbose create avd --force --name "${EMULATOR_NAME}" --device "${EMULATOR_DEVICE}" --package "${EMULATOR_PACKAGE}"
# Create non-root user with identical host uid/gid.
# It will helps with permissions on shared volumes.
ARG HOST_UID
ARG HOST_GID
RUN groupadd -g $HOST_GID jenkins && \
useradd --no-log-init --system --uid $HOST_UID --gid jenkins jenkins --create-home
# Define environment variables.
ENV JAVA_HOME=/opt/java/openjdk/
ENV ANDROID_ABI=x86_64
ENV ANDROID_HOME=/opt/android
ENV PATH="$PATH:/opt/java/openjdk/bin:$ANDROID_SDK_ROOT/cmdline-tools/tools:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/build-tools/${BUILD_TOOLS}"
CMD [ "/bin/bash" ]
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment