#!/bin/bash -x set -e set -o functrace PS4=' ${FUNCNAME[0]}: $LINENO: ' SUDO=${SUDO:-sudo} function check_no_osd_down() { ! ceph osd dump | grep ' down ' } function wait_no_osd_down() { for i in $(seq 1 300) ; do if ! check_no_osd_down ; then echo "waiting for osd(s) to come back up" sleep 1 else break fi done check_no_osd_down } function get_pg() { local pool obj map_output pg pool=$1 obj=$2 declare -a map_output map_output=($(ceph osd map $1 $2)) for (( i=0; i<${#map_output[*]}; i++ )) ; do if [ "${map_output[$i]}" == "pg" ] ; then pg=${map_output[((i+2))]} break fi done pg=$(echo $pg | sed 's/[()]//g') echo $pg } function expect_false() { set -x if "$@"; then return 1; else return 0; fi } TMPDIR=/tmp/cephtool$$ mkdir $TMPDIR trap "rm -fr $TMPDIR" 0 TMPFILE=$TMPDIR/test_invalid.$$ # # retry_eagain max cmd args ... # # retry cmd args ... if it exits on error and its output contains the # string EAGAIN, at most $max times # function retry_eagain() { local max=$1 shift local status local tmpfile=$TMPDIR/retry_eagain.$$ local count for count in $(seq 1 $max) ; do status=0 "$@" > $tmpfile 2>&1 || status=$? if test $status = 0 || ! grep --quiet EAGAIN $tmpfile ; then break fi sleep 1 done if test $count = $max ; then echo retried with non zero exit status, $max times: "$@" >&2 fi cat $tmpfile rm $tmpfile return $status } # # map_enxio_to_eagain cmd arg ... # # add EAGAIN to the output of cmd arg ... if the output contains # ENXIO. # function map_enxio_to_eagain() { local status=0 local tmpfile=$TMPDIR/map_enxio_to_eagain.$$ "$@" > $tmpfile 2>&1 || status=$? if test $status != 0 && grep --quiet ENXIO $tmpfile ; then echo "EAGAIN added by $0::map_enxio_to_eagain" >> $tmpfile fi cat $tmpfile rm $tmpfile return $status } function check_response() { expected_string=$1 retcode=$2 expected_retcode=$3 if [ "$expected_retcode" -a $retcode != $expected_retcode ] ; then echo "return code invalid: got $retcode, expected $expected_retcode" >&2 exit 1 fi if ! grep --quiet -- "$expected_string" $TMPFILE ; then echo "Didn't find $expected_string in output" >&2 cat $TMPFILE >&2 exit 1 fi } function get_config_value_or_die() { local target config_opt raw val target=$1 config_opt=$2 raw="`$SUDO ceph daemon $target config get $config_opt 2>/dev/null`" if [[ $? -ne 0 ]]; then echo "error obtaining config opt '$config_opt' from '$target': $raw" exit 1 fi raw=`echo $raw | sed -e 's/[{} "]//g'` val=`echo $raw | cut -f2 -d:` echo "$val" return 0 } function expect_config_value() { local target config_opt expected_val val target=$1 config_opt=$2 expected_val=$3 val=$(get_config_value_or_die $target $config_opt) if [[ "$val" != "$expected_val" ]]; then echo "expected '$expected_val', got '$val'" exit 1 fi } function ceph_watch_start() { local whatch_opt=--watch if [ -n "$1" ]; then whatch_opt=--watch-$1 fi CEPH_WATCH_FILE=${TMPDIR}/CEPH_WATCH_$$ ceph $whatch_opt > $CEPH_WATCH_FILE & CEPH_WATCH_PID=$! } function ceph_watch_wait() { local regexp=$1 local timeout=30 if [ -n "$2" ]; then timeout=$2 fi for i in `seq ${timeout}`; do sleep 1 grep -q "$regexp" $CEPH_WATCH_FILE && break done kill $CEPH_WATCH_PID grep "$regexp" $CEPH_WATCH_FILE } function test_mon_injectargs() { CEPH_ARGS='--mon_debug_dump_location the.dump' ceph tell osd.0 injectargs --no-osd_debug_op_order >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'false'" ! grep "the.dump" $TMPFILE || return 1 ceph tell osd.0 injectargs '--osd_debug_op_order --osd_failsafe_full_ratio .99' >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'true' osd_failsafe_full_ratio = '0.99'" ceph tell osd.0 injectargs --no-osd_debug_op_order >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'false'" ceph tell osd.0 injectargs -- --osd_debug_op_order >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'true'" ceph tell osd.0 injectargs -- '--osd_debug_op_order --osd_failsafe_full_ratio .98' >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'true' osd_failsafe_full_ratio = '0.98'" } function test_mon_injectargs_SI() { # Test SI units during injectargs and 'config set' # We only aim at testing the units are parsed accordingly # and don't intend to test whether the options being set # actually expect SI units to be passed. # Keep in mind that all integer based options (i.e., INT, # LONG, U32, U64) will accept SI unit modifiers. initial_value=$(get_config_value_or_die "mon.a" "mon_pg_warn_min_objects") $SUDO ceph daemon mon.a config set mon_pg_warn_min_objects 10 expect_config_value "mon.a" "mon_pg_warn_min_objects" 10 $SUDO ceph daemon mon.a config set mon_pg_warn_min_objects 10K expect_config_value "mon.a" "mon_pg_warn_min_objects" 10240 $SUDO ceph daemon mon.a config set mon_pg_warn_min_objects 1G expect_config_value "mon.a" "mon_pg_warn_min_objects" 1073741824 $SUDO ceph daemon mon.a config set mon_pg_warn_min_objects 10F > $TMPFILE || true check_response "'10F': (22) Invalid argument" # now test with injectargs ceph tell mon.a injectargs '--mon_pg_warn_min_objects 10' expect_config_value "mon.a" "mon_pg_warn_min_objects" 10 ceph tell mon.a injectargs '--mon_pg_warn_min_objects 10K' expect_config_value "mon.a" "mon_pg_warn_min_objects" 10240 ceph tell mon.a injectargs '--mon_pg_warn_min_objects 1G' expect_config_value "mon.a" "mon_pg_warn_min_objects" 1073741824 # < /dev/null accounts for the fact that ceph will go in interactive mode # because injectargs is discarded (actually saved for the benefit of # a tell command that never comes) expect_false ceph injectargs mon.a '--mon_pg_warn_min_objects 10F' < /dev/null 2> /dev/null $SUDO ceph daemon mon.a config set mon_pg_warn_min_objects $initial_value } function test_tiering() { # tiering ceph osd pool create slow 2 ceph osd pool create slow2 2 ceph osd pool create cache 2 ceph osd pool create cache2 2 ceph osd tier add slow cache ceph osd tier add slow cache2 expect_false ceph osd tier add slow2 cache # test some state transitions ceph osd tier cache-mode cache writeback ceph osd tier cache-mode cache forward ceph osd tier cache-mode cache readonly ceph osd tier cache-mode cache forward ceph osd tier cache-mode cache none ceph osd tier cache-mode cache writeback expect_false ceph osd tier cache-mode cache none expect_false ceph osd tier cache-mode cache readonly # test with dirty objects in the tier pool # tier pool currently set to 'writeback' rados -p cache put /etc/passwd /etc/passwd ceph tell osd.* flush_pg_stats || true # 1 dirty object in pool 'cache' ceph osd tier cache-mode cache forward expect_false ceph osd tier cache-mode cache none expect_false ceph osd tier cache-mode cache readonly ceph osd tier cache-mode cache writeback # remove object from tier pool rados -p cache rm /etc/passwd rados -p cache cache-flush-evict-all ceph tell osd.* flush_pg_stats || true # no dirty objects in pool 'cache' ceph osd tier cache-mode cache forward ceph osd tier cache-mode cache none ceph osd tier cache-mode cache readonly TRIES=0 while ! ceph osd pool set cache pg_num 3 --yes-i-really-mean-it 2>$TMPFILE do grep 'currently creating pgs' $TMPFILE TRIES=$(( $TRIES + 1 )) test $TRIES -ne 60 sleep 3 done expect_false ceph osd pool set cache pg_num 4 ceph osd tier cache-mode cache none ceph osd tier set-overlay slow cache expect_false ceph osd tier set-overlay slow cache2 expect_false ceph osd tier remove slow cache ceph osd tier remove-overlay slow ceph osd tier set-overlay slow cache2 ceph osd tier remove-overlay slow ceph osd tier remove slow cache ceph osd tier add slow2 cache expect_false ceph osd tier set-overlay slow cache ceph osd tier set-overlay slow2 cache ceph osd tier remove-overlay slow2 ceph osd tier remove slow2 cache ceph osd tier remove slow cache2 # make sure a non-empty pool fails rados -p cache2 put /etc/passwd /etc/passwd while ! ceph df | grep cache2 | grep ' 1 ' ; do echo waiting for pg stats to flush sleep 2 done expect_false ceph osd tier add slow cache2 ceph osd tier add slow cache2 --force-nonempty ceph osd tier remove slow cache2 ceph osd pool ls | grep cache2 ceph osd pool ls -f json-pretty | grep cache2 ceph osd pool ls detail | grep cache2 ceph osd pool ls detail -f json-pretty | grep cache2 ceph osd pool delete cache cache --yes-i-really-really-mean-it ceph osd pool delete cache2 cache2 --yes-i-really-really-mean-it # convenient add-cache command ceph osd pool create cache3 2 ceph osd tier add-cache slow cache3 1024000 ceph osd dump | grep cache3 | grep bloom | grep 'false_positive_probability: 0.05' | grep 'target_bytes 1024000' | grep '1200s x4' ceph osd tier remove slow cache3 ceph osd pool ls | grep cache3 ceph osd pool delete cache3 cache3 --yes-i-really-really-mean-it ! ceph osd pool ls | grep cache3 || exit 1 ceph osd pool delete slow2 slow2 --yes-i-really-really-mean-it ceph osd pool delete slow slow --yes-i-really-really-mean-it # protection against pool removal when used as tiers ceph osd pool create datapool 2 ceph osd pool create cachepool 2 ceph osd tier add-cache datapool cachepool 1024000 ceph osd pool delete cachepool cachepool --yes-i-really-really-mean-it 2> $TMPFILE || true check_response "EBUSY: pool 'cachepool' is a tier of 'datapool'" ceph osd pool delete datapool datapool --yes-i-really-really-mean-it 2> $TMPFILE || true check_response "EBUSY: pool 'datapool' has tiers cachepool" ceph osd tier remove datapool cachepool ceph osd pool delete cachepool cachepool --yes-i-really-really-mean-it ceph osd pool delete datapool datapool --yes-i-really-really-mean-it # check health check ceph osd pool create datapool 2 ceph osd pool create cache4 2 ceph osd tier add datapool cache4 ceph osd pool set cache4 target_max_objects 5 ceph osd pool set cache4 target_max_bytes 1000 for f in `seq 1 5` ; do rados -p cache4 put foo$f /etc/passwd done while ! ceph df | grep cache4 | grep ' 5 ' ; do echo waiting for pg stats to flush sleep 2 done ceph health | grep WARN | grep cache4 ceph health detail | grep cache4 | grep 'target max' | grep objects ceph health detail | grep cache4 | grep 'target max' | grep 'B' ceph osd tier remove datapool cache4 ceph osd pool delete cache4 cache4 --yes-i-really-really-mean-it ceph osd pool delete datapool datapool --yes-i-really-really-mean-it # make sure 'tier remove' behaves as we expect # i.e., removing a tier from a pool that's not its base pool only # results in a 'pool foo is now (or already was) not a tier of bar' # ceph osd pool create basepoolA 2 ceph osd pool create basepoolB 2 poolA_id=$(ceph osd dump | grep 'pool.*basepoolA' | awk '{print $2;}') poolB_id=$(ceph osd dump | grep 'pool.*basepoolB' | awk '{print $2;}') ceph osd pool create cache5 2 ceph osd pool create cache6 2 ceph osd tier add basepoolA cache5 ceph osd tier add basepoolB cache6 ceph osd tier remove basepoolB cache5 2>&1 | grep 'not a tier of' ceph osd dump | grep "pool.*'cache5'" 2>&1 | grep "tier_of[ \t]\+$poolA_id" ceph osd tier remove basepoolA cache6 2>&1 | grep 'not a tier of' ceph osd dump | grep "pool.*'cache6'" 2>&1 | grep "tier_of[ \t]\+$poolB_id" ceph osd tier remove basepoolA cache5 2>&1 | grep 'not a tier of' ! ceph osd dump | grep "pool.*'cache5'" 2>&1 | grep "tier_of" || exit 1 ceph osd tier remove basepoolB cache6 2>&1 | grep 'not a tier of' ! ceph osd dump | grep "pool.*'cache6'" 2>&1 | grep "tier_of" || exit 1 ! ceph osd dump | grep "pool.*'basepoolA'" 2>&1 | grep "tiers" || exit 1 ! ceph osd dump | grep "pool.*'basepoolB'" 2>&1 | grep "tiers" || exit 1 ceph osd pool delete cache6 cache6 --yes-i-really-really-mean-it ceph osd pool delete cache5 cache5 --yes-i-really-really-mean-it ceph osd pool delete basepoolB basepoolB --yes-i-really-really-mean-it ceph osd pool delete basepoolA basepoolA --yes-i-really-really-mean-it } function test_auth() { ceph auth add client.xx mon allow osd "allow *" ceph auth export client.xx >client.xx.keyring ceph auth add client.xx -i client.xx.keyring rm -f client.xx.keyring ceph auth list | grep client.xx ceph auth get client.xx | grep caps | grep mon ceph auth get client.xx | grep caps | grep osd ceph auth get-key client.xx ceph auth print-key client.xx ceph auth print_key client.xx ceph auth caps client.xx osd "allow rw" expect_false "ceph auth get client.xx | grep caps | grep mon" ceph auth get client.xx | grep osd | grep "allow rw" ceph auth export | grep client.xx ceph auth export -o authfile ceph auth import -i authfile ceph auth export -o authfile2 diff authfile authfile2 rm authfile authfile2 ceph auth del client.xx # # get / set auid # local auid=444 ceph-authtool --create-keyring --name client.TEST --gen-key --set-uid $auid TEST-keyring ceph auth import --in-file TEST-keyring rm TEST-keyring ceph auth get client.TEST > $TMPFILE check_response "auid = $auid" ceph --format json-pretty auth get client.TEST > $TMPFILE check_response '"auid": '$auid ceph auth list > $TMPFILE check_response "auid: $auid" ceph --format json-pretty auth list > $TMPFILE check_response '"auid": '$auid ceph auth del client.TEST } function test_auth_profiles() { ceph auth add client.xx-profile-ro mon 'allow profile read-only' ceph auth add client.xx-profile-rw mon 'allow profile read-write' ceph auth add client.xx-profile-rd mon 'allow profile role-definer' ceph auth export > client.xx.keyring # read-only is allowed all read-only commands (auth excluded) ceph -n client.xx-profile-ro -k client.xx.keyring status ceph -n client.xx-profile-ro -k client.xx.keyring osd dump ceph -n client.xx-profile-ro -k client.xx.keyring pg dump ceph -n client.xx-profile-ro -k client.xx.keyring mon dump ceph -n client.xx-profile-ro -k client.xx.keyring mds dump # read-only gets access denied for rw commands or auth commands ceph -n client.xx-profile-ro -k client.xx.keyring log foo >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-ro -k client.xx.keyring osd set noout >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-ro -k client.xx.keyring auth list >& $TMPFILE || true check_response "EACCES: access denied" # read-write is allowed for all read-write commands (except auth) ceph -n client.xx-profile-rw -k client.xx.keyring status ceph -n client.xx-profile-rw -k client.xx.keyring osd dump ceph -n client.xx-profile-rw -k client.xx.keyring pg dump ceph -n client.xx-profile-rw -k client.xx.keyring mon dump ceph -n client.xx-profile-rw -k client.xx.keyring mds dump ceph -n client.xx-profile-rw -k client.xx.keyring log foo ceph -n client.xx-profile-rw -k client.xx.keyring osd set noout ceph -n client.xx-profile-rw -k client.xx.keyring osd unset noout # read-write gets access denied for auth commands ceph -n client.xx-profile-rw -k client.xx.keyring auth list >& $TMPFILE || true check_response "EACCES: access denied" # role-definer is allowed RWX 'auth' commands and read-only 'mon' commands ceph -n client.xx-profile-rd -k client.xx.keyring auth list ceph -n client.xx-profile-rd -k client.xx.keyring auth export ceph -n client.xx-profile-rd -k client.xx.keyring auth add client.xx-profile-foo ceph -n client.xx-profile-rd -k client.xx.keyring status ceph -n client.xx-profile-rd -k client.xx.keyring osd dump >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-rd -k client.xx.keyring pg dump >& $TMPFILE || true check_response "EACCES: access denied" # read-only 'mon' subsystem commands are allowed ceph -n client.xx-profile-rd -k client.xx.keyring mon dump # but read-write 'mon' commands are not ceph -n client.xx-profile-rd -k client.xx.keyring mon add foo 1.1.1.1 >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-rd -k client.xx.keyring mds dump >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-rd -k client.xx.keyring log foo >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-rd -k client.xx.keyring osd set noout >& $TMPFILE || true check_response "EACCES: access denied" ceph -n client.xx-profile-rd -k client.xx.keyring auth del client.xx-profile-ro ceph -n client.xx-profile-rd -k client.xx.keyring auth del client.xx-profile-rw # add a new role-definer with the existing role-definer ceph -n client.xx-profile-rd -k client.xx.keyring \ auth add client.xx-profile-rd2 mon 'allow profile role-definer' ceph -n client.xx-profile-rd -k client.xx.keyring \ auth export > client.xx.keyring.2 # remove old role-definer using the new role-definer ceph -n client.xx-profile-rd2 -k client.xx.keyring.2 \ auth del client.xx-profile-rd # remove the remaining role-definer with admin ceph auth del client.xx-profile-rd2 rm -f client.xx.keyring client.xx.keyring.2 } function test_mon_misc() { # with and without verbosity ceph osd dump | grep '^epoch' ceph --concise osd dump | grep '^epoch' # df ceph df > $TMPFILE grep GLOBAL $TMPFILE grep -v DIRTY $TMPFILE ceph df detail > $TMPFILE grep CATEGORY $TMPFILE grep DIRTY $TMPFILE ceph df --format json > $TMPFILE grep 'total_bytes' $TMPFILE grep -v 'dirty' $TMPFILE ceph df detail --format json > $TMPFILE grep 'rd_bytes' $TMPFILE grep 'dirty' $TMPFILE ceph df --format xml | grep '' ceph df detail --format xml | grep '' ceph fsid ceph health ceph health detail ceph health --format json-pretty ceph health detail --format xml-pretty ceph_watch_start mymsg="this is a test log message $$.$(date)" ceph log "$mymsg" ceph_watch_wait "$mymsg" } function check_mds_active() { ceph mds dump | grep active } function wait_mds_active() { for i in $(seq 1 300) ; do if ! check_mds_active ; then echo "waiting for an active MDS daemon" sleep 5 else break fi done check_mds_active } function get_mds_gids() { ceph mds dump --format=json | python -c "import json; import sys; print ' '.join([m['gid'].__str__() for m in json.load(sys.stdin)['info'].values()])" } function fail_all_mds() { ceph mds cluster_down mds_gids=$(get_mds_gids) for mds_gid in $mds_gids ; do ceph mds fail $mds_gid done if check_mds_active ; then echo "An active MDS remains, something went wrong" ceph mds dump exit -1 fi } function remove_all_fs() { existing_fs=$(ceph fs ls --format=json | python -c "import json; import sys; print ' '.join([fs['name'] for fs in json.load(sys.stdin)])") if [ -n "$existing_fs" ] ; then fail_all_mds echo "Removing existing filesystem '${existing_fs}'..." ceph fs rm $existing_fs --yes-i-really-mean-it echo "Removed '${existing_fs}'." fi } # So that tests requiring MDS can skip if one is not configured # in the cluster at all function mds_exists() { ceph auth list | grep "^mds" } function test_mds_tell() { if ! mds_exists ; then echo "Skipping test, no MDS found" return fi remove_all_fs ceph osd pool create fs_data 10 ceph osd pool create fs_metadata 10 ceph fs new cephfs fs_metadata fs_data wait_mds_active # Test injectargs by GID old_mds_gids=$(get_mds_gids) echo Old GIDs: $old_mds_gids for mds_gid in $old_mds_gids ; do ceph tell mds.$mds_gid injectargs "--debug-mds 20" done # Test respawn by rank ceph tell mds.0 respawn new_mds_gids=$old_mds_gids while [ $new_mds_gids -eq $old_mds_gids ] ; do sleep 5 new_mds_gids=$(get_mds_gids) done echo New GIDs: $new_mds_gids # Test respawn by ID ceph tell mds.a respawn new_mds_gids=$old_mds_gids while [ $new_mds_gids -eq $old_mds_gids ] ; do sleep 5 new_mds_gids=$(get_mds_gids) done echo New GIDs: $new_mds_gids remove_all_fs ceph osd pool delete fs_data fs_data --yes-i-really-really-mean-it ceph osd pool delete fs_metadata fs_metadata --yes-i-really-really-mean-it } function test_mon_mds() { remove_all_fs ceph osd pool create fs_data 10 ceph osd pool create fs_metadata 10 ceph fs new cephfs fs_metadata fs_data ceph mds cluster_down ceph mds cluster_up ceph mds compat rm_incompat 4 ceph mds compat rm_incompat 4 # We don't want any MDSs to be up, their activity can interfere with # the "current_epoch + 1" checking below if they're generating updates fail_all_mds # Check for default crash_replay_interval set automatically in 'fs new' ceph osd dump | grep fs_data > $TMPFILE check_response "crash_replay_interval 45 " ceph mds compat show expect_false ceph mds deactivate 2 ceph mds dump # XXX mds fail, but how do you undo it? mdsmapfile=$TMPDIR/mdsmap.$$ current_epoch=$(ceph mds getmap -o $mdsmapfile --no-log-to-stderr 2>&1 | grep epoch | sed 's/.*epoch //') [ -s $mdsmapfile ] ((epoch = current_epoch + 1)) ceph mds setmap -i $mdsmapfile $epoch rm $mdsmapfile ceph osd pool create data2 10 ceph osd pool create data3 10 data2_pool=$(ceph osd dump | grep 'pool.*data2' | awk '{print $2;}') data3_pool=$(ceph osd dump | grep 'pool.*data3' | awk '{print $2;}') ceph mds add_data_pool $data2_pool ceph mds add_data_pool $data3_pool ceph mds add_data_pool 100 >& $TMPFILE || true check_response "Error ENOENT" ceph mds add_data_pool foobarbaz >& $TMPFILE || true check_response "Error ENOENT" ceph mds remove_data_pool $data2_pool ceph mds remove_data_pool $data3_pool ceph osd pool delete data2 data2 --yes-i-really-really-mean-it ceph osd pool delete data3 data3 --yes-i-really-really-mean-it ceph mds set_max_mds 4 ceph mds set_max_mds 3 ceph mds set max_mds 4 expect_false ceph mds set max_mds asdf expect_false ceph mds set inline_data true ceph mds set inline_data true --yes-i-really-mean-it ceph mds set inline_data yes --yes-i-really-mean-it ceph mds set inline_data 1 --yes-i-really-mean-it expect_false ceph mds set inline_data --yes-i-really-mean-it ceph mds set inline_data false ceph mds set inline_data no ceph mds set inline_data 0 expect_false ceph mds set inline_data asdf ceph mds set max_file_size 1048576 expect_false ceph mds set max_file_size 123asdf expect_false ceph mds set allow_new_snaps expect_false ceph mds set allow_new_snaps true ceph mds set allow_new_snaps true --yes-i-really-mean-it ceph mds set allow_new_snaps 0 ceph mds set allow_new_snaps false ceph mds set allow_new_snaps no expect_false ceph mds set allow_new_snaps taco # we should never be able to add EC pools as data or metadata pools # create an ec-pool... ceph osd pool create mds-ec-pool 10 10 erasure set +e ceph mds add_data_pool mds-ec-pool 2>$TMPFILE check_response 'erasure-code' $? 22 set -e ec_poolnum=$(ceph osd dump | grep "pool.* 'mds-ec-pool" | awk '{print $2;}') data_poolnum=$(ceph osd dump | grep "pool.* 'fs_data" | awk '{print $2;}') metadata_poolnum=$(ceph osd dump | grep "pool.* 'fs_metadata" | awk '{print $2;}') fail_all_mds # Check that 'fs reset' runs ceph fs reset cephfs --yes-i-really-mean-it fail_all_mds # Clean up to enable subsequent newfs tests ceph fs rm cephfs --yes-i-really-mean-it set +e ceph mds newfs $metadata_poolnum $ec_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'erasure-code' $? 22 ceph mds newfs $ec_poolnum $data_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'erasure-code' $? 22 ceph mds newfs $ec_poolnum $ec_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'erasure-code' $? 22 ceph fs new cephfs fs_metadata mds-ec-pool 2>$TMPFILE check_response 'erasure-code' $? 22 ceph fs new cephfs mds-ec-pool fs_data 2>$TMPFILE check_response 'erasure-code' $? 22 ceph fs new cephfs mds-ec-pool mds-ec-pool 2>$TMPFILE check_response 'erasure-code' $? 22 set -e # ... however if we create a cache tier in front of the EC pool, we should # be permitted to use it... ceph osd pool create mds-tier 2 ceph osd tier add mds-ec-pool mds-tier ceph osd tier set-overlay mds-ec-pool mds-tier ceph osd tier cache-mode mds-tier writeback tier_poolnum=$(ceph osd dump | grep "pool.* 'mds-tier" | awk '{print $2;}') set -e ceph fs new cephfs fs_metadata mds-ec-pool # While a FS exists using the tiered pools, I should not be allowed # to remove the tier set +e ceph osd tier remove-overlay mds-ec-pool 2>$TMPFILE check_response 'in use by CephFS' $? 16 ceph osd tier remove mds-ec-pool mds-tier 2>$TMPFILE check_response 'in use by CephFS' $? 16 set -e fail_all_mds ceph fs rm cephfs --yes-i-really-mean-it # ... but we should be forbidden from using the cache pool in the FS directly. set +e ceph mds newfs $metadata_poolnum $tier_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'in use as a cache tier' $? 22 ceph mds newfs $tier_poolnum $data_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'in use as a cache tier' $? 22 ceph mds newfs $tier_poolnum $tier_poolnum --yes-i-really-mean-it 2>$TMPFILE check_response 'in use as a cache tier' $? 22 ceph fs new cephfs fs_metadata mds-tier 2>$TMPFILE check_response 'in use as a cache tier' $? 22 ceph fs new cephfs mds-tier fs_data 2>$TMPFILE check_response 'in use as a cache tier' $? 22 ceph fs new cephfs mds-tier mds-tier 2>$TMPFILE check_response 'in use as a cache tier' $? 22 set -e # Clean up tier + EC pools ceph osd tier remove-overlay mds-ec-pool ceph osd tier remove mds-ec-pool mds-tier # Create a FS using the 'cache' pool now that it's no longer a tier ceph fs new cephfs fs_metadata mds-tier # We should be forbidden from using this pool as a tier now that # it's in use for CephFS set +e ceph osd tier add mds-ec-pool mds-tier 2>$TMPFILE check_response 'in use by CephFS' $? 16 set -e fail_all_mds ceph fs rm cephfs --yes-i-really-mean-it # Create a FS and check that we can subsequently add a cache tier to it ceph fs new cephfs fs_metadata fs_data # Adding overlay to FS pool should be permitted, RADOS clients handle this. ceph osd tier add fs_metadata mds-tier ceph osd tier cache-mode mds-tier writeback ceph osd tier set-overlay fs_metadata mds-tier # Clean up FS fail_all_mds ceph fs rm cephfs --yes-i-really-mean-it # Clean up overlay/tier relationship ceph osd tier remove-overlay fs_metadata ceph osd tier remove fs_metadata mds-tier ceph osd pool delete mds-tier mds-tier --yes-i-really-really-mean-it ceph osd pool delete mds-ec-pool mds-ec-pool --yes-i-really-really-mean-it ceph mds stat # ceph mds tell mds.a getmap # ceph mds rm # ceph mds rmfailed # ceph mds set_state # ceph mds stop ceph osd pool delete fs_data fs_data --yes-i-really-really-mean-it ceph osd pool delete fs_metadata fs_metadata --yes-i-really-really-mean-it } function test_mon_mon() { # no mon add/remove ceph mon dump ceph mon getmap -o $TMPDIR/monmap.$$ [ -s $TMPDIR/monmap.$$ ] # ceph mon tell ceph mon_status } function test_mon_osd() { # # osd blacklist # bl=192.168.0.1:0/1000 ceph osd blacklist add $bl ceph osd blacklist ls | grep $bl ceph osd blacklist rm $bl expect_false "ceph osd blacklist ls | grep $bl" bl=192.168.0.1 # test without nonce, invalid nonce ceph osd blacklist add $bl ceph osd blacklist ls | grep $bl ceph osd blacklist rm $bl expect_false "ceph osd blacklist ls | grep $bl" expect_false "ceph osd blacklist $bl/-1" expect_false "ceph osd blacklist $bl/foo" # # osd crush # ceph osd crush reweight-all ceph osd crush tunables legacy ceph osd crush show-tunables | grep argonaut ceph osd crush tunables bobtail ceph osd crush show-tunables | grep bobtail ceph osd crush tunables firefly ceph osd crush show-tunables | grep firefly ceph osd crush set-tunable straw_calc_version 0 ceph osd crush get-tunable straw_calc_version | grep 0 ceph osd crush set-tunable straw_calc_version 1 ceph osd crush get-tunable straw_calc_version | grep 1 # # osd scrub # # how do I tell when these are done? ceph osd scrub 0 ceph osd deep-scrub 0 ceph osd repair 0 for f in noup nodown noin noout noscrub nodeep-scrub nobackfill norecover notieragent full do ceph osd set $f ceph osd unset $f done expect_false ceph osd set bogus expect_false ceph osd unset bogus ceph osd set noup ceph osd down 0 ceph osd dump | grep 'osd.0 down' ceph osd unset noup for ((i=0; i < 100; i++)); do if ! ceph osd dump | grep 'osd.0 up'; then echo "waiting for osd.0 to come back up" sleep 10 else break fi done ceph osd dump | grep 'osd.0 up' ceph osd thrash 0 ceph osd dump | grep 'osd.0 up' ceph osd find 1 ceph --format plain osd find 1 # falls back to json-pretty ceph osd metadata 1 | grep 'distro' ceph --format plain osd metadata 1 | grep 'distro' # falls back to json-pretty ceph osd out 0 ceph osd dump | grep 'osd.0.*out' ceph osd in 0 ceph osd dump | grep 'osd.0.*in' ceph osd find 0 f=$TMPDIR/map.$$ ceph osd getcrushmap -o $f [ -s $f ] rm $f ceph osd getmap -o $f [ -s $f ] rm $f save=$(ceph osd getmaxosd | sed -e 's/max_osd = //' -e 's/ in epoch.*//') ceph osd setmaxosd 10 ceph osd getmaxosd | grep 'max_osd = 10' ceph osd setmaxosd $save ceph osd getmaxosd | grep "max_osd = $save" for id in `ceph osd ls` ; do retry_eagain 5 map_enxio_to_eagain ceph tell osd.$id version done ceph osd rm 0 2>&1 | grep 'EBUSY' local old_osds=$(echo $(ceph osd ls)) id=`ceph osd create` ceph osd lost $id --yes-i-really-mean-it expect_false ceph osd setmaxosd $id local new_osds=$(echo $(ceph osd ls)) for id in $(echo $new_osds | sed -e "s/$old_osds//") ; do ceph osd rm $id done uuid=`uuidgen` id=`ceph osd create $uuid` id2=`ceph osd create $uuid` [ "$id" = "$id2" ] ceph osd rm $id ceph osd ls ceph osd pool create data 10 ceph osd lspools | grep data ceph osd map data foo | grep 'pool.*data.*object.*foo.*pg.*up.*acting' ceph osd pool delete data data --yes-i-really-really-mean-it ceph osd pause ceph osd dump | grep 'flags pauserd,pausewr' ceph osd unpause ceph osd tree ceph osd perf ceph osd blocked-by ceph osd stat | grep up, } function test_mon_osd_pool() { # # osd pool # ceph osd pool create data 10 ceph osd pool mksnap data datasnap rados -p data lssnap | grep datasnap ceph osd pool rmsnap data datasnap ceph osd pool delete data data --yes-i-really-really-mean-it ceph osd pool create data2 10 ceph osd pool rename data2 data3 ceph osd lspools | grep data3 ceph osd pool delete data3 data3 --yes-i-really-really-mean-it ceph osd pool create replicated 12 12 replicated ceph osd pool create replicated 12 12 replicated ceph osd pool create replicated 12 12 # default is replicated ceph osd pool create replicated 12 # default is replicated, pgp_num = pg_num # should fail because the type is not the same expect_false ceph osd pool create replicated 12 12 erasure ceph osd lspools | grep replicated ceph osd pool delete replicated replicated --yes-i-really-really-mean-it } function test_mon_osd_pool_quota() { # # test osd pool set/get quota # # create tmp pool ceph osd pool create tmp-quota-pool 36 # # set erroneous quotas # expect_false ceph osd pool set-quota tmp-quota-pool max_fooness 10 expect_false ceph osd pool set-quota tmp-quota-pool max_bytes -1 expect_false ceph osd pool set-quota tmp-quota-pool max_objects aaa # # set valid quotas # ceph osd pool set-quota tmp-quota-pool max_bytes 10 ceph osd pool set-quota tmp-quota-pool max_objects 10M # # get quotas # ceph osd pool get-quota tmp-quota-pool | grep 'max bytes.*10B' ceph osd pool get-quota tmp-quota-pool | grep 'max objects.*10240k objects' # # get quotas in json-pretty format # ceph osd pool get-quota tmp-quota-pool --format=json-pretty | \ grep '"quota_max_objects":.*10485760' ceph osd pool get-quota tmp-quota-pool --format=json-pretty | \ grep '"quota_max_bytes":.*10' # # reset pool quotas # ceph osd pool set-quota tmp-quota-pool max_bytes 0 ceph osd pool set-quota tmp-quota-pool max_objects 0 # # test N/A quotas # ceph osd pool get-quota tmp-quota-pool | grep 'max bytes.*N/A' ceph osd pool get-quota tmp-quota-pool | grep 'max objects.*N/A' # # cleanup tmp pool ceph osd pool delete tmp-quota-pool tmp-quota-pool --yes-i-really-really-mean-it } function test_mon_pg() { ceph pg debug unfound_objects_exist ceph pg debug degraded_pgs_exist ceph pg deep-scrub 0.0 ceph pg dump ceph pg dump pgs_brief --format=json ceph pg dump pgs --format=json ceph pg dump pools --format=json ceph pg dump osds --format=json ceph pg dump sum --format=json ceph pg dump all --format=json ceph pg dump pgs_brief osds --format=json ceph pg dump pools osds pgs_brief --format=json ceph pg dump_json ceph pg dump_pools_json ceph pg dump_stuck inactive ceph pg dump_stuck unclean ceph pg dump_stuck stale ceph pg dump_stuck undersized ceph pg dump_stuck degraded # can't test this... # ceph pg force_create_pg ceph pg getmap -o $TMPDIR/map.$$ [ -s $TMPDIR/map.$$ ] ceph pg map 0.0 | grep acting ceph pg repair 0.0 ceph pg scrub 0.0 ceph pg send_pg_creates ceph pg set_full_ratio 0.90 ceph pg dump --format=plain | grep '^full_ratio 0.9' ceph pg set_full_ratio 0.95 ceph pg set_nearfull_ratio 0.90 ceph pg dump --format=plain | grep '^nearfull_ratio 0.9' ceph pg set_nearfull_ratio 0.85 ceph pg stat | grep 'pgs:' ceph pg 0.0 query ceph tell 0.0 query ceph quorum enter ceph quorum_status ceph report | grep osd_stats ceph status ceph -s # # tell osd version # ceph tell osd.0 version expect_false ceph tell osd.9999 version # back to pg stuff ceph tell osd.0 dump_pg_recovery_stats | grep Started ceph osd reweight 0 0.9 expect_false ceph osd reweight 0 -1 ceph osd reweight 0 1 ceph osd primary-affinity osd.0 .9 expect_false ceph osd primary-affinity osd.0 -2 ceph osd primary-affinity osd.0 1 ceph osd pg-temp 0.0 0 1 2 ceph osd pg-temp 0.0 1 0 2 expect_false ceph osd pg-temp asdf qwer expect_false ceph osd pg-temp 0.0 asdf expect_false ceph osd pg-temp 0.0 # don't test ceph osd primary-temp for now } function test_mon_osd_pool_set() { TEST_POOL_GETSET=pool_getset ceph osd pool create $TEST_POOL_GETSET 10 for s in pg_num pgp_num size min_size crash_replay_interval crush_ruleset; do ceph osd pool get $TEST_POOL_GETSET $s done old_size=$(ceph osd pool get $TEST_POOL_GETSET size | sed -e 's/size: //') (( new_size = old_size + 1 )) ceph osd pool set $TEST_POOL_GETSET size $new_size ceph osd pool get $TEST_POOL_GETSET size | grep "size: $new_size" ceph osd pool set $TEST_POOL_GETSET size $old_size ceph osd pool create pool_erasure 12 12 erasure set +e ceph osd pool set pool_erasure size 4444 2>$TMPFILE check_response 'not change the size' set -e ceph osd pool get pool_erasure erasure_code_profile auid=5555 ceph osd pool set $TEST_POOL_GETSET auid $auid ceph osd pool get $TEST_POOL_GETSET auid | grep $auid ceph --format=xml osd pool get $TEST_POOL_GETSET auid | grep $auid ceph osd pool set $TEST_POOL_GETSET auid 0 for flag in hashpspool nodelete nopgchange nosizechange; do ceph osd pool set $TEST_POOL_GETSET $flag false ceph osd pool set $TEST_POOL_GETSET $flag true ceph osd pool set $TEST_POOL_GETSET $flag 1 ceph osd pool set $TEST_POOL_GETSET $flag 0 expect_false ceph osd pool set $TEST_POOL_GETSET $flag asdf expect_false ceph osd pool set $TEST_POOL_GETSET $flag 2 done ceph osd pool set $TEST_POOL_GETSET nopgchange 1 expect_false ceph osd pool set $TEST_POOL_GETSET pg_num 10 expect_false ceph osd pool set $TEST_POOL_GETSET pgp_num 10 ceph osd pool set $TEST_POOL_GETSET nopgchange 0 ceph osd pool set $TEST_POOL_GETSET pg_num 10 ceph osd pool set $TEST_POOL_GETSET pgp_num 10 ceph osd pool set $TEST_POOL_GETSET nosizechange 1 expect_false ceph osd pool set $TEST_POOL_GETSET size 2 expect_false ceph osd pool set $TEST_POOL_GETSET min_size 2 ceph osd pool set $TEST_POOL_GETSET nosizechange 0 ceph osd pool set $TEST_POOL_GETSET size 2 ceph osd pool set $TEST_POOL_GETSET min_size 2 ceph osd pool set $TEST_POOL_GETSET nodelete 1 expect_false ceph osd pool delete $TEST_POOL_GETSET $TEST_POOL_GETSET --yes-i-really-really-mean-it ceph osd pool set $TEST_POOL_GETSET nodelete 0 ceph osd pool delete $TEST_POOL_GETSET $TEST_POOL_GETSET --yes-i-really-really-mean-it ceph osd pool get rbd crush_ruleset | grep 'crush_ruleset: 0' } function test_mon_osd_tiered_pool_set() { # this is really a tier pool ceph osd pool create real-tier 2 ceph osd tier add rbd real-tier ceph osd pool set real-tier hit_set_type explicit_hash ceph osd pool get real-tier hit_set_type | grep "hit_set_type: explicit_hash" ceph osd pool set real-tier hit_set_type explicit_object ceph osd pool get real-tier hit_set_type | grep "hit_set_type: explicit_object" ceph osd pool set real-tier hit_set_type bloom ceph osd pool get real-tier hit_set_type | grep "hit_set_type: bloom" expect_false ceph osd pool set real-tier hit_set_type i_dont_exist ceph osd pool set real-tier hit_set_period 123 ceph osd pool get real-tier hit_set_period | grep "hit_set_period: 123" ceph osd pool set real-tier hit_set_count 12 ceph osd pool get real-tier hit_set_count | grep "hit_set_count: 12" ceph osd pool set real-tier hit_set_fpp .01 ceph osd pool get real-tier hit_set_fpp | grep "hit_set_fpp: 0.01" ceph osd pool set real-tier target_max_objects 123 ceph osd pool get real-tier target_max_objects | \ grep 'target_max_objects:[ \t]\+123' ceph osd pool set real-tier target_max_bytes 123456 ceph osd pool get real-tier target_max_bytes | \ grep 'target_max_bytes:[ \t]\+123456' ceph osd pool set real-tier cache_target_dirty_ratio .123 ceph osd pool get real-tier cache_target_dirty_ratio | \ grep 'cache_target_dirty_ratio:[ \t]\+0.123' expect_false ceph osd pool set real-tier cache_target_dirty_ratio -.2 expect_false ceph osd pool set real-tier cache_target_dirty_ratio 1.1 ceph osd pool set real-tier cache_target_full_ratio .123 ceph osd pool get real-tier cache_target_full_ratio | \ grep 'cache_target_full_ratio:[ \t]\+0.123' ceph osd dump -f json-pretty | grep '"cache_target_full_ratio_micro": 123000' ceph osd pool set real-tier cache_target_full_ratio 1.0 ceph osd pool set real-tier cache_target_full_ratio 0 expect_false ceph osd pool set real-tier cache_target_full_ratio 1.1 ceph osd pool set real-tier cache_min_flush_age 123 ceph osd pool get real-tier cache_min_flush_age | \ grep 'cache_min_flush_age:[ \t]\+123' ceph osd pool set real-tier cache_min_evict_age 234 ceph osd pool get real-tier cache_min_evict_age | \ grep 'cache_min_evict_age:[ \t]\+234' # this is not a tier pool ceph osd pool create fake-tier 2 expect_false ceph osd pool set fake-tier hit_set_type explicit_hash expect_false ceph osd pool get fake-tier hit_set_type expect_false ceph osd pool set fake-tier hit_set_type explicit_object expect_false ceph osd pool get fake-tier hit_set_type expect_false ceph osd pool set fake-tier hit_set_type bloom expect_false ceph osd pool get fake-tier hit_set_type expect_false ceph osd pool set fake-tier hit_set_type i_dont_exist expect_false ceph osd pool set fake-tier hit_set_period 123 expect_false ceph osd pool get fake-tier hit_set_period expect_false ceph osd pool set fake-tier hit_set_count 12 expect_false ceph osd pool get fake-tier hit_set_count expect_false ceph osd pool set fake-tier hit_set_fpp .01 expect_false ceph osd pool get fake-tier hit_set_fpp expect_false ceph osd pool set fake-tier target_max_objects 123 expect_false ceph osd pool get fake-tier target_max_objects expect_false ceph osd pool set fake-tier target_max_bytes 123456 expect_false ceph osd pool get fake-tier target_max_bytes expect_false ceph osd pool set fake-tier cache_target_dirty_ratio .123 expect_false ceph osd pool get fake-tier cache_target_dirty_ratio expect_false ceph osd pool set fake-tier cache_target_dirty_ratio -.2 expect_false ceph osd pool set fake-tier cache_target_dirty_ratio 1.1 expect_false ceph osd pool set fake-tier cache_target_full_ratio .123 expect_false ceph osd pool get fake-tier cache_target_full_ratio expect_false ceph osd pool set fake-tier cache_target_full_ratio 1.0 expect_false ceph osd pool set fake-tier cache_target_full_ratio 0 expect_false ceph osd pool set fake-tier cache_target_full_ratio 1.1 expect_false ceph osd pool set fake-tier cache_min_flush_age 123 expect_false ceph osd pool get fake-tier cache_min_flush_age expect_false ceph osd pool set fake-tier cache_min_evict_age 234 expect_false ceph osd pool get fake-tier cache_min_evict_age ceph osd tier remove rbd real-tier ceph osd pool delete real-tier real-tier --yes-i-really-really-mean-it ceph osd pool delete fake-tier fake-tier --yes-i-really-really-mean-it } function test_mon_osd_erasure_code() { ceph osd erasure-code-profile set fooprofile a=b c=d ceph osd erasure-code-profile set fooprofile a=b c=d expect_false ceph osd erasure-code-profile set fooprofile a=b c=d e=f ceph osd erasure-code-profile set fooprofile a=b c=d e=f --force ceph osd erasure-code-profile set fooprofile a=b c=d e=f expect_false ceph osd erasure-code-profile set fooprofile a=b c=d e=f g=h # # cleanup by removing profile 'fooprofile' ceph osd erasure-code-profile rm fooprofile } function test_mon_osd_misc() { set +e # expect error about missing 'pool' argument ceph osd map 2>$TMPFILE; check_response 'pool' $? 22 # expect error about unused argument foo ceph osd ls foo 2>$TMPFILE; check_response 'unused' $? 22 # expect "not in range" for invalid full ratio ceph pg set_full_ratio 95 2>$TMPFILE; check_response 'not in range' $? 22 # expect "not in range" for invalid overload percentage ceph osd reweight-by-utilization 80 2>$TMPFILE; check_response 'not in range' $? 22 set -e ceph osd reweight-by-utilization 110 ceph osd reweight-by-pg 110 ceph osd reweight-by-pg 110 rbd expect_false ceph osd reweight-by-pg 110 boguspoolasdfasdfasdf } function test_mon_heap_profiler() { do_test=1 set +e # expect 'heap' commands to be correctly parsed ceph heap stats 2>$TMPFILE if [[ $? -eq 22 && `grep 'tcmalloc not enabled' $TMPFILE` ]]; then echo "tcmalloc not enabled; skip heap profiler test" do_test=0 fi set -e [[ $do_test -eq 0 ]] && return 0 ceph heap start_profiler ceph heap dump ceph heap stop_profiler ceph heap release } function test_osd_bench() { # test osd bench limits # As we should not rely on defaults (as they may change over time), # lets inject some values and perform some simple tests # max iops: 10 # 100 IOPS # max throughput: 10485760 # 10MB/s # max block size: 2097152 # 2MB # duration: 10 # 10 seconds ceph tell osd.0 injectargs "\ --osd-bench-duration 10 \ --osd-bench-max-block-size 2097152 \ --osd-bench-large-size-max-throughput 10485760 \ --osd-bench-small-size-max-iops 10" # anything with a bs larger than 2097152 must fail expect_false ceph tell osd.0 bench 1 2097153 # but using 'osd_bench_max_bs' must succeed ceph tell osd.0 bench 1 2097152 # we assume 1MB as a large bs; anything lower is a small bs # for a 4096 bytes bs, for 10 seconds, we are limited by IOPS # max count: 409600 (bytes) # more than max count must not be allowed expect_false ceph tell osd.0 bench 409601 4096 # but 409600 must be succeed ceph tell osd.0 bench 409600 4096 # for a large bs, we are limited by throughput. # for a 2MB block size for 10 seconds, assuming 10MB/s throughput, # the max count will be (10MB * 10s) = 100MB # max count: 104857600 (bytes) # more than max count must not be allowed expect_false ceph tell osd.0 bench 104857601 2097152 # up to max count must be allowed ceph tell osd.0 bench 104857600 2097152 } function test_mon_tell() { ceph tell mon.a version ceph tell mon.b version expect_false ceph tell mon.foo version sleep 1 ceph_watch_start debug ceph tell mon.a version ceph_watch_wait 'mon.0 \[DBG\] from.*cmd=\[{"prefix": "version"}\]: dispatch' ceph_watch_start debug ceph tell mon.b version ceph_watch_wait 'mon.1 \[DBG\] from.*cmd=\[{"prefix": "version"}\]: dispatch' } # # New tests should be added to the TESTS array below # # Individual tests may be run using the '-t ' argument # The user can specify '-t ' as many times as she wants # # Tests will be run in order presented in the TESTS array, or in # the order specified by the '-t ' options. # # '-l' will list all the available test names # '-h' will show usage # # The test maintains backward compatibility: not specifying arguments # will run all tests following the order they appear in the TESTS array. # set +x MON_TESTS+=" mon_injectargs" MON_TESTS+=" mon_injectargs_SI" MON_TESTS+=" tiering" MON_TESTS+=" auth" MON_TESTS+=" auth_profiles" MON_TESTS+=" mon_misc" MON_TESTS+=" mon_mon" MON_TESTS+=" mon_osd" MON_TESTS+=" mon_osd_pool" MON_TESTS+=" mon_osd_pool_quota" MON_TESTS+=" mon_pg" MON_TESTS+=" mon_osd_pool_set" MON_TESTS+=" mon_osd_tiered_pool_set" MON_TESTS+=" mon_osd_erasure_code" MON_TESTS+=" mon_osd_misc" MON_TESTS+=" mon_heap_profiler" MON_TESTS+=" mon_tell" OSD_TESTS+=" osd_bench" MDS_TESTS+=" mds_tell" MDS_TESTS+=" mon_mds" TESTS+=$MON_TESTS TESTS+=$OSD_TESTS TESTS+=$MDS_TESTS # # "main" follows # function list_tests() { echo "AVAILABLE TESTS" for i in $TESTS; do echo " $i" done } function usage() { echo "usage: $0 [-h|-l|-t [-t ...]]" } tests_to_run=() sanity_check=true while [[ $# -gt 0 ]]; do opt=$1 case "$opt" in "-l" ) do_list=1 ;; "--asok-does-not-need-root" ) SUDO="" ;; "--no-sanity-check" ) sanity_check=false ;; "--test-mon" ) tests_to_run+="$MON_TESTS" ;; "--test-osd" ) tests_to_run+="$OSD_TESTS" ;; "--test-mds" ) tests_to_run+="$MDS_TESTS" ;; "-t" ) shift if [[ -z "$1" ]]; then echo "missing argument to '-t'" usage ; exit 1 fi tests_to_run+=" $1" ;; "-h" ) usage ; exit 0 ;; esac shift done if [[ $do_list -eq 1 ]]; then list_tests ; exit 0 fi if test -z "$tests_to_run" ; then tests_to_run="$TESTS" fi if $sanity_check ; then wait_no_osd_down fi for i in $tests_to_run; do if $sanity_check ; then check_no_osd_down fi set -x test_${i} set +x done if $sanity_check ; then check_no_osd_down fi set -x echo OK