diff --git a/.gitignore b/.gitignore index 84b1e47..76b5fe4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -/immortalize /work/ diff --git a/.realize.yaml b/.realize.yaml index c00d67f..fb93879 100755 --- a/.realize.yaml +++ b/.realize.yaml @@ -4,6 +4,9 @@ schema: commands: build: status: true + args: + - -o + - work/immortalize watcher: extensions: - go diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 1638af2..c669bc7 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -17,6 +17,11 @@ steps: gs://$_CACHE_BUCKET/$_GITHUB_REPO/tree/$BRANCH_NAME/$_CACHE_NAME.tar.gz \ /var/tmp/$_CACHE_NAME.tar.gz && \ tar xvzf /var/tmp/$_CACHE_NAME.tar.gz -C $_CACHE_BASEDIR) || exit 0 +- name: gcr.io/cloud-builders/curl + entrypoint: bash + args: + - -c + - mv $_CACHE_BASEDIR/$_CACHE_DIR/gopkg gopath/pkg || exit 0 # Build - name: gcr.io/cloud-builders/go:debian @@ -29,7 +34,41 @@ steps: - PROJECT_ROOT=$_GITHUB_REPO - GO111MODULE=on +# Test +- name: gcr.io/cloud-builders/npm + entrypoint: bash + args: + - -c + - | + mkdir -p $_CACHE_BASEDIR/$_CACHE_DIR && cd $_CACHE_BASEDIR/$_CACHE_DIR + if [ ! -f node_modules/.bin/bats ]; then + echo '{"private": true}' > package.json + npm install bats@$_BATS_VERSION + fi +- name: gcr.io/cloud-builders/curl + entrypoint: bash + args: + - -c + - | + mkdir -p $_CACHE_BASEDIR/$_CACHE_DIR + if [ ! -f $_CACHE_BASEDIR/$_CACHE_DIR/time ]; then + apt-get update && apt-get install -y time + cp /usr/bin/time $_CACHE_BASEDIR/$_CACHE_DIR/time + fi +- name: gcr.io/cloud-builders/npm + entrypoint: bash + args: + - -c + - $_CACHE_BASEDIR/$_CACHE_DIR/node_modules/.bin/bats -t test + # Save cache +- name: gcr.io/cloud-builders/curl + entrypoint: bash + args: + - -c + - | + mkdir -p $_CACHE_BASEDIR/$_CACHE_DIR && \ + mv gopath/pkg $_CACHE_BASEDIR/$_CACHE_DIR/gopkg - name: gcr.io/cloud-builders/gsutil entrypoint: bash args: @@ -118,9 +157,9 @@ artifacts: substitutions: _CACHE_BUCKET: kunoichimarket-cloudbuild-cache _ARTIFACT_BUCKET: kunoichimarket-cloudbuild-artifact - _CACHE_NAME: gopkg - _CACHE_BASEDIR: gopath - _CACHE_DIR: pkg + _CACHE_NAME: cache + _CACHE_BASEDIR: work + _CACHE_DIR: cache _GITHUB_REPO: github.com/kuno1/immortalize _GITHUB_USER: kuno1bot # _ENCRYPTED_GITHUB_TOKEN is generated with the following commands: @@ -135,4 +174,5 @@ substitutions: _GITHUB_API: https://api.github.com/repos/kuno1/immortalize _GITHUB_UPLOADS: https://uploads.github.com/repos/kuno1/immortalize _BIN_NAME: immortalize + _BATS_VERSION: 1.1.0 _MAIN_BRANCH: master diff --git a/test-bin/command-one b/test-bin/command-one new file mode 100755 index 0000000..9b76edf --- /dev/null +++ b/test-bin/command-one @@ -0,0 +1,24 @@ +#!/bin/bash -eu + +# https://stackoverflow.com/questions/9256644 +trap_with_arg() { + func="$1" ; shift + for sig ; do + # shellcheck disable=SC2064 + trap "$func $sig" "$sig" + done +} + +func_trap() { + >&2 echo "Trapped: $1" + exit 1 +} + +trap_with_arg func_trap INT TERM EXIT + +for i in {1..8}; do + sleep 0.5 + >&2 echo "$i / 8" +done + +exit 1 diff --git a/test-bin/command-zero b/test-bin/command-zero new file mode 100755 index 0000000..2ef405c --- /dev/null +++ b/test-bin/command-zero @@ -0,0 +1,22 @@ +#!/bin/bash -eu + +# https://stackoverflow.com/questions/9256644 +trap_with_arg() { + func="$1" ; shift + for sig ; do + # shellcheck disable=SC2064 + trap "$func $sig" "$sig" + done +} + +func_trap() { + echo "Trapped: $1" + exit 0 +} + +trap_with_arg func_trap INT TERM EXIT + +for i in {1..8}; do + sleep 0.5 + >&2 echo "$i / 8" +done diff --git a/test/test.bats b/test/test.bats new file mode 100644 index 0000000..b54d184 --- /dev/null +++ b/test/test.bats @@ -0,0 +1,66 @@ +#!/usr/bin/env bats + +result () { + >&3 cat work/time + # Floor the time + awk '{split($0,a,"."); print a[1]}' < work/time +} + +time_cmd= + +measure () { + if [ "$time_cmd" == '' ]; then + if [ -f /usr/bin/time ]; then + time_cmd=/usr/bin/time + elif [ -f work/cache/time ]; then + time_cmd=work/cache/time + else + >&3 echo 'Error: time command does not exist.' + exit 1 + fi + fi + + # Measure immortalize and redirect stdout/stderr to file descriptor 3. + # Details: + # https://github.com/bats-core/bats-core#file-descriptor-3-read-this-if-bats-hangs + "$time_cmd" -f '%e' -o work/time ./work/immortalize "$@" >&3 2>&1 & + # Store time's PID + echo "$!" > work/pid +} + +sigterm () { + # Send SIGTERM to immortalize by using time's PID + pkill -P "$(< work/pid)" +} + +# MIN -> COM +@test "MIN -> COM" { + measure -min-lifetime 2 -command test-bin/command-zero + wait + [ "$(result)" == 4 ] +} + +# COM -> MIN +@test "COM -> MIN" { + measure -min-lifetime 6 -command test-bin/command-zero + wait + [ "$(result)" == 4 ] +} + +# SIG -> MIN +@test "SIG -> MIN" { + measure -min-lifetime 2 -command test-bin/command-zero + sleep 1 + sigterm + wait + [ "$(result)" == 2 ] +} + +# MIN -> SIG +@test "MIN -> SIG" { + measure -min-lifetime 2 -command test-bin/command-zero + sleep 3 + sigterm + wait + [ "$(result)" == 3 ] +}