// 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.buildtool;

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

import com.google.common.util.concurrent.Futures;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.LoggingUtil;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test case for crashes caused by exceptions happening during package lookups during the
 * execution phase under certain conditions. To trigger a failure we must:
 *
 * <ul>
 * <li>have a populated action cache on disk but no in memory state (ie: build after restart)</li>
 * <li>have a build that does include scanning where the includes are not explicitly declared
 *      and reside in a directory below a package (common)</li>
 * <li>have some sort of filesystem event that would trigger exceptions between the loading
 *      and execution phase (ie: network disconnecting, credentials expiring, etc)</li>
 * </ul>
 */
@RunWith(JUnit4.class)
public class ExecutionPhaseContainingPackageLookupTest extends IoHookTestCase {

  @Test
  public void testIOExceptionDuringExecutionPhaseContainingPackageLookup() throws Exception {
    // Our main code that includes the include we'll be scanning for during the exec phase.
    write(
        "foo/BUILD",
        "cc_library(name = 'foo', srcs = ['foo.cc'], deps = ['//bar', '//notfinished'])");
    write(
        "foo/foo.cc",
        "#include \"bar/includes/include.h\"",
        "#include \"notfinished/includes/include.h\"",
        "int main() { return -1; }");

    // Dummy package containing a not immediately obvious include.
    write("bar/BUILD",
        "cc_library(name = 'bar', srcs = [], hdrs_check = 'loose',",
        "           visibility = ['//visibility:public'])");
    write("bar/includes/include.h");

    // Package that won't have its BUILD file looked up when the second build aborts.
    write(
        "notfinished/BUILD",
        "cc_library(name = 'notfinished', srcs = [], hdrs_check = 'loose',",
        "           visibility = ['//visibility:public'])");
    write("notfinished/includes/include.h");

    // Build and toss the analysis cache, imperative to make sure we go to disk in
    // the next build.
    addOptions("--discard_analysis_cache", "--features=cc_include_scanning");
    buildTarget("//foo:foo");

    final AtomicBoolean interrupted = new AtomicBoolean(true);

    // GoogleBuildIntegrationTestCase installs a remote logger that calls Runtime.halt, and
    // SkyframeBuilder calls logToRemote when there's a BuildFileNotFoundException, and the code
    // below triggers a BuildFileNotFoundException. Previously, the ActionExecutionFunction was
    // rethrowing that exception as a ActionExecutionFunctionException during error bubbling, but
    // it now ignores it, which triggers the code path in SkyframeBuilder. However, the test runner
    // catches Runtime.halt, and throws an exception instead. We just overwrite the remote logger
    // with one that silently ignores the log.
    LoggingUtil.installRemoteLoggerForTesting(Futures.immediateFuture(Logger.getAnonymousLogger()));

    // Now we want any lookup for "bar/includes/BUILD" to throw an IOException.
    setListener(
        (op, path) -> {
          if (path.getPathString().contains("notfinished/includes/BUILD")) {
            // Make sure we don't have the PackageLookup results for notfinished/includes before
            // we throw an IOException below. This tests that we'll still throw the proper
            // exception even without all the deps being present.
            try {
              Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS);
              interrupted.set(false);
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
            }
          } else if (path.getPathString().contains("bar/includes/BUILD")) {
            throw new IOException("FAIIIIIILLLLLLLLL");
          }
        });

    BuildFailedException bfe =
        assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    assertThat(bfe).hasMessageThat().contains("no such package 'bar/includes'");
    assertThat(interrupted.get()).isTrue();
  }

}
