/*
 * Copyright 2013 Google Inc.
 *
 * 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.
 */

// Author: jkarlin@google.com (Josh Karlin)

// Unit-test the distributed pathways through the RewriteContext class.
// In these tests the RewriteTestBase::other_* objects represent the task
// that gets distributed to.

#include "net/instaweb/rewriter/public/rewrite_context.h"

#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/http_cache.h"
#include "net/instaweb/http/public/rate_controlling_url_async_fetcher.h"
#include "net/instaweb/rewriter/cached_result.pb.h"
#include "net/instaweb/rewriter/public/fake_filter.h"
#include "net/instaweb/rewriter/public/output_resource_kind.h"
#include "net/instaweb/rewriter/public/rewrite_context_test_base.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_stats.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/test_distributed_fetcher.h"
#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
#include "pagespeed/kernel/base/base64_util.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"  // for Timer, etc
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/html/html_parse_test_base.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/http_names.h"  // for Code::kOK
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/semantic_type.h"
#include "pagespeed/kernel/thread/mock_scheduler.h"

namespace net_instaweb {

class HtmlFilter;

namespace {

// Hook provided to TestRewriteDriverFactory to add a new filter when a
// rewrite_driver is created. A CreateFilterCallback must outlive any filters it
// creates as the filter's id comes from this.
class CreateFilterCallback
    : public TestRewriteDriverFactory::CreateFilterCallback {
 public:
  CreateFilterCallback(const StringPiece& id, bool blocking)
      : id_(id.as_string()), blocking_(blocking) {}
  virtual ~CreateFilterCallback() {}

  virtual HtmlFilter* Done(RewriteDriver* driver) {
    FakeFilter* filter = new FakeFilter(id_.c_str(), driver,
                                        semantic_type::kStylesheet);
    if (blocking_) {
      filter->set_exceed_deadline(true);
    }
    return filter;
  }

 private:
  GoogleString id_;
  bool blocking_;
  DISALLOW_COPY_AND_ASSIGN(CreateFilterCallback);
};

}  // namespace

// A class for testing the distributed paths through the rewrite context. It
// uses the RewriteContextTestBase's "other" RewriteDriver, factory, and options
// as a second task to perform distributed rewrites on. Call
// SetupDistributedTest to configure the test class.
class DistributedRewriteContextTest : public RewriteContextTestBase {
 protected:
  enum HttpRequestType {
    kHeadRequest,
    kGetRequest
  };

  DistributedRewriteContextTest() {
    distributed_rewrite_failures_ = statistics()->GetVariable(
        RewriteContext::kNumDistributedRewriteFailures);
    distributed_rewrite_successes_ = statistics()->GetVariable(
        RewriteContext::kNumDistributedRewriteSuccesses);
    distributed_metadata_failures_ = statistics()->GetVariable(
        RewriteContext::kNumDistributedMetadataFailures);
    fetch_failures_ =
        statistics()->GetVariable(RewriteStats::kNumResourceFetchFailures);
    fetch_successes_ =
        statistics()->GetVariable(RewriteStats::kNumResourceFetchSuccesses);
  }

  // Sets the options to be the same for the two tasks and configures a shared
  // LRU cache between them. Note that when a distributed call is made, the
  // fetcher will call the RewriteContextTestBase's "other" driver directly (see
  // TestDistributedFetcher).
  void SetupDistributedTest() {
    SetupSharedCache();
    options_->DistributeFilter(TrimWhitespaceRewriter::kFilterId);
    options_->set_distributed_rewrite_servers("example.com:80");
    options_->set_distributed_rewrite_key("1234123");
    // Make sure they have the same options so that they generate the same
    // metadata keys.
    other_options()->Merge(*options());
    InitTrimFilters(kRewrittenResource);
    InitResources();
    // Default to empty request headers.
    rewrite_driver()->SetRequestHeaders(request_headers_);
  }

  void InitTwoFilters(OutputResourceKind kind) {
    InitUpperFilter(kind, rewrite_driver());
    InitUpperFilter(kind, other_rewrite_driver());
    options_->DistributeFilter(UpperCaseRewriter::kFilterId);
    SetupDistributedTest();
  }

  // A wrapper function with friend access to RewriteDriver.
  bool DistributeFetch(const StringPiece& url, const StringPiece& filter_id,
                       AsyncFetch* async_fetch) {
    return rewrite_driver_->DistributeFetch(url, filter_id, async_fetch);
  }

  // TODO(jkarlin): Instead of CheckDistributedFetch where we pass in the
  // expected values an alternative idea is to create a DistributedFetch
  // function that returns a struct with all of the resulting stats that we can
  // EXPECT_EQ from the calling sites. That might be more readable.

  void CheckDistributedFetch(int distributed_fetch_success_count,
                             int distributed_fetch_failure_count,
                             int local_fetch_required, int rewritten) {
    EXPECT_EQ(distributed_fetch_success_count + distributed_fetch_failure_count,
              counting_distributed_fetcher()->fetch_count());
    EXPECT_EQ(local_fetch_required,
              counting_url_async_fetcher()->fetch_count());
    EXPECT_EQ(
        0, other_factory_->counting_distributed_async_fetcher()->fetch_count());
    EXPECT_EQ(distributed_fetch_success_count,
              distributed_rewrite_successes_->Get());
    EXPECT_EQ(distributed_fetch_failure_count,
              distributed_rewrite_failures_->Get());
    EXPECT_EQ(0, trim_filter_->num_rewrites());
    EXPECT_EQ(rewritten, other_trim_filter_->num_rewrites());
    EXPECT_EQ(0, distributed_metadata_failures_->Get());
  }

  bool FetchValidatedMetadata(StringPiece key, StringPiece input_url,
                              StringPiece correct_url,
                              HttpRequestType request_type) {
    GoogleString output;
    ResponseHeaders response_headers;
    RequestHeaders req_headers;
    bool valid_metadata = false;
    req_headers.Add(HttpAttributes::kXPsaRequestMetadata, key);
    if (request_type == kHeadRequest) {
      req_headers.set_method(RequestHeaders::kHead);
    }
    rewrite_driver()->SetRequestHeaders(req_headers);
    EXPECT_TRUE(
        FetchResourceUrl(input_url, &req_headers, &output, &response_headers));

    // Check if the metadata is valid.
    if (response_headers.Has(HttpAttributes::kXPsaResponseMetadata)) {
      GoogleString encoded_serialized =
          response_headers.Lookup1(HttpAttributes::kXPsaResponseMetadata);
      GoogleString decoded_serialized;
      Mime64Decode(encoded_serialized, &decoded_serialized);
      OutputPartitions partitions;
      EXPECT_TRUE(partitions.ParseFromString(decoded_serialized));
      EXPECT_STREQ(correct_url, partitions.partition(0).url());
      valid_metadata = true;
    }

    // If we did a HEAD request we don't expect any output
    if (request_type == kHeadRequest) {
      EXPECT_STREQ("", output);
    }
    return valid_metadata;
  }

  RequestHeaders request_headers_;  // default request headers
  Variable* fetch_failures_;
  Variable* fetch_successes_;
  Variable* distributed_rewrite_failures_;
  Variable* distributed_rewrite_successes_;
  Variable* distributed_metadata_failures_;
};

TEST_F(DistributedRewriteContextTest,
       NoDistributedHtmlRewriteWithoutSettingKeyOnDistributedTask) {
  SetupDistributedTest();
  // Clear the distributed task's key. The end result should be unoptimized
  // due to no metadata being returned since the key couldn't be validated.
  other_options()->ClearSignatureForTesting();
  other_options()->set_distributed_rewrite_key("");
  other_server_context()->ComputeSignature(other_options());
  ValidateNoChanges("trimmable", CssLinkHref("a.css"));
  EXPECT_EQ(1, counting_distributed_fetcher()->fetch_count());
}

TEST_F(DistributedRewriteContextTest,
       NoDistributedHtmlRewriteWithDifferentKeyOnDistributedTask) {
  SetupDistributedTest();
  // Set a different distributed task key from the ingress task. The end result
  // should be unoptimized due to no metadata being returned since the key
  // couldn't be validated.
  other_options()->ClearSignatureForTesting();
  other_options()->set_distributed_rewrite_key("wrong key");
  other_server_context()->ComputeSignature(other_options());
  ValidateNoChanges("trimmable", CssLinkHref("a.css"));
  EXPECT_EQ(1, counting_distributed_fetcher()->fetch_count());
  // But the optimization should have happened on the distributed task and
  // should be cached.
  EXPECT_EQ(
      3, lru_cache()->num_inserts());  // metadata, resource, optimized resource
  EXPECT_EQ(1, other_trim_filter_->num_rewrites());
  EXPECT_EQ(0, trim_filter_->num_rewrites());
}

// Copy of the RewriteContextTest.TrimRewrittenOptimizable test modified for
// distributed rewrites.
TEST_F(DistributedRewriteContextTest, TrimRewrittenOptimizable) {
  SetupDistributedTest();

  // Ingress task: Misses on metadata and distributes.
  // Rewrite task: Misses on metadata, misses on http data, writes original
  // resources, optimized resource, and metadata.
  ValidateExpected(
      "trimmable", CssLinkHref("a.css"),
      CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                         "a.css", "css")));

  CheckDistributedFetch(1,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        1);  // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  ClearStats();

  // The second time we request this URL, we should find no additional cache
  // inserts or fetches. The rewrite should complete using a single cache hit
  // for the metadata. No cache misses will occur.
  ValidateExpected(
      "trimmable", CssLinkHref("a.css"),
      CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                         "a.css", "css")));
  CheckDistributedFetch(0,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        0);  // number of rewrites
  EXPECT_EQ(1, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// Copy of the RewriteContextTest.TrimRewrittenNonOptimizable test modified for
// distributed rewrites.
TEST_F(DistributedRewriteContextTest, TrimRewrittenNonOptimizable) {
  SetupDistributedTest();

  // In this case, the resource is not optimizable.  The cache pattern is
  // exactly the same as when the resource was on-the-fly and optimizable.
  // We'll cache the successfully fetched resource, and the OutputPartitions
  // which indicates the unsuccessful optimization.
  ValidateNoChanges("no_trimmable", CssLinkHref("b.css"));
  CheckDistributedFetch(1,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        1);  // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(2, lru_cache()->num_inserts());
  ClearStats();

  // We should have cached the failed rewrite, no misses, fetches, or inserts.
  ValidateNoChanges("no_trimmable", CssLinkHref("b.css"));
  CheckDistributedFetch(0,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites
  EXPECT_EQ(1, lru_cache()->num_hits());  // partition
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// Copy of the RewriteContextTest.TrimRepeatedOptimizable test modified for
// distributed rewrites.
TEST_F(DistributedRewriteContextTest, TrimRepeatedOptimizable) {
  // Make sure two instances of the same link are handled properly,
  // when optimization succeeds.
  SetupDistributedTest();
  ValidateExpected(
      "trimmable2", StrCat(CssLinkHref("a.css"), CssLinkHref("a.css")),
      StrCat(CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId,
                                "0", "a.css", "css")),
             CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId,
                                "0", "a.css", "css"))));
  CheckDistributedFetch(1,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        1);  // number of rewrites
}

TEST_F(DistributedRewriteContextTest, TwoFilters) {
  InitTwoFilters(kOnTheFlyResource);

  ValidateExpected(
      "two_filters", CssLinkHref("a.css"),
      CssLinkHref(
          Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                 Encode("", UpperCaseRewriter::kFilterId, "0", "a.css", "css"),
                 "css")));
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());
  EXPECT_EQ(1, trim_filter_->num_rewrites());  // not distributed
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
}

// Same as TwoFilters but this time write to HTTP cache.
TEST_F(DistributedRewriteContextTest, TwoFiltersRewritten) {
  InitTwoFilters(kRewrittenResource);

  ValidateExpected(
      "two_filters", CssLinkHref("a.css"),
      CssLinkHref(
          Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                 Encode("", UpperCaseRewriter::kFilterId, "0", "a.css", "css"),
                 "css")));
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());
  EXPECT_EQ(1, trim_filter_->num_rewrites());  // not distributed
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
  // num_hits = 0 proves that we didn't use the cache to pipe the output of the
  // first filter in the chain to the second, instead we used the slot like we
  // were supposed to.
  EXPECT_EQ(0, lru_cache()->num_hits());
  // Miss uc (UpperCaseRewriter) metadata on ingress and distributed task.
  // Miss http input on distributed task.
  // Miss tw metadata on ingress task (but don't distribute).
  EXPECT_EQ(4, lru_cache()->num_misses());
  // uc (UpperCaseRewriter) inserts metadata, original http content, and
  // optimized http content.
  // tw filter inserts metadata and optimized http content.
  EXPECT_EQ(5, lru_cache()->num_inserts());
}

TEST_F(DistributedRewriteContextTest, TwoFiltersDelayedFetches) {
  other_factory_->SetupWaitFetcher();
  InitTwoFilters(kOnTheFlyResource);
  test_distributed_fetcher_.set_blocking_fetch(false);

  ValidateNoChanges("trimmable1", CssLinkHref("a.css"));
  OtherCallFetcherCallbacks();
  rewrite_driver_->WaitForShutDown();
  ValidateExpected(
      "delayed_fetches", CssLinkHref("a.css"),
      CssLinkHref(
          Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                 Encode("", UpperCaseRewriter::kFilterId, "0", "a.css", "css"),
                 "css")));
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());
  EXPECT_EQ(1, trim_filter_->num_rewrites());  // not distributed
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
}

TEST_F(DistributedRewriteContextTest, RepeatedTwoFilters) {
  // Make sure if we have repeated URLs and chaining, it still works right. Note
  // that both trim and upper are distributed, but when chained only the first
  // should distribute.
  InitTwoFilters(kRewrittenResource);

  ValidateExpected(
      "two_filters2", StrCat(CssLinkHref("a.css"), CssLinkHref("a.css")),
      StrCat(CssLinkHref(Encode(
                 "", TrimWhitespaceRewriter::kFilterId, "0",
                 Encode("", UpperCaseRewriter::kFilterId, "0", "a.css", "css"),
                 "css")),
             CssLinkHref(Encode(
                 "", TrimWhitespaceRewriter::kFilterId, "0",
                 Encode("", UpperCaseRewriter::kFilterId, "0", "a.css", "css"),
                 "css"))));
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());
  EXPECT_EQ(1, trim_filter_->num_rewrites());  // not distributed
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
}

// Test that we can successfully reconstruct a resource built from chained
// filters when rewrites are distributed.
TEST_F(DistributedRewriteContextTest, ReconstructDistributedTwoFilter) {
  // Need to use normal filters that the ServerContext::decoding_driver knows
  // about so that we can IsPagespeedResource() can recognize the filters in
  // the chained URL.
  options_->EnableFilter(RewriteOptions::kCombineCss);
  options_->EnableFilter(RewriteOptions::kRewriteCss);
  options_->DistributeFilter(RewriteOptions::kCssFilterId);
  SetupDistributedTest();

  SetResponseWithDefaultHeaders("a.css", kContentTypeCss,
                                " div { display: block;  }", 100);

  GoogleString encoded_url = Encode(
      kTestDomain, RewriteOptions::kCssCombinerId, "1",
      Encode("", RewriteOptions::kCssFilterId, "0", "a.css", "css"), "css");

  // Fetch the .pagespeed. resource and ensure that the two-filter
  // reconstruction is distributed properly.
  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));
  // Content should be optimized (note that the combiner doesn't do anything in
  // this case, but it at least ran).
  EXPECT_EQ("div{display:block}", content);
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());

  // Ingress task starts on cc filter, misses HTTP, metadata once, and then
  // fetches its CssFilter input, which distributes.
  // Distributed task CssFilter misses HTTP, metadata once, input resource once,
  // and then fetches the input resource and inserts the metadata, original
  // resource, and optimized resource into cache.
  // Ingress task writes its metadata and optimized to cache.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(5, lru_cache()->num_misses());
  EXPECT_EQ(5, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(3, http_cache()->cache_misses()->Get());
  EXPECT_EQ(3, http_cache()->cache_inserts()->Get());
}

// Test that we can successfully reconstruct a resource built from chained
// filters when rewrites are distributed and make sure that it blocks.
TEST_F(DistributedRewriteContextTest, ReconstructDistributedTwoFilterBlocks) {
  // We need to use filters with ids that the decoding driver knows about so
  // that IsPagespeedResource can recognize the filters in the encoded URL. So
  // we use a fake CSS filter and combiner. We give the ingress task one of each
  // and a fake filter to the distributed task, which times out.
  FakeFilter* fake_css_filter =
      new FakeFilter(RewriteOptions::kCssFilterId, rewrite_driver(),
                     semantic_type::kStylesheet);
  fake_css_filter->set_exceed_deadline(true);
  fake_css_filter->set_output_content_type(&kContentTypeCss);
  FakeFilter* fake_css_combiner =
      new FakeFilter(RewriteOptions::kCssCombinerId, rewrite_driver(),
                     semantic_type::kStylesheet);
  fake_css_combiner->set_output_content_type(&kContentTypeCss);
  FakeFilter* other_fake_css_filter =
      new FakeFilter(RewriteOptions::kCssFilterId, other_rewrite_driver(),
                     semantic_type::kStylesheet);
  other_fake_css_filter->set_exceed_deadline(true);
  other_fake_css_filter->set_output_content_type(&kContentTypeCss);
  rewrite_driver()->AppendRewriteFilter(fake_css_filter);
  rewrite_driver()->AppendRewriteFilter(fake_css_combiner);
  other_rewrite_driver()->AppendRewriteFilter(other_fake_css_filter);

  // Distribute the CSS filter.
  options_->DistributeFilter(RewriteOptions::kCssFilterId);

  // Make sure that any cloned drivers get fake CSS filters too.
  CreateFilterCallback create_filter_callback(RewriteOptions::kCssFilterId,
                                              true);
  CreateFilterCallback other_create_filter_callback(
      RewriteOptions::kCssFilterId, true);
  factory()->AddCreateFilterCallback(&create_filter_callback);
  other_factory()->AddCreateFilterCallback(&other_create_filter_callback);

  SetupDistributedTest();

  // This is the encoded URL to reconstruct.
  GoogleString encoded_url = Encode(
      kTestDomain, RewriteOptions::kCssCombinerId, "1",
      Encode("", RewriteOptions::kCssFilterId, "0", "a.css", "css"), "css");

  // Reconstruct the chained rewrite.
  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));
  EXPECT_EQ(StrCat(" a :", RewriteOptions::kCssFilterId, ":",
                   RewriteOptions::kCssCombinerId),
            content);
  EXPECT_EQ(1, distributed_rewrite_successes_->Get());
  EXPECT_EQ(0, distributed_rewrite_failures_->Get());

  // Ingress task starts on cc filter, misses HTTP, metadata, and then fetches
  // its CssFilter input, which distributes.
  // Distributed task CssFilter misses HTTP, metadata, and input resource and
  // then fetches the input resource and inserts the metadata, original
  // resource, and optimized resource into cache.
  // Ingress task writes its metadata and optimized resource to cache.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(5, lru_cache()->num_misses());
  EXPECT_EQ(5, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(3, http_cache()->cache_misses()->Get());
  EXPECT_EQ(3, http_cache()->cache_inserts()->Get());
}

// Simulate distributed fetch failure and ensure that we don't modify the URL.
TEST_F(DistributedRewriteContextTest, IngressDistributedRewriteFailFallback) {
  SetupDistributedTest();
  // Break the response after the headers have written but before data is
  // complete.
  test_distributed_fetcher()->set_fail_after_headers(true);
  ValidateNoChanges("trimmable", CssLinkHref("a.css"));

  // Ingress: Misses metadata, and does not optimize after unsuccessful
  // distributed fetch.
  // Distributed task: Misses metadata and original resource. Inserts metadata,
  // original, and optimized.  Returned stream is broken.
  CheckDistributedFetch(0,                // successful distributed fetches
                        1,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        1);               // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());  // partition
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());

  ClearStats();

  // Try again, this time we should have the result in shared cache.
  ValidateExpected(
      "trimmable", CssLinkHref("a.css"),
      CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                         "a.css", "css")));

  // Ingress: Misses metadata, and does not optimize after unsuccessful
  // distributed fetch.
  // Distributed task: Misses metadata and original resource. Inserts metadata,
  // original, and optimized.  Returned stream is broken.
  CheckDistributedFetch(0,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites
  EXPECT_EQ(1, lru_cache()->num_hits());  // partition
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// If the distributed fetcher returns a 404 then that's what needs to be
// returned.
TEST_F(DistributedRewriteContextTest, DistributedRewriteNotFound) {
  SetupDistributedTest();
  static const char fourofour[] = "fourofour.css";
  GoogleString orig_url = StrCat(kTestDomain, fourofour);
  SetFetchResponse404(orig_url);
  ValidateNoChanges("trimmable", CssLinkHref(fourofour));
  // Ingress task misses on metadata, gets unsuccessful fetch and returns
  // original unoptimized reference.
  // Distributed task misses on metadata and original resource fetch, fails its
  // fetch (404) and writes that back to metadata and original resource,
  // returning failure.
  CheckDistributedFetch(0,                // successful distributed fetches
                        1,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());  // partition
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(2, lru_cache()->num_inserts());

  ClearStats();
  // Try again, this time it should be a quick metadata lookup at the ingress
  // task.
  ValidateNoChanges("trimmable", CssLinkHref(fourofour));
  CheckDistributedFetch(0,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites
  EXPECT_EQ(1, lru_cache()->num_hits());  // partition
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// Similar to RewriteContextTest.TrimDelayed test but modified for distributed
// rewrites.
TEST_F(DistributedRewriteContextTest, TrimDelayed) {
  //  In this run, we will delay the URL fetcher's callback so that the initial
  //  rewrite will not take place until after the HTML has been flushed.
  SetupDistributedTest();
  other_factory_->SetupWaitFetcher();
  test_distributed_fetcher_.set_blocking_fetch(false);

  // First time distribute but the external fetch doesn't finish by ingress task
  // (or deadline task's for that matter) deadline.
  ValidateNoChanges("trimmable", CssLinkHref("a.css"));
  CheckDistributedFetch(0,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites

  // Let the distributed rewriter finish up its fetch and rewrite.
  OtherCallFetcherCallbacks();
  // Let the ingress task finish up as well.
  rewrite_driver_->WaitForShutDown();
  factory_->mock_scheduler()->AwaitQuiescence();

  // Now the rewrite is done, make sure the stats look right.
  // Ingress: same as before
  // Distributed: puts the original and optimized resource and metadata in
  // cache.
  CheckDistributedFetch(1,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        1);               // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());  // partition
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());

  // Second time the ingress metadata hits and that's all that's necessary.
  ClearStats();
  ValidateExpected(
      "trimmable", CssLinkHref("a.css"),
      CssLinkHref(Encode("", TrimWhitespaceRewriter::kFilterId, "0",
                         "a.css", "css")));

  CheckDistributedFetch(0,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        0);               // number of rewrites
  EXPECT_EQ(1, lru_cache()->num_hits());  // partition
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// Copy of the RewriteContextTest.TrimRepeatedNonOptimizable test modified for
// distributed rewrites.
TEST_F(DistributedRewriteContextTest, TrimRepeatedNonOptimizable) {
  // Make sure two instances of the same link are handled properly when
  // optimization fails.

  SetupDistributedTest();
  ValidateNoChanges("notrimmable2",
                    StrCat(CssLinkHref("b.css"), CssLinkHref("b.css")));
  // Ingress task misses metadata and distributes rewrite.
  // Distributed task misses metadata and original resource, inserts
  // meteadata, optimized, and unoptimized resource.
  CheckDistributedFetch(1,                // successful distributed fetches
                        0,                // unsuccessful distributed fetches
                        0,                // number of ingress fetches
                        1);               // number of rewrites
  EXPECT_EQ(0, lru_cache()->num_hits());  // partition
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(2, lru_cache()->num_inserts());
}

// Distribute a .pagespeed. reconstruction.
TEST_F(DistributedRewriteContextTest, IngressDistributedRewriteFetch) {
  SetupDistributedTest();
  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  // Fetch the .pagespeed. resource and ensure that the rewrite was distributed.
  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));
  // Content should be optimized.
  EXPECT_EQ("a", content);

  // Make sure the TTL is long and the result is cacheable.
  EXPECT_EQ(Timer::kYearMs, response_headers.cache_ttl_ms());
  EXPECT_TRUE(response_headers.IsProxyCacheable());
  EXPECT_TRUE(response_headers.IsBrowserCacheable());

  CheckDistributedFetch(1,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        1);  // number of rewrites

  // Ingress task distributes.
  // Rewrite task misses on two HTTP lookups (once for rewritten resource plus
  // once for original resource) and one metdata lookup. Then inserts original
  // resource, optimized resource, and metadata.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(2, http_cache()->cache_misses()->Get());
  EXPECT_EQ(2, http_cache()->cache_inserts()->Get());

  // On the second .pagespeed. request the optimized resource should be in the
  // shared cache.
  ClearStats();
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));

  // Content should be optimized.
  EXPECT_EQ("a", content);

  // The ingress url fetcher should not have run.
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(1, counting_distributed_fetcher()->fetch_count());

  // Ingress task hits on one HTTP lookup and returns it.
  EXPECT_EQ(1, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(1, http_cache()->cache_hits()->Get());
  EXPECT_EQ(0, http_cache()->cache_misses()->Get());
  EXPECT_EQ(0, http_cache()->cache_inserts()->Get());
}

// Test that distribute_fetches=false is honored.
TEST_F(DistributedRewriteContextTest, DistributeFetchesDisabled) {
  SetupDistributedTest();
  options()->ClearSignatureForTesting();
  options()->set_distribute_fetches(false);
  server_context()->ComputeSignature(options());

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  // Fetch the .pagespeed. resource and ensure that the rewrite was not
  // distributed.
  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));
  // Content should be optimized.
  EXPECT_EQ("a", content);

  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(0, counting_distributed_fetcher()->fetch_count());

  // Ingress task misses on two HTTP lookups (rewritten resource plus once for
  // original resource) and one metadata lookup. Then inserts original resource,
  // optimized resource, and metadata.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(2, http_cache()->cache_misses()->Get());
  EXPECT_EQ(2, http_cache()->cache_inserts()->Get());

  // On the second .pagespeed. request the optimized resource should be in the
  // shared cache.
  ClearStats();
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));

  // Content should be optimized.
  EXPECT_EQ("a", content);

  // No fetching.
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(0, counting_distributed_fetcher()->fetch_count());

  // Ingress task hits on one HTTP lookup and returns it.
  EXPECT_EQ(1, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(1, http_cache()->cache_hits()->Get());
  EXPECT_EQ(0, http_cache()->cache_misses()->Get());
  EXPECT_EQ(0, http_cache()->cache_inserts()->Get());
}

// If the distributed fetcher returns a 404 then that's what should be
// returned.
TEST_F(DistributedRewriteContextTest, IngressDistributedRewriteNotFoundFetch) {
  SetupDistributedTest();
  GoogleString orig_url = StrCat(kTestDomain, "fourofour.css");
  GoogleString encoded_url =
      Encode(kTestDomain, TrimWhitespaceRewriter::kFilterId, "0",
             "fourofour.css", "css");
  SetFetchResponse404(orig_url);

  // Fetch the .pagespeed. resource and ensure that the rewrite gets
  // distributed.
  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;

  EXPECT_FALSE(FetchResourceUrl(encoded_url, &request_headers, &content,
                                &response_headers));
  // Should be a 404 response.
  EXPECT_EQ(HttpStatus::kNotFound, response_headers.status_code());

  // The distributed fetcher should have run once on the ingress task and the
  // url fetcher should have run once on the rewrite task.  The result goes to
  // shared cache.
  CheckDistributedFetch(0,   // successful distributed fetches
                        1,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        0);  // number of rewrites

  // Ingress task distributes and streams back the 404.
  // Rewrite task misses on two HTTP lookups (once for rewritten resource plus
  // once for original resource) and one metadata lookup. Then inserts 404'd
  // original resource and metadata.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(2, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(2, http_cache()->cache_misses()->Get());
  EXPECT_EQ(1, http_cache()->cache_inserts()->Get());

  // Fetching again causes another reconstruction and therefore another
  // distributed rewrite, even though we hit the 404 in cache.
  //
  // ingress task: distribute because 404, it fails (because 404).
  //
  // rewrite task: 2 .pagespeed. misses, 1 metadata hit, 1 http hit, then fetch
  // again because 404, fetch locally and hit. Return.
  ClearStats();
  EXPECT_FALSE(FetchResourceUrl(encoded_url, &request_headers, &content,
                                &response_headers));
  CheckDistributedFetch(0,   // successful distributed fetches
                        1,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        0);  // number of rewrites

  EXPECT_EQ(3, lru_cache()->num_hits());
  EXPECT_EQ(1, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
}

// Simulate distributed fetch failure, which means that we stream back a failed
// response.
TEST_F(DistributedRewriteContextTest,
       IngressDistributedRewriteFailFallbackFetch) {
  SetupDistributedTest();
  test_distributed_fetcher()->set_fail_after_headers(true);

  // Mock the optimized .pagespeed. response from the rewrite task.
  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_FALSE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));

  EXPECT_STREQ("", content);

  // Ingress task distributes, which fails, but pick up original resource from
  // shared cache.
  CheckDistributedFetch(0,   // successful distributed fetches
                        1,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        1);  // number of rewrites

  // Ingress task: Distributed rewrite streams but then fails.
  // Distributed task: Misses http cache, then metadata. Fetches original
  // (misses in process), writes it, optimizes, writes optimized, and writes
  // metadata.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(2, http_cache()->cache_misses()->Get());
  EXPECT_EQ(2, http_cache()->cache_inserts()->Get());
}

// Simulate distributed fetch failure due to a bad URL to test PrepareRequest
// failure handling.
TEST_F(DistributedRewriteContextTest,
       IngressDistributedRewriteFailPrepareRequest) {
  SetupDistributedTest();
  GoogleString content;
  StringAsyncFetch async_fetch(rewrite_driver_->request_context(), &content);

  // Attempt a distributed fetch with a bad URL. PrepareRequest should fail and
  // the result should be a FetchResource() call.
  EXPECT_TRUE(
      DistributeFetch("", TrimWhitespaceRewriter::kFilterId, &async_fetch));

  // Tried to distribute but didn't get through PrepareRequest and fell
  // back to a FetchResource.
  EXPECT_TRUE(rewrite_driver_->tried_to_distribute_fetch());
  CheckDistributedFetch(0,   // successful distributed fetches
                        0,   // unsuccessful distributed fetches
                        0,   // number of ingress fetches
                        0);  // number of rewrites
}

// Simulate distributed fetch failure where the error occurs before headers
// complete (such as a connection error to the distributed task). This should
// fall back to local processing.
TEST_F(DistributedRewriteContextTest,
       IngressDistributedRewriteEarlyFailFallbackFetch) {
  SetupDistributedTest();
  test_distributed_fetcher()->set_error_before_headers_complete(true);

  // Mock the optimized .pagespeed. response from the rewrite task.
  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));

  // Should be optimized.
  EXPECT_STREQ("a", content);

  // .pagespeed. request fails, causing local rewrite.
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(
      0, other_factory_->counting_distributed_async_fetcher()->fetch_count());
  EXPECT_EQ(0, distributed_rewrite_successes_->Get());
  EXPECT_EQ(1, distributed_rewrite_failures_->Get());
  EXPECT_EQ(1, trim_filter_->num_rewrites());
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
  EXPECT_EQ(0, distributed_metadata_failures_->Get());

  // Ingress task: Distributed rewrite streams but fails early, resorts to local
  // rewrite. Misses http cache, then metadata. Fetches original (misses in
  // process), writes it, optimizes, writes optimized, and writes metadata.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(3, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(2, http_cache()->cache_misses()->Get());
  EXPECT_EQ(2, http_cache()->cache_inserts()->Get());
}

TEST_F(DistributedRewriteContextTest, ReturnMetadataOnRequest) {
  // Sends a fetch that asks for metadata in the response headers and checks
  // that it's in the response.

  // We need to make distributed_rewrite_servers != "" and set a
  // distributed_rewrite_key in order to return metadata.
  options()->set_distributed_rewrite_servers("example.com");
  static const char kDistributedKey[] = "1234123";
  options()->set_distributed_rewrite_key(kDistributedKey);
  static const char kCacheFragment[] = "a-cache-fragment";
  options()->set_cache_fragment(kCacheFragment);
  InitTrimFilters(kRewrittenResource);
  InitResources();

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");
  GoogleString bad_encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "1", "a.css", "css");

  // Note that the .pagespeed. path with metadata request headers do not
  // check the http cache up front.  If they did that and hit they would
  // not have metadata to return.  Therefore the tests below have fewer
  // cache misses than you might have expected.

  // The first .pagespeed. request.  It should hit the reconstruction path.
  // We'll miss on the metadata and the input resource.  Then fetch once
  // and put optimized resource, input resource, and metadata in cache.
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                     kGetRequest));
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(2, lru_cache()->num_misses());
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // We should get metadata even though the optimized output is cached.
  ClearStats();
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                     kGetRequest));
  EXPECT_EQ(2, lru_cache()->num_hits());  // 1 metadata and 1 http
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());

  // If we use the wrong encoding the metadata + subsequent HTTP cache will hit,
  // following the fallback path.
  ClearStats();
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, bad_encoded_url,
                                     encoded_url, kGetRequest));
  // Expect the bad url to miss twice (RewriteDriver::CacheCallback tries
  // twice). We should then hit the metadata and good http url.
  EXPECT_EQ(2, lru_cache()->num_hits());  // 1 metadata and 1 http
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());

  // If we clear the caches and use the wrong URL it should use the
  // reconstruction path and return the right URL and the metadata.
  ClearStats();
  lru_cache()->Clear();
  http_cache()->Delete(encoded_url, kCacheFragment);
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, bad_encoded_url,
                                     encoded_url, kGetRequest));
  // We should fetch once and insert the input, optimized, and metadata into
  // cache.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(2, lru_cache()->num_misses());  // 1 metadata and 1 http input
  EXPECT_EQ(3, lru_cache()->num_inserts());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
}

TEST_F(DistributedRewriteContextTest, HeadMetadata) {
  // Verify that a HEAD request that asks for metadata returns the metadata
  // but not the content.  We don't check cache hit/miss numbers because that
  // would be redundant with RewriteContextTest.ReturnMetadataOnRequest.

  // We need to make distributed_rewrite_servers != "" in order to return
  // metedata.
  options()->set_distributed_rewrite_servers("example.com");
  static const char kDistributedKey[] = "1234123";
  options()->set_distributed_rewrite_key(kDistributedKey);
  static const char kCacheFragment[] = "a-cache-fragment";
  options()->set_cache_fragment(kCacheFragment);
  InitTrimFilters(kRewrittenResource);
  InitResources();

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");
  GoogleString bad_encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "1", "a.css", "css");

  // Reconstruction path.
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                     kHeadRequest));

  // Second fetch, verify that we skip the initial http cache check and do
  // return metadata.
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                     kHeadRequest));

  // Bad .pagespeed. hash but still gets resolved.
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, bad_encoded_url,
                                     encoded_url, kHeadRequest));

  // Bad .pagespeed. hash and empty cache but should still reconstruct properly.
  lru_cache()->Clear();
  http_cache()->Delete(encoded_url, kCacheFragment);
  EXPECT_TRUE(FetchValidatedMetadata(kDistributedKey, bad_encoded_url,
                                     encoded_url, kHeadRequest));
}

TEST_F(DistributedRewriteContextTest, NoMetadataWithoutRewriteOption) {
  // Ensure that we don't return metadata if we're not configured
  // to run with distributed rewrites.
  static const char kDistributedKey[] = "1234123";
  options()->set_distributed_rewrite_key(kDistributedKey);
  InitTrimFilters(kRewrittenResource);
  InitResources();

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  // We didn't set rewrite tasks in options, so we shouldn't get any metadata.
  EXPECT_FALSE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                      kGetRequest));
}

TEST_F(DistributedRewriteContextTest, NoMetadataWithoutSettingKey) {
  // Ensure that we don't return metadata if we're not configured
  // to run with distributed rewrites.
  options()->set_distributed_rewrite_servers("example.com");
  static const char kDistributedKey[] = "1234123";
  // Neglect to set the distributed rewrite key in options.
  InitTrimFilters(kRewrittenResource);
  InitResources();

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  // We didn't set a distributed rewrite key in options, so we shouldn't get any
  // metadata.
  EXPECT_FALSE(
      FetchValidatedMetadata("", encoded_url, encoded_url, kGetRequest));
  EXPECT_FALSE(FetchValidatedMetadata(kDistributedKey, encoded_url, encoded_url,
                                      kGetRequest));
}

TEST_F(DistributedRewriteContextTest, NoMetadataWithBadKeys) {
  // Ensure that we don't return metadata if we're not configured
  // to run with distributed rewrites.
  options()->set_distributed_rewrite_servers("example.com");
  static const char kDistributedKey[] = "a1234123";
  options()->set_distributed_rewrite_key(kDistributedKey);
  InitTrimFilters(kRewrittenResource);
  InitResources();

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  EXPECT_FALSE(
      FetchValidatedMetadata("", encoded_url, encoded_url, kGetRequest));
  // Changing case doesn't work.
  EXPECT_FALSE(FetchValidatedMetadata("A1234123", encoded_url, encoded_url,
                                      kGetRequest));
  // Sanity check that it does work with the correct key.
  EXPECT_TRUE(FetchValidatedMetadata("a1234123", encoded_url, encoded_url,
                                     kGetRequest));
}

// If we try to distribute an HTML rewrite for a resource whose URL is too long
// we should handle it gracefully.
TEST_F(DistributedRewriteContextTest, GracefullyHandleURLTooLong) {
  SetupDistributedTest();

  // Create a long URL that could feasibly exist but cannot be extended into a
  // .pagespeed. resource.
  GoogleString long_url = kTestDomain;
  for (int i = long_url.size(),
           max_size = options()->max_url_segment_size() - 4;
       i < max_size; ++i) {
    long_url += "a";
  }
  long_url = StrCat(long_url, ".css");

  SetResponseWithDefaultHeaders(long_url, kContentTypeCss, " hello ", 60);

  ValidateNoChanges("long_url", CssLinkHref(long_url));
  EXPECT_EQ(0, counting_distributed_fetcher()->fetch_count());
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(
      0, other_factory_->counting_distributed_async_fetcher()->fetch_count());
  EXPECT_EQ(0, distributed_rewrite_successes_->Get());
  // Even though we didn't have a distributed fetch, we do have a distributed
  // rewrite failure since when prepping for the fetch we failed because the URL
  // was too long.
  EXPECT_EQ(1, distributed_rewrite_failures_->Get());
  EXPECT_EQ(0, trim_filter_->num_rewrites());
  EXPECT_EQ(0, other_trim_filter_->num_rewrites());
  EXPECT_EQ(0, distributed_metadata_failures_->Get());
}

// The distributed task should recognize if a distributed task can be rate
// controlled.
TEST_F(DistributedRewriteContextTest, QueueFetchOnDistributedHtmlTask) {
  SetupDistributedTest();

  // Tack on a rate controlling fetcher which does not allow queueing of any
  // fetches on the distributed task. A distribution of a background rewrite
  // should be dropped by the rate controller since it can't queue.
  other_rewrite_driver_->SetSessionFetcher(new RateControllingUrlAsyncFetcher(
      other_rewrite_driver_->async_fetcher(),
      0,  // max fetch global queue size
      0,  // fetches per host outgoing queueing threshold
      0,  // fetches per host queued request threshold
      other_server_context_->thread_system(),
      other_server_context_->statistics()));

  ValidateNoChanges("trimmable", CssLinkHref("a.css"));
  EXPECT_EQ(1, counting_distributed_fetcher()->fetch_count());
  EXPECT_EQ(0, other_factory_->counting_url_async_fetcher()->fetch_count());
}

// The distributed task should recognize that a distributed fetch cannot be rate
// controlled.
TEST_F(DistributedRewriteContextTest, QueueFetchOnDistributedFetchTask) {
  SetupDistributedTest();

  // Tack on a rate controlling fetcher which does not allow queueing of any
  // fetches on the distributed task. A distribution of a fetch request should
  // bypass rate controlling.
  other_rewrite_driver_->SetSessionFetcher(new RateControllingUrlAsyncFetcher(
      other_rewrite_driver_->async_fetcher(),
      0,  // max fetch global queue size
      0,  // fetches per host outgoing queueing threshold
      0,  // fetches per host queued request threshold
      other_server_context_->thread_system(),
      other_server_context_->statistics()));

  GoogleString encoded_url = Encode(
      kTestDomain, TrimWhitespaceRewriter::kFilterId, "0", "a.css", "css");

  GoogleString content;
  ResponseHeaders response_headers;
  RequestHeaders request_headers;
  EXPECT_TRUE(FetchResourceUrl(encoded_url, &request_headers, &content,
                               &response_headers));
  // Content should be optimized.
  EXPECT_EQ("a", content);
  EXPECT_EQ(1, counting_distributed_fetcher()->fetch_count());
  EXPECT_EQ(1, other_factory_->counting_url_async_fetcher()->fetch_count());
}

}  // namespace net_instaweb
