github.com/whyrusleeping/gx@v0.14.3/tests/lib/test-lib.sh (about)

     1  # Test framework for go-ipfs
     2  #
     3  # Copyright (c) 2014 Christian Couder
     4  # MIT Licensed; see the LICENSE file in this repository.
     5  #
     6  # We are using sharness (https://github.com/mlafeldt/sharness)
     7  # which was extracted from the Git test framework.
     8  
     9  # set sharness verbosity. we set the env var directly as
    10  # it's too late to pass in --verbose, and --verbose is harder
    11  # to pass through in some cases.
    12  test "$TEST_VERBOSE" = 1 && verbose=t
    13  
    14  cwd=$(pwd)
    15  SHARNESS_LIB="lib/sharness/sharness.sh"
    16  
    17  . "$SHARNESS_LIB" || {
    18  	echo >&2 "Cannot source: $SHARNESS_LIB"
    19  	echo >&2 "Please check Sharness installation."
    20  	exit 1
    21  }
    22  
    23  # add current directory to path, for ipfs tool.
    24  # after loading sharness, so that ./bin takes precedence over ./.
    25  PATH="$cwd"/bin:${PATH}
    26  export PATH
    27  
    28  # assert the `ipfs` we're using is the right one.
    29  if test `which ipfs` != "$cwd/bin/ipfs"; then
    30  	echo >&2 "Found ipfs executable but it's not $cwd/bin/ipfs"
    31  	echo >&2 "Check PATH: $PATH"
    32  	exit 1
    33  fi
    34  
    35  # Please put go-ipfs specific shell functions below
    36  
    37  # grab + output options
    38  test "$TEST_NO_FUSE" != 1 && test_set_prereq FUSE
    39  test "$TEST_EXPENSIVE" = 1 && test_set_prereq EXPENSIVE
    40  
    41  if test "$TEST_VERBOSE" = 1; then
    42  	echo '# TEST_VERBOSE='"$TEST_VERBOSE"
    43  	echo '# TEST_NO_FUSE='"$TEST_NO_FUSE"
    44  	echo '# TEST_EXPENSIVE='"$TEST_EXPENSIVE"
    45  fi
    46  
    47  test_cmp_repeat_10_sec() {
    48  	for i in $(test_seq 1 100)
    49  	do
    50  		test_cmp "$1" "$2" >/dev/null && return
    51  		go-sleep 100ms
    52  	done
    53  	test_cmp "$1" "$2"
    54  }
    55  
    56  test_fsh() {
    57  	echo "> $@"
    58  	eval "$@"
    59  	echo ""
    60  	false
    61  }
    62  
    63  test_run_repeat_60_sec() {
    64  	for i in $(test_seq 1 600)
    65  	do
    66  		(test_eval_ "$1") && return
    67  		go-sleep 100ms
    68  	done
    69  	return 1 # failed
    70  }
    71  
    72  test_wait_output_n_lines_60_sec() {
    73  	for i in $(test_seq 1 600)
    74  	do
    75  		test $(cat "$1" | wc -l | tr -d " ") -ge $2 && return
    76  		go-sleep 100ms
    77  	done
    78  	actual=$(cat "$1" | wc -l | tr -d " ")
    79  	test_fsh "expected $2 lines of output. got $actual"
    80  }
    81  
    82  test_wait_open_tcp_port_10_sec() {
    83  	for i in $(test_seq 1 100)
    84  	do
    85  		# this is not a perfect check, but it's portable.
    86  		# cant count on ss. not installed everywhere.
    87  		# cant count on netstat using : or . as port delim. differ across platforms.
    88  		echo $(netstat -aln | egrep "^tcp.*LISTEN" | egrep "[.:]$1" | wc -l) -gt 0
    89  		if [ $(netstat -aln | egrep "^tcp.*LISTEN" | egrep "[.:]$1" | wc -l) -gt 0 ]; then
    90  			return 0
    91  		fi
    92  		go-sleep 100ms
    93  	done
    94  	return 1
    95  }
    96  
    97  
    98  # test_config_set helps us make sure _we really did set_ a config value.
    99  # it sets it and then tests it. This became elaborate because ipfs config
   100  # was setting really weird things and am not sure why.
   101  test_config_set() {
   102  
   103  	# grab flags (like --bool in "ipfs config --bool")
   104  	test_cfg_flags="" # unset in case.
   105  	test "$#" = 3 && { test_cfg_flags=$1; shift; }
   106  
   107  	test_cfg_key=$1
   108  	test_cfg_val=$2
   109  
   110  	# when verbose, tell the user what config values are being set
   111  	test_cfg_cmd="ipfs config $test_cfg_flags \"$test_cfg_key\" \"$test_cfg_val\""
   112  	test "$TEST_VERBOSE" = 1 && echo "$test_cfg_cmd"
   113  
   114  	# ok try setting the config key/val pair.
   115  	ipfs config $test_cfg_flags "$test_cfg_key" "$test_cfg_val"
   116  	echo "$test_cfg_val" >cfg_set_expected
   117  	ipfs config "$test_cfg_key" >cfg_set_actual
   118  	test_cmp cfg_set_expected cfg_set_actual
   119  }
   120  
   121  test_init_ipfs() {
   122  
   123  	# we have a problem where initializing daemons with the same api port
   124  	# often fails-- it hangs indefinitely. The proper solution is to make
   125  	# ipfs pick an unused port for the api on startup, and then use that.
   126  	# Unfortunately, ipfs doesnt yet know how to do this-- the api port
   127  	# must be specified. Until ipfs learns how to do this, we must use
   128  	# specific port numbers, which may still fail but less frequently
   129  	# if we at least use different ones.
   130  
   131  	# Using RANDOM like this is clearly wrong-- it samples with replacement
   132  	# and it doesnt even check the port is unused. this is a trivial stop gap
   133  	# until the proper solution is implemented.
   134  	RANDOM=$$
   135  	PORT_API=$((RANDOM % 3000 + 5100))
   136  	ADDR_API="/ip4/127.0.0.1/tcp/$PORT_API"
   137  
   138  	PORT_GWAY=$((RANDOM % 3000 + 8100))
   139  	ADDR_GWAY="/ip4/127.0.0.1/tcp/$PORT_GWAY"
   140  
   141  	PORT_SWARM=$((RANDOM % 3000 + 12000))
   142  	ADDR_SWARM="[
   143    \"/ip4/0.0.0.0/tcp/$PORT_SWARM\"
   144  ]"
   145  
   146  
   147  	# we set the Addresses.API config variable.
   148  	# the cli client knows to use it, so only need to set.
   149  	# todo: in the future, use env?
   150  
   151  	test_expect_success "ipfs init succeeds" '
   152  		export IPFS_PATH="$(pwd)/.ipfs" &&
   153  		ipfs init -b=1024 > /dev/null
   154  	'
   155  
   156  	test_expect_success "prepare config -- mounting and bootstrap rm" '
   157  		mkdir mountdir ipfs ipns &&
   158  		test_config_set Mounts.IPFS "$(pwd)/ipfs" &&
   159  		test_config_set Mounts.IPNS "$(pwd)/ipns" &&
   160  		test_config_set Addresses.API "$ADDR_API" &&
   161  		test_config_set Addresses.Gateway "$ADDR_GWAY" &&
   162  		test_config_set --json Addresses.Swarm "$ADDR_SWARM" &&
   163  		ipfs bootstrap rm --all ||
   164  		test_fsh cat "\"$IPFS_PATH/config\""
   165  	'
   166  
   167  }
   168  
   169  test_config_ipfs_gateway_readonly() {
   170  	ADDR_GWAY=$1
   171  	test_expect_success "prepare config -- gateway address" '
   172  		test "$ADDR_GWAY" != "" &&
   173  		test_config_set "Addresses.Gateway" "$ADDR_GWAY"
   174  	'
   175  
   176  	# tell the user what's going on if they messed up the call.
   177  	if test "$#" = 0; then
   178  		echo "#			Error: must call with an address, for example:"
   179  		echo '#			test_config_ipfs_gateway_readonly "/ip4/0.0.0.0/tcp/5002"'
   180  		echo '#'
   181  	fi
   182  }
   183  
   184  test_config_ipfs_gateway_writable() {
   185  
   186  	test_config_ipfs_gateway_readonly $1
   187  
   188  	test_expect_success "prepare config -- gateway writable" '
   189  		test_config_set --bool Gateway.Writable true ||
   190  		test_fsh cat "\"$IPFS_PATH/config\""
   191  	'
   192  }
   193  
   194  test_launch_ipfs_daemon() {
   195  
   196  	args="$@"
   197  
   198  	test_expect_success "'ipfs daemon' succeeds" '
   199  		ipfs daemon $args >actual_daemon 2>daemon_err &
   200  	'
   201  
   202  	# we say the daemon is ready when the API server is ready.
   203  	test_expect_success "'ipfs daemon' is ready" '
   204  		IPFS_PID=$! &&
   205  		pollEndpoint -ep=/version -host=$ADDR_API -v -tout=1s -tries=60 2>poll_apierr > poll_apiout ||
   206  		test_fsh cat actual_daemon || test_fsh cat daemon_err || test_fsh cat poll_apierr || test_fsh cat poll_apiout
   207  	'
   208  
   209  	if test "$ADDR_GWAY" != ""; then
   210  		test_expect_success "'ipfs daemon' output includes Gateway address" '
   211  			pollEndpoint -ep=/version -host=$ADDR_GWAY -v -tout=1s -tries=60 2>poll_gwerr > poll_gwout ||
   212  			test_fsh cat daemon_err || test_fsh cat poll_gwerr || test_fsh cat poll_gwout
   213  		'
   214  	fi
   215  }
   216  
   217  test_mount_ipfs() {
   218  
   219  	# make sure stuff is unmounted first.
   220  	test_expect_success FUSE "'ipfs mount' succeeds" '
   221  		umount "$(pwd)/ipfs" || true &&
   222  		umount "$(pwd)/ipns" || true &&
   223  		ipfs mount >actual
   224  	'
   225  
   226  	test_expect_success FUSE "'ipfs mount' output looks good" '
   227  		echo "IPFS mounted at: $(pwd)/ipfs" >expected &&
   228  		echo "IPNS mounted at: $(pwd)/ipns" >>expected &&
   229  		test_cmp expected actual
   230  	'
   231  
   232  }
   233  
   234  test_launch_ipfs_daemon_and_mount() {
   235  
   236  	test_init_ipfs
   237  	test_launch_ipfs_daemon
   238  	test_mount_ipfs
   239  
   240  }
   241  
   242  test_kill_repeat_10_sec() {
   243  	# try to shut down once + wait for graceful exit
   244  	kill $1
   245  	for i in $(test_seq 1 100)
   246  	do
   247  		go-sleep 100ms
   248  		! kill -0 $1 2>/dev/null && return
   249  	done
   250  
   251  	# if not, try once more, which will skip graceful exit
   252  	kill $1
   253  	go-sleep 1s
   254  	! kill -0 $1 2>/dev/null && return
   255  
   256  	# ok, no hope. kill it to prevent it messing with other tests
   257  	kill -9 $1 2>/dev/null
   258  	return 1
   259  }
   260  
   261  test_kill_ipfs_daemon() {
   262  
   263  	test_expect_success "'ipfs daemon' is still running" '
   264  		kill -0 $IPFS_PID
   265  	'
   266  
   267  	test_expect_success "'ipfs daemon' can be killed" '
   268  		test_kill_repeat_10_sec $IPFS_PID
   269  	'
   270  }
   271  
   272  test_curl_resp_http_code() {
   273  	curl -I "$1" >curl_output || {
   274  		echo "curl error with url: '$1'"
   275  		echo "curl output was:"
   276  		cat curl_output
   277  		return 1
   278  	}
   279  	shift &&
   280  	RESP=$(head -1 curl_output) &&
   281  	while test "$#" -gt 0
   282  	do
   283  		expr "$RESP" : "$1" >/dev/null && return
   284  		shift
   285  	done
   286  	echo "curl response didn't match!"
   287  	echo "curl response was: '$RESP'"
   288  	echo "curl output was:"
   289  	cat curl_output
   290  	return 1
   291  }
   292  
   293  test_must_be_empty() {
   294  	if test -s "$1"
   295  	then
   296  		echo "'$1' is not empty, it contains:"
   297  		cat "$1"
   298  		return 1
   299  	fi
   300  }
   301  
   302  test_should_contain() {
   303  	test "$#" = 2 || error "bug in the test script: not 2 parameters to test_should_contain"
   304  	if ! grep -q "$1" "$2"
   305  	then
   306  		echo "'$2' does not contain '$1', it contains:"
   307  		cat "$2"
   308  		return 1
   309  	fi
   310  }
   311  
   312  test_str_contains() {
   313  	find=$1
   314  	shift
   315  	echo "$@" | grep "$find" >/dev/null
   316  }
   317  
   318  disk_usage() {
   319      # normalize du across systems
   320      case $(uname -s) in
   321          Linux)
   322              DU="du -sb"
   323              ;;
   324          FreeBSD)
   325              DU="du -s -A -B 1"
   326              ;;
   327          Darwin | DragonFly)
   328              DU="du"
   329              ;;
   330      esac
   331          $DU "$1" | awk "{print \$1}"
   332  }
   333  
   334  # output a file's permission in human readable format
   335  generic_stat() {
   336      # normalize stat across systems
   337      case $(uname -s) in
   338          Linux)
   339              _STAT="stat -c %A"
   340              ;;
   341          FreeBSD | Darwin | DragonFly)
   342              _STAT="stat -f %Sp"
   343              ;;
   344      esac
   345      $_STAT "$1"
   346  }
   347  
   348  test_check_peerid() {
   349  	peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
   350  	test "$peeridlen" = "46" || {
   351  		echo "Bad peerid '$1' with len '$peeridlen'"
   352  		return 1
   353  	}
   354  }
   355  
   356  
   357  make_package() {
   358  	dir=$1
   359  	lang=$2
   360  	mkdir -p $dir
   361  	test_expect_success "gx init succeeds" '
   362  		(cd $dir && gx init --lang="$lang")
   363  	'
   364  }
   365  
   366  publish_package() {
   367  	pkgdir=$1
   368  	(cd $pkgdir && gx publish) | awk '{ print $6 }'
   369  }
   370  
   371  pkg_run() {
   372  	dir=$1
   373  	shift
   374  	(cd $dir && $@)
   375  }