From 1044e40e8aacee18711d7e24df23d866af0fdd6c Mon Sep 17 00:00:00 2001 From: Milan Lenco Date: Tue, 26 Sep 2023 15:05:00 +0200 Subject: [PATCH] Test replacement of one application with another When device configuration is updated using tools like Terraform, it is possible that in one configuration iteration a user application is removed and immediately replaced with another. Because the previous and the new applications could have conflicting configurations, it is important for EVE to execute operations of replacement carefully and in the right order. And in case EVE fails to create the new app because the obsolete one still holds some resources (e.g. allocated IP address), it should make a retry attempt after the obsolete app is fully removed. Note that these scenarious were not working in EVE properly until the version 10.10, when a patch was submitted, meaning that this is the minimal version for this test to pass. Signed-off-by: Milan Lenco --- pkg/defaults/defaults.go | 2 +- tests/app/testdata/app_replace_test.txt | 73 +++++++++++++++++++++++++ tests/workflow/eden.workflow.tests.txt | 4 +- tests/workflow/user-apps.tests.txt | 9 ++- 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 tests/app/testdata/app_replace_test.txt diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 4cafe98e8..8f8ab1e1d 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -53,7 +53,7 @@ const ( DefaultRegistryPort = 5050 //tags, versions, repos - DefaultEVETag = "10.9.0" // DefaultEVETag tag for EVE image + DefaultEVETag = "10.10.0" // DefaultEVETag tag for EVE image DefaultAdamTag = "0.0.43" DefaultRedisTag = "7" DefaultRegistryTag = "2.7" diff --git a/tests/app/testdata/app_replace_test.txt b/tests/app/testdata/app_replace_test.txt new file mode 100644 index 000000000..48038cf8e --- /dev/null +++ b/tests/app/testdata/app_replace_test.txt @@ -0,0 +1,73 @@ +# Here we test two application configurations that cannot coexist at the same time. +# First, we deploy application app1 into network with only one free IP address +# and then try to deploy another application into the same network. The second +# application should stay in the error state as long as the first app exist. +# However, once the first application is deleted, the second application should be +# automatically deployed and take the IP of the removed first app. +# In the second part of the test we replace application with another within the same +# config iteration. EVE should first remove the obsolete application before deploying +# the new one, otherwise it will fail to allocate IP address (since only one IP address +# is available at a time). + +[!exec:jq] stop +[!exec:grep] stop +[!exec:bash] stop +[!exec:uuidgen] stop + +# Starting of reboot detector with a 1 reboot limit +! test eden.reboot.test -test.v -timewait=0 -reboot=0 -count=1 & + +message 'Resetting of EVE' +eden eve reset +exec sleep 30 + +# Create network with only single IP address left for allocation for applications. +# Note that one IP is used for the bridge. +eden -t 1m network create 10.11.12.0/30 -n n1 +test eden.network.test -test.v -timewait 10m ACTIVATED n1 + +# Deploy application that will use the only IP address available +eden -t 1m pod deploy -n app1 -p 8027:80 docker://nginx --networks=n1 --memory 512MB +test eden.app.test -test.v -timewait 10m RUNNING app1 + +# Try to deploy another application, but there is no free IP left. +eden -t 1m pod deploy -n app2 -p 8028:80 docker://nginx --networks=n1 --memory 512MB +exec -t 5m bash wait_for_app_error.sh app2 'no free IP addresses in DHCP range' + +# Now undeploy the first app and the second one should come up. +eden pod delete app1 +test eden.app.test -test.v -timewait 10m - app1 +test eden.app.test -test.v -timewait 10m RUNNING app2 + +# Change the second app UUID which is effectively the same as replacing +# one application with another in one config iteration. +exec -t 1m bash change-app-uuid.sh app2 +test eden.app.test -test.v -timewait 5m RUNNING app2 + +# Cleanup. +eden pod delete app2 +test eden.app.test -test.v -timewait 10m - app2 +eden -t 1m network delete n1 +test eden.network.test -test.v -timewait 2m - n1 + +-- wait_for_app_error.sh -- +#!/bin/sh + +APP="$1" +ERR="$2" + +EDEN={{EdenConfig "eden.root"}}/{{EdenConfig "eden.bin-dist"}}/{{EdenConfig "eden.eden-bin"}} +until $EDEN pod ps | grep "^$APP" | grep "$ERR"; do sleep 3; done + +-- change-app-uuid.sh -- +#!/bin/sh + +APP="$1" +NEW_UUID="$(uuidgen)" + +EDEN={{EdenConfig "eden.root"}}/{{EdenConfig "eden.bin-dist"}}/{{EdenConfig "eden.eden-bin"}} +$EDEN controller edge-node get-config --file device.cfg +UUID=$(jq -r '.apps[] | select(.displayname == "'$APP'") | .uuidandversion.uuid' < device.cfg) +sed -i "s/\"uuid\": \"$UUID\"/\"uuid\": \"$NEW_UUID\"/" device.cfg +$EDEN controller edge-node set-config --file device.cfg +while $EDEN pod ps | grep $UUID; do sleep 3; done diff --git a/tests/workflow/eden.workflow.tests.txt b/tests/workflow/eden.workflow.tests.txt index 923f9eacd..736a1738a 100644 --- a/tests/workflow/eden.workflow.tests.txt +++ b/tests/workflow/eden.workflow.tests.txt @@ -158,8 +158,10 @@ eden.escript.test -testdata ../registry/testdata/ -test.run TestEdenScripts/regi eden.escript.test -testdata ../eclient/testdata/ -test.run TestEdenScripts/air-gapped-switch /bin/echo Eden 2 dockers test (26/{{$tests}}) eden.escript.test -testdata ../docker/testdata/ -test.run TestEdenScripts/2dockers_test -/bin/echo Eden 2 dockers test with app state detector (27/{{$tests}}) +/bin/echo Eden 2 dockers test with app state detector (27.1/{{$tests}}) eden.escript.test -testdata ../app/testdata/ -test.run TestEdenScripts/2dockers_test +/bin/echo Testing replacement of one application with another (27.2/{{$tests}}) +eden.escript.test -testdata ../app/testdata/ -test.run TestEdenScripts/app_replace_test /bin/echo Eden Nginx (28/{{$tests}}) eden.escript.test -testdata ../eclient/testdata/ -test.run TestEdenScripts/ngnix diff --git a/tests/workflow/user-apps.tests.txt b/tests/workflow/user-apps.tests.txt index 404470cda..0bdaa061e 100644 --- a/tests/workflow/user-apps.tests.txt +++ b/tests/workflow/user-apps.tests.txt @@ -1,5 +1,5 @@ # Number of tests -{{$tests := 8}} +{{$tests := 9}} # EDEN_TEST_SETUP env. var. -- "y"(default) performs the EDEN setup steps {{$setup := "y"}} {{$setup_env := EdenGetEnv "EDEN_TEST_SETUP"}} @@ -38,8 +38,11 @@ eden.escript.test -testdata ../docker/testdata/ -test.run TestEdenScripts/2docke /bin/echo Eden 2 dockers test with app state detector (6/{{$tests}}) eden.escript.test -testdata ../app/testdata/ -test.run TestEdenScripts/2dockers_test -/bin/echo Eden Mariadb (7/{{$tests}}) +/bin/echo Testing replacement of one application with another (7/{{$tests}}) +eden.escript.test -testdata ../app/testdata/ -test.run TestEdenScripts/app_replace_test + +/bin/echo Eden Mariadb (8/{{$tests}}) eden.escript.test -testdata ../eclient/testdata/ -test.run TestEdenScripts/maridb -/bin/echo Eden nodered (8/{{$tests}}) +/bin/echo Eden nodered (9/{{$tests}}) eden.escript.test -testdata ../eclient/testdata/ -test.run TestEdenScripts/nodered