Skip to content

Commit f6bedae

Browse files
committed
ci: Debug
1 parent 6ab4180 commit f6bedae

3 files changed

Lines changed: 47 additions & 89 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -278,26 +278,9 @@ jobs:
278278
name: ${{ matrix.name }}
279279
path: releases/release_*/${{ matrix.artifact-files }}
280280

281-
integration_test_android_prebuild:
282-
name: "Prebuild the test binary for integration tests on android"
283-
runs-on: self-hosted
284-
steps:
285-
- uses: actions/checkout@v4
286-
with:
287-
submodules: recursive
288-
289-
- name: Prebuild
290-
run: |
291-
./docker/linux.sh \
292-
--container ouisync-integration-test-android-prebuild-$GITHUB_RUN_ID \
293-
--srcdir . \
294-
--cache \
295-
integration-test --platform android --prebuild
296-
297281
integration_test_android:
298282
name: "run integration tests on android ${{ matrix.api-level }}"
299283
runs-on: self-hosted
300-
needs: ["integration_test_android_prebuild"]
301284
strategy:
302285
fail-fast: false
303286
matrix:
@@ -342,7 +325,6 @@ jobs:
342325
# # Upload only when the tests fail
343326
# if: failure() || cancelled()
344327

345-
346328
# TODO: Integration tests on both linux and windows currently fail or hang. Commenting them out until they are fixed.
347329
# integration_test_desktop:
348330
# name: run integration tests on ${{ matrix.name }}

android/settings.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,3 @@ includeBuild('../ouisync/bindings/kotlin') {
4646
substitute module('ie.equalit.ouinet:ouisync-service-debug') using project(':ouisync-service')
4747
}
4848
}
49-

docker/linux.sh

Lines changed: 47 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ container_name=$default_container_name
3030
# Is cache enabled (see `$cache_paths` to see what's cached)?
3131
cache=
3232

33-
# Is gradle cache enabled? Needed only for android integration test and build
34-
cache_gradle=
35-
3633
# Name of the docker volume to put the cache on
3734
cache_volume="$base_name-cache"
3835

@@ -47,6 +44,10 @@ cache_paths=(
4744
# Cargo per project
4845
/opt/ouisync-app/ouisync/target
4946

47+
# Gradle
48+
/root/.gradle/caches
49+
/root/.gradle/wrapper
50+
5051
# Dart
5152
/root/.pub-cache
5253

@@ -84,7 +85,6 @@ function print_help() {
8485
echo "Options:"
8586
echo " --platform <linux|android> Platform for which to run the tests"
8687
echo " --api <API> Android API level to run in"
87-
echo " --prebuild Only build the test binary, don't run the tests. Useful for seeding the cache."
8888
;;
8989
"analyze")
9090
echo "Analyze the dart source code"
@@ -136,8 +136,8 @@ function print_help() {
136136
esac
137137
}
138138

139-
function build_container() {
140-
log_group_begin "Building image $image_name"
139+
function build_image() {
140+
log_group_begin "Build image $image_name"
141141

142142
ndk_version=$(cat ndk-version.txt)
143143
dock build -t $image_name --build-arg NDK_VERSION=$ndk_version - < docker/Dockerfile.linux
@@ -155,48 +155,11 @@ function create_cache_volume() {
155155
log_group_end
156156
}
157157

158-
# Gradle cache doesn't work well when accessed from multiple containers concurrently. This is
159-
# because the Gradle daemons need to communicate with each other over localhost TCP sockets in
160-
# order to coordinate locking and this doesn't work when each daemon runs in a separate container
161-
# (due to network separation). One way around this is to run the containers with `--network host`
162-
# but that comes with its own issues and is generally not worth it. To solve this, we copy
163-
# (using rsync) the Gradle cache files from the cache volume to the container at the beginning of
164-
# the run and the copy them back at the end of it. We use file locks to synchronize the copies.
165-
gradle_cache_root=/root/.gradle
166-
gradle_cache_dirs=(caches wrapper)
167-
168-
function gradle_cache_rsync() {
169-
local lock_mode=$1
170-
local src=$2
171-
local dst=$3
172-
173-
exe mkdir -p "${gradle_cache_dirs[@]/#/$src/}"
174-
exe flock $lock_mode /mnt/cache/gradle.lock \
175-
rsync \
176-
-a \
177-
--exclude='*.lock' \
178-
${gradle_cache_dirs[@]/*/--include=/&/ --include=/&/***} \
179-
--exclude='*' \
180-
"$src/" "$dst"
181-
}
182-
183-
function restore_gradle_cache() {
184-
log_group_begin "Restore gradle cache"
185-
gradle_cache_rsync --shared /mnt/cache$gradle_cache_root $gradle_cache_root
186-
log_group_end
187-
}
188-
189-
function save_gradle_cache() {
190-
log_group_begin "Save gradle cache"
191-
gradle_cache_rsync --exclusive $gradle_cache_root /mnt/cache$gradle_cache_root
192-
log_group_end
193-
}
194-
195158
function start_container() {
196159
if [ -z "$commit" -a -z "$srcdir" ]; then error "Missing one of --commit or --srcdir"; fi
197160
if [ -n "$commit" -a -n "$srcdir" ]; then error "--commit and --src are mutually exclusive"; fi
198161

199-
build_container
162+
build_image
200163

201164
if [ "$cache" = 1 ]; then
202165
create_cache_volume
@@ -256,10 +219,6 @@ function start_container() {
256219
fi
257220
log_group_end
258221

259-
if [ "$cache" = 1 -a "$cache_gradle" = 1 ]; then
260-
restore_gradle_cache
261-
fi
262-
263222
# Generate bindings (TODO: This should be done automatically)
264223
log_group_begin "Generate bindings"
265224
exe -w /opt/ouisync-app/ouisync/bindings/dart -t dart pub get
@@ -270,19 +229,15 @@ function start_container() {
270229
exe -w /opt/ouisync-app -t dart pub get
271230
log_group_end
272231

273-
# Run cargo sweep to delete all cargo artifacts older than 30 days (prevents unbounded cache grow)
274232
if [ "$cache" = 1 ]; then
233+
# Run cargo sweep to delete all cargo artifacts older than 30 days (prevents unbounded cache grow)
275234
log_group_begin "Prune cached cargo artifacts"
276235
exe -w /opt/ouisync-app/ouisync -t cargo sweep --recursive --time 30
277236
log_group_end
278237
fi
279238
}
280239

281240
function stop_container() {
282-
if [ "$cache" = 1 -a "$cache_gradle" ]; then
283-
save_gradle_cache
284-
fi
285-
286241
echo "Stop container $container_name"
287242
dock container stop $container_name
288243
}
@@ -335,7 +290,7 @@ function manage_container() {
335290
stop_container
336291
;;
337292
build)
338-
build_container
293+
build_image
339294
;;
340295
esac
341296
}
@@ -349,7 +304,6 @@ function init() {
349304
# Build the release artifacts for linux and android
350305
function build() {
351306
rsync_include_git=1
352-
cache_gradle=1
353307

354308
local dst_dir="./releases/$container_name"
355309
local flavor=
@@ -434,6 +388,27 @@ function unit_test() {
434388

435389
####################################################################################################
436390

391+
# emulator_serial=
392+
393+
# # Find serial number of the emulator running the given avd
394+
# function emulator_find_serial() {
395+
# local expected_avd=$1
396+
397+
# # Find the serial number
398+
# while true; do
399+
# for serial in $(adb devices | grep emulator | cut -f1); do
400+
# local actual_avd=$(adb -s $serial emu avd name | head -n1 | sed 's/[^[:alnum:]-]//g')
401+
402+
# if [ "$expected_avd" = "$actual_avd" ]; then
403+
# emulator_serial=$serial
404+
# return
405+
# fi
406+
# done
407+
408+
# sleep 1
409+
# done
410+
# }
411+
437412
# Wait for the emulator to boot
438413
function emulator_wait_boot() {
439414
while true; do
@@ -511,44 +486,46 @@ function emulator_stop() {
511486
}
512487

513488
function integration_test_android() {
514-
cache_gradle=1
489+
# Share also the build directoty between the integration test jobs, to speed them up
490+
cache_paths+=("/opt/ouisync-app/build")
491+
515492
init
516493

517494
local api=
518-
local prebuild=
519495

520496
while true; do
521497
case ${1-} in
522498
--api)
523499
api="${2-}"
524500
shift 2
525501
;;
526-
--prebuild)
527-
prebuild=1
528-
shift
529-
;;
530502
*)
531503
break
532504
;;
533505
esac
534506
done
535507

536-
if [ "$prebuild" = 1 ]; then
537-
log_group_begin "Pre-build the test binary"
538-
exe -w /opt/ouisync-app -t flutter build apk --debug --flavor itest --target-platform android-x64
539-
log_group_end
540-
return
541-
fi
542-
543508
if [ -z "$api" ]; then
544509
error "Missing --api"
545510
fi
546511

547512
emulator_start --api $api
548513

549514
log_group_begin "Run tests"
550-
exe -w /opt/ouisync-app -t flutter \
551-
test integration_test --flavor itest --ignore-timeouts $@
515+
516+
# Note: While multiple gradle daemons can safely access the gradle home directory
517+
# (~/.gradle) concurrently when running on the same machine, the same is not true when they run
518+
# on different containers while the gradle home is shared between them. This is because the
519+
# daemons need to coordinate locking and they use localhost TCP sockets to do that which
520+
# doesn't work in containers due to network isolation. To work around that, we put a big fat
521+
# lock around this whole command so that only one container can run it at a time.
522+
#
523+
# TODO: This is not optimal. Try to find a way to split the test building and running into two
524+
# steps and put the lock only around the build step (which needs to happen only once anyway).
525+
exe -w /opt/ouisync-app -t \
526+
flock /mnt/cache/gradle.lock \
527+
flutter test integration_test --flavor itest --ignore-timeouts $@
528+
552529
log_group_end
553530

554531
emulator_stop

0 commit comments

Comments
 (0)