-
Notifications
You must be signed in to change notification settings - Fork 4
/
odounit.sh
executable file
·683 lines (577 loc) · 21 KB
/
odounit.sh
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
#!/usr/bin/env bash
# e - script stops on error (return != 0)
# u - error if undefined variable
set -eu
# Version of the script
SCRIPT_VERSION=0.9.0.1
# Temp file where the output of the docker running the test suite is stored.
LOG=/tmp/odounit-odoo-container.log
# Temp file where debug tracing is written. Tail it to debug the script.
TRACE=/tmp/odoutils-trace.log
# Temp folder for building the custom docker image
DOCKER_BUILD_DIR=/tmp/odoutils-docker-build
# Base names for dockers.
# The actual name incorporates a hash that is dependent on module to test, odoo version and database version.
# Base name of the docker container with odoo that runs the test suite.
DOCKER_ODOO=run-odoo-tests-odoo
# Base name of the docker container that runs the postgres that is backing the odoo instance running the test suite.
DOCKER_PG=run-odoo-tests-pg
# Base name of the user-defined bridge network that connects the odoo container with the database container.
DOCKER_NETWORK=run-odoo-tests-network
# Name of the docker image that is used to run the test suite.
DOCKER_ODOO_IMAGE_NAME=odoo:15
# Name of the docker image that is used for the backing database of the odoo instance that runs the test suite.
DOCKER_PG_IMAGE_NAME=postgres:latest
# Run in loop, or run once. 0: loop / 1: once
ONCE=0
# PLAIN=0 -> Output in interactive mode with screen clear and color.
# PLAIN=1 -> Do not clear the screen, and do not use ANSI escape codes to add colors to the output.
PLAIN=0
# Run in flaky test destection mode. Loop until a test fails, then stop.
FLAKY=0
# Set to 1 as soon as user hits CTRL_C.
STOP_ISSUED=0
# Did the last run of the test suite fail? 0: All tests passed, 1: At least one test failed, 2: Some other (unknown error) occured.
# -1 if test suite was not yet run.
LAST_RUN_FAILED=-1
function trace() {
echo "$1" >>"$TRACE" 2>&1
}
function stop_odoo() {
trace "Stopping odoo server"
docker stop $DOCKER_ODOO_FULL_NAME >>$TRACE 2>&1
}
function stop_database() {
trace "Stopping postgres server"
docker stop $DOCKER_PG_FULL_NAME >>$TRACE 2>&1
}
# Stop both database and odoo docker (database first)
function stop_containers() {
stop_database
stop_odoo
}
function ctrl_c_once() {
STOP_ISSUED=1
stop_containers
exit 0
}
function ctrl_c() {
STOP_ISSUED=1
echo $(tput sgr 0)
ctrl_c_once
}
function please_install {
echo "$0 requires these command to run:"
echo
echo " - figlet"
echo " - tput (from package ncurses-bin)"
echo " - docker (from docker.io)"
echo
echo "Please install them."
echo
echo "On Ubuntu for example:"
echo
echo "$ sudo apt-get install figlet ncurses-bin docker.io"
echo
echo "On MacOS for example:"
echo
echo "% brew install --cask docker"
echo "% brew install figlet ncurses"
echo
exit 1
}
function usage_message {
echo "Usage: $0 [-h | -t | -r] [-i modules_to_install] [-p] [-o] [-g] module_to_test1 [module_to_test_2]"
}
function help_message {
echo "$0 is a test suite runner for odoo modules. It is designed to allow you get quick feedback on changes"
echo "you make in the test suite or the implementation of your module."
echo "It can be used interactively (default), in which case it will continuously monitor your sources and"
echo "(re)run the test suite when a change is detected. A clear visual message is given when tests pass or fail."
echo
echo "Alternatively you can use it to run a test suite once, and check the exit code for scripting purposes in a CI/CD setup."
echo
echo "It uses docker containers to isolate the entire process of running the tests from the rest of your system."
echo
echo "Options:"
echo
echo " -g select the version of odoo to use for running the test suite. Tested with: 14,15 and 16. "
echo
echo " -h Displays this help message."
echo
echo " -o Run test suite once. Do not enter loop to re-run test suite on file change."
echo
echo " -p Do not output in color. Do not clear screen."
echo
echo " -r Delete the database and odoo containers, as well as the bridge network between them."
echo " The containers and network will be re-created when you run the tests next time."
echo " The exit code is 0, also when nothing was deleted."
echo
echo " -t Specify the tests to run (default is all tests in all installed modules) manually. "
echo " Uses the same syntax as --test-tags in odoo command line."
echo
echo " -f Detect flaky tests. Run test suite until a test fails, then stop."
echo
echo
echo " -v Displays the version of the script."
echo
echo " -d Trace the script for debugging purposes."
echo " Run the script itself first in a separate terminal session, then $0 -d to trace it."
echo
echo "Exit codes: (mostly useful in combination with --once --plain, for scripting purposes)"
echo
echo " 0 All tests passed."
echo " 1 At least one test failed."
echo " 2 An (unkown) error occured during running of the tests. (Module install failed / ...)"
echo
echo "Examples:"
echo
echo "Run the test suite of module 'my_module' in a loop and show full color output:"
echo "$ $0 my_module"
echo
echo "Run the test suite for module 'my_module' once and output in plain text:"
echo "$ $0 -p -o my_module"
echo
echo "Delete all containers and log files (by default containers are created and then reused for speed):"
echo "$ $0 -r"
echo
echo "Run test suite for module_A and module_B (both modules will be installed and tests for both will be run):"
echo "$ $0 module_A module_B"
}
# Output big text with figlet
# Fixes issue with background color sequence not getting applied correctly.
# First clear to end of line for 6 line, then re-positiotn cursor back up, then output figlet.
# $1 message to display
function big_text {
if [ "$PLAIN" -eq 0 ]; then
echo "$(tput el)"
echo "$(tput el)"
echo "$(tput el)"
echo "$(tput el)"
echo "$(tput el)"
echo "$(tput el)"
echo -n "$(tput cuu1)"
echo -n "$(tput cuu1)"
echo -n "$(tput cuu1)"
echo -n "$(tput cuu1)"
echo -n "$(tput cuu1)"
echo -n "$(tput cuu1)"
figlet -t -c "$1"
else
echo "$1"
fi
}
function remove_everything {
if [ $(docker ps -a | grep "$DOCKER_ODOO" | wc -l) -gt 0 ]; then
trace "Deleting all odoo containers."
docker rm -v -f $(docker ps -a | grep "$DOCKER_ODOO" | cut -f 1 -d ' ') >>$TRACE
else
trace "No odoo containers found to delete."
fi
if [ $(docker ps -a | grep "$DOCKER_PG" | wc -l) -gt 0 ]; then
trace "Deleting all pg containers."
docker rm -v -f $(docker ps -a | grep "$DOCKER_PG" | cut -f 1 -d ' ') >>$TRACE
else
trace "No pg containers found to delete."
fi
if [ $(docker network ls | grep "$DOCKER_NETWORK" | wc -l) -gt 0 ]; then
trace "Deleting all networks."
docker network rm $(docker network ls | grep "$DOCKER_NETWORK" | cut -f 1 -d ' ') >>$TRACE
else
trace "No bridge networks found to delete."
fi
if [ $(docker image ls | grep "^odounit-" | wc -l) -gt 0 ]; then
trace "Deleting odounit images."
docker image rm $(docker image ls | awk 'BEGIN {IFS="\t"} $0 ~ /^odounit-/ { print $1 ":" $2 }') >>$TRACE
else
trace "No odounit images found to delete."
fi
trace "Truncating log and trace files."
truncate --size 0 $LOG >>$TRACE 2>&1
trace "truncating trace files. BYE BYE! :)"
truncate --size 0 $TRACE >/dev/null 2>&1
}
function run_tests {
trace "run_tests starting."
timestamp=$(date --rfc-3339=seconds | sed "s/ /T/")
trace "Timestamp when we are running: $timestamp"
trace "(Re)starting the odoo server to run the test suite."
if [ $PLAIN -eq 0 ]; then
docker start -i $DOCKER_ODOO_FULL_NAME 2>&1 | tee "$LOG"
else
docker start -i $DOCKER_ODOO_FULL_NAME 2>&1 | sed 's/\x1b\[[0-9;]*[mGKHF]//g' | tee "$LOG"
fi
#docker logs -f --since $timestamp $DOCKER_ODOO_FULL_NAME 2>&1 | tee "$LOG"
trace "Server finished running the odoo test suite."
if [ $(cat "$LOG" | grep "ERROR.* odoo .*test.*FAIL:" | wc -l) -ne 0 ]; then
LAST_RUN_FAILED=1
if [ "$PLAIN" -eq 0 ]; then
echo -n "$(tput bold)$(tput setaf 15)$(tput setab 1)"
fi
trace "Displaying FAILED message."
big_text "FAILED!"
trace "Displaying list of failed tests."
if [ "$PLAIN" -eq 0 ]; then
echo "$(tput smso)These tests failed:$(tput rmso)"
else
echo "These tests failed:"
fi
cat "$LOG" | grep "ERROR.*odoo.*test.*FAIL:" | sed 's/.*FAIL: //g' | cut -c -$(tput cols)
error_count=$(cat "$LOG" | grep "ERROR.* odoo .*test.*FAIL:" | wc -l)
trace "Counted $error_count errors in the odoo logs."
[ "$PLAIN" -eq 0 ] && echo "$(tput sgr0)"
elif [ $(cat $LOG | grep 'ERROR.* odoo .*' | wc -l) -ne 0 ]; then
LAST_RUN_FAILED=2
trace "Errors other than FAIL detected.."
if [ "$PLAIN" -eq 0 ]; then
echo -n "$(tput bold)$(tput setaf 15)$(tput setab 4)"
fi
big_text "Unknown"
[ "$PLAIN" -eq 0 ] && echo "$(tput sgr0)"
else
LAST_RUN_FAILED=0
if [ "$PLAIN" -eq 0 ]; then
echo -n "$(tput bold)$(tput setaf 15)$(tput setab 2)"
fi
trace "Displaying SUCCESS message."
big_text "Success"
[ "$PLAIN" -eq 0 ] && echo "$(tput sgr0)"
fi
trace "run_tests ended."
}
# Check that $@ has one or more modules to test.
# Also validate that these modules exist in the CWD (hcurrent working directory).
# Will remove any trailing / as a convenience feature. Auto-completion in bash of a folder adds /.
#
# $@ the remaining command line arguments, after parsing (and thus removal of) flags and their arguments.
#
# echoes a comma-separated list of modules to install and test.
function parse_cmd_line_arguments() {
RET=""
trace "Parsing [" $# "] command line arguments."
for m in $@; do
trace "Removing any trailing / if present for ["$m"]"
m=$(echo "$m" | sed 's/\///g')
if [ -z "$RET" ]; then
RET="$m"
else
RET="${RET},${m}"
fi
done
trace "Generated comma-separated list of modules to install ["$RET"]"
echo "$RET"
}
# Takes a comma-seperated list of modules, and converts it into a set of test tags for odoo
# e.g. modA,modB -> /modA,/modB
#
# $1 comma-seperated list of modules.
#
# echoes test tags back.
function create_test_tags_from_modules() {
trace "Converting modules list ["$1"] into testing tags."
RET=""
modules=$(echo "$1" | sed "s/,/\n/g")
trace "Converted comma-separated into space-separated: ["$modules"]"
for module in $modules; do
if [ -z "$RET" ]; then
RET="/${module}"
else
RET="$RET,/${module}"
fi
done
trace "Final list of test tags: ["$RET"]"
echo "$RET"
}
# Function to calculate the hash of the watched files and folders for restarting.
#
# echoes back a hash value.
function calculate_hash() {
timestamps=$(find "$@" -type f -exec ls -l --full-time {} + | sort)
trace "timestamps: $timestamps"
# if requirements.txt exists, read from file. Otherwise default to empty.
if [ -f requirements.txt ]; then
trace "reading requirements.txt"
requirements=$(cat requirements.txt)
else
requirements=""
fi
trace "requirements: $requirements"
hash=$(echo "$timestamps\n$requirements" | md5sum | cut -d ' ' -f1)
trace "Calculated hash: $hash"
echo "$hash"
}
function create_log_suppress_module() {
# $1 is the location where you want to create the odoo module
# that contains the code that does the log suppressions during debugging.
trace "Creating log suppression module at $1/log_suppress"
mkdir "$1/log_suppress"
cat >"$1/log_suppress/__init__.py" <<EOT
import logging
import sys
def filter_logs_during_debug(record):
debugging = False
thread_ids = sys._current_frames().keys()
for thread_id in thread_ids:
frame = sys._current_frames()[thread_id]
while frame:
code = frame.f_code
# if name is 'trace_dispatch' in filename ending in 'bdb.py' than we are in debugging mode.
# Unfortunatile threading only adds gettrace() function as of python 3.10.
if code.co_name == 'trace_dispatch' and code.co_filename.endswith('bdb.py'):
debugging = True
break
frame = frame.f_back
return not debugging
root_logger = logging.getLogger()
handlers = root_logger.handlers
for handler in handlers:
handler.addFilter(filter_logs_during_debug)
EOT
# Write manifest
cat >"$1/log_suppress/__manifest__.py" <<EOT
{
'name': 'Log suppress for pdb',
'version': '1.0.0',
'author': 'Dimitry D hondt',
'license': 'LGPL-3',
'depends': [
],
'summary': "Module that suppresses logging output during debugging sessions.",
'description': "Module that suppresses logging output during debugging sessions.",
'category': '',
'demo': [],
'data': [],
'installable': True,
'application': False,
'auto_install': True,
'assets': { },
'sequence': 100,
}
EOT
trace "Done creating log suppression module."
}
# Create a docker image that contains all the pip dependencies found in requirements.txt
function create_docker_image() {
# If the docker image exists -> skip
trace "Scanning if docker exists: odounit-$DOCKER_HASH"
if [ $(docker image ls | grep "odounit-$DOCKER_HASH" | wc -l) -eq 1 ]; then
trace "Docker image is already available. Skipping build step for docker."
return
fi
trace "Docker image not found. Creating it."
rm -rf "$DOCKER_BUILD_DIR"
mkdir -p "$DOCKER_BUILD_DIR"
create_log_suppress_module $DOCKER_BUILD_DIR
touch "$DOCKER_BUILD_DIR/Dockerfile"
echo "FROM $DOCKER_ODOO_IMAGE_NAME" >>"$DOCKER_BUILD_DIR/Dockerfile"
echo "" >>"$DOCKER_BUILD_DIR/Dockerfile"
[ -f requirements.txt ] && cp requirements.txt "$DOCKER_BUILD_DIR"
echo "USER root" >>"$DOCKER_BUILD_DIR/Dockerfile"
[ -f requirements.txt ] && echo "COPY requirements.txt ." >>"$DOCKER_BUILD_DIR/Dockerfile"
echo "RUN mkdir /usr/lib/python3/dist-packages/odoo/addons/log_suppress" >>"$DOCKER_BUILD_DIR/Dockerfile"
echo "COPY log_suppress/* /usr/lib/python3/dist-packages/odoo/addons/log_suppress/" >>"$DOCKER_BUILD_DIR/Dockerfile"
[ -f requirements.txt ] && echo "RUN pip3 install -r requirements.txt" >>"$DOCKER_BUILD_DIR/Dockerfile"
echo "USER odoo" >>"$DOCKER_BUILD_DIR/Dockerfile"
echo "Dockerfile:"
cat "$DOCKER_BUILD_DIR/Dockerfile"
docker build "$DOCKER_BUILD_DIR" -t "odounit-${DOCKER_HASH}"
}
trace "*** Script starting..."
# If we are running on WSL, check that the docker command
trace "Verifying that docker command is available."
# is telling us to start the docker engine via the UI...
if [ $(docker 2>&1 | grep "could not be found" | wc -l) -ne 0 ]; then
docker
echo
echo "***************************************************************************"
echo "*** Please make sure the docker engine is started using docker desktop. ***"
echo "***************************************************************************"
echo
exit 2
fi
if [ $(docker ps 2>&1 | grep "Cannot connect to" | wc -l) -ne 0 ]; then
echo
echo "***************************************************************************"
echo "*** Please make sure the docker engine is started using docker desktop. ***"
echo "***************************************************************************"
echo
exit 2
fi
trace "Starting parse of command line."
while getopts "dg:hoprt:fv" opt; do
trace "Parsing option [$opt] now:"
case $opt in
d)
touch "$TRACE"
tail -f "$TRACE"
exit 0
;;
g)
trace "-g detected"
VERSION=$OPTARG
DOCKER_ODOO_IMAGE_NAME=odoo:$VERSION
case $VERSION in
13 | 14 | 15)
DOCKER_PG_IMAGE_NAME=postgres:10
;;
16)
DOCKER_PG_IMAGE_NAME=postgres:12
;;
esac
trace "Will use DOCKER_ODOO_IMAGE_NAME [$DOCKER_ODOO_IMAGE_NAME] and DOCKER_PG_IMAGE_NAME [$DOCKER_PG_IMAGE_NAME]."
;;
h)
trace "-h detected -> Showing help message."
usage_message
echo
help_message
echo
exit 0
;;
o)
trace "-o detected."
ONCE=1
;;
p)
trace "-p detected. Setting PLAIN=1."
PLAIN=1
;;
r)
trace "-r detected. deleting conatiner + networks."
echo "Removing docker images + postgres and odoo containers used for running tests."
echo "They will be created automatically again when you run $0."
remove_everything
echo "Done."
exit 0
;;
t)
TEST_TAGS=$OPTARG
trace "Will run with --test-tags $TEST_TAGS"
;;
f)
FLAKY=1
trace "Will run in flaky mode: loop until one failing test is found."
;;
v)
echo "Script version: $SCRIPT_VERSION"
exit 0
;;
esac
done
trace "Shifting arguments to find module name."
trace "Command line = [$@]."
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
echo "No module to test was specified."
echo
usage_message
exit 2
fi
for m in $@; do
trace "Removing any trailing / if present for ["$m"]"
m=$(echo "$m" | sed 's/\///g')
trace "Validating that ["$m"] is a valid directory in CWD."
if [ ! -d "$m" ]; then
echo "ERROR: Module [$m] is not a folder in the current working directory [$(pwd)]."
echo
echo "Please specify a valid odoo module."
exit 2
fi
done
# Parse command line argument, validate and convert into comma-separated list of modules to install and test.
MODULES=$(parse_cmd_line_arguments $@)
# Convert list of modules into a set of odoo testing tags.
if [ -z "${TEST_TAGS:-}" ]; then
echo "Will run all tests in installed modules [$MODULES]."
TEST_TAGS=$(create_test_tags_from_modules "$MODULES")
else
echo "Will run with custom --test-tags $TEST_TAGS."
fi
trace "Finished parsing of command line."
# Check if all dependencies are installed..
trace "Verifying that figlet is installed."
[ "$PLAIN" -eq 0 ] && (command -v figlet >>$TRACE 2>&1 || please_install figlet figlet)
trace "Verifying that tput is installed."
[ "$PLAIN" -eq 0 ] && (command -v tput >>$TRACE 2>&1 || please_install tput ncurses-bin)
trace "Verifying that docker is installed."
command -v docker >>$TRACE 2>&1 || please_install docker docker.io
# Log all variables for debugging purposes.
trace "Current DOCKER_ODOO_IMAGE_NAME=$DOCKER_ODOO_IMAGE_NAME"
trace "Current DOCKER_PG_IMAGE_NAME=$DOCKER_PG_IMAGE_NAME"
trace "Current DOCKER_NETWORK=$DOCKER_NETWORK"
# Calculate full names for containers and network bridge
REQUIREMENTS_TXT=""
if [ -f "requirements.txt" ]; then
REQUIREMENTS_HASH=$(cat requirements.txt | md5sum | awk 'BEGIN {IFS="\t"} { print $1 }')
else
REQUIREMENTS_HASH=""
fi
DOCKER_HASH=$(echo "$REQUIREMENTS_HASH" "$MODULES" "$TEST_TAGS" "$DOCKER_ODOO_IMAGE_NAME" "$DOCKER_PG_IMAGE_NAME" | md5sum | cut -d ' ' -f1)
DOCKER_NETWORK_FULL_NAME="$DOCKER_NETWORK-$DOCKER_HASH"
DOCKER_PG_FULL_NAME="$DOCKER_PG-$DOCKER_HASH"
DOCKER_ODOO_FULL_NAME="$DOCKER_ODOO-$DOCKER_HASH"
trace "DOCKER_HASH=$DOCKER_HASH"
trace "DOCKER_NETWORK_FULL_NAME=$DOCKER_NETWORK_FULL_NAME"
trace "DOCKER_PG_FULL_NAME=$DOCKER_PG_FULL_NAME"
trace "DOCKER_ODOO_FULL_NAME=$DOCKER_ODOO_FULL_NAME"
trace "PLAIN=$PLAIN"
trace "ONCE=$ONCE"
create_docker_image
echo "Checking if the user-defined bridge network exists." >>$TRACE
if [ $(docker network ls | grep "$DOCKER_NETWORK_FULL_NAME" | wc -l) -eq 0 ]; then
trace "Creating the user-defined bridge network."
docker network create "$DOCKER_NETWORK_FULL_NAME" >>$TRACE 2>&1
else
trace "User defined bridge network $DOCKER_NETWORK_FULL_NAME still exists, re-using it."
fi
trace "Checking if the postgres docker [$DOCKER_PG_FULL_NAME] exists."
if [ $(docker ps -a | grep "$DOCKER_PG_FULL_NAME" | wc -l) -eq 0 ]; then
trace "Creating a postgres server."
docker create -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --network "$DOCKER_NETWORK_FULL_NAME" --name "$DOCKER_PG_FULL_NAME" "$DOCKER_PG_IMAGE_NAME" >>$TRACE 2>&1
else
trace "Docker $DOCKER_PG_FULL_NAME still exists, re-using it."
fi
trace "Checking if the odoo docker exists."
if [ $(docker ps -a | grep "$DOCKER_ODOO_FULL_NAME" | wc -l) -eq 0 ]; then
trace "Creating the odoo server to run the tests."
command="docker create -v $(pwd):/mnt/extra-addons --name $DOCKER_ODOO_FULL_NAME --network $DOCKER_NETWORK_FULL_NAME -e HOST=$DOCKER_PG_FULL_NAME --tty --interactive odounit-$DOCKER_HASH --limit-time-real 1800 --limit-time-cpu 1800 -d odoo -u $MODULES -i $MODULES --stop-after-init --without-demo all --test-tags $TEST_TAGS"
#command="docker create -v $(pwd):/mnt/extra-addons --name $DOCKER_ODOO_FULL_NAME --network $DOCKER_NETWORK_FULL_NAME -e HOST=$DOCKER_PG_FULL_NAME --tty --interactive $DOCKER_ODOO_IMAGE_NAME --limit-time-real 1800 --limit-time-cpu 1800 -d odoo -u $MODULES -i $MODULES --stop-after-init --without-demo all --test-tags $TEST_TAGS"
echo "$command"
$command
else
trace "Docker $DOCKER_ODOO_FULL_NAME still exists, re-using it."
fi
# Make sure database is started.
trace "Starting the postgres server."
docker start $DOCKER_PG_FULL_NAME >>$TRACE 2>&1
if [ "$ONCE" -eq 1 ]; then
trap ctrl_c_once INT
run_tests
stop_containers
exit $LAST_RUN_FAILED
elif [ "$FLAKY" -eq 1 ]; then
trap ctrl_c_once INT
while [ "$STOP_ISSUED" -eq 0 ]; do
run_tests
if [ "$LAST_RUN_FAILED" -ne 0 ]; then
stop_containers
exit
fi
echo "All tests passed. Running again in 3s. Hit CTRL-C now to stop loop."
sleep 3
done
else
trap ctrl_c INT
CURRENT_HASH=$(calculate_hash)
run_tests
while true; do
if [ "$(calculate_hash)" != "$CURRENT_HASH" ]; then
CURRENT_HASH=$(calculate_hash)
run_tests
fi
if [ "$(calculate_hash)" == "$CURRENT_HASH" ]; then
sleep 1
fi
done
fi
stop_containers