#!/bin/bash
#
# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Test rules provided in Bazel not tested by examples
#

set -u
ADDITIONAL_BUILD_FLAGS=$1
WORKER_TYPE_LOG_STRING=$2
WORKER_PROTOCOL=$3
shift 3

# Load the test setup defined in the parent directory
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CURRENT_DIR}/../integration_test_setup.sh" \
  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }

# TODO(philwo): Change this so the path to the custom worker gets passed in as an argument to the
# test, once the bug that makes using the "args" attribute with sh_tests in Bazel impossible is
# fixed.
example_worker=$(find $BAZEL_RUNFILES -name ExampleWorker_deploy.jar)

add_to_bazelrc "build -s"
add_to_bazelrc "build --spawn_strategy=worker,standalone"
add_to_bazelrc "build --experimental_worker_allow_json_protocol"
add_to_bazelrc "build --worker_verbose --worker_max_instances=1"
add_to_bazelrc "build --debug_print_action_contexts"
add_to_bazelrc "build --noexperimental_worker_multiplex"
add_to_bazelrc "build ${ADDITIONAL_BUILD_FLAGS}"

function set_up() {
  # Run each test in a separate folder so that their output files don't get cached.
  WORKSPACE_SUBDIR=$(basename $(mktemp -d ${WORKSPACE_DIR}/testXXXXXX))
  cd ${WORKSPACE_SUBDIR}
  BINS=$(bazel info $PRODUCT_NAME-bin)/${WORKSPACE_SUBDIR}
  OUTPUT_BASE="$(bazel info output_base)"

  # Tell Bazel to shut down all running workers. Faster than a full shutdown.
  bazel build --worker_quit_after_build &> $TEST_log \
    || fail "'bazel build --worker_quit_after_build' during test set_up failed"
}

function tear_down() {
  # This makes sure the blocker from test_missing_worker_directory is gone.
  rm -rf "${OUTPUT_BASE}/{blaze,bazel}-workers"
}

function write_hello_library_files() {
  mkdir -p java/main
  cat >java/main/BUILD <<EOF
java_binary(name = 'main',
    deps = [':hello_library'],
    srcs = ['Main.java'],
    main_class = 'main.Main')

java_library(name = 'hello_library',
             srcs = ['HelloLibrary.java']);
EOF

  cat >java/main/Main.java <<EOF
package main;
import main.HelloLibrary;
public class Main {
  public static void main(String[] args) {
    HelloLibrary.funcHelloLibrary();
    System.out.println("Hello, World!");
  }
}
EOF

  cat >java/main/HelloLibrary.java <<EOF
package main;
public class HelloLibrary {
  public static void funcHelloLibrary() {
    System.out.print("Hello, Library!;");
  }
}
EOF
}

function test_compiles_hello_library_using_persistent_javac() {
  write_hello_library_files

  bazel build java/main:main &> "$TEST_log" \
    || fail "build failed"
  expect_log "Created new ${WORKER_TYPE_LOG_STRING} Javac worker (id [0-9]\+)"
  $BINS/java/main/main | grep -q "Hello, Library!;Hello, World!" \
    || fail "comparison failed"
}

function test_compiles_hello_library_using_persistent_javac_sibling_layout() {
  write_hello_library_files

  bazel build \
    --experimental_sibling_repository_layout java/main:main \
    --worker_max_instances=Javac=1 \
    &> "$TEST_log" || fail "build failed"
  expect_log "Created new ${WORKER_TYPE_LOG_STRING} Javac worker (id [0-9]\+)"
  $BINS/java/main/main | grep -q "Hello, Library!;Hello, World!" \
    || fail "comparison failed"
}

function prepare_example_worker() {
  cp ${example_worker} worker_lib.jar
  chmod +w worker_lib.jar
  echo "exampledata" > worker_data.txt

  mkdir worker_data_dir
  echo "veryexample" > worker_data_dir/more_data.txt

  cat >work.bzl <<EOF
def _impl(ctx):
  worker = ctx.executable.worker
  output = ctx.outputs.out

  argfile_inputs = []
  argfile_arguments = []
  if ctx.attr.multiflagfiles:
    # Generate one flagfile per command-line arg, alternate between @ and --flagfile= style.
    # This is used to test the code that handles multiple flagfiles and the --flagfile= style.
    idx = 1
    for arg in ["--output_file=" + output.path] + ctx.attr.args:
      argfile = ctx.actions.declare_file("%s_worker_input_%s" % (ctx.label.name, idx))
      ctx.actions.write(output=argfile, content=arg)
      argfile_inputs.append(argfile)
      flagfile_prefix = "@" if (idx % 2 == 0) else "--flagfile="
      argfile_arguments.append(flagfile_prefix + argfile.path)
      idx += 1
  else:
    # Generate the "@"-file containing the command-line args for the unit of work.
    argfile = ctx.actions.declare_file("%s_worker_input" % ctx.label.name)
    argfile_contents = "\n".join(["--output_file=" + output.path] + ctx.attr.args)
    ctx.actions.write(output=argfile, content=argfile_contents)
    argfile_inputs.append(argfile)
    argfile_arguments.append("@" + argfile.path)

  execution_requirements = {"supports-workers": "1", "requires-worker-protocol": "$WORKER_PROTOCOL"}
  if ctx.attr.worker_key_mnemonic:
    execution_requirements["worker-key-mnemonic"] = ctx.attr.worker_key_mnemonic

  ctx.actions.run(
      inputs=argfile_inputs + ctx.files.srcs,
      outputs=[output],
      executable=worker,
      progress_message="Working on %s" % ctx.label.name,
      mnemonic=ctx.attr.action_mnemonic,
      execution_requirements=execution_requirements,
      arguments=ctx.attr.worker_args + argfile_arguments,
  )

work = rule(
    implementation=_impl,
    attrs={
        "worker": attr.label(cfg="exec", mandatory=True, allow_files=True, executable=True),
        "worker_args": attr.string_list(),
        "worker_key_mnemonic": attr.string(),
        "action_mnemonic": attr.string(default = "Work"),
        "args": attr.string_list(),
        "srcs": attr.label_list(allow_files=True),
        "multiflagfiles": attr.bool(default=False),
    },
    outputs = {"out": "%{name}.out"},
)
EOF
  cat >BUILD <<EOF
load(":work.bzl", "work")

java_import(
  name = "worker_lib",
  jars = ["worker_lib.jar"],
)

java_binary(
  name = "worker",
  main_class = "com.google.devtools.build.lib.worker.ExampleWorker",
  runtime_deps = [
    ":worker_lib",
  ],
  data = [
    ":worker_data.txt",
    ":worker_data_dir",
  ]
)
EOF
}

function test_example_worker() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["hello world"],
)

work(
  name = "hello_world_uppercase",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--uppercase", "hello world"],
)
EOF

  bazel build  :hello_world &> "$TEST_log" \
    || fail "build failed"
  assert_equals "hello world" "$(cat $BINS/hello_world.out)"

  bazel build  :hello_world_uppercase &> "$TEST_log" \
    || fail "build failed"
  assert_equals "HELLO WORLD" "$(cat $BINS/hello_world_uppercase.out)"
}

function test_worker_requests() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["hello world", "--print_requests"],
)

work(
  name = "hello_world_uppercase",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--uppercase", "hello world", "--print_requests"],
)
EOF

  bazel build  :hello_world &> "$TEST_log" \
    || fail "build failed"
  assert_contains "hello world" "$BINS/hello_world.out"
  assert_contains "arguments: \"hello world\"" "$BINS/hello_world.out"
  assert_contains "path:.*hello_world_worker_input" "$BINS/hello_world.out"
  assert_not_contains "request_id" "$BINS/hello_world.out"

  bazel build  :hello_world_uppercase &> "$TEST_log" \
    || fail "build failed"
  assert_contains "HELLO WORLD" "$BINS/hello_world_uppercase.out"
  assert_contains "arguments: \"hello world\"" "$BINS/hello_world_uppercase.out"
  assert_contains "path:.*hello_world_uppercase_worker_input" "$BINS/hello_world_uppercase.out"
  assert_not_contains "request_id" "$BINS/hello_world_uppercase.out"
}

function test_missing_worker_directory() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
)
work(
  name = "hello_world2",
  worker = ":worker",
)
EOF

  if bazel info bazel-bin >/dev/null 2>&1; then
    WORKER_DIR="${OUTPUT_BASE}/bazel-workers"
  else
    WORKER_DIR="${OUTPUT_BASE}/blaze-workers"
  fi

  # Old worker dirs can survive a regular `bazel clean`.
  bazel clean --expunge || fail "initial clean failed"
  mkdir -p "${OUTPUT_BASE}" || fail "Can't create outputbase"
  echo "FOO" > "${WORKER_DIR}" || fail "Can't block worker dir"
  assert_contains "FOO" "${WORKER_DIR}"
  # It should be OK to run without workers even without a worker directory.
  bazel build :hello_world --spawn_strategy=standalone \
      --strategy=Javac=standalone &> "$TEST_log" \
    || fail "local build failed"

  assert_contains "FOO" "${WORKER_DIR}"

  # ...but once we try to create a worker, we should get an error.
  bazel build :hello_world2 --spawn_strategy=worker &> "$TEST_log" \
    && fail "expected worker build to fail" || true

  expect_log "IOException.*-workers"
  rm -rf "${WORKER_DIR}"
}

function test_shared_worker() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  action_mnemonic = "Hello",
  worker_key_mnemonic = "SharedWorker",
  args = ["--write_uuid"],
)

work(
  name = "goodbye_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  action_mnemonic = "Goodbye",
  worker_key_mnemonic = "SharedWorker",
  args = ["--write_uuid"],
)
EOF
  bazel build :hello_world :goodbye_world &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_1=$(cat $BINS/hello_world.out | grep UUID | cut -d' ' -f2)
  worker_uuid_2=$(cat $BINS/goodbye_world.out | grep UUID | cut -d' ' -f2)
  assert_equals "$worker_uuid_1" "$worker_uuid_2"
}

function test_multiple_flagfiles() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "multi_hello_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["hello", "world", "nice", "to", "meet", "you"],
  multiflagfiles = True,
)
EOF

  bazel build  :multi_hello_world &> "$TEST_log" \
    || fail "build failed"
  assert_equals "hello world nice to meet you" "$(cat $BINS/multi_hello_world.out)"
}

function test_workers_quit_after_build() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_counter"],
) for idx in range(10)]
EOF

  bazel build --worker_quit_after_build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"
  work_count=$(cat $BINS/hello_world_1.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "1" $work_count

  bazel build --worker_quit_after_build :hello_world_2 &> "$TEST_log" \
    || fail "build failed"
  work_count=$(cat $BINS/hello_world_2.out | grep COUNTER | cut -d' ' -f2)
  # If the worker hadn't quit as we told it, it would have been reused, causing this to be a "2".
  assert_equals "1" $work_count
}

# Disabled for being flaky, see b/182373389
function DISABLED_test_build_succeeds_even_if_worker_exits() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--exit_after=1", "--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF
  # The worker dies after finishing the action, so the build succeeds.
  bazel build --worker_verbose :hello_world_1 &> "$TEST_log" \
    || fail "build failed"

  # This time, the worker is dead before the build starts, so a new one is made.
  bazel build --worker_verbose :hello_world_2 &> "$TEST_log" \
    || fail "build failed"

  expect_log "Work worker (id [0-9]\+) has unexpectedly died with exit code 0."
}

function test_build_fails_if_worker_dies_during_action() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}","--exit_during=1"],
  args = [
    "--write_uuid",
    "--write_counter",
  ],
) for idx in range(10)]
EOF

  bazel build --worker_verbose :hello_world_1 &> "$TEST_log" \
    && fail "expected build to fail" || true

  expect_log "Worker process did not return a WorkResponse:"
  # Worker log gets displayed on error, including verbosity messages.
  expect_log "VERBOSE: Pretending to do work."
}

function test_worker_restarts_when_worker_binary_changes() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  echo "First run" >> $TEST_log
  bazel build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_1=$(cat $BINS/hello_world_1.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_1.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "1" $work_count

  echo "Second run" >> $TEST_log
  bazel build :hello_world_2 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_2=$(cat $BINS/hello_world_2.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_2.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "2" $work_count

  # Check that the same worker was used twice.
  assert_equals "$worker_uuid_1" "$worker_uuid_2"

  # Modify the example worker jar to trigger a rebuild of the worker.
  tr -cd '[:alnum:]' < /dev/urandom | head -c32 > dummy_file
  zip worker_lib.jar dummy_file
  rm dummy_file

  bazel build :hello_world_3 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_3=$(cat $BINS/hello_world_3.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_3.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "1" $work_count

  expect_log "worker .* can no longer be used, because its files have changed on disk"
  expect_log "worker_lib.jar: .* -> .*"

  # Check that we used a new worker.
  assert_not_equals "$worker_uuid_2" "$worker_uuid_3"
}

function test_worker_restarts_when_worker_runfiles_change() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  bazel build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_1=$(cat $BINS/hello_world_1.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_1.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "1" $work_count

  bazel build :hello_world_2 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_2=$(cat $BINS/hello_world_2.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_2.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "2" $work_count

  # Check that the same worker was used twice.
  assert_equals "$worker_uuid_1" "$worker_uuid_2"

  # "worker_data.txt" is included in the "data" attribute of the example worker.
  echo "changeddata" > worker_data.txt

  bazel build :hello_world_3 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_3=$(cat $BINS/hello_world_3.out | grep UUID | cut -d' ' -f2)
  work_count=$(cat $BINS/hello_world_3.out | grep COUNTER | cut -d' ' -f2)
  assert_equals "1" $work_count

  expect_log "worker .* can no longer be used, because its files have changed on disk"
  expect_log "worker_data.txt: .* -> .*"

  # Check that we used a new worker.
  assert_not_equals "$worker_uuid_2" "$worker_uuid_3"
}

# When a worker does not conform to the protocol and returns a response that is not a parseable
# protobuf, it must be killed and a helpful error message should be printed.
function test_build_fails_when_worker_returns_junk() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--poison_after=1", "--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  bazel build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"

  # A failing worker should cause the build to fail.
  bazel build :hello_world_2 &> "$TEST_log" \
    && fail "expected build to fail" || true

  # Check that a helpful error message was printed.
  expect_log "Worker process returned an unparseable WorkResponse!"
  expect_log "Did you try to print something to stdout"
  expect_log "Not UTF-8, printing first 1024 bytes as hex"
  expect_log "49 27 6D 20 61 20 70 6F  69 73 6F 6E 65 64 20 77  |I'm a po isoned w|"
}

function test_input_digests() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--print_inputs"],
  srcs = [":input.txt"],
) for idx in range(10)]
EOF

  echo "hello world" > input.txt
  bazel build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"
  worker_uuid_1=$(cat $BINS/hello_world_1.out | grep UUID | cut -d' ' -f2)
  hash1=$(egrep "INPUT .*/input.txt " $BINS/hello_world_1.out | cut -d' ' -f3)

  bazel build :hello_world_2 >> "$TEST_log" 2>&1 \
    || fail "build failed"
  worker_uuid_2=$(cat $BINS/hello_world_2.out | grep UUID | cut -d' ' -f2)
  hash2=$(egrep "INPUT .*/input.txt " $BINS/hello_world_2.out | cut -d' ' -f3)

  assert_equals "$worker_uuid_1" "$worker_uuid_2"
  assert_equals "$hash1" "$hash2"

  echo "changeddata" > input.txt

  bazel build :hello_world_3 >> "$TEST_log" 2>&1 \
    || fail "build failed"
  worker_uuid_3=$(cat $BINS/hello_world_3.out | grep UUID | cut -d' ' -f2)
  hash3=$(egrep "INPUT .*/input.txt " $BINS/hello_world_3.out | cut -d' ' -f3)

  assert_equals "$worker_uuid_2" "$worker_uuid_3"
  assert_not_equals "$hash2" "$hash3"
}

function test_worker_verbose() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  bazel build --worker_quit_after_build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"
  expect_log "Created new ${WORKER_TYPE_LOG_STRING} Work worker (id [0-9]\+)"
  expect_log "Destroying Work worker (id [0-9]\+)"
  expect_log "Build completed, shutting down worker pool..."
}

function test_logs_are_deleted_on_server_restart() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  bazel build --worker_quit_after_build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"

  expect_log "Created new ${WORKER_TYPE_LOG_STRING} Work worker (id [0-9]\+)"

  worker_log=$(egrep -o -- 'logging to .*/b(azel|laze)-workers/worker-[0-9]-Work.log' "$TEST_log" | sed 's/^logging to //')

  [ -e "$worker_log" ] \
    || fail "Worker log was not found"

  # Running a build after a server shutdown should trigger the removal of old worker log files.
  bazel shutdown &> $TEST_log
  bazel build &> $TEST_log

  [ ! -e "$worker_log" ] \
    || fail "Worker log was not deleted"
}

function test_requires_worker_protocol_missing_defaults_to_proto {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world_proto",
  worker = ":worker",
  worker_args = ["--worker_protocol=proto"],
  args = ["hello world"],
)
work(
  name = "hello_world_json",
  worker = ":worker",
  worker_args = ["--worker_protocol=json"],
)
EOF

  sed -i.bak 's/=execution_requirements/={"supports-workers": "1"}/g' work.bzl
  rm -f work.bzl.bak

  bazel build :hello_world_proto &> "$TEST_log" \
    || fail "build failed"
  assert_equals "hello world" "$(cat $BINS/hello_world_proto.out)"

  bazel build :hello_world_json &> "$TEST_log" \
    && fail "expected proto build with json worker to fail" || true
}

function test_missing_execution_requirements_fallback_to_standalone() {
  prepare_example_worker
  # This test ignores the WORKER_PROTOCOL test arg since it doesn't use the
  # persistent worker when execution falls back to standalone.
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
  args = ["--write_uuid", "--write_counter"],
)
EOF

  sed -i.bak '/execution_requirements=execution_requirements/d' work.bzl
  rm -f work.bzl.bak

  bazel build --worker_quit_after_build :hello_world &> "$TEST_log" \
    || fail "build failed"

  expect_not_log "Created new ${WORKER_TYPE_LOG_STRING} Work worker (id [0-9]\+)"
  expect_not_log "Destroying Work worker (id [0-9]\+)"

  # WorkerSpawnStrategy falls back to standalone strategy, so we still expect the output to be generated.
  [ -e "$BINS/hello_world.out" ] \
    || fail "Worker did not produce output"
}

function test_environment_is_clean() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_world",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["--print_env"],
)
EOF

  bazel shutdown &> "$TEST_log" \
    || fail "shutdown failed"
  CAKE=LIE bazel build --worker_quit_after_build :hello_world &> "$TEST_log" \
    || fail "build failed"

  fgrep CAKE=LIE $BINS/hello_world.out \
    && fail "environment variable leaked into worker env" || true
}

function test_workers_quit_on_clean() {
  prepare_example_worker
  cat >>BUILD <<EOF
work(
  name = "hello_clean",
  worker = ":worker",
  worker_args = ["--worker_protocol=${WORKER_PROTOCOL}"],
  args = ["hello clean"],
)
EOF

  bazel build :hello_clean &> "$TEST_log" \
    || fail "build failed"
  assert_equals "hello clean" "$(cat $BINS/hello_clean.out)"
  expect_log "Created new ${WORKER_TYPE_LOG_STRING} Work worker (id [0-9]\+)"

  bazel clean &> "$TEST_log" \
    || fail "clean failed"
  expect_log "Clean command is running, shutting down worker pool..."
  expect_log "Destroying Work worker (id [0-9]\+)"
}

function test_crashed_worker_causes_log_dump() {
  prepare_example_worker
  cat >>BUILD <<EOF
[work(
  name = "hello_world_%s" % idx,
  worker = ":worker",
  worker_args = [
    "--poison_after=1",
    "--hard_poison",
    "--worker_protocol=${WORKER_PROTOCOL}"
  ],
  args = ["--write_uuid", "--write_counter"],
) for idx in range(10)]
EOF

  bazel build :hello_world_1 &> "$TEST_log" \
    || fail "build failed"

  bazel build :hello_world_2 &> "$TEST_log" \
    && fail "expected build to fail" || true

  expect_log "^---8<---8<--- Start of log, file at /"
  expect_log "Worker process did not return a WorkResponse:"
  expect_log "I'm a very poisoned worker and will just crash."
  expect_log "^---8<---8<--- End of log ---8<---8<---"
}

run_suite "Worker integration tests"
