// 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.
package com.google.devtools.build.lib.shell;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
import static org.junit.Assume.assumeTrue;

import com.google.devtools.build.lib.util.OS;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests of the interaction of Thread.interrupt and Command.execute.
 *
 * Read http://www.ibm.com/developerworks/java/library/j-jtp05236/
 * for background material.
 *
 * NOTE: This test is dependent on thread timings.  Under extreme machine load
 * it's possible that this test could fail spuriously or intermittently.  In
 * that case, adjust the timing constants to increase the tolerance.
 */
@RunWith(JUnit4.class)
public class InterruptibleTest {

  private final Thread mainThread = Thread.currentThread();

  // Interrupt main thread after 1 second.  Hopefully by then /bin/sleep
  // should be running.
  private final Thread interrupter = new Thread() {
      @Override
      public void run() {
        try {
          Thread.sleep(1000); // 1 sec
        } catch (InterruptedException e) {
          throw new IllegalStateException("Unexpected interrupt!");
        }
        mainThread.interrupt();
      }
    };

  private Command command;

  @Before
  public final void startInterrupter() throws Exception  {
    Thread.interrupted(); // side effect: clear interrupted status
    assertWithMessage("Unexpected interruption!").that(mainThread.isInterrupted()).isFalse();

    // We interrupt after 1 sec, so this gives us plenty of time for the library to notice the
    // subprocess exit.
    this.command = new Command(new String[] { "/bin/sleep", "20" });

    interrupter.start();
  }

  @After
  public final void waitForInterrupter() throws Exception  {
    interrupter.join();
    Thread.interrupted(); // Clear interrupted status, or else other tests may fail.
  }

  /**
   * Test that interrupting a thread in an "uninterruptible" Command.execute marks the thread as
   * interrupted, and does not terminate the subprocess.
   */
  @Test
  public void testUninterruptibleCommandRunsToCompletion() throws Exception {
    assumeTrue(OS.getCurrent() != OS.WINDOWS);

    CommandResult result =
        command.executeAsync(Command.NO_INPUT, Command.CONTINUE_SUBPROCESS_ON_INTERRUPT).get();
    assertThat(result.getTerminationStatus().success()).isTrue();
    assertThat(result.getStderr()).isEmpty();
    assertThat(result.getStdout()).isEmpty();

    // The interrupter thread should have exited about 1000ms ago.
    assertWithMessage("Interrupter thread is still alive!").that(interrupter.isAlive()).isFalse();

    // The interrupter thread should have set the main thread's interrupt flag.
    assertWithMessage("Main thread was not interrupted during command execution!")
        .that(mainThread.isInterrupted())
        .isTrue();
  }

  /**
   * Test that interrupting a thread in an "interruptible" Command.execute does terminate the
   * subprocess, and also marks the thread as interrupted.
   */
  @Test
  public void testInterruptibleCommandRunsToCompletion() throws Exception {
    assumeTrue(OS.getCurrent() != OS.WINDOWS);

    AbnormalTerminationException expected =
        assertThrows(AbnormalTerminationException.class, () -> command.execute());
    assertThat(expected).hasMessageThat().isEqualTo("Process terminated by signal 15");
    assertThat(expected.getResult().getTerminationStatus().exited()).isFalse();

    // The interrupter thread should have set the main thread's interrupt flag.
    assertWithMessage("Main thread was not interrupted during command execution!")
        .that(mainThread.isInterrupted())
        .isTrue();
  }
}
