summaryrefslogtreecommitdiff
path: root/qa/vagrant/src/test/resources/packaging/scripts/packaging_test_utils.bash
blob: ff7255c5417434e4f88c494e8220ec1a24ec52bc (plain)
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
#!/bin/sh

# This file contains some utilities to test the elasticsearch scripts,
# the .deb/.rpm packages and the SysV/Systemd scripts.

# WARNING: This testing file must be executed as root and can
# dramatically change your system. It removes the 'elasticsearch'
# user/group and also many directories. Do not execute this file
# unless you know exactly what you are doing.

# Licensed to Elasticsearch under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Checks if necessary commands are available to run the tests

if [ ! -x /usr/bin/which ]; then
    echo "'which' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which wget 2>/dev/null`" ]; then
    echo "'wget' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which curl 2>/dev/null`" ]; then
    echo "'curl' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which pgrep 2>/dev/null`" ]; then
    echo "'pgrep' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which unzip 2>/dev/null`" ]; then
    echo "'unzip' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which tar 2>/dev/null`" ]; then
    echo "'tar' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which unzip 2>/dev/null`" ]; then
    echo "'unzip' command is mandatory to run the tests"
    exit 1
fi

if [ ! -x "`which java 2>/dev/null`" ]; then
    echo "'java' command is mandatory to run the tests"
    exit 1
fi

# Returns 0 if the 'dpkg' command is available
is_dpkg() {
    [ -x "`which dpkg 2>/dev/null`" ]
}

# Returns 0 if the 'rpm' command is available
is_rpm() {
    [ -x "`which rpm 2>/dev/null`" ]
}

# Skip test if the 'dpkg' command is not supported
skip_not_dpkg() {
    is_dpkg || skip "dpkg is not supported"
}

# Skip test if the 'rpm' command is not supported
skip_not_rpm() {
    is_rpm || skip "rpm is not supported"
}

skip_not_dpkg_or_rpm() {
    is_dpkg || is_rpm || skip "only dpkg or rpm systems are supported"
}

# Returns 0 if the system supports Systemd
is_systemd() {
    [ -x /bin/systemctl ]
}

# Skip test if Systemd is not supported
skip_not_systemd() {
    if [ ! -x /bin/systemctl ]; then
        skip "systemd is not supported"
    fi
}

# Returns 0 if the system supports SysV
is_sysvinit() {
    [ -x "`which service 2>/dev/null`" ]
}

# Skip test if SysV is not supported
skip_not_sysvinit() {
    if [ -x "`which service 2>/dev/null`" ] && is_systemd; then
        skip "sysvinit is supported, but systemd too"
    fi
    if [ ! -x "`which service 2>/dev/null`" ]; then
        skip "sysvinit is not supported"
    fi
}

# Skip if tar is not supported
skip_not_tar_gz() {
    if [ ! -x "`which tar 2>/dev/null`" ]; then
        skip "tar is not supported"
    fi
}

# Skip if unzip is not supported
skip_not_zip() {
    if [ ! -x "`which unzip 2>/dev/null`" ]; then
        skip "unzip is not supported"
    fi
}

assert_file_exist() {
    local file="$1"
    echo "Should exist: ${file}"
    local file=$(readlink -m "${file}")
    [ -e "$file" ]
}

assert_file_not_exist() {
    local file="$1"
    echo "Should not exist: ${file}"
    local file=$(readlink -m "${file}")
    [ ! -e "$file" ]
}

assert_file() {
    local file="$1"
    local type=$2
    local user=$3
    local privileges=$4

    assert_file_exist "$file"

    if [ "$type" = "d" ]; then
        echo "And be a directory...."
        [ -d "$file" ]
    else
        echo "And be a regular file...."
        [ -f "$file" ]
    fi

    if [ "x$user" != "x" ]; then
        realuser=$(ls -ld "$file" | awk '{print $3}')
        [ "$realuser" = "$user" ]
    fi

    if [ "x$privileges" != "x" ]; then
        realprivileges=$(find "$file" -maxdepth 0 -printf "%m")
        [ "$realprivileges" = "$privileges" ]
    fi
}

assert_output() {
    echo "$output" | grep -E "$1"
}

# Checks that all directories & files are correctly installed
# after a package (deb/rpm) install
verify_package_installation() {

    run id elasticsearch
    [ "$status" -eq 0 ]

    run getent group elasticsearch
    [ "$status" -eq 0 ]

    # Home dir
    assert_file "/usr/share/elasticsearch" d root 755
    # Bin dir
    assert_file "/usr/share/elasticsearch/bin" d root 755
    assert_file "/usr/share/elasticsearch/lib" d root 755
    # Conf dir
    assert_file "/etc/elasticsearch" d root 755
    assert_file "/etc/elasticsearch/elasticsearch.yml" f root 644
    assert_file "/etc/elasticsearch/logging.yml" f root 644
    # Data dir
    assert_file "/var/lib/elasticsearch" d elasticsearch 755
    # Log dir
    assert_file "/var/log/elasticsearch" d elasticsearch 755
    # Plugins dir
    assert_file "/usr/share/elasticsearch/plugins" d elasticsearch 755
    # PID dir
    assert_file "/var/run/elasticsearch" d elasticsearch 755
    # Readme files
    assert_file "/usr/share/elasticsearch/NOTICE.txt" f root 644
    assert_file "/usr/share/elasticsearch/README.textile" f root 644

    if is_dpkg; then
        # Env file
        assert_file "/etc/default/elasticsearch" f root 644

        # Doc files
        assert_file "/usr/share/doc/elasticsearch" d root 755
        assert_file "/usr/share/doc/elasticsearch/copyright" f root 644

    fi

    if is_rpm; then
        # Env file
        assert_file "/etc/sysconfig/elasticsearch" f root 644
        # License file
        assert_file "/usr/share/elasticsearch/LICENSE.txt" f root 644
    fi

    if is_systemd; then
        assert_file "/usr/lib/systemd/system/elasticsearch.service" f root 644
        assert_file "/usr/lib/tmpfiles.d/elasticsearch.conf" f root 644
        assert_file "/usr/lib/sysctl.d/elasticsearch.conf" f root 644
    fi
}

# Install the rpm or deb package.
# -u upgrade rather than install. This only matters for rpm.
# -v the version to upgrade to. Defaults to the version under test.
install_package() {
    local version=$(cat version)
    local rpmCommand='-i'
    while getopts ":uv:" opt; do
        case $opt in
            u)
                rpmCommand='-U'
                ;;
            v)
                version=$OPTARG
                ;;
            \?)
                echo "Invalid option: -$OPTARG" >&2
                ;;
        esac
    done
    if is_rpm; then
        rpm $rpmCommand elasticsearch-$version.rpm
    elif is_dpkg; then
        dpkg -i elasticsearch-$version.deb
    else
        skip "Only rpm or deb supported"
    fi
}

# Checks that all directories & files are correctly installed
# after a archive (tar.gz/zip) install
verify_archive_installation() {
    assert_file "$ESHOME" d
    assert_file "$ESHOME/bin" d
    assert_file "$ESHOME/bin/elasticsearch" f
    assert_file "$ESHOME/bin/elasticsearch.in.sh" f
    assert_file "$ESHOME/bin/plugin" f
    assert_file "$ESCONFIG" d
    assert_file "$ESCONFIG/elasticsearch.yml" f
    assert_file "$ESCONFIG/logging.yml" f
    assert_file "$ESHOME/lib" d
    assert_file "$ESHOME/NOTICE.txt" f
    assert_file "$ESHOME/LICENSE.txt" f
    assert_file "$ESHOME/README.textile" f
}

# Deletes everything before running a test file
clean_before_test() {

    # List of files to be deleted
    ELASTICSEARCH_TEST_FILES=("/usr/share/elasticsearch" \
                            "/etc/elasticsearch" \
                            "/var/lib/elasticsearch" \
                            "/var/log/elasticsearch" \
                            "/tmp/elasticsearch" \
                            "/etc/default/elasticsearch" \
                            "/etc/sysconfig/elasticsearch"  \
                            "/var/run/elasticsearch"  \
                            "/usr/share/doc/elasticsearch" \
                            "/tmp/elasticsearch" \
                            "/usr/lib/systemd/system/elasticsearch.conf" \
                            "/usr/lib/tmpfiles.d/elasticsearch.conf" \
                            "/usr/lib/sysctl.d/elasticsearch.conf")

    # Kills all processes of user elasticsearch
    if id elasticsearch > /dev/null 2>&1; then
        pkill -u elasticsearch 2>/dev/null || true
    fi

    # Kills all running Elasticsearch processes
    ps aux | grep -i "org.elasticsearch.bootstrap.Elasticsearch" | awk {'print $2'} | xargs kill -9 > /dev/null 2>&1 || true

    # Removes RPM package
    if is_rpm; then
        rpm --quiet -e elasticsearch > /dev/null 2>&1 || true
    fi

    if [ -x "`which yum 2>/dev/null`" ]; then
        yum remove -y elasticsearch > /dev/null 2>&1 || true
    fi

    # Removes DEB package
    if is_dpkg; then
        dpkg --purge elasticsearch > /dev/null 2>&1 || true
    fi

    if [ -x "`which apt-get 2>/dev/null`" ]; then
        apt-get --quiet --yes purge elasticsearch > /dev/null 2>&1 || true
    fi

    # Removes user & group
    userdel elasticsearch > /dev/null 2>&1 || true
    groupdel elasticsearch > /dev/null 2>&1 || true


    # Removes all files
    for d in "${ELASTICSEARCH_TEST_FILES[@]}"; do
        if [ -e "$d" ]; then
            rm -rf "$d"
        fi
    done
}

# Start elasticsearch and wait for it to come up with a status.
# $1 - expected status - defaults to green
start_elasticsearch_service() {
    local desiredStatus=${1:-green}

    if [ -f "/tmp/elasticsearch/bin/elasticsearch" ]; then
        # su and the Elasticsearch init script work together to break bats.
        # sudo isolates bats enough from the init script so everything continues
        # to tick along
        sudo -u elasticsearch /tmp/elasticsearch/bin/elasticsearch -d \
            -p /tmp/elasticsearch/elasticsearch.pid
    elif is_systemd; then
        run systemctl daemon-reload
        [ "$status" -eq 0 ]

        run systemctl enable elasticsearch.service
        [ "$status" -eq 0 ]

        run systemctl is-enabled elasticsearch.service
        [ "$status" -eq 0 ]

        run systemctl start elasticsearch.service
        [ "$status" -eq 0 ]

    elif is_sysvinit; then
        run service elasticsearch start
        [ "$status" -eq 0 ]
    fi

    wait_for_elasticsearch_status $desiredStatus

    if [ -r "/tmp/elasticsearch/elasticsearch.pid" ]; then
        pid=$(cat /tmp/elasticsearch/elasticsearch.pid)
        [ "x$pid" != "x" ] && [ "$pid" -gt 0 ]

        echo "Looking for elasticsearch pid...."
        ps $pid
    elif is_systemd; then
        run systemctl is-active elasticsearch.service
        [ "$status" -eq 0 ]

        run systemctl status elasticsearch.service
        [ "$status" -eq 0 ]

    elif is_sysvinit; then
        run service elasticsearch status
        [ "$status" -eq 0 ]
    fi
}

stop_elasticsearch_service() {
    if [ -r "/tmp/elasticsearch/elasticsearch.pid" ]; then
        pid=$(cat /tmp/elasticsearch/elasticsearch.pid)
        [ "x$pid" != "x" ] && [ "$pid" -gt 0 ]

        kill -SIGTERM $pid
    elif is_systemd; then
        run systemctl stop elasticsearch.service
        [ "$status" -eq 0 ]

        run systemctl is-active elasticsearch.service
        [ "$status" -eq 3 ]

        echo "$output" | grep -E 'inactive|failed'

    elif is_sysvinit; then
        run service elasticsearch stop
        [ "$status" -eq 0 ]

        run service elasticsearch status
        [ "$status" -ne 0 ]
    fi
}

# Waits for Elasticsearch to reach some status.
# $1 - expected status - defaults to green
wait_for_elasticsearch_status() {
    local desiredStatus=${1:-green}

    echo "Making sure elasticsearch is up..."
    wget -O - --retry-connrefused --waitretry=1 --timeout=60 http://localhost:9200 || {
          echo "Looks like elasticsearch never started. Here is its log:"
          if [ -r "/tmp/elasticsearch/elasticsearch.pid" ]; then
              cat /tmp/elasticsearch/log/elasticsearch.log
          else
              if [ -e '/var/log/elasticsearch/elasticsearch.log' ]; then
                  cat /var/log/elasticsearch/elasticsearch.log
              else
                  echo "The elasticsearch log doesn't exist. Maybe /vag/log/messages has something:"
                  tail -n20 /var/log/messages
              fi
          fi
          false
    }

    echo "Tring to connect to elasticsearch and wait for expected status..."
    curl -sS "http://localhost:9200/_cluster/health?wait_for_status=$desiredStatus&timeout=60s&pretty"
    if [ $? -eq 0 ]; then
        echo "Connected"
    else
        echo "Unable to connect to Elastisearch"
        false
    fi

    echo "Checking that the cluster health matches the waited for status..."
    run curl -sS -XGET 'http://localhost:9200/_cat/health?h=status&v=false'
    if [ "$status" -ne 0 ]; then
        echo "error when checking cluster health. code=$status output="
        echo $output
        false
    fi
    echo $output | grep $desiredStatus || {
        echo "unexpected status:  '$output' wanted '$desiredStatus'"
        false
    }
}

# Executes some very basic Elasticsearch tests
run_elasticsearch_tests() {
    # TODO this assertion is the same the one made when waiting for
    # elasticsearch to start
    run curl -XGET 'http://localhost:9200/_cat/health?h=status&v=false'
    [ "$status" -eq 0 ]
    echo "$output" | grep -w "green"

    curl -s -XPOST 'http://localhost:9200/library/book/1?refresh=true&pretty' -d '{
      "title": "Elasticsearch - The Definitive Guide"
    }'

    curl -s -XGET 'http://localhost:9200/_cat/count?h=count&v=false&pretty' |
      grep -w "1"

    curl -s -XDELETE 'http://localhost:9200/_all'
}

# Move the config directory to another directory and properly chown it.
move_config() {
    local oldConfig="$ESCONFIG"
    export ESCONFIG="${1:-$(mktemp -d -t 'config.XXXX')}"
    echo "Moving configuration directory from $oldConfig to $ESCONFIG"

    # Move configuration files to the new configuration directory
    mv "$oldConfig"/* "$ESCONFIG"
    chown -R elasticsearch:elasticsearch "$ESCONFIG"
    assert_file_exist "$ESCONFIG/elasticsearch.yml"
}