-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathci-run-maestro.sh
More file actions
executable file
·278 lines (215 loc) · 9.26 KB
/
Copy pathci-run-maestro.sh
File metadata and controls
executable file
·278 lines (215 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/bin/bash
# Script used in CI environment (Continuous Integration - eg Jenkins) to run Maestro end to end tests (see
# .maestro for test flows
ROOTDIR=$(realpath $(dirname $BASH_SOURCE))
# Root directory for TestServerController to use (each server will get its own sub directory)
# TestServerController will create the directory automatically.
TESTSERVERCONTROLLER_BASEDIR="$ROOTDIR/build/testservercontroller/workspace"
TESTSERVERCONTROLLER_DOWNLOAD_URL="https://devserver3.ustadmobile.com/jenkins/job/TestServerController/9/artifact/build/distributions/testservercontroller-0.0.8.zip"
TESTSERVERCONTROLLER_BASENAME="testservercontroller-0.0.8"
echo "ROOTDIR=$ROOTDIR BASH_SOURCE=$BASH_SOURCE"
if [ ! -e $ROOTDIR/build/testservercontroller/$TESTSERVERCONTROLLER_BASENAME ]; then
if [ ! -e $ROOTDIR/build/testservercontroller ]; then
mkdir -p $ROOTDIR/build/testservercontroller
fi
wget --quiet --output-document=$ROOTDIR/build/testservercontroller/$TESTSERVERCONTROLLER_BASENAME.zip $TESTSERVERCONTROLLER_DOWNLOAD_URL
unzip -q -d $ROOTDIR/build/testservercontroller/ \
$ROOTDIR/build/testservercontroller/$TESTSERVERCONTROLLER_BASENAME.zip
fi
TESTCONTROLLER_BIN=$ROOTDIR/build/testservercontroller/$TESTSERVERCONTROLLER_BASENAME/bin/testservercontroller
if [ "$TESTCONTROLLER_PORT" == "" ]; then
TESTCONTROLLER_PORT=8094
fi
if [ "$TESTCONTROLLER_URL" == "" ]; then
if [ "$URL_SUBSTITUTION" != "" ]; then
TESTCONTROLLER_URL=$(echo $URL_SUBSTITUTION | sed s/_PORT_/$TESTCONTROLLER_PORT/g)
else
echo "ci-run-maestro: no TESTCONTROLLER_URL set: using hostname - this might not be correct"
TESTCONTROLLER_URL="http://$(hostname -I | awk '{print $1}'):$TESTCONTROLLER_PORT/"
fi
fi
echo "ci-run-maestro: TESTCONTROLLER_URL is $TESTCONTROLLER_URL"
if [ "$TEST_LEARNINGSPACE_PORTRANGE" == "" ]; then
TEST_LEARNINGSPACE_PORTRANGE="8000-9000"
fi
function cleanup() {
if [ "$TESTCONTROLLER_PID" != "" ]; then
echo "ci-run-maestro: note 'No instance for key AttributeKey: KOIN_SCOPE' can be safely ignored"
echo "ci-run-maestro: Stopping TestServerController"
wget -qO- "${TESTCONTROLLER_URL}shutdown"
sleep 10
if [ -d "/proc/$PID" ]; then
echo "ci-run-maestro: calling kill just in case (no such process error can be ignored)"
kill $TESTCONTROLLER_PID
fi
fi
}
trap cleanup EXIT
DIR_ADMIN_AUTH_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
if [ "$SCHOOL_ADMIN_PASSWORD" == "" ]; then
SCHOOL_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
fi
if [ "$GIT_TAG_NAME" != "" ]; then
VERSION=$GIT_TAG_NAME
else
GRADLE_PROP_LINE=$(grep version= $ROOTDIR/gradle.properties)
# Use bash parameter expansion to remove version=prefix
VERSION=${GRADLE_PROP_LINE#version=}
fi
# The Maestro test needs to use basic auth (which is base64 encoded) to authenticate to request the
# creation of the school, that is encoded here and passed to Maestro to avoid using Maestro's
# Javascript (which does not have the btoa function)
DIR_ADMIN_TO_ENCODE="admin:$DIR_ADMIN_AUTH_PASS"
DIR_ADMIN_AUTH_HEADER="Basic $(printf '%s' $DIR_ADMIN_TO_ENCODE | base64)"
export JAVA_OPTS="-Dlogs_dir=$TESTSERVERCONTROLLER_BASEDIR/logs/"
$TESTCONTROLLER_BIN \
-P:ktor.deployment.port=$TESTCONTROLLER_PORT \
-P:testservercontroller.portRange=$TEST_LEARNINGSPACE_PORTRANGE \
-P:testservercontroller.urlsubstitution=$URL_SUBSTITUTION \
-P:testservercontroller.basedir=$TESTSERVERCONTROLLER_BASEDIR \
-P:testservercontroller.env.DIR_ADMIN_AUTH=$DIR_ADMIN_AUTH_PASS \
-P:testservercontroller.env.VERSION=$VERSION \
-P:ktor.deployment.shutdown.url=/shutdown \
-P:testservercontroller.cmd="$ROOTDIR/ci-run-test-server.sh" &
TESTCONTROLLER_PID=$!
wait-port $TESTCONTROLLER_PORT
echo "ci-run-maestro: TestServerController now running on port $TESTCONTROLLER_PORT (pid $TESTCONTROLLER_PID)"
# Can now run maestro - the TESTSERVERCONTROLLER url is known and we also know the admin auth to create a new school etc.
echo "Run Maestro using $TESTSERVERCONTROLLER_URL"
if [ ! -e build/results ]; then
mkdir -p build/results
fi
if [ ! -e build/maestro/results ]; then
mkdir -p build/maestro/output
fi
TEST_APP_URL_ARG=""
if [ "$TEST_APP_URL" != "" ]; then
TEST_APP_URL_ARG=" --env TEST_APP_URL=$TEST_APP_URL "
fi
if [ "$1" == "cloud" ]; then
if [ "$MAESTRO_CLOUD_PROJECTID" == "" ]; then
echo "Must set Maestro cloud project id as MAESTRO_CLOUD_PROJECTID environment var"
exit 1
fi
if [ "$MAESTRO_CLOUD_APIKEY" == "" ]; then
echo "Must set Maestro cloud API key as MAESTRO_CLOUD_APIKEY environment var"
exit 1
fi
BRANCH_ARG=""
PULLREQUEST_ARG=""
NAME_ARG=""
COMMIT_ARG=""
BRANCH_ARG=""
DEVICE_OS_ARG=""
if [ "$BUILD_TAG" != "" ]; then
NAME_ARG="--name=$BUILD_TAG"
fi
if [ "$GIT_BRANCH" != "" ]; then
BRANCH_ARG="--branch=$BRANCH"
fi
if [ "$GIT_COMMIT" != "" ]; then
COMMIT_ARG="--commit-sha=$GIT_COMMIT"
fi
if [ "$PULLREQUEST" != "" ]; then
PULLREQUEST_ARG="--pull-request-id=$PULLREQUEST"
fi
if [ "$DEVICE_OS_ARG" == "" ]; then
DEVICE_OS_ARG="--device-os=android-35"
fi
maestro cloud \
--api-key=$MAESTRO_CLOUD_APIKEY \
--project-id=$MAESTRO_CLOUD_PROJECTID \
--app-file=./respect-app-compose/build/outputs/apk/release/respect-app-compose-release.apk \
--flows=.maestro/flows \
$DEVICE_OS_ARG \
--format=junit \
--output=build/maestro/report.xml \
--timeout=300 \
$NAME_ARG \
--repo-name=Respect \
--repo-owner=UstadMobile \
$COMMIT_ARG \
$BRANCH_ARG \
$PULLREQUEST_ARG \
--env DIR_ADMIN_AUTH_PASS=$DIR_ADMIN_AUTH_PASS \
--env TESTCONTROLLER_URL=$TESTCONTROLLER_URL \
--env SCHOOL_ADMIN_PASSWORD=$SCHOOL_ADMIN_PASSWORD \
--env DIR_ADMIN_AUTH_HEADER="$DIR_ADMIN_AUTH_HEADER" \
--env SCHOOL_NAME=TestSchool \
$TEST_APP_URL_ARG \
| tee $WORKSPACE/build/testservercontroller/workspace/lastMaestroRun.log # | tee: Saves to file, Shows on Jenkins Console
MAESTRO_STATUS=${PIPESTATUS[0]}
echo "ci-run-maestro: Cloud run finished (Status: $MAESTRO_STATUS). Extracting URL.."
MAESTRO_LOG_FILE="$TESTSERVERCONTROLLER_BASEDIR/lastMaestroRun.log"
if [ -f "$MAESTRO_LOG_FILE" ]; then
# This searches for any URL with stable part of the path — /upload/ — regardless of host
export MAESTRO_CLOUD_URL=$(grep -oE 'https://[^ ]*/upload/[^ ]*' "$MAESTRO_LOG_FILE" | tail -1)
if [ -n "$MAESTRO_CLOUD_URL" ]; then
echo "ci-run-maestro: Found URL: $MAESTRO_CLOUD_URL"
export MAESTRO_EMAIL="$MAESTRO_EMAIL"
export RECIVO_API_KEY="$RECIVO_API_KEY"
export RECIVO_ORG_ID="$RECIVO_ORG_ID"
echo "ci-run-maestro: Navigating to downloader script..."
cd "$WORKSPACE/.maestro/video-downloader"
# Ensure executable
chmod +x ci-run-cypress.sh
# Execute the script
./ci-run-cypress.sh || echo "ci-run-maestro: Video downloader script encountered an error (ignoring)"
# Return to original directory
cd "$WORKSPACE"
else
echo "ci-run-maestro: Skipping video download (No Cloud URL found in logs)."
fi
else
echo "ci-run-maestro: Log file not found. Skipping download."
fi
else
maestro test \
--env DIR_ADMIN_AUTH_PASS=$DIR_ADMIN_AUTH_PASS \
--env TESTCONTROLLER_URL=$TESTCONTROLLER_URL \
--env SCHOOL_ADMIN_PASSWORD=$SCHOOL_ADMIN_PASSWORD \
--env DIR_ADMIN_AUTH_HEADER="$DIR_ADMIN_AUTH_HEADER" \
--env SCHOOL_NAME=TestSchool \
$TEST_APP_URL_ARG \
--format=junit \
--test-output-dir=build/maestro/output \
--output=build/maestro/report.xml \
.maestro/flows/*.yaml
MAESTRO_STATUS=$?
fi
echo "ci-run-maestro: Maestro test completed. Workspaces are in $TESTSERVERCONTROLLER_BASEDIR"
function check_databases() {
echo "Checking database integrity..."
while read -r db; do
echo "Checking: $(basename "$db")"
if [ "$(sqlite3 "$db" "PRAGMA integrity_check;")" = "ok" ]; then
echo "PASS: $db"
else
echo "FAIL: $db"
exit 1
fi
done < <(find "$TESTSERVERCONTROLLER_BASEDIR" -path "*/e2e-client-artifacts/*.db")
}
check_databases
echo "All databases passed integrity check."
function create_test_artifact_zip() {
echo "ci-run-maestro: Archiving test artifacts..."
local OUTPUT_ZIP="$ROOTDIR/build/EndToEnd_Test_Artifacts_$(date +%d%m%Y_%H%M%S).zip"
if [ -d "$TESTSERVERCONTROLLER_BASEDIR" ]; then
cd "$TESTSERVERCONTROLLER_BASEDIR"
zip -r "$OUTPUT_ZIP" . \
-x "lastMaestroRun.log" \
-x "*/respect-server*/*" \
-x "*/process.pid" \
-x "*/stderr.log" \
-x "*/data/dir-admin.txt" \
-x "*/data/respect-app.db.lck" \
-x "*/data/server.properties"
cd "$ROOTDIR"
echo "ci-run-maestro: Artifacts zipped to $OUTPUT_ZIP"
else
echo "ci-run-maestro: Workspace directory not found, skipping zip."
fi
}
trap create_test_artifact_zip EXIT
exit $MAESTRO_STATUS