File: stresstest.sh

package info (click to toggle)
incus 6.0.5-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 25,788 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (208 lines) | stat: -rwxr-xr-x 5,001 bytes parent folder | download | duplicates (3)
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
#!/bin/bash
export PATH="$GOPATH/bin:$PATH"

# /tmp isn't mounted exec on most systems, so we can't actually start
# containers that are created there.
SRC_DIR="$(pwd)"
INCUS_DIR="$(mktemp -d -p "$(pwd)")"
chmod 777 "${INCUS_DIR}"
INCUS_CONF="$(mktemp -d)"
export SRC_DIR INCUS_DIR INCUS_CONF
export INCUS_FUIDMAP_DIR="${INCUS_DIR}/fuidmap"
mkdir -p "${INCUS_FUIDMAP_DIR}"
BASEURL=https://127.0.0.1:18443
RESULT=failure

set -e
if [ -n "$INCUS_DEBUG" ]; then
    set -x
    debug=--debug
fi

echo "==> Running the Incus testsuite"

BASEURL=https://127.0.0.1:18443
my_curl() {
    curl -k -s --cert "${INCUS_CONF}/client.crt" --key "${INCUS_CONF}/client.key" "${@}"
}

wait_for() {
    op="$("${@}" | jq -r .operation)"
    my_curl "$BASEURL$op/wait"
}

incus() {
    INJECTED=0
    CMD="$(command -v incus)"
    for arg in "${@}"; do
        if [ "$arg" = "--" ]; then
            INJECTED=1
            CMD="$CMD $debug"
            CMD="$CMD --"
        else
            CMD="$CMD \"$arg\""
        fi
    done

    if [ "$INJECTED" = "0" ]; then
        CMD="$CMD $debug"
    fi

    eval "$CMD"
}

cleanup() {
    read -rp "Tests Completed ($RESULT): hit enter to continue" _
    echo "==> Cleaning up"

    # Try to stop all the containers
    my_curl "$BASEURL/1.0/instances" | jq -r .metadata[] 2> /dev/null | while read -r line; do
        wait_for my_curl -X PUT "$BASEURL$line/state" -d "{\"action\":\"stop\",\"force\":true}"
    done

    # kill the daemons which share our pgrp as parent
    mygrp="$(awk '{ print $5 }' /proc/self/stat)"
    for p in $(pidof incus); do
        pgrp="$(awk '{ print $5 }' "/proc/$p/stat")"
        if [ "$pgrp" = "$mygrp" ]; then
            do_kill_incus "$p"
        fi
    done

    # Apparently we need to wait a while for everything to die
    sleep 3
    rm -Rf "${INCUS_DIR}"
    rm -Rf "${INCUS_CONF}"

    echo ""
    echo ""
    echo "==> Test result: $RESULT"
}

trap cleanup EXIT HUP INT TERM

if ! command -v incus > /dev/null; then
    echo "==> Couldn't find incus" && false
fi

spawn_incus() {
    # INCUS_DIR is local here because since `inc` is actually a function, it
    # overwrites the environment and we would lose INCUS_DIR's value otherwise.
    local INCUS_DIR

    addr=$1
    incusdir=$2
    shift
    shift
    echo "==> Spawning incusd on $addr in $incusdir"
    INCUS_DIR="$incusdir" incusd "${debug}" "${@}" > "$incusdir/incus.log" 2>&1 &

    echo "==> Confirming incusd on $addr is responsive"
    INCUS_DIR="$incusdir" incus admin waitready

    echo "==> Binding to network"
    INCUS_DIR="$incusdir" incus config set core.https_address "$addr"
}

spawn_incus 127.0.0.1:18443 "$INCUS_DIR"

## tests go here
if [ ! -e "$INCUS_TEST_IMAGE" ]; then
    echo "Please define INCUS_TEST_IMAGE"
    false
fi
incus image import "$INCUS_TEST_IMAGE" --alias busybox

incus image list
incus list

NUMCREATES=5
createthread() {
    echo "createthread: I am $$"
    for i in $(seq "$NUMCREATES"); do
        echo "createthread: starting loop $i out of $NUMCREATES"
        declare -a pids
        for j in $(seq 20); do
            incus launch busybox "b.$i.$j" &
            pids[j]=$!
        done
        for j in $(seq 20); do
            # ignore errors if the task has already exited
            wait "${pids[j]}" 2> /dev/null || true
        done
        echo "createthread: deleting..."
        for j in $(seq 20); do
            incus delete "b.$i.$j" &
            pids[j]=$!
        done
        for j in $(seq 20); do
            # ignore errors if the task has already exited
            wait "${pids[j]}" 2> /dev/null || true
        done
    done
    exit 0
}

listthread() {
    echo "listthread: I am $$"
    while true; do
        incus list
        sleep 2s
    done
    exit 0
}

configthread() {
    echo "configthread: I am $$"
    for i in $(seq 20); do
        incus profile create "p$i"
        incus profile set "p$i" limits.memory 100MiB
        incus profile delete "p$i"
    done
    exit 0
}

disturbthread() {
    echo "disturbthread: I am $$"
    while true; do
        incus profile create empty
        incus init busybox disturb1
        incus profile assign disturb1 empty
        incus start disturb1
        incus exec disturb1 -- ps -ef
        incus stop disturb1 --force
        incus delete disturb1
        incus profile delete empty
    done
    exit 0
}

echo "Starting create thread"
createthread 2>&1 | tee "$INCUS_DIR/createthread.out" &
p1=$!

echo "starting the disturb thread"
disturbthread 2>&1 | tee "$INCUS_DIR/disturbthread.out" &
pdisturb=$!

echo "Starting list thread"
listthread 2>&1 | tee "$INCUS_DIR/listthread.out" &
p2=$!
echo "Starting config thread"
configthread 2>&1 | tee "$INCUS_DIR/configthread.out" &
p3=$!

# wait for listthread to finish
wait "$p1"
# and configthread, it should be quick
wait "$p3"

echo "The creation loop is done, killing the list and disturb threads"

kill "$p2"
wait "$p2" || true

kill "$pdisturb"
wait "$pdisturb" || true

RESULT=success