forked from openwallet-foundation/owl-agent-test-harness
-
Notifications
You must be signed in to change notification settings - Fork 0
/
manage
executable file
·1104 lines (954 loc) · 33.7 KB
/
manage
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
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# set -x
# Set of valid agents - add new agents here
export VALID_AGENTS=$(ls aries-backchannels/*/Dockerfile.* | sed "s/^.*file.//" | tr "\n" " " | sort -u)
export MSYS_NO_PATHCONV=1
# getDockerHost; for details refer to https://github.com/bcgov/DITP-DevOps/tree/main/code/snippets#getdockerhost
. /dev/stdin <<<"$(cat <(curl -s --raw https://raw.githubusercontent.com/bcgov/DITP-DevOps/main/code/snippets/getDockerHost))"
export DOCKERHOST=$(getDockerHost)
SCRIPT_HOME="$( cd "$( dirname "$0" )" && pwd )"
export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-aath}"
export AGENT_TIMEOUT=30
export LEDGER_TIMEOUT=60
# these two can be overrode via env vars
export LEDGER_URL_CONFIG="${LEDGER_URL_CONFIG}"
export TAILS_SERVER_URL_CONFIG="${TAILS_SERVER_URL_CONFIG}"
export AGENT_CONFIG_FILE="${AGENT_CONFIG_FILE}"
# these are derived from the above two
LEDGER_URL_HOST="${LEDGER_URL_CONFIG:-http://localhost:9000}"
LEDGER_URL_INTERNAL="${LEDGER_URL_CONFIG:-http://${DOCKERHOST}:9000}"
TAILS_SERVER_URL_HOST="${TAILS_SERVER_URL_CONFIG:-http://localhost:6543}"
TAILS_SERVER_URL_INTERNAL="${TAILS_SERVER_URL_CONFIG:-http://${DOCKERHOST}:6543}"
CLOUD_AGENCY_URL="${CLOUD_AGENCY_URL:-http://localhost:8000}"
# important: inside the internal URLs, we replace "://localhost:" with "://${DOCKERHOST}:"
# so it works inside docker.
LEDGER_URL_INTERNAL="$(echo ${LEDGER_URL_INTERNAL} | sed "s/:\/\/localhost:/:\/\/${DOCKERHOST}:/" )"
TAILS_SERVER_URL_INTERNAL="$(echo ${TAILS_SERVER_URL_INTERNAL} | sed "s/:\/\/localhost:/:\/\/${DOCKERHOST}:/" )"
CLOUD_AGENCY_URL_INTERNAL="$(echo ${CLOUD_AGENCY_URL} | sed "s/:\/\/localhost:/:\/\/${DOCKERHOST}:/" )"
# Running on Windows?
if [[ "$OSTYPE" == "msys" ]]; then
# Prefix interactive terminal commands ...
terminalEmu="winpty"
fi
export INTERACTIVE="-it"
if [[ "$NO_TTY" == "1" ]]; then
unset INTERACTIVE
fi
#Running on Play with Docker?
if [ "${PWD_HOST_FQDN}" != "" ]; then
if [ "${PWD_HOST_FQDN}" == "labs.play-with-docker.com" ]; then
export ETH_CONFIG="eth1"
elif [ "${PWD_HOST_FQDN}" == "play-with-docker.vonx.io" ]; then
export ETH_CONFIG="eth0"
else
export ETH_CONFIG="eth0"
fi
myhost=`ifconfig ${ETH_CONFIG} | grep inet | cut -d':' -f2 | cut -d' ' -f1 | sed 's/\./\-/g'`
if [ "${GENESIS_URL}" == "" ]; then
export GENESIS_URL="http://ip${myhost}-${SESSION_ID}-9000.direct.${PWD_HOST_FQDN}/genesis"
fi
# Check if von-network is running
# Should this be moved out of the Play with Docker section?
if [ "${1}" == "run" ]; then
curl -s ${GENESIS_URL} > /dev/null
res=$?
if test "$res" != "0"; then
echo "Error: Unable to find the genesis file for the Indy Network"
echo "Is von-network running?"
echo GENESIS_URL: ${GENESIS_URL}
exit 1
fi
fi
fi
# =================================================================================================================
# Usage:
# -----------------------------------------------------------------------------------------------------------------
usage () {
cat <<-EOF
Usage: $0 [command] [options]
Commands:
build [ -a agent ]* args
Build the docker images for the agents and the test harness.
You need to do this first.
- "agent" must be one from the supported list: ${VALID_AGENTS}
- multiple agents may be built by specifying multiple -a options
- By default, all agents and the harness will be built
rebuild [ -a agent ]* args
Same as build, but adds the --no-cache option to force building from scratch
run [ -a/b/f/m/d agent ] [-r allure [-e comparison]] [ -i <ini file> ] [ -o <output file> ] [ -n ] [ -v <AIP level> ] [ -t tags ]*
Run the tagged tests using the specified agents for Acme, Bob, Faber and Mallory.
Select the agents for the roles of Acme (-a), Bob (-b), Faber (-f) and Mallory (-m).
- For all to be set to the same, use "-d" for default.
- The value for agent must be one of: ${VALID_AGENTS}
Use -t option(s) to indicate tests with the gives tag(s) are to be executed.
-t options can NOT have spaces, even if the option is quoted; use a behave INI file instead (-i option)
For not running tagged tests, specify a ~ before the tag, e.g. "-t ~@wip" runs tests that don't have the "@wip" tag
Use -v to specify the AIP level, in case the agent needs to customize its startup configuration
"-v 10" or "-v 20"
Use the -i option to use the specified file as the behave.ini file for the run
- Default is the behave.ini file in the "aries-test-harness" folder
Use the -r option to output to allure
(allure is the only supported option)
Use the -e option to compare current results to Known Good Results (KGR)
(comparison is the only supported option)
Use the -n option to start ngrok endpoints for each agent
(this is *required* when testing with a Mobile agent)
Examples:
$0 run -a acapy -b vcx -f vcx -m acapy - Run all the tests using the specified agents per role
$0 run -d vcx - Run all tests for all features using the vcx agent in all roles
$0 run -d acapy -t @SmokeTest -t @P1 - Run the tests tagged @SmokeTest and/or @P1 (priority 1) using all ACA-Py agents
$0 run -d acapy -b mobile -n -t @MobileTest - Run the mobile tests using ngrok endpoints
tags - Get a list of the tags on the features tests
tests - Get a list of the test scenarios in the features, including the associated tags
test [-r allure [-e comparison]] [ -i <ini file> ] [ -o <output file> ] [ -n ] [ -v <AIP level> ] [ -t tags ]*
Run the tagged tests using the set of agents that were started with the 'start' command, using all the same parameters as 'run',
except -a/b/f/m/d/n.
scenarios - synonym for tests, but longer and harder to spell
service [start|stop|logs|clean] service-name
Run the given service command on the given service. Commands:
- start: start the service, creating the AATH docker network if necessary.
- stop: stop the service, deleting the AATH docker network if it's now unused.
- logs: print the scrolling logs of the service. Ctrl-C to exit.
- clean: clean up the service containers and build files, if any.
start [ -a/b/f/m/d agent ]* [-n]
Initialize the test harness using the specified agents for Acme, Bob, Faber and Mallory.
Select the agents for the roles of Acme (-a), Bob (-b), Faber (-f) and Mallory (-m).
- For all to be set to the same, use "-d" for default.
- The value for agent must be one of: ${VALID_AGENTS}
Use the -n option to start ngrok endpoints for each agent
(this is *required* when testing with a Mobile agent)
stop - stop the test harness.
rebuild - Rebuild the docker images.
dockerhost - Print the ip address of the Docker Host Adapter as it is seen by containers running in docker.
EOF
exit 1
}
# -----------------------------------------------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------------------------------------------
toLower() {
echo $(echo ${@} | tr '[:upper:]' '[:lower:]')
}
function echoRed (){
_msg="${@}"
_red='\e[31m'
_nc='\e[0m' # No Color
echo -e "${_red}${_msg}${_nc}"
}
function initDockerBuildArgs() {
dockerBuildArgs=""
# HTTP proxy, prefer lower case
if [[ "${http_proxy}" ]]; then
dockerBuildArgs=" ${dockerBuildArgs} --build-arg http_proxy=${http_proxy}"
else
if [[ "${HTTP_PROXY}" ]]; then
dockerBuildArgs=" ${dockerBuildArgs} --build-arg http_proxy=${HTTP_PROXY}"
fi
fi
# HTTPS proxy, prefer lower case
if [[ "${https_proxy}" ]]; then
dockerBuildArgs=" ${dockerBuildArgs} --build-arg https_proxy=${https_proxy}"
else
if [[ "${HTTPS_PROXY}" ]]; then
dockerBuildArgs=" ${dockerBuildArgs} --build-arg https_proxy=${HTTPS_PROXY}"
fi
fi
echo ${dockerBuildArgs}
}
function initEnv() {
if [ -f .env ]; then
while read line; do
if [[ ! "$line" =~ ^\# ]] && [[ "$line" =~ .*= ]]; then
export ${line//[$'\r\n']}
fi
done <.env
fi
for arg in "$@"; do
# Remove recognized arguments from the list after processing.
shift
case "$arg" in
*=*)
export "${arg}"
;;
*)
# If not recognized, save it for later procesing ...
set -- "$@" "$arg"
;;
esac
done
export LOG_LEVEL=${LOG_LEVEL:-info}
export RUST_LOG=${RUST_LOG:-warning}
}
# TODO: set up image builds so you don't need to use `./manage rebuild` to refresh remote source repo
# - image Dockerfile has an ARG for the commit hash,
# - build script grabs the HEAD commit hash from the agent's github repo
# Build images -- add more backchannels here...
# TODO: Define args to build only what's needed
buildImages() {
args=${@}
echo Agents to build: ${BUILD_AGENTS}
for agent in ${BUILD_AGENTS}; do
export BACKCHANNEL_FOLDER=$(dirname "$(find aries-backchannels -name *.${agent})" )
echo Backchannel Folder: ${BACKCHANNEL_FOLDER}
if [ -e "${BACKCHANNEL_FOLDER}/Dockerfile.${agent}" ]; then
echo "Building ${agent}-agent-backchannel ..."
local REPO_ARGS
REPO_ARGS=
if [[ -f "${BACKCHANNEL_FOLDER}/${agent}.repoenv" ]]; then
source "${BACKCHANNEL_FOLDER}/${agent}.repoenv"
if [[ -n "${REPO_URL}" ]]; then
local REPO_COMMIT
if [[ -z ${REPO_BRANCH} ]]; then
REPO_BRANCH=HEAD
fi
REPO_COMMIT=$(git ls-remote ${REPO_URL} ${REPO_BRANCH} | cut -f1)
REPO_ARGS="--build-arg REPO_URL=${REPO_URL} --build-arg REPO_COMMIT=${REPO_COMMIT}"
fi
fi
if ! docker build \
${args} \
$(initDockerBuildArgs) \
${REPO_ARGS} \
-t "${agent}-agent-backchannel" \
-f "${BACKCHANNEL_FOLDER}/Dockerfile.${agent}" "aries-backchannels/"; then
echo "Docker image build failed."
exit 1
fi
else
echo "Unable to find Dockerfile to build agent: ${agent}"
echo "Must be one one of: ${VALID_AGENTS}"
fi
done
echo "Building aries-test-harness ..."
if ! docker build \
${args} \
$(initDockerBuildArgs) \
-t 'aries-test-harness' \
-f 'aries-test-harness/Dockerfile.harness' 'aries-test-harness/'; then
echo "Docker image build failed."
exit 1
fi
}
pingLedger(){
ledger_url=${1}
# ping ledger web browser for genesis txns
local rtnCd=$(curl -s --write-out '%{http_code}' --output /dev/null ${ledger_url}/genesis)
if (( ${rtnCd} == 200 )); then
return 0
else
return 1
fi
}
waitForLedger(){
(
# Wait for ledger server to start ...
local startTime=${SECONDS}
local rtnCd=0
printf "waiting for ledger to start"
# use ledger URL from host
while ! pingLedger "$LEDGER_URL_HOST"; do
printf "."
local duration=$(($SECONDS - $startTime))
if (( ${duration} >= ${LEDGER_TIMEOUT} )); then
echoRed "\nThe Indy Ledger failed to start within ${duration} seconds.\n"
rtnCd=1
break
fi
sleep 1
done
echo
return ${rtnCd}
)
}
pingTailsServer(){
tails_server_url=${1}
# ping tails server (ask for a non-existant registry and should return 404)
local rtnCd=$(curl -s --write-out '%{http_code}' --output /dev/null ${tails_server_url}/404notfound)
if (( ${rtnCd} == 404 )); then
return 0
else
return 1
fi
}
waitForTailsServer(){
(
# Wait for tails server to start ...
local startTime=${SECONDS}
local rtnCd=0
printf "waiting for tails server to start"
# use tails server URL from host
while ! pingTailsServer "$TAILS_SERVER_URL_HOST"; do
printf "."
local duration=$(($SECONDS - $startTime))
if (( ${duration} >= ${LEDGER_TIMEOUT} )); then
echoRed "\nThe tails server failed to start within ${duration} seconds.\n"
rtnCd=1
break
fi
sleep 1
done
echo
return ${rtnCd}
)
}
pingCloudAgency(){
cloud_agency_url=${1}
local rtnCd=$(curl -s --write-out '%{http_code}' --output /dev/null ${cloud_agency_url})
if (( ${rtnCd} == 200 )); then
return 0
else
return 1
fi
}
pingUniresolver(){
# ping uniresolver server
local rtnCd=$(curl -s --write-out '%{http_code}' --output /dev/null http://localhost:8080)
if (( ${rtnCd} == 200 )); then
return 0
else
return 1
fi
}
waitForCloudAgency(){
(
# Wait for cloud agency to start ...
local startTime=${SECONDS}
local rtnCd=0
printf "waiting for cloud agency to start"
while ! pingCloudAgency "$CLOUD_AGENCY_URL"; do
printf "."
local duration=$(($SECONDS - $startTime))
if (( ${duration} >= ${LEDGER_TIMEOUT} )); then
echoRed "\nThe agency failed to start within ${duration} seconds.\n"
rtnCd=1
break
fi
sleep 1
done
echo
return ${rtnCd}
)
}
waitForUniresolver(){
(
# Wait for uniresolver to start ...
local startTime=${SECONDS}
local rtnCd=0
printf "waiting for uniresolver to start"
while ! pingUniresolver ; do
printf "."
local duration=$(($SECONDS - $startTime))
if (( ${duration} >= ${LEDGER_TIMEOUT} )); then
echoRed "\nUniversal Resolver failed to start within ${duration} seconds.\n"
rtnCd=1
break
fi
sleep 1
done
echo
return ${rtnCd}
)
}
startCloudAgency(){
docker-compose -f ./aries-backchannels/aries-vcx/ci/docker-compose.yml up -d
}
dockerhost_url_templates() {
# generate acapy plugin config file, writing $DOCKERHOST into URLs
pushd ${SCRIPT_HOME}/aries-backchannels/acapy/ > /dev/null
mkdir -p .build/acapy-main.data
mkdir -p .build/acapy.data
sed "s/REPLACE_WITH_DOCKERHOST/${DOCKERHOST}/g" plugin-config.template | tee > .build/plugin-config.yml
rm -f .build/acapy-main.data/plugin-config.yml .build/acapy.data/plugin-config.yml
cp .build/plugin-config.yml .build/acapy-main.data/plugin-config.yml
mv .build/plugin-config.yml .build/acapy.data/plugin-config.yml
popd > /dev/null
}
pingAgent(){
name=${1}
port=${2}
# ping agent using a backchannel-exposed api
rtnCd=$(curl -s --write-out '%{http_code}' --output /dev/null http://localhost:${port}/agent/command/status/)
if (( ${rtnCd} == 200 )); then
return 0
else
return 1
fi
}
waitForAgent(){
(
name=${1}
# Wait for agent to start ...
local startTime=${SECONDS}
rtnCd=0
printf "waiting for ${name} agent to start"
while ! pingAgent ${@}; do
printf "."
local duration=$(($SECONDS - $startTime))
if (( ${duration} >= ${AGENT_TIMEOUT} )); then
echoRed "\nThe agent failed to start within ${duration} seconds.\n"
rtnCd=1
break
fi
sleep 1
done
echo
return ${rtnCd}
)
}
startAgent() {
local NAME=$1
local CONTAINER_NAME=$2
local IMAGE_NAME=$3
local PORT_RANGE=$4
local BACKCHANNEL_PORT=$5
local AGENT_ENDPOINT_PORT=$6
local AIP_CONFIG=$7
local AGENT_NAME=$8
local BACKCHANNEL_DIR=$(dirname "$(find aries-backchannels -name *.${AGENT_NAME})" )
local ENV_PATH="$(find $BACKCHANNEL_DIR -name *${AGENT_NAME}.env)"
local ENV_FILE_ARG=
if [[ -n $ENV_PATH ]]; then
ENV_FILE_ARG="--env-file=$ENV_PATH"
# echo $ENV_FILE_ARG
fi
local DATA_VOLUME_PATH="$(find $BACKCHANNEL_DIR -wholename */${AGENT_NAME}.data)"
local DATA_VOLUME_ARG=
# optional data volume folder
if [[ -n DATA_VOLUME_PATH ]]; then
DATA_VOLUME_ARG="-v $(pwd)/$DATA_VOLUME_PATH:/data-mount:z"
fi
if [ ! "$(docker ps -q -f name=$CONTAINER_NAME)" ]; then
if [[ "${USE_NGROK}" = "true" ]]; then
echo "Starting ngrok for ${NAME} Agent ..."
if [[ "${IMAGE_NAME}" = "dotnet-agent-backchannel" ]]; then
docker run -d --rm --name "${CONTAINER_NAME}-ngrok" wernight/ngrok ngrok http "${CONTAINER_NAME}:${BACKCHANNEL_PORT}" --log stdout > /dev/null
else
docker run -d --rm --name "${CONTAINER_NAME}-ngrok" wernight/ngrok ngrok http "${CONTAINER_NAME}:${AGENT_ENDPOINT_PORT}" --log stdout > /dev/null
fi
sleep 1
export NGROK_NAME="${CONTAINER_NAME}-ngrok"
docker network connect aath_network "${CONTAINER_NAME}-ngrok"
else
export NGROK_NAME=
fi
echo "Starting ${NAME} Agent using ${IMAGE_NAME} ..."
export BACKCHANNEL_EXTRA_ARGS_NAME="BACKCHANNEL_EXTRA_${AGENT_NAME//-/_}"
export BACKCHANNEL_EXTRA_ARGS=`echo ${!BACKCHANNEL_EXTRA_ARGS_NAME}`
if [[ -z ${AGENT_CONFIG_FILE} ]]; then
local container_id=$(docker run -dt --name "${CONTAINER_NAME}" --expose "${PORT_RANGE}" -p "${PORT_RANGE}:${PORT_RANGE}" ${DATA_VOLUME_ARG} ${ENV_FILE_ARG} -e "NGROK_NAME=${NGROK_NAME}" -e "EXTRA_ARGS=${BACKCHANNEL_EXTRA_ARGS}" -e "DOCKERHOST=${DOCKERHOST}" -e "AGENT_NAME=${NAME}" -e "LEDGER_URL=${LEDGER_URL_INTERNAL}" -e "TAILS_SERVER_URL=${TAILS_SERVER_URL_INTERNAL}" -e "CLOUD_AGENCY_URL=${CLOUD_AGENCY_URL_INTERNAL}" -e "AIP_CONFIG=${AIP_CONFIG}" "${IMAGE_NAME}" -p "${BACKCHANNEL_PORT}" -i false)
else
local container_id=$(docker run -dt --name "${CONTAINER_NAME}" --expose "${PORT_RANGE}" -p "${PORT_RANGE}:${PORT_RANGE}" ${DATA_VOLUME_ARG} ${ENV_FILE_ARG} -e "AGENT_CONFIG_FILE=${AGENT_CONFIG_FILE}" -e "NGROK_NAME=${NGROK_NAME}" -e "EXTRA_ARGS=${BACKCHANNEL_EXTRA_ARGS}" -e "DOCKERHOST=${DOCKERHOST}" -e "AGENT_NAME=${NAME}" -e "LEDGER_URL=${LEDGER_URL_INTERNAL}" -e "TAILS_SERVER_URL=${TAILS_SERVER_URL_INTERNAL}" -e "CLOUD_AGENCY_URL=${CLOUD_AGENCY_URL_INTERNAL}" -e "AIP_CONFIG=${AIP_CONFIG}" "${IMAGE_NAME}" -p "${BACKCHANNEL_PORT}" -i false)
fi
sleep 1
if [[ "${USE_NGROK}" = "true" ]]; then
docker network connect aath_network "${CONTAINER_NAME}"
elif [[ "${AGENT_NAME}" = "afgo-master" || "${AGENT_NAME}" = "afgo-interop" ]]; then
docker network connect aath_network "${CONTAINER_NAME}"
fi
if [[ "${IMAGE_NAME}" = "mobile-agent-backchannel" ]]; then
echo "Tail-ing log files for ${NAME} agent in ${container_id}"
docker logs -f ${container_id} &
fi
else
echo "${NAME} Agent already running, skipping..."
fi
}
writeEnvProperties() {
ACME_VERSION=$(getAgentVersion 9020)
BOB_VERSION=$(getAgentVersion 9030)
FABER_VERSION=$(getAgentVersion 9040)
MALLORY_VERSION=$(getAgentVersion 9050)
env_file="$(pwd)/aries-test-harness/allure/allure-results/environment.properties"
declare -a env_array
env_array+=("role.acme=$ACME_AGENT")
env_array+=("acme.agent.version=$ACME_VERSION")
env_array+=("role.bob=$BOB_AGENT")
env_array+=("bob.agent.version=$BOB_VERSION")
env_array+=("role.faber=$FABER_AGENT")
env_array+=("faber.agent.version=$FABER_VERSION")
env_array+=("role.mallory=$MALLORY_AGENT")
env_array+=("mallory.agent.version=$MALLORY_VERSION")
printf "%s\n" "${env_array[@]}" > $env_file
}
getAgentVersion(){
port=${1}
# get agent version using a backchannel-exposed api
version=$(curl -s http://localhost:${port}/agent/command/version/)
echo "$version"
# if (( ${rtnCd} == 200 )); then
# echo "$version"
# else
# echo "unknown"
# fi
}
createNetwork() {
if [[ -z `docker network ls -q --filter "name=aath_network"` ]]; then
docker network create aath_network > /dev/null
fi
}
cleanupNetwork() {
if [[ -z `docker ps -q --filter "network=aath_network"` && `docker network ls -q --filter "name=aath_network"` ]]; then
docker network rm aath_network > /dev/null
fi
}
auxiliaryService() {
local SERVICE_NAME
local SERVICE_COMMAND
SERVICE_NAME=$1
SERVICE_COMMAND=$2
if [[ -f "./services/${SERVICE_NAME}/wrapper.sh" ]]; then
(./services/${SERVICE_NAME}/wrapper.sh $SERVICE_COMMAND)
else
echo "service ${SERVICE_NAME} doesn't exist"
fi
}
startServices() {
# sets if services this procedure starts should be stopped automatically
local AUTO_CLEANUP
if [[ "auto" = $1 ]]; then
AUTO_CLEANUP=true
else
AUTO_CLEANUP=false
fi
if [[ "all" = $1 ]]; then
auxiliaryService orb start
fi
# if we're *not* using an external VON ledger, start the local one
if [[ -z ${LEDGER_URL_CONFIG} ]]; then
if [[ -z `docker ps -q --filter="name=von_webserver_1"` ]]; then
echo "starting local von-network..."
auxiliaryService von-network start
if [[ $AUTO_CLEANUP ]]; then
export STARTED_LOCAL_LEDGER=true
fi
fi
fi
if ! waitForLedger; then
echoRed "\nThe Indy Ledger is not running.\n"
exit 1
fi
if [[ -z `docker ps -q --filter="name=uni-resolver-web.local"` ]]; then
echo "starting local uniresolver..."
auxiliaryService uniresolver start
if [[ $AUTO_CLEANUP ]]; then
export STARTED_LOCAL_UNIRESOLVER=true
fi
fi
# if we're *not* using an external indy tails server, start the local one
if [[ -z ${TAILS_SERVER_URL_CONFIG} ]]; then
if [[ -z `docker ps -q --filter="name=docker_tails-server_1"` ]]; then
echo "starting local indy-tails-server..."
auxiliaryService indy-tails start
if [[ $AUTO_CLEANUP ]]; then
export STARTED_LOCAL_TAILS=true
fi
fi
fi
if ! waitForTailsServer; then
echoRed "\nThe Indy Tails Server is not running.\n"
exit 1
fi
if ! waitForUniresolver; then
echoRed "\nUniversal Resolver is not running.\n"
exit 1
fi
}
stopServices() {
if [[ "auto" = $1 ]]; then
if [[ ${STARTED_LOCAL_UNIRESOLVER} ]]; then
echo "stopping local uniresolver..."
auxiliaryService uniresolver stop
fi
if [[ ${STARTED_LOCAL_TAILS} ]]; then
echo "stopping local indy-tails-server..."
auxiliaryService indy-tails stop
fi
if [[ ${STARTED_LOCAL_LEDGER} ]]; then
echo "stopping local von-network..."
auxiliaryService von-network stop
fi
elif [[ "all" = $1 ]]; then
auxiliaryService uniresolver stop
auxiliaryService orb stop
auxiliaryService indy-tails stop
auxiliaryService von-network stop
fi
}
serviceCommand() {
local SERVICE_COMMAND
SERVICE_COMMAND=$1
local SERVICE_TARGET
SERVICE_TARGET=$2
# TODO: allow multiple services to be named - but can we handle logs command then?
if [[ "all" = $SERVICE_TARGET ]]; then
case "${SERVICE_COMMAND}" in
start)
createNetwork
startServices all
;;
stop)
stopServices all
cleanupNetwork
;;
*)
echo err: \'start\' and \'stop\' are only valid commands for target \'all\'
;;
esac
return
fi
case "${SERVICE_COMMAND}" in
start)
createNetwork
auxiliaryService ${SERVICE_TARGET} ${SERVICE_COMMAND}
;;
logs)
auxiliaryService ${SERVICE_TARGET} ${SERVICE_COMMAND}
;;
stop|clean)
auxiliaryService ${SERVICE_TARGET} ${SERVICE_COMMAND}
cleanupNetwork
;;
*)
auxiliaryService ${SERVICE_TARGET} ${SERVICE_COMMAND}
;;
esac
}
startHarness(){
echo Agents to be used:
echo " Acme - ${ACME}"
echo " Bob - ${BOB}"
echo " Faber - ${FABER}"
echo " Mallory - ${MALLORY}"
echo ""
createNetwork
startServices auto
# Only start cloud agency if vcx is in the agent list to run.
if [[ "${ACME}" = "aries-vcx" ]] || [[ "${BOB}" = "aries-vcx" ]] || [[ "${MALLORY}" = "aries-vcx" ]] || [[ "${FABER}" = "aries-vcx" ]]; then
startCloudAgency
if ! waitForCloudAgency; then
echoRed "\nThe cloud agency not running.\n"
exit 1
fi
fi
dockerhost_url_templates
export AIP_CONFIG=${AIP_CONFIG:-10}
# Only start agents that are asked for in the ./manage start command
if [[ "$ACME" != "none" ]]; then
export ACME_AGENT=${ACME_AGENT:-${ACME}-agent-backchannel}
startAgent Acme acme_agent "$ACME_AGENT" "9020-9029" 9020 9021 "$AIP_CONFIG" "$ACME"
fi
if [[ "$BOB" != "none" ]]; then
export BOB_AGENT=${BOB_AGENT:-${BOB}-agent-backchannel}
startAgent Bob bob_agent "$BOB_AGENT" "9030-9039" 9030 9031 "$AIP_CONFIG" "$BOB"
fi
if [[ "$FABER" != "none" ]]; then
export FABER_AGENT=${FABER_AGENT:-${FABER}-agent-backchannel}
startAgent Faber faber_agent "$FABER_AGENT" "9040-9049" 9040 9041 "$AIP_CONFIG" "$FABER"
fi
if [[ "$MALLORY" != "none" ]]; then
export MALLORY_AGENT=${MALLORY_AGENT:-${MALLORY}-agent-backchannel}
startAgent Mallory mallory_agent "$MALLORY_AGENT" "9050-9059" 9050 9051 "$AIP_CONFIG" "$MALLORY"
fi
echo
# Check if agents were successfully started.
if [[ "$ACME" != "none" ]]; then
waitForAgent Acme 9020
fi
if [[ "$BOB" != "none" ]]; then
waitForAgent Bob 9030
fi
if [[ "$FABER" != "none" ]]; then
waitForAgent Faber 9040
fi
if [[ "$MALLORY" != "none" ]]; then
waitForAgent Mallory 9050
fi
echo
export PROJECT_ID=${PROJECT_ID:-general}
echo
# Allure Reports environment.properties file handling
# Only do this if reporting parameter is passed.
if [[ "${REPORT}" = "allure" ]]; then
writeEnvProperties
fi
}
deleteAgents() {
deleteAgent acme_agent
deleteAgent bob_agent
deleteAgent faber_agent
deleteAgent mallory_agent
}
deleteAgent() {
agent=$1
docker rm -f $agent || 1
}
runTests() {
runArgs=${@}
if [[ "${TAGS}" ]]; then
echo "Tags: ${TAGS}"
else
echo "No tags specified; all tests will be run."
fi
echo
# Behave.ini file handling
export BEHAVE_INI_TMP="$(pwd)/behave.ini.tmp"
cp ${BEHAVE_INI} ${BEHAVE_INI_TMP}
if [[ "${REPORT}" = "allure" ]]; then
echo "Executing tests with Allure Reports."
${terminalEmu} docker run ${INTERACTIVE} --rm --network="host" -v ${BEHAVE_INI_TMP}:/aries-test-harness/behave.ini -v "$(pwd)/aries-test-harness/allure/allure-results:/aries-test-harness/allure/allure-results/" aries-test-harness -k ${runArgs} -f allure_behave.formatter:AllureFormatter -o ./allure/allure-results -f progress -D Acme=http://0.0.0.0:9020 -D Bob=http://0.0.0.0:9030 -D Faber=http://0.0.0.0:9040 -D Mallory=http://0.0.0.0:9050
else
${terminalEmu} docker run ${INTERACTIVE} --rm --network="host" -v ${BEHAVE_INI_TMP}:/aries-test-harness/behave.ini aries-test-harness -k ${runArgs} -D Acme=http://0.0.0.0:9020 -D Bob=http://0.0.0.0:9030 -D Faber=http://0.0.0.0:9040 -D Mallory=http://0.0.0.0:9050
fi
local docker_result=$?
rm ${BEHAVE_INI_TMP}
# Export agent logs
if [[ "${GITHUB_ACTIONS}" != "true" ]]; then
echo ""
echo "Exporting Agent logs."
mkdir -p .logs
docker logs acme_agent > .logs/acme_agent.log
docker logs bob_agent > .logs/bob_agent.log
docker logs faber_agent > .logs/faber_agent.log
docker logs mallory_agent > .logs/mallory_agent.log
if [[ "${USE_NGROK}" = "true" ]]; then
echo "Exporting ngrok Agent logs."
docker logs acme_agent-ngrok > .logs/acme_agent-ngrok.log
docker logs bob_agent-ngrok > .logs/bob_agent-ngrok.log
docker logs faber_agent-ngrok > .logs/faber_agent-ngrok.log
docker logs mallory_agent-ngrok > .logs/mallory_agent-ngrok.log
fi
fi
}
stopIfExists(){
local CONTAINER_NAME
CONTAINER_NAME=$1
local CONTAINER_ID
CONTAINER_ID=`docker ps -q --filter "name=${CONTAINER_NAME}"`
if [[ ${CONTAINER_ID} ]]; then
docker stop ${CONTAINER_ID} > /dev/null
fi
}
stopHarness(){
echo "Cleanup:"
echo " - Shutting down all the agents ..."
docker stop acme_agent bob_agent faber_agent mallory_agent > /dev/null
docker rm -v acme_agent bob_agent faber_agent mallory_agent > /dev/null
stopIfExists acme_agent-ngrok
stopIfExists bob_agent-ngrok
stopIfExists faber_agent-ngrok
stopIfExists mallory_agent-ngrok
printf "Done\n"
if [[ "${REPORT}" = "allure" ]]; then
if [[ "${REPORT_ERROR_TYPE}" = "comparison" ]]; then
# TODO run the same_as_yesterday.py script and capture the result
echo "Checking results vs KGR ..."
${terminalEmu} docker run ${INTERACTIVE} --rm -v "$(pwd)/aries-test-harness/allure/allure-results:/aries-test-harness/allure/allure-results/" --entrypoint /aries-test-harness/allure/same_as_yesterday.sh -e PROJECT_ID=${PROJECT_ID} aries-test-harness
docker_result=$?
fi
fi
stopServices auto
cleanupNetwork
if [ -n "${docker_result}" ] && [ ! "${docker_result}" = "0" ]; then
echo "Exit with error code ${docker_result}"
exit ${docker_result}
fi
}
isAgent() {
result=false
for agent in ${VALID_AGENTS}; do
if [[ "${1}" == "${agent}" ]]; then
result=true
fi
done
echo $result
}
printLetsEncryptWarning() {
[ -n "${LetsEncryptWarningPrinted}" ] && return
cat << EOWARN
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>> WARNING
>> This applies to mobile testing using Android-Based digital wallet,
>> as far as we know.
If you are using a mobile/smartphone-based Wallet, the test harness is going to
make use of the https://ngrok.com/ infrastructure, generating url like this one
https://aabbccdd.ngrok.io
The Ngrok infrastructure makes use of a wildcard TLS certificate *.ngrok.io,
certified by Let's Encrypt (https://letsencrypt.org/).
However, some OS and platform are still making use of an expired root
certificate, namely "DST Root CA X3", which expired on September 30th 2021.
Ref: https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021
If:
- The wallet your are testing somehow never manages to establish a
connection after scanning the first QR code.
Then:
- you might be facing this issue.
The solution is to disable the expired certificate into your android device
trusted certificate store.
Here's how: Of course, your mileage might vary depending on brand and device:
* The simplest way is to launch your setting application
a. Use the search bar to find "certificate"-related entries
(you can probably use a shorter substring)
b. This should display a few entries, including something like
Trusted Certificates (or the equivalent in your phone language)
c. Selecting this should display two list of trusted certificates:
the System ones and the ones input by the user
d. Go to the System list of trusted certificates, and simply find the
DST Root CA X3 in the sorted list
e. Click on the certificate and deactivate it.
* If the search does not work for you, we are aware of two alternate ways
to access the trusted certificates store, but again we cannot document for
all brand/models
* Either:
Settings
=> Biometrics & security
=> Other security settings
=> View security certificates
* Or:
Settings
=> Security
=> Advanced
=> Encryption and Credentials
=> Trusted Certificates
* Then go to step b. above to disable the faulty certificate.
Now, if the faulty certificate is not is your trust store, then you have
another issue, sorry.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
EOWARN
LetsEncryptWarningPrinted=1
}
# -----------------------------------------------------------------------------------------------------------------
# Initialization:
# -----------------------------------------------------------------------------------------------------------------
# Command to run must be the first argument
COMMAND=$(toLower ${1})
shift
# Handle run args
if [[ "${COMMAND}" == "run" || "${COMMAND}" == "start" || "${COMMAND}" == "test" ]]; then
ACME="none"
BOB="none"
FABER="none"
MALLORY="none"
TAGS=""
BEHAVE_INI=aries-test-harness/behave.ini
while getopts "hna:b:c:f:m:r:e:d:t:v:i:" FLAG; do
case $FLAG in
h ) usage ;;
: ) usage ;;
\? ) #unrecognized option - show help
echo -e \\n"Invalid script option: -${OPTARG}"\\n
usage
;;
r ) export REPORT=${OPTARG}
;;
e ) export REPORT_ERROR_TYPE=${OPTARG}
;;
a ) export ACME=${OPTARG}
;;
b ) export BOB=${OPTARG}
;;
f ) export FABER=${OPTARG}
;;
m ) export MALLORY=${OPTARG}
;;
t ) export TAGS="${TAGS} --tags=${OPTARG}"
;;
v ) export AIP_CONFIG=${OPTARG}
;;
i ) export BEHAVE_INI=${OPTARG}
;;
n ) export USE_NGROK="true"
;;
d )
export ACME=${OPTARG}
export BOB=${OPTARG}
export FABER=${OPTARG}
export MALLORY=${OPTARG}