From 98b2d3427abaff6c2d1c96a5ae144cd40a22cdae Mon Sep 17 00:00:00 2001 From: Paul Weil Date: Wed, 6 Apr 2016 12:14:28 -0400 Subject: [PATCH] add basic building and testing scripts moving to ii/II namespace --- .gitignore | 1 + .travis.yml | 17 +++ Makefile | 57 ++++++++ hack/build-go.sh | 17 +++ hack/cmd_util.sh | 264 +++++++++++++++++------------------ hack/common.sh | 85 +++++++++++ hack/install-tools.sh | 12 ++ hack/lib/util/environment.sh | 30 ++-- hack/test-end-to-end.sh | 10 +- hack/test-go.sh | 131 +++++++++++++++++ hack/text.sh | 108 +++++++------- hack/util.sh | 36 ++--- hack/verify-gofmt.sh | 29 ++++ test/end-to-end/e2e.sh | 26 ++-- 14 files changed, 586 insertions(+), 237 deletions(-) create mode 100644 .travis.yml create mode 100644 Makefile create mode 100755 hack/build-go.sh create mode 100755 hack/common.sh create mode 100755 hack/install-tools.sh create mode 100755 hack/test-go.sh create mode 100755 hack/verify-gofmt.sh diff --git a/.gitignore b/.gitignore index b19d855..6311a84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/_output image-inspector *.a *.swp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5c37357 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +language: go + +go: + - 1.5.3 + - 1.6 + +install: + - export PATH=$GOPATH/bin:./_tools/etcd/bin:$PATH + - make install-travis + +script: + - make verify test-unit + +notifications: + irc: "chat.freenode.net#openshift-dev" + +sudo: false diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e99f86e --- /dev/null +++ b/Makefile @@ -0,0 +1,57 @@ +# Old-skool build tools. +# +# Targets (see each target for more information): +# all: Build code. +# build: Build code. +# test-unit: Run unit tests. +# clean: Clean up. + +OUT_DIR = _output +OUT_PKG_DIR = Godeps/_workspace/pkg + +# Build code. +# +# Example: +# make +# make all +all build: + hack/build-go.sh +.PHONY: all build + +# Remove all build artifacts. +# +# Example: +# make clean +clean: + rm -rf $(OUT_DIR) $(OUT_PKG_DIR) +.PHONY: clean + +# Verify code conventions are properly setup. +# +# Example: +# make verify +verify: build + hack/verify-gofmt.sh +.PHONY: verify + +# Run unit tests. +# +# Args: +# WHAT: Directory names to test. All *_test.go files under these +# directories will be run. If not specified, "everything" will be tested. +# TESTS: Same as WHAT. +# GOFLAGS: Extra flags to pass to 'go' when building. +# TESTFLAGS: Extra flags that should only be passed to hack/test-go.sh +# +# Example: +# make test-unit +# make test-unit WHAT=pkg/build GOFLAGS=-v +test-unit: + GOTEST_FLAGS="$(TESTFLAGS)" hack/test-go.sh $(WHAT) $(TESTS) +.PHONY: test-unit + +# Install travis dependencies +# +install-travis: + hack/install-tools.sh +.PHONY: install-travis diff --git a/hack/build-go.sh b/hack/build-go.sh new file mode 100755 index 0000000..dbdb317 --- /dev/null +++ b/hack/build-go.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# This script sets up a go workspace locally and builds all go components. + +set -o errexit +set -o nounset +set -o pipefail + +STARTTIME=$(date +%s) +CODE_ROOT=$(dirname "${BASH_SOURCE}")/.. +source "${CODE_ROOT}/hack/util.sh" +source "${CODE_ROOT}/hack/common.sh" +ii::log::install_errexit + +ii::build::build_binaries "$@" + +ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret" diff --git a/hack/cmd_util.sh b/hack/cmd_util.sh index cfcf475..cea2d60 100644 --- a/hack/cmd_util.sh +++ b/hack/cmd_util.sh @@ -5,137 +5,137 @@ # This utility file contains functions that wrap commands to be tested. All wrapper functions run commands # in a sub-shell and redirect all output. Tests in test-cmd *must* use these functions for testing. -# We assume ${OS_ROOT} is set -source "${OS_ROOT}/hack/text.sh" -source "${OS_ROOT}/hack/util.sh" +# We assume ${II_ROOT} is set +source "${II_ROOT}/hack/text.sh" +source "${II_ROOT}/hack/util.sh" # expect_success runs the cmd and expects an exit code of 0 -function os::cmd::expect_success() { - if [[ $# -ne 1 ]]; then echo "os::cmd::expect_success expects only one argument, got $#"; exit 1; fi +function ii::cmd::expect_success() { + if [[ $# -ne 1 ]]; then echo "ii::cmd::expect_success expects only one argument, got $#"; exit 1; fi local cmd=$1 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" } # expect_failure runs the cmd and expects a non-zero exit code -function os::cmd::expect_failure() { - if [[ $# -ne 1 ]]; then echo "os::cmd::expect_failure expects only one argument, got $#"; exit 1; fi +function ii::cmd::expect_failure() { + if [[ $# -ne 1 ]]; then echo "ii::cmd::expect_failure expects only one argument, got $#"; exit 1; fi local cmd=$1 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::failure_func" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::failure_func" } # expect_success_and_text runs the cmd and expects an exit code of 0 # as well as running a grep test to find the given string in the output -function os::cmd::expect_success_and_text() { - if [[ $# -ne 2 ]]; then echo "os::cmd::expect_success_and_text expects two arguments, got $#"; exit 1; fi +function ii::cmd::expect_success_and_text() { + if [[ $# -ne 2 ]]; then echo "ii::cmd::expect_success_and_text expects two arguments, got $#"; exit 1; fi local cmd=$1 local expected_text=$2 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::success_func" "${expected_text}" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::success_func" "${expected_text}" } # expect_failure_and_text runs the cmd and expects a non-zero exit code # as well as running a grep test to find the given string in the output -function os::cmd::expect_failure_and_text() { - if [[ $# -ne 2 ]]; then echo "os::cmd::expect_failure_and_text expects two arguments, got $#"; exit 1; fi +function ii::cmd::expect_failure_and_text() { + if [[ $# -ne 2 ]]; then echo "ii::cmd::expect_failure_and_text expects two arguments, got $#"; exit 1; fi local cmd=$1 local expected_text=$2 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::failure_func" "${expected_text}" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::failure_func" "${expected_text}" } # expect_success_and_not_text runs the cmd and expects an exit code of 0 # as well as running a grep test to ensure the given string is not in the output -function os::cmd::expect_success_and_not_text() { - if [[ $# -ne 2 ]]; then echo "os::cmd::expect_success_and_not_text expects two arguments, got $#"; exit 1; fi +function ii::cmd::expect_success_and_not_text() { + if [[ $# -ne 2 ]]; then echo "ii::cmd::expect_success_and_not_text expects two arguments, got $#"; exit 1; fi local cmd=$1 local expected_text=$2 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::success_func" "${expected_text}" "os::cmd::internal::failure_func" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::success_func" "${expected_text}" "ii::cmd::internal::failure_func" } # expect_failure_and_not_text runs the cmd and expects a non-zero exit code # as well as running a grep test to ensure the given string is not in the output -function os::cmd::expect_failure_and_not_text() { - if [[ $# -ne 2 ]]; then echo "os::cmd::expect_failure_and_not_text expects two arguments, got $#"; exit 1; fi +function ii::cmd::expect_failure_and_not_text() { + if [[ $# -ne 2 ]]; then echo "ii::cmd::expect_failure_and_not_text expects two arguments, got $#"; exit 1; fi local cmd=$1 local expected_text=$2 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::failure_func" "${expected_text}" "os::cmd::internal::failure_func" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::failure_func" "${expected_text}" "ii::cmd::internal::failure_func" } # expect_code runs the cmd and expects a given exit code -function os::cmd::expect_code() { - if [[ $# -ne 2 ]]; then echo "os::cmd::expect_code expects two arguments, got $#"; exit 1; fi +function ii::cmd::expect_code() { + if [[ $# -ne 2 ]]; then echo "ii::cmd::expect_code expects two arguments, got $#"; exit 1; fi local cmd=$1 local expected_cmd_code=$2 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::specific_code_func ${expected_cmd_code}" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::specific_code_func ${expected_cmd_code}" } # expect_code_and_text runs the cmd and expects the given exit code # as well as running a grep test to find the given string in the output -function os::cmd::expect_code_and_text() { - if [[ $# -ne 3 ]]; then echo "os::cmd::expect_code_and_text expects three arguments, got $#"; exit 1; fi +function ii::cmd::expect_code_and_text() { + if [[ $# -ne 3 ]]; then echo "ii::cmd::expect_code_and_text expects three arguments, got $#"; exit 1; fi local cmd=$1 local expected_cmd_code=$2 local expected_text=$3 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::specific_code_func ${expected_cmd_code}" "${expected_text}" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::specific_code_func ${expected_cmd_code}" "${expected_text}" } # expect_code_and_not_text runs the cmd and expects the given exit code # as well as running a grep test to ensure the given string is not in the output -function os::cmd::expect_code_and_not_text() { - if [[ $# -ne 3 ]]; then echo "os::cmd::expect_code_and_not_text expects three arguments, got $#"; exit 1; fi +function ii::cmd::expect_code_and_not_text() { + if [[ $# -ne 3 ]]; then echo "ii::cmd::expect_code_and_not_text expects three arguments, got $#"; exit 1; fi local cmd=$1 local expected_cmd_code=$2 local expected_text=$3 - os::cmd::internal::expect_exit_code_run_grep "${cmd}" "os::cmd::internal::specific_code_func ${expected_cmd_code}" "${expected_text}" "os::cmd::internal::failure_func" + ii::cmd::internal::expect_exit_code_run_grep "${cmd}" "ii::cmd::internal::specific_code_func ${expected_cmd_code}" "${expected_text}" "ii::cmd::internal::failure_func" } millisecond=1 second=$(( 1000 * millisecond )) minute=$(( 60 * second )) -# os::cmd::try_until_success runs the cmd in a small interval until either the command succeeds or times out -# the default time-out for os::cmd::try_until_success is 60 seconds. -# the default interval for os::cmd::try_until_success is 200ms -function os::cmd::try_until_success() { - if [[ $# -lt 1 ]]; then echo "os::cmd::try_until_success expects at least one arguments, got $#"; exit 1; fi +# ii::cmd::try_until_success runs the cmd in a small interval until either the command succeeds or times out +# the default time-out for ii::cmd::try_until_success is 60 seconds. +# the default interval for ii::cmd::try_until_success is 200ms +function ii::cmd::try_until_success() { + if [[ $# -lt 1 ]]; then echo "ii::cmd::try_until_success expects at least one arguments, got $#"; exit 1; fi local cmd=$1 local duration=${2:-minute} local interval=${3:-0.2} - os::cmd::internal::run_until_exit_code "${cmd}" "os::cmd::internal::success_func" "${duration}" "${interval}" + ii::cmd::internal::run_until_exit_code "${cmd}" "ii::cmd::internal::success_func" "${duration}" "${interval}" } -# os::cmd::try_until_failure runs the cmd until either the command fails or times out -# the default time-out for os::cmd::try_until_failure is 60 seconds. -function os::cmd::try_until_failure() { - if [[ $# -lt 1 ]]; then echo "os::cmd::try_until_success expects at least one argument, got $#"; exit 1; fi +# ii::cmd::try_until_failure runs the cmd until either the command fails or times out +# the default time-out for ii::cmd::try_until_failure is 60 seconds. +function ii::cmd::try_until_failure() { + if [[ $# -lt 1 ]]; then echo "ii::cmd::try_until_success expects at least one argument, got $#"; exit 1; fi local cmd=$1 local duration=${2:-$minute} local interval=${3:-0.2} - os::cmd::internal::run_until_exit_code "${cmd}" "os::cmd::internal::failure_func" "${duration}" "${interval}" + ii::cmd::internal::run_until_exit_code "${cmd}" "ii::cmd::internal::failure_func" "${duration}" "${interval}" } -# os::cmd::try_until_text runs the cmd until either the command outputs the desired text or times out -# the default time-out for os::cmd::try_until_text is 60 seconds. -function os::cmd::try_until_text() { - if [[ $# -lt 2 ]]; then echo "os::cmd::try_until_success expects at least two arguments, got $#"; exit 1; fi +# ii::cmd::try_until_text runs the cmd until either the command outputs the desired text or times out +# the default time-out for ii::cmd::try_until_text is 60 seconds. +function ii::cmd::try_until_text() { + if [[ $# -lt 2 ]]; then echo "ii::cmd::try_until_success expects at least two arguments, got $#"; exit 1; fi local cmd=$1 local text=$2 local duration=${3:-minute} local interval=${4:-0.2} - os::cmd::internal::run_until_text "${cmd}" "${text}" "${duration}" "${interval}" + ii::cmd::internal::run_until_text "${cmd}" "${text}" "${duration}" "${interval}" } -# Functions in the os::cmd::internal namespace are discouraged from being used outside of os::cmd +# Functions in the ii::cmd::internal namespace are discouraged from being used outside of ii::cmd # In order to harvest stderr and stdout at the same time into different buckets, we need to stick them into files # in an intermediate step @@ -144,7 +144,7 @@ os_cmd_internal_tmpdir="${BASETMPDIR}/test-cmd" os_cmd_internal_tmpout="${os_cmd_internal_tmpdir}/tmp_stdout.log" os_cmd_internal_tmperr="${os_cmd_internal_tmpdir}/tmp_stderr.log" -# os::cmd::internal::expect_exit_code_run_grep runs the provided test command and expects a specific +# ii::cmd::internal::expect_exit_code_run_grep runs the provided test command and expects a specific # exit code from that command as well as the success of a specified `grep` invocation. Output from the # command to be tested is suppressed unless either `VERBOSE=1` or the test fails. This function bypasses # any error exiting settings or traps set by upstream callers by masking the return code of the command @@ -160,53 +160,53 @@ os_cmd_internal_tmperr="${os_cmd_internal_tmpdir}/tmp_stderr.log" # Returns: # - 0: if all assertions met # - 1: if any assertions fail -function os::cmd::internal::expect_exit_code_run_grep() { +function ii::cmd::internal::expect_exit_code_run_grep() { local cmd=$1 # default expected cmd code to 0 for success - local cmd_eval_func=${2:-os::cmd::internal::success_func} + local cmd_eval_func=${2:-ii::cmd::internal::success_func} # default to nothing local grep_args=${3:-} # default expected test code to 0 for success - local test_eval_func=${4:-os::cmd::internal::success_func} + local test_eval_func=${4:-ii::cmd::internal::success_func} - os::cmd::internal::init_tempdir + ii::cmd::internal::init_tempdir - local name=$(os::cmd::internal::describe_call "${cmd}" "${cmd_eval_func}" "${grep_args}" "${test_eval_func}") + local name=$(ii::cmd::internal::describe_call "${cmd}" "${cmd_eval_func}" "${grep_args}" "${test_eval_func}") echo "Running ${name}..." - local start_time=$(os::cmd::internal::seconds_since_epoch) + local start_time=$(ii::cmd::internal::seconds_since_epoch) - local cmd_result=$( os::cmd::internal::run_collecting_output "${cmd}"; echo $? ) + local cmd_result=$( ii::cmd::internal::run_collecting_output "${cmd}"; echo $? ) local cmd_succeeded=$( ${cmd_eval_func} "${cmd_result}"; echo $? ) local test_result=0 if [[ -n "${grep_args}" ]]; then - test_result=$( os::cmd::internal::run_collecting_output 'os::cmd::internal::get_results | grep -Eq "${grep_args}"'; echo $? ) + test_result=$( ii::cmd::internal::run_collecting_output 'ii::cmd::internal::get_results | grep -Eq "${grep_args}"'; echo $? ) fi local test_succeeded=$( ${test_eval_func} "${test_result}"; echo $? ) - local end_time=$(os::cmd::internal::seconds_since_epoch) + local end_time=$(ii::cmd::internal::seconds_since_epoch) local time_elapsed=$(echo "scale=3; ${end_time} - ${start_time}" | bc | xargs printf '%5.3f') # in decimal seconds, we need leading zeroes for parsing later # some commands are multi-line, so we may need to clear more than just the previous line local cmd_length=$(echo "${cmd}" | wc -l) for (( i=0; i<${cmd_length}; i++ )); do - os::text::clear_last_line + ii::text::clear_last_line done local return_code if (( cmd_succeeded && test_succeeded )); then - os::text::print_green "SUCCESS after ${time_elapsed}s: ${name}" + ii::text::print_green "SUCCESS after ${time_elapsed}s: ${name}" if [[ -n ${VERBOSE-} ]]; then - os::cmd::internal::print_results + ii::cmd::internal::print_results fi return_code=0 else - local cause=$(os::cmd::internal::assemble_causes "${cmd_succeeded}" "${test_succeeded}") + local cause=$(ii::cmd::internal::assemble_causes "${cmd_succeeded}" "${test_succeeded}") - os::text::print_red_bold "FAILURE after ${time_elapsed}s: ${name}: ${cause}" - os::text::print_red "$(os::cmd::internal::print_results)" + ii::text::print_red_bold "FAILURE after ${time_elapsed}s: ${name}: ${cause}" + ii::text::print_red "$(ii::cmd::internal::print_results)" return_code=1 fi @@ -215,33 +215,33 @@ function os::cmd::internal::expect_exit_code_run_grep() { } -# os::cmd::internal::init_tempdir initializes the temporary directory -function os::cmd::internal::init_tempdir() { +# ii::cmd::internal::init_tempdir initializes the temporary directory +function ii::cmd::internal::init_tempdir() { mkdir -p "${os_cmd_internal_tmpdir}" rm -f "${os_cmd_internal_tmpdir}"/tmp_std{out,err}.log } -# os::cmd::internal::describe_call determines the file:line of the latest function call made +# ii::cmd::internal::describe_call determines the file:line of the latest function call made # from outside of this file in the call stack, and the name of the function being called from # that line, returning a string describing the call -function os::cmd::internal::describe_call() { +function ii::cmd::internal::describe_call() { local cmd=$1 local cmd_eval_func=$2 local grep_args=${3:-} local test_eval_func=${4:-} - local caller_id=$(os::cmd::internal::determine_caller) + local caller_id=$(ii::cmd::internal::determine_caller) local full_name="${caller_id}: executing '${cmd}'" - local cmd_expectation=$(os::cmd::internal::describe_expectation "${cmd_eval_func}") + local cmd_expectation=$(ii::cmd::internal::describe_expectation "${cmd_eval_func}") local full_name="${full_name} expecting ${cmd_expectation}" if [[ -n "${grep_args}" ]]; then local text_expecting= case "${test_eval_func}" in - "os::cmd::internal::success_func") + "ii::cmd::internal::success_func") text_expecting="text" ;; - "os::cmd::internal::failure_func") + "ii::cmd::internal::failure_func") text_expecting="not text" ;; esac full_name="${full_name} and ${text_expecting} '${grep_args}'" @@ -250,9 +250,9 @@ function os::cmd::internal::describe_call() { echo "${full_name}" } -# os::cmd::internal::determine_caller determines the file relative to the OpenShift Origin root directory -# and line number of the function call to the outer os::cmd wrapper function -function os::cmd::internal::determine_caller() { +# ii::cmd::internal::determine_caller determines the file relative to the OpenShift Origin root directory +# and line number of the function call to the outer ii::cmd wrapper function +function ii::cmd::internal::determine_caller() { local call_depth= local len_sources="${#BASH_SOURCE[@]}" for (( i=0; i<${len_sources}; i++ )); do @@ -274,15 +274,15 @@ function os::cmd::internal::determine_caller() { echo "${caller_file}:${caller_line}" } -# os::cmd::internal::describe_expectation describes a command return code evaluation function -function os::cmd::internal::describe_expectation() { +# ii::cmd::internal::describe_expectation describes a command return code evaluation function +function ii::cmd::internal::describe_expectation() { local func=$1 case "${func}" in - "os::cmd::internal::success_func") + "ii::cmd::internal::success_func") echo "success" ;; - "os::cmd::internal::failure_func") + "ii::cmd::internal::failure_func") echo "failure" ;; - "os::cmd::internal::specific_code_func"*[0-9]) + "ii::cmd::internal::specific_code_func"*[0-9]) local code=$(echo "${func}" | grep -Eo "[0-9]+$") echo "exit code ${code}" ;; "") @@ -290,9 +290,9 @@ function os::cmd::internal::describe_expectation() { esac } -# os::cmd::internal::seconds_since_epoch returns the number of seconds elapsed since the epoch +# ii::cmd::internal::seconds_since_epoch returns the number of seconds elapsed since the epoch # with milli-second precision -function os::cmd::internal::seconds_since_epoch() { +function ii::cmd::internal::seconds_since_epoch() { local ns=$(date +%s%N) # if `date` doesn't support nanoseconds, return second precision if [[ "$ns" == *N ]]; then @@ -302,9 +302,9 @@ function os::cmd::internal::seconds_since_epoch() { echo $(bc <<< "scale=3; ${ns}/1000000000") } -# os::cmd::internal::run_collecting_output runs the command given, piping stdout and stderr into +# ii::cmd::internal::run_collecting_output runs the command given, piping stdout and stderr into # the given files, and returning the exit code of the command -function os::cmd::internal::run_collecting_output() { +function ii::cmd::internal::run_collecting_output() { local cmd=$1 local result= @@ -314,9 +314,9 @@ function os::cmd::internal::run_collecting_output() { return "${result}" } -# os::cmd::internal::success_func determines if the input exit code denotes success +# ii::cmd::internal::success_func determines if the input exit code denotes success # this function returns 0 for false and 1 for true to be compatible with arithmetic tests -function os::cmd::internal::success_func() { +function ii::cmd::internal::success_func() { local exit_code=$1 # use a negated test to get output correct for (( )) @@ -324,9 +324,9 @@ function os::cmd::internal::success_func() { return $? } -# os::cmd::internal::failure_func determines if the input exit code denotes failure +# ii::cmd::internal::failure_func determines if the input exit code denotes failure # this function returns 0 for false and 1 for true to be compatible with arithmetic tests -function os::cmd::internal::failure_func() { +function ii::cmd::internal::failure_func() { local exit_code=$1 # use a negated test to get output correct for (( )) @@ -334,9 +334,9 @@ function os::cmd::internal::failure_func() { return $? } -# os::cmd::internal::specific_code_func determines if the input exit code matches the given code +# ii::cmd::internal::specific_code_func determines if the input exit code matches the given code # this function returns 0 for false and 1 for true to be compatible with arithmetic tests -function os::cmd::internal::specific_code_func() { +function ii::cmd::internal::specific_code_func() { local expected_code=$1 local exit_code=$2 @@ -345,45 +345,45 @@ function os::cmd::internal::specific_code_func() { return $? } -# os::cmd::internal::get_results prints the stderr and stdout files -function os::cmd::internal::get_results() { +# ii::cmd::internal::get_results prints the stderr and stdout files +function ii::cmd::internal::get_results() { cat "${os_cmd_internal_tmpout}" "${os_cmd_internal_tmperr}" } -# os::cmd::internal::get_try_until_results returns a concise view of the stdout and stderr output files +# ii::cmd::internal::get_try_until_results returns a concise view of the stdout and stderr output files # using a timeline format, where consecutive output lines that are the same are condensed into one line # with a counter -function os::cmd::internal::print_try_until_results() { +function ii::cmd::internal::print_try_until_results() { if grep -vq $'\x1e' "${os_cmd_internal_tmpout}"; then echo "Standard output from the command:" - os::cmd::internal::compress_output "${os_cmd_internal_tmpout}" + ii::cmd::internal::compress_output "${os_cmd_internal_tmpout}" else echo "There was no output from the command." fi if grep -vq $'\x1e' "${os_cmd_internal_tmperr}"; then echo "Standard error from the command:" - os::cmd::internal::compress_output "${os_cmd_internal_tmperr}" + ii::cmd::internal::compress_output "${os_cmd_internal_tmperr}" else echo "There was no error output from the command." fi } -# os::cmd::internal::mark_attempt marks the end of an attempt in the stdout and stderr log files +# ii::cmd::internal::mark_attempt marks the end of an attempt in the stdout and stderr log files # this is used to make the try_until_* output more concise -function os::cmd::internal::mark_attempt() { +function ii::cmd::internal::mark_attempt() { echo -e '\x1e' >> "${os_cmd_internal_tmpout}" | tee "${os_cmd_internal_tmperr}" } -# os::cmd::internal::compress_output compresses an output file into timeline representation -function os::cmd::internal::compress_output() { +# ii::cmd::internal::compress_output compresses an output file into timeline representation +function ii::cmd::internal::compress_output() { local logfile=$1 - awk -f ${OS_ROOT}/hack/compress.awk $logfile + awk -f ${II_ROOT}/hack/compress.awk $logfile } -# os::cmd::internal::print_results pretty-prints the stderr and stdout files -function os::cmd::internal::print_results() { +# ii::cmd::internal::print_results pretty-prints the stderr and stdout files +function ii::cmd::internal::print_results() { if [[ -s "${os_cmd_internal_tmpout}" ]]; then echo "Standard output from the command:" cat "${os_cmd_internal_tmpout}"; echo @@ -399,9 +399,9 @@ function os::cmd::internal::print_results() { fi } -# os::cmd::internal::assemble_causes determines from the two input booleans which part of the test +# ii::cmd::internal::assemble_causes determines from the two input booleans which part of the test # failed and generates a nice delimited list of failure causes -function os::cmd::internal::assemble_causes() { +function ii::cmd::internal::assemble_causes() { local cmd_succeeded=$1 local test_succeeded=$2 @@ -418,7 +418,7 @@ function os::cmd::internal::assemble_causes() { } -# os::cmd::internal::run_until_exit_code runs the provided command until the exit code test given +# ii::cmd::internal::run_until_exit_code runs the provided command until the exit code test given # succeeds or the timeout given runs out. Output from the command to be tested is suppressed unless # either `VERBOSE=1` or the test fails. This function bypasses any error exiting settings or traps # set by upstream callers by masking the return code of the command with the return code of setting @@ -434,61 +434,61 @@ function os::cmd::internal::assemble_causes() { # Returns: # - 0: if all assertions met before timeout # - 1: if timeout occurs -function os::cmd::internal::run_until_exit_code() { +function ii::cmd::internal::run_until_exit_code() { local cmd=$1 local cmd_eval_func=$2 local duration=$3 local interval=$4 - os::cmd::internal::init_tempdir + ii::cmd::internal::init_tempdir - local description=$(os::cmd::internal::describe_call "${cmd}" "${cmd_eval_func}") + local description=$(ii::cmd::internal::describe_call "${cmd}" "${cmd_eval_func}") local duration_seconds=$(echo "scale=3; $(( duration )) / 1000" | bc | xargs printf '%5.3f') local description="${description}; re-trying every ${interval}s until completion or ${duration_seconds}s" echo "Running ${description}..." - local start_time=$(os::cmd::internal::seconds_since_epoch) + local start_time=$(ii::cmd::internal::seconds_since_epoch) local deadline=$(( $(date +%s000) + $duration )) local cmd_succeeded=0 while [ $(date +%s000) -lt $deadline ]; do - local cmd_result=$( os::cmd::internal::run_collecting_output "${cmd}"; echo $? ) + local cmd_result=$( ii::cmd::internal::run_collecting_output "${cmd}"; echo $? ) cmd_succeeded=$( ${cmd_eval_func} "${cmd_result}"; echo $? ) if (( cmd_succeeded )); then break fi sleep "${interval}" - os::cmd::internal::mark_attempt + ii::cmd::internal::mark_attempt done - local end_time=$(os::cmd::internal::seconds_since_epoch) + local end_time=$(ii::cmd::internal::seconds_since_epoch) local time_elapsed=$(echo "scale=9; ${end_time} - ${start_time}" | bc | xargs printf '%5.3f') # in decimal seconds, we need leading zeroes for parsing later # some commands are multi-line, so we may need to clear more than just the previous line local cmd_length=$(echo "${cmd}" | wc -l) for (( i=0; i<${cmd_length}; i++ )); do - os::text::clear_last_line + ii::text::clear_last_line done local return_code if (( cmd_succeeded )); then - os::text::print_green "SUCCESS after ${time_elapsed}s: ${description}" + ii::text::print_green "SUCCESS after ${time_elapsed}s: ${description}" if [[ -n ${VERBOSE-} ]]; then - os::cmd::internal::print_try_until_results + ii::cmd::internal::print_try_until_results fi return_code=0 else - os::text::print_red_bold "FAILURE after ${time_elapsed}s: ${description}: the command timed out" + ii::text::print_red_bold "FAILURE after ${time_elapsed}s: ${description}: the command timed out" - os::text::print_red "$(os::cmd::internal::print_try_until_results)" + ii::text::print_red "$(ii::cmd::internal::print_try_until_results)" return_code=1 fi return "${return_code}" } -# os::cmd::internal::run_until_text runs the provided command until the command output contains the +# ii::cmd::internal::run_until_text runs the provided command until the command output contains the # given text or the timeout given runs out. Output from the command to be tested is suppressed unless # either `VERBOSE=1` or the test fails. This function bypasses any error exiting settings or traps # set by upstream callers by masking the return code of the command with the return code of setting @@ -504,56 +504,56 @@ function os::cmd::internal::run_until_exit_code() { # Returns: # - 0: if all assertions met before timeout # - 1: if timeout occurs -function os::cmd::internal::run_until_text() { +function ii::cmd::internal::run_until_text() { local cmd=$1 local text=$2 local duration=$3 local interval=$4 - os::cmd::internal::init_tempdir + ii::cmd::internal::init_tempdir - local description=$(os::cmd::internal::describe_call "${cmd}" "" "${text}" "os::cmd::internal::success_func") + local description=$(ii::cmd::internal::describe_call "${cmd}" "" "${text}" "ii::cmd::internal::success_func") local duration_seconds=$(echo "scale=3; $(( duration )) / 1000" | bc | xargs printf '%5.3f') local description="${description}; re-trying every ${interval}s until completion or ${duration_seconds}s" echo "Running ${description}..." - local start_time=$(os::cmd::internal::seconds_since_epoch) + local start_time=$(ii::cmd::internal::seconds_since_epoch) local deadline=$(( $(date +%s000) + $duration )) local test_succeeded=0 while [ $(date +%s000) -lt $deadline ]; do - local cmd_result=$( os::cmd::internal::run_collecting_output "${cmd}"; echo $? ) - local test_result=$( os::cmd::internal::run_collecting_output 'os::cmd::internal::get_results | grep -Eq "${text}"'; echo $? ) - test_succeeded=$( os::cmd::internal::success_func "${test_result}"; echo $? ) + local cmd_result=$( ii::cmd::internal::run_collecting_output "${cmd}"; echo $? ) + local test_result=$( ii::cmd::internal::run_collecting_output 'ii::cmd::internal::get_results | grep -Eq "${text}"'; echo $? ) + test_succeeded=$( ii::cmd::internal::success_func "${test_result}"; echo $? ) if (( test_succeeded )); then break fi sleep "${interval}" - os::cmd::internal::mark_attempt + ii::cmd::internal::mark_attempt done - local end_time=$(os::cmd::internal::seconds_since_epoch) + local end_time=$(ii::cmd::internal::seconds_since_epoch) local time_elapsed=$(echo "scale=9; ${end_time} - ${start_time}" | bc | xargs printf '%5.3f') # in decimal seconds, we need leading zeroes for parsing later # some commands are multi-line, so we may need to clear more than just the previous line local cmd_length=$(echo "${cmd}" | wc -l) for (( i=0; i<${cmd_length}; i++ )); do - os::text::clear_last_line + ii::text::clear_last_line done local return_code if (( test_succeeded )); then - os::text::print_green "SUCCESS after ${time_elapsed}s: ${description}" + ii::text::print_green "SUCCESS after ${time_elapsed}s: ${description}" if [[ -n ${VERBOSE-} ]]; then - os::cmd::internal::print_try_until_results + ii::cmd::internal::print_try_until_results fi return_code=0 else - os::text::print_red_bold "FAILURE after ${time_elapsed}s: ${description}: the command timed out" + ii::text::print_red_bold "FAILURE after ${time_elapsed}s: ${description}: the command timed out" - os::text::print_red "$(os::cmd::internal::print_try_until_results)" + ii::text::print_red "$(ii::cmd::internal::print_try_until_results)" return_code=1 fi diff --git a/hack/common.sh b/hack/common.sh new file mode 100755 index 0000000..6a16f9b --- /dev/null +++ b/hack/common.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# The root of the build/dist directory +readonly II_ROOT=$( + unset CDPATH + ii_root=$(dirname "${BASH_SOURCE}")/.. + + cd "${ii_root}" + ii_root=`pwd` + if [ -h "${ii_root}" ]; then + readlink "${ii_root}" + else + pwd + fi +) + +readonly II_GOPATH=$( + unset CDPATH + cd ${II_ROOT}/../../../.. + pwd +) + +readonly II_GO_PACKAGE=github.com/openshift/image-inspector +readonly II_OUTPUT_SUBPATH="${II_OUTPUT_SUBPATH:-_output/local}" +readonly II_OUTPUT="${II_ROOT}/${II_OUTPUT_SUBPATH}" +readonly II_OUTPUT_BINPATH="${II_OUTPUT}/bin" + +# ii::build::setup_env will check that the `go` commands is available in +# ${PATH}. If not running on Travis, it will also check that the Go version is +# good enough for the webdav code requirements (1.5+). +# +# Output Vars: +# export GOPATH - A modified GOPATH to our created tree along with extra +# stuff. +# export GOBIN - This is actively unset if already set as we want binaries +# placed in a predictable place. +ii::build::setup_env() { + if [[ -z "$(which go)" ]]; then + cat <&2 } - os::log::stack $stack_skip + ii::log::stack $stack_skip echo "Exiting with status ${code}" >&2 exit "${code}" } -os::log::with-severity() { +ii::log::with-severity() { local msg=$1 local severity=$2 echo "[$2] ${1}" } -os::log::info() { - os::log::with-severity "${1}" "INFO" +ii::log::info() { + ii::log::with-severity "${1}" "INFO" } -os::log::warn() { - os::log::with-severity "${1}" "WARNING" +ii::log::warn() { + ii::log::with-severity "${1}" "WARNING" } -os::log::error() { - os::log::with-severity "${1}" "ERROR" +ii::log::error() { + ii::log::with-severity "${1}" "ERROR" } find_files() { @@ -398,11 +398,11 @@ find_files() { # Asks golang what it thinks the host platform is. The go tool chain does some # slightly different things when the target platform matches the host platform. -os::util::host_platform() { +ii::util::host_platform() { echo "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" } -os::util::sed() { +ii::util::sed() { if [[ "$(go env GOHOSTOS)" == "darwin" ]]; then sed -i '' "$@" else @@ -410,7 +410,7 @@ os::util::sed() { fi } -os::util::base64decode() { +ii::util::base64decode() { if [[ "$(go env GOHOSTOS)" == "darwin" ]]; then base64 -D $@ else @@ -418,7 +418,7 @@ os::util::base64decode() { fi } -os::util::get_object_assert() { +ii::util::get_object_assert() { local object=$1 local request=$2 local expected=$3 diff --git a/hack/verify-gofmt.sh b/hack/verify-gofmt.sh new file mode 100755 index 0000000..69d7031 --- /dev/null +++ b/hack/verify-gofmt.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# GoFmt apparently is changing @ head... + +set -o errexit +set -o nounset +set -o pipefail + +GO_VERSION=($(go version)) + +if [[ -z $(echo "${GO_VERSION[2]}" | grep -E 'go1.4|go1.5') ]]; then + echo "Unknown go version '${GO_VERSION}', skipping gofmt." >&2 + exit 0 +fi + +CODE_ROOT=$(dirname "${BASH_SOURCE}")/.. +source "${CODE_ROOT}/hack/common.sh" +source "${CODE_ROOT}/hack/util.sh" + +cd "${CODE_ROOT}" + +bad_files=$(find_files | xargs gofmt -s -l) +if [[ -n "${bad_files}" ]]; then + echo "!!! gofmt needs to be run on the following files: " >&2 + echo "${bad_files}" + echo "Try running 'gofmt -s -d [path]'" >&2 + echo "Or autocorrect with 'hack/verify-gofmt.sh | xargs -n 1 gofmt -s -w'" >&2 + exit 1 +fi diff --git a/test/end-to-end/e2e.sh b/test/end-to-end/e2e.sh index 6da889e..e046a9d 100755 --- a/test/end-to-end/e2e.sh +++ b/test/end-to-end/e2e.sh @@ -6,25 +6,25 @@ set -o errexit set -o nounset set -o pipefail -OS_ROOT=$(dirname "${BASH_SOURCE}")/../.. -source "${OS_ROOT}/hack/util.sh" -source "${OS_ROOT}/hack/cmd_util.sh" -os::log::install_errexit +II_ROOT=$(dirname "${BASH_SOURCE}")/../.. +source "${II_ROOT}/hack/util.sh" +source "${II_ROOT}/hack/cmd_util.sh" +ii::log::install_errexit -source "${OS_ROOT}/hack/lib/util/environment.sh" -os::util::environment::setup_time_vars +source "${II_ROOT}/hack/lib/util/environment.sh" +ii::util::environment::setup_time_vars # test args -os::cmd::expect_failure_and_text "image-inspector --help" "Usage of" -os::cmd::expect_failure_and_text "image-inspector" "Docker image to inspect must be specified" -os::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --dockercfg=badfile" "badfile does not exist" -os::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --dockercfg=badfile --username=foo" "Only specify dockercfg file or username/password pair for authentication" -os::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --password-file=foo" "foo does not exist" -os::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --scan-type=foo" "foo is not one of the available scan-type" +ii::cmd::expect_failure_and_text "image-inspector --help" "Usage of" +ii::cmd::expect_failure_and_text "image-inspector" "Docker image to inspect must be specified" +ii::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --dockercfg=badfile" "badfile does not exist" +ii::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --dockercfg=badfile --username=foo" "Only specify dockercfg file or username/password pair for authentication" +ii::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --password-file=foo" "foo does not exist" +ii::cmd::expect_failure_and_text "image-inspector --image=fedora:22 --scan-type=foo" "foo is not one of the available scan-type" # test extraction -os::cmd::expect_success_and_text "image-inspector --image=fedora:22 2>&1" "Extracting image fedora:22" +ii::cmd::expect_success_and_text "image-inspector --image=fedora:22 2>&1" "Extracting image fedora:22" # TODO # test serving