// Copyright 2020 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.util;

import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toList;

import com.google.devtools.build.lib.server.FailureDetails;
import com.google.devtools.build.lib.server.FailureDetails.Crash;
import com.google.devtools.build.lib.server.FailureDetails.Crash.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.protobuf.ProtocolStringList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link CrashFailureDetails}. */
@RunWith(JUnit4.class)
public final class CrashFailureDetailsTest {

  private static final String TEST_EXCEPTION_NAME =
      "com.google.devtools.build.lib.util.CrashFailureDetailsTest$TestException";

  @Test
  public void nestedThrowables() {
    // This test confirms that throwables' details are recorded: their messages, types, stack
    // frames, and causes. The outermost throwable is recorded at index 0.

    FailureDetail failureDetail =
        CrashFailureDetails.forThrowable(
            functionForStackFrameTests_A(functionForStackFrameTests_B()));

    assertThat(failureDetail.getMessage())
        .isEqualTo(
            String.format(
                "Crashed: (%s) myMessage_A, (%s) myMessage_B",
                TEST_EXCEPTION_NAME, TEST_EXCEPTION_NAME));
    assertThat(failureDetail.hasCrash()).isTrue();
    Crash crash = failureDetail.getCrash();
    assertThat(crash.getCode()).isEqualTo(Code.CRASH_UNKNOWN);

    assertThat(crash.getCausesCount()).isEqualTo(2);

    FailureDetails.Throwable outerCause = crash.getCauses(0);
    assertThat(outerCause.getMessage()).isEqualTo("myMessage_A");
    assertThat(outerCause.getThrowableClass()).isEqualTo(TEST_EXCEPTION_NAME);
    assertThat(outerCause.getStackTraceCount()).isAtLeast(2);
    assertThat(outerCause.getStackTrace(0))
        .contains(
            "com.google.devtools.build.lib.util.CrashFailureDetailsTest."
                + "functionForStackFrameTests_A");
    assertThat(outerCause.getStackTrace(1))
        .contains("com.google.devtools.build.lib.util.CrashFailureDetailsTest.nestedThrowables");

    FailureDetails.Throwable innerCause = crash.getCauses(1);
    assertThat(innerCause.getMessage()).isEqualTo("myMessage_B");
    assertThat(innerCause.getThrowableClass()).isEqualTo(TEST_EXCEPTION_NAME);
    assertThat(innerCause.getStackTraceCount()).isAtLeast(2);
    assertThat(innerCause.getStackTrace(0))
        .contains(
            "com.google.devtools.build.lib.util.CrashFailureDetailsTest."
                + "functionForStackFrameTests_B");
    assertThat(innerCause.getStackTrace(1))
        .contains("com.google.devtools.build.lib.util.CrashFailureDetailsTest.nestedThrowables");
  }

  @Test
  public void causeLimit() {
    // This test confirms that at most 5 throwables are recorded.
    TestException inner5 = new TestException("inner5");
    TestException inner4 = new TestException("inner4", inner5);
    TestException inner3 = new TestException("inner3", inner4);
    TestException inner2 = new TestException("inner2", inner3);
    TestException inner1 = new TestException("inner1", inner2);
    TestException outer = new TestException("outer", inner1);

    assertThat(CrashFailureDetails.forThrowable(outer).getCrash().getCausesCount()).isEqualTo(5);
  }

  @Test
  public void testMessageLimit() {
    TestException exception = new TestException("x".repeat(5000));

    String crashMessage =
        CrashFailureDetails.forThrowable(exception).getCrash().getCauses(0).getMessage();

    assertThat(crashMessage).hasLength(2000);
    assertThat(crashMessage).endsWith("[truncated]");
  }

  @Test
  public void causeCycle() {
    // This test confirms that throwables in a cause cycle are visited at most once.
    TestException inner2 = new TestException("inner2");
    TestException inner1 = new TestException("inner1", inner2);
    TestException outer = new TestException("outer", inner1);
    inner2.initCause(inner1);

    List<FailureDetails.Throwable> causesList =
        CrashFailureDetails.forThrowable(outer).getCrash().getCausesList();
    assertThat(causesList.stream().map(FailureDetails.Throwable::getMessage).collect(toList()))
        .containsExactly("outer", "inner1", "inner2");
  }

  @Test
  public void deepStack() {
    ProtocolStringList stackTraceList =
        CrashFailureDetails.forThrowable(functionForDeepStackTrace(1001))
            .getCrash()
            .getCauses(0)
            .getStackTraceList();
    assertThat(stackTraceList).hasSize(1000);

    // Check that the deepest 1000 frames were recorded:
    for (String stackFrame : stackTraceList) {
      assertThat(stackFrame).contains("CrashFailureDetailsTest.functionForDeepStackTrace");
    }
  }

  @Test
  public void detailedExitConstruction_oom() {
    assertThat(
            CrashFailureDetails.detailedExitCodeForThrowable(new OutOfMemoryError()).getExitCode())
        .isEqualTo(ExitCode.OOM_ERROR);
  }

  @Test
  public void detailedExitConstruction_wrappedOom() {
    assertThat(
            CrashFailureDetails.detailedExitCodeForThrowable(
                    new IllegalStateException(new OutOfMemoryError()))
                .getExitCode())
        .isEqualTo(ExitCode.OOM_ERROR);
  }

  @Test
  public void detailedExtitConstruction_otherCrash() {
    assertThat(
            CrashFailureDetails.detailedExitCodeForThrowable(new IllegalStateException())
                .getExitCode())
        .isEqualTo(ExitCode.BLAZE_INTERNAL_ERROR);
  }

  private static TestException functionForStackFrameTests_A(TestException cause) {
    return new TestException("myMessage_A", cause);
  }

  private static TestException functionForStackFrameTests_B() {
    return new TestException("myMessage_B");
  }

  private static TestException functionForDeepStackTrace(int framesToBuild) {
    if (framesToBuild <= 1) {
      return new TestException("myMessage_deep");
    } else {
      return functionForDeepStackTrace(framesToBuild - 1);
    }
  }

  private static class TestException extends Exception {
    private TestException(String message) {
      super(message);
    }

    private TestException(String message, Throwable cause) {
      super(message, cause);
    }
  }
}
