/*
 * Copyright 2010 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: jmarantz@google.com (Joshua D. Marantz)

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

#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/logging_proto_impl.h"
#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/http/public/wait_url_async_fetcher.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/file_load_policy.h"
#include "net/instaweb/rewriter/public/mock_resource_callback.h"
#include "net/instaweb/rewriter/public/output_resource_kind.h"
#include "net/instaweb/rewriter/public/request_properties.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/resource_slot.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_stats.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/single_rewrite_context.h"
#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/test_url_namer.h"
#include "pagespeed/kernel/base/abstract_mutex.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/hasher.h"
#include "pagespeed/kernel/base/mock_message_handler.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/null_mutex.h"
#include "pagespeed/kernel/base/sha1_signature.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"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/html/empty_html_filter.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_parse_test_base.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/http_options.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/semantic_type.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
#include "pagespeed/kernel/thread/worker_test_base.h"

namespace net_instaweb {

class RewriteFilter;

class RewriteDriverTest : public RewriteTestBase {
 protected:
  RewriteDriverTest() {}

  bool CanDecodeUrl(const StringPiece& url) {
    GoogleUrl gurl(url);
    RewriteFilter* filter;
    OutputResourcePtr resource(
        rewrite_driver()->DecodeOutputResource(gurl, &filter));
    return (resource.get() != NULL);
  }

  GoogleString BaseUrlSpec() {
    return rewrite_driver()->base_url().Spec().as_string();
  }

  // A helper to call ComputeCurrentFlushWindowRewriteDelayMs() that allows
  // us to keep it private.
  int64 GetFlushTimeout() {
    return rewrite_driver()->ComputeCurrentFlushWindowRewriteDelayMs();
  }

  bool IsDone(RewriteDriver::WaitMode wait_mode, bool deadline_reached) {
    ScopedMutex lock(rewrite_driver()->rewrite_mutex());
    return rewrite_driver()->IsDone(wait_mode, deadline_reached);
  }

  void IncrementAsyncEventsCount() {
    rewrite_driver()->IncrementAsyncEventsCount();
  }

  void DecrementAsyncEventsCount() {
    rewrite_driver()->DecrementAsyncEventsCount();
  }

  void SetupResponsesForDownstreamCacheTesting() {
    // Setup responses for the resources.
    const char kCss[] = "* { display: none; }";
    SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);
    SetResponseWithDefaultHeaders("test/b.css", kContentTypeCss, kCss, 100);

    // Setup a fake response for the expected purge path.
    SetResponseWithDefaultHeaders("http://localhost:1234/purge/",
                                  kContentTypeCss, "", 100);
  }

  void ProcessHtmlForDownstreamCacheTesting() {
    GoogleString input_html(
        StrCat(CssLinkHref("a.css"), "  ", CssLinkHref("test/b.css")));
    ParseUrl(kTestDomain, input_html);
  }

  void TestBlockingRewrite(RequestHeaders* request_headers,
                           bool expected_blocking_rewrite,
                           bool expected_fast_blocking_rewrite) {
    rewrite_driver()->EnableBlockingRewrite(request_headers);
    EXPECT_EQ(expected_blocking_rewrite,
              rewrite_driver()->fully_rewrite_on_flush());
    EXPECT_EQ(expected_fast_blocking_rewrite,
              rewrite_driver()->fast_blocking_rewrite());
    // Reset the flags to their default values after the test.
    rewrite_driver()->set_fully_rewrite_on_flush(false);
    rewrite_driver()->set_fast_blocking_rewrite(true);
    EXPECT_FALSE(request_headers->Has(
        HttpAttributes::kXPsaBlockingRewrite));
    EXPECT_FALSE(request_headers->Has(
        HttpAttributes::kXPsaBlockingRewriteMode));
  }

  void TestPendingEventsIsDone(bool wait_for_completion) {
    EXPECT_TRUE(IsDone(RewriteDriver::kWaitForShutDown, false));
    EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, false));

    IncrementAsyncEventsCount();
    EXPECT_FALSE(IsDone(RewriteDriver::kWaitForShutDown, false));
    EXPECT_EQ(wait_for_completion,
              IsDone(RewriteDriver::kWaitForCompletion, false));
    DecrementAsyncEventsCount();

    EXPECT_TRUE(IsDone(RewriteDriver::kWaitForShutDown, false));
    EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, false));
  }

  void TestPendingEventsDriverCleanup(bool blocking_rewrite,
                                      bool fast_blocking_rewrite) {
    RewriteDriver* other_driver =
        server_context()->NewRewriteDriver(CreateRequestContext());
    other_driver->set_fully_rewrite_on_flush(blocking_rewrite);
    other_driver->set_fast_blocking_rewrite(fast_blocking_rewrite);
    other_driver->IncrementAsyncEventsCount();
    other_driver->Cleanup();
    other_driver->DecrementAsyncEventsCount();
    EXPECT_EQ(0, server_context()->num_active_rewrite_drivers());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(RewriteDriverTest);
};

namespace {

const char kBikePngFile[] = "BikeCrashIcn.png";

const char kNonRewrittenCachableHtml[] =
    "<html>\n<link rel=stylesheet href=a.css>  "
    "<link rel=stylesheet href=test/b.css></html>";

const char kRewrittenCachableHtmlWithCacheExtension[] =
    "<html>\n"
    "<link rel=stylesheet href=a.css.pagespeed.ce.0.css>  "
    "<link rel=stylesheet href=test/b.css.pagespeed.ce.0.css>"
    "</html>";

const char kRewrittenCachableHtmlWithCollapseWhitespace[] =
    "<html>\n<link rel=stylesheet href=a.css> "
    "<link rel=stylesheet href=test/b.css></html>";

TEST_F(RewriteDriverTest, NoChanges) {
  ValidateNoChanges("no_changes",
                    "<head><script src=\"foo.js\"></script></head>"
                    "<body><form method=\"post\">"
                    "<input type=\"checkbox\" checked>"
                    "</form></body>");
}

TEST_F(RewriteDriverTest, CloneMarksNested) {
  RequestHeaders request_headers;
  request_headers.Add(HttpAttributes::kAccept, "image/webp");
  request_headers.Add("a", "b");
  request_headers.Add(HttpAttributes::kVia, "1.1 google");
  rewrite_driver()->SetRequestHeaders(request_headers);
  RewriteDriver* clone1 = rewrite_driver()->Clone();
  EXPECT_TRUE(clone1->is_nested());
  EXPECT_TRUE(clone1->request_properties()->SupportsWebpRewrittenUrls());
  EXPECT_TRUE(rewrite_driver()->request_headers()->HasValue("a", "b"));
  EXPECT_TRUE(clone1->request_headers()->HasValue("a", "b"));
  EXPECT_TRUE(rewrite_driver()->request_headers()->HasValue(
      HttpAttributes::kVia, "1.1 google"));
  EXPECT_FALSE(clone1->request_headers()->HasValue(
      HttpAttributes::kVia, "1.1 google"));
  clone1->Cleanup();

  RewriteDriver* parent2 =
      server_context()->NewRewriteDriver(CreateRequestContext());
  parent2->SetRequestHeaders(request_headers);
  RewriteDriver* clone2 = parent2->Clone();
  EXPECT_TRUE(clone2->is_nested());
  clone2->Cleanup();
  parent2->Cleanup();
}

TEST_F(RewriteDriverTest, TestLegacyUrl) {
  GoogleString hash(32, '0');
  rewrite_driver()->AddFilters();
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/jm." + hash + ".orig"))
      << "not enough dots";
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/jm.0.orig.js"))
      << "hash too short";
  EXPECT_TRUE(CanDecodeUrl("http://example.com/dir/123/jm."+hash+".orig.js"));
  EXPECT_TRUE(CanDecodeUrl(
      "http://x.com/dir/123/jm.0123456789abcdef0123456789ABCDEF.orig.js"));
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/xx."+hash+".orig.js"))
      << "invalid filter xx";
  GoogleString bad_hash(32, 'z');
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/jm." + bad_hash +
                            ".orig.js"))
      << "invalid hash code -- not hex";
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/jm.ab.orig.js"))
      << "invalid hash code -- not 32 chars";
  EXPECT_FALSE(CanDecodeUrl("http://example.com/dir/123/jm."
                            + hash + ".orig.x"))
      << "invalid extension";
}

TEST_F(RewriteDriverTest, TestValidUrlSignatures) {
  StringPiece key("helloworld");
  options()->set_url_signing_key(key);
  EXPECT_EQ(10, options()->sha1signature()->SignatureSizeInChars());
  rewrite_driver()->AddFilters();
  EXPECT_TRUE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.UQ_aP9rObnq.css"))
      << "valid signature";
  EXPECT_FALSE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.UAAAAAAAAAA.css"))
      << "invalid signature";
  EXPECT_FALSE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.U.css"))
      << "no signature";
}

TEST_F(RewriteDriverTest, TestIgnoringUrlSignatures) {
  options()->set_url_signing_key("helloworld");
  options()->set_accept_invalid_signatures(true);
  EXPECT_EQ(10, options()->sha1signature()->SignatureSizeInChars());
  rewrite_driver()->AddFilters();
  EXPECT_TRUE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.UQ_aP9rObnq.css"))
      << "valid signature, ignored";
  EXPECT_TRUE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.UAAAAAAAAAA.css"))
      << "invalid signature, ignored";
  EXPECT_TRUE(CanDecodeUrl(
      "http://signed-urls.example.com/mod_pagespeed_example/styles/"
      "A.all_styles.css.pagespeed.cf.U.css"))
      << "no signature, ignored";
}

TEST_F(RewriteDriverTest, PagespeedObliviousPositiveTest) {
  RewriteOptions* ops = options();
  ops->set_oblivious_pagespeed_urls(false);  // Decode Pagespeed URL.
  rewrite_driver()->AddFilters();

  EXPECT_TRUE(CanDecodeUrl(
      "http://www.example.com/foresee-trigger.js.pagespeed.jm.0D45DpKAeI.js"));
}

TEST_F(RewriteDriverTest, PagespeedObliviousNegativeTest) {
  RewriteOptions* ops = options();
  ops->set_oblivious_pagespeed_urls(true);  // Don't decode Pagespeed URL.
  rewrite_driver()->AddFilters();
  EXPECT_FALSE(CanDecodeUrl(
      "http://www.example.com/foresee-trigger.js.pagespeed.jm.0D45DpKAeI.js"));
}

TEST_F(RewriteDriverTest, TestModernUrl) {
  rewrite_driver()->AddFilters();

  // Sanity-check on a valid one
  EXPECT_TRUE(CanDecodeUrl(
      Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg")));

  // Query is OK, too.
  EXPECT_TRUE(CanDecodeUrl(
      StrCat(Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg"),
             "?s=ok")));

  // Invalid filter code
  EXPECT_FALSE(CanDecodeUrl(
      Encode("http://example.com/", "NOFILTER", "HASH", "Puzzle.jpg", "jpg")));

  // Nonsense extension -- we will just ignore it these days.
  EXPECT_TRUE(CanDecodeUrl(
      Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpgif")));

  // No hash
  GoogleString encoded_url(Encode("http://example.com/", "ce", "123456789",
                                  "Puzzle.jpg", "jpg"));
  GlobalReplaceSubstring("123456789", "", &encoded_url);
  EXPECT_FALSE(CanDecodeUrl(encoded_url));
}

class RewriteDriverTestUrlNamer : public RewriteDriverTest {
 public:
  RewriteDriverTestUrlNamer() {
    SetUseTestUrlNamer(true);
  }
};

TEST_F(RewriteDriverTestUrlNamer, TestEncodedUrls) {
  rewrite_driver()->AddFilters();

  // Sanity-check on a valid one
  EXPECT_TRUE(CanDecodeUrl(
      Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg")));

  // Query is OK, too.
  EXPECT_TRUE(CanDecodeUrl(
      StrCat(Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg"),
             "?s=ok")));

  // Invalid filter code
  EXPECT_FALSE(CanDecodeUrl(
      Encode("http://example.com/", "NOFILTER", "HASH", "Puzzle.jpg", "jpg")));

  // Nonsense extension -- we will just ignore it these days.
  EXPECT_TRUE(CanDecodeUrl(
      Encode("http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpgif")));

  // No hash
  GoogleString encoded_url(Encode("http://example.com/", "ce", "123456789",
                                  "Puzzle.jpg", "jpg"));
  GlobalReplaceSubstring("123456789", "", &encoded_url);
  EXPECT_FALSE(CanDecodeUrl(encoded_url));

  // Valid proxy domain but invalid decoded URL.
  encoded_url = Encode("http://example.com/", "ce", "0", "Puzzle.jpg", "jpg");
  GlobalReplaceSubstring("example.com/",
                         "example.comWYTHQ000JRJFCAAKYU1EMA6VUBDTS4DESLRWIPMS"
                         "KKMQH0XYN1FURDBBSQ9AYXVX3TZDKZEIJNLRHU05ATHBAWWAG2+"
                         "ADDCXPWGGP1VTHJIYU13IIFQYSYMGKIMSFIEBM+HCAACVNGO8CX"
                         "XO%81%9F%F1m/", &encoded_url);
  // By default TestUrlNamer doesn't proxy but we need it to for this test.
  TestUrlNamer::SetProxyMode(true);
  EXPECT_FALSE(CanDecodeUrl(encoded_url));
}

TEST_F(RewriteDriverTestUrlNamer, TestDecodeUrls) {
  // Sanity-check on a valid one
  GoogleUrl gurl_good(Encode(
      "http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg"));
  rewrite_driver()->AddFilters();
  StringVector urls;
  TestUrlNamer::SetProxyMode(true);
  EXPECT_TRUE(rewrite_driver()->DecodeUrl(gurl_good, &urls));
  EXPECT_EQ(1, urls.size());
  EXPECT_EQ("http://example.com/Puzzle.jpg", urls[0]);

  // Invalid filter code
  urls.clear();
  GoogleUrl gurl_bad(Encode(
      "http://example.com/", "NOFILTER", "HASH", "Puzzle.jpg", "jpgif"));
  EXPECT_FALSE(rewrite_driver()->DecodeUrl(gurl_bad, &urls));

  // Combine filters
  urls.clear();
  GoogleUrl gurl_multi(Encode(
      "http://example.com/", "cc", "HASH", MultiUrl("a.css", "b.css"), "css"));
  EXPECT_TRUE(rewrite_driver()->DecodeUrl(gurl_multi, &urls));
  EXPECT_EQ(2, urls.size());
  EXPECT_EQ("http://example.com/a.css", urls[0]);
  EXPECT_EQ("http://example.com/b.css", urls[1]);

  // Invalid Url.
  urls.clear();
  GoogleUrl gurl_invalid("invalid url");
  EXPECT_FALSE(rewrite_driver()->DecodeUrl(gurl_invalid, &urls));
  EXPECT_EQ(0, urls.size());

  // ProxyMode off
  urls.clear();
  TestUrlNamer::SetProxyMode(false);
  SetUseTestUrlNamer(false);
  gurl_good.Reset(Encode(
      "http://example.com/", "ce", "HASH", "Puzzle.jpg", "jpg"));
  EXPECT_TRUE(rewrite_driver()->DecodeUrl(gurl_good, &urls));
  EXPECT_EQ(1, urls.size());
  EXPECT_EQ("http://example.com/Puzzle.jpg", urls[0]);

  urls.clear();
  gurl_multi.Reset(Encode(
      "http://example.com/", "cc", "HASH", MultiUrl("a.css", "b.css"), "css"));
  EXPECT_TRUE(rewrite_driver()->DecodeUrl(gurl_multi, &urls));
  EXPECT_EQ(2, urls.size());
  EXPECT_EQ("http://example.com/a.css", urls[0]);
  EXPECT_EQ("http://example.com/b.css", urls[1]);
}

// Test to make sure we do not put in extra things into the cache.
// This is using the CSS rewriter, which caches the output.
TEST_F(RewriteDriverTest, TestCacheUse) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

// Test to make sure when we fetch a with a Via header, "public"
// is added to the Cache-Control.
TEST_F(RewriteDriverTest, ViaPublicPageSpeedResource) {
  RequestHeaders request_headers;
  request_headers.Add(HttpAttributes::kVia, "1.1 google");
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString url = Encode(kTestDomain, RewriteOptions::kCssFilterId,
                            hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  ResponseHeaders response;
  GoogleString contents;
  ASSERT_TRUE(FetchResourceUrl(url, &request_headers, &contents, &response));
  EXPECT_TRUE(response.HasValue(HttpAttributes::kCacheControl, "public"));

  // Warm load.
  response.Clear();
  ASSERT_TRUE(FetchResourceUrl(url, &request_headers, &contents, &response));
  EXPECT_TRUE(response.HasValue(HttpAttributes::kCacheControl, "public"));
}

// Extension of above with cache invalidation.
TEST_F(RewriteDriverTest, TestCacheUseWithInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  // Set cache invalidation timestamp (to now, so that response date header is
  // in the "past") and load. Should get inserted again.
  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  options()->UpdateCacheInvalidationTimestampMs(now_ms);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  // We expect: identical input a new rname entry (its version # changed),
  // and the output which may not may not auto-advance due to MockTimer
  // black magic.
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(2, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, TestCacheUseWithUrlPatternAllInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  // Set cache invalidation (to now) for all URLs with "a.css" and also
  // invalidate all metadata (the last 'false' argument below).
  options()->AddUrlCacheInvalidationEntry("*a.css*", now_ms, false);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  // We expect: identical input, a new rewrite entry (its version # changed),
  // and the output which may not may not auto-advance due to MockTimer black
  // magic.
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(2, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, TestCacheUseWithUrlPatternOnlyInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  // Set cache invalidation (to now) for all URLs with "a.css". Does not
  // invalidate any metadata (the last 'true' argument below).
  options()->AddUrlCacheInvalidationEntry("*a.css*", now_ms, true);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  // The output rewritten URL is invalidated, the input is also invalidated, and
  // fetched again.  The rewrite entry does not change, and gets reinserted.
  // Thus, we have identical input, rname entry, and the output.
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(3, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, TestCacheUseWithRewrittenUrlAllInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  // Set a URL cache invalidation entry for output URL.  Original input URL is
  // not affected.  Also invalidate all metadata (the
  // ignores_metadata_and_pcache argument being false below).
  options()->AddUrlCacheInvalidationEntry(
      css_minified_url, now_ms, false /* ignores_metadata_and_pcache */);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  // We expect:  a new rewrite entry (its version # changed), and identical
  // output.
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(1, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, TestCacheUseWithRewrittenUrlOnlyInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  // Set cache invalidation (to now) for output URL.  Original input URL is not
  // affected.  Does not invalidate any metadata (the last 'true' argument
  // below).
  options()->AddUrlCacheInvalidationEntry(css_minified_url, now_ms, true);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  // We expect:  identical rewrite entry and output.
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(2, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, TestCacheUseWithOriginalUrlInvalidation) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  const char kMinCss[] = "*{display:none}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString css_minified_url =
      Encode(kTestDomain, RewriteOptions::kCssFilterId,
             hasher()->Hash(kMinCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_minified_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result.
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  // Warm load. This one should not change the number of inserts at all
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  // Set cache invalidation (to now) for input URL.  Rewritten output URL is not
  // affected.  So there will be no cache inserts or reinserts.
  // Note:  Whether we invalidate all metadata (the last argument below) is
  // immaterial in this test.
  options()->AddUrlCacheInvalidationEntry("http://test.com/a.css", now_ms,
                                          false);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(css_minified_url));
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

// Similar to TestCacheUse, but with cache-extender which reconstructs on the
// fly.
TEST_F(RewriteDriverTest, TestCacheUseOnTheFly) {
  AddFilter(RewriteOptions::kExtendCacheCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString cache_extended_url =
      Encode(kTestDomain, RewriteOptions::kCacheExtenderId,
             hasher()->Hash(kCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(cache_extended_url));

  // We should have 2 things inserted:
  // 1) the source data
  // 2) the rname entry for the result (only in sync)
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(2, cold_num_inserts);

  // Warm load. This one does a read-check to avoid a re-inserts in the
  // rname entry.
  EXPECT_TRUE(TryFetchResource(cache_extended_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(2, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

// Verifies that the computed rewrite delay agrees with expectations
// depending on the configuration of constituent delay variables.
TEST_F(RewriteDriverTest, TestComputeCurrentFlushWindowRewriteDelayMs) {
  options()->set_rewrite_deadline_ms(1000);

  // "Start" a parse to configure the start time in the driver.
  ASSERT_TRUE(rewrite_driver()->StartParseId("http://site.com/",
                                             "compute_flush_window_test",
                                             kContentTypeHtml));

  // The per-page deadline is initially unconfigured.
  EXPECT_EQ(1000, GetFlushTimeout());

  // If the per-page deadline is less than the per-flush window timeout,
  // the per-page deadline is returned.
  rewrite_driver()->set_max_page_processing_delay_ms(500);
  EXPECT_EQ(500, GetFlushTimeout());

  // If the per-page deadline exceeds the per-flush window timeout, the flush
  // timeout is returned.
  rewrite_driver()->set_max_page_processing_delay_ms(1750);
  EXPECT_EQ(1000, GetFlushTimeout());

  // If we advance mock time to leave less than a flush window timeout remaining
  // against the page deadline, the appropriate page deadline difference is
  // returned.
  SetTimeMs(start_time_ms() + 1000);
  EXPECT_EQ(750, GetFlushTimeout());  // 1750 - 1000

  // If we advance mock time beyond the per-page limit, a value of 1 is
  // returned. (This is required since values <= 0 are interpreted by internal
  // timeout functions as unlimited.)
  SetTimeMs(start_time_ms() + 2000);
  EXPECT_EQ(1, GetFlushTimeout());

  rewrite_driver()->FinishParse();
}

// Extension of above with cache invalidation.
TEST_F(RewriteDriverTest, TestCacheUseOnTheFlyWithInvalidation) {
  AddFilter(RewriteOptions::kExtendCacheCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);

  GoogleString cache_extended_url =
      Encode(kTestDomain, RewriteOptions::kCacheExtenderId,
             hasher()->Hash(kCss), "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(cache_extended_url));

  // We should have 2 things inserted:
  // 1) the source data
  // 2) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(2, cold_num_inserts);

  // Warm load. This one does a read-check to avoid a re-inserts in the
  // rname entry.
  EXPECT_TRUE(TryFetchResource(cache_extended_url));
  EXPECT_EQ(cold_num_inserts, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
  EXPECT_EQ(2, lru_cache()->num_hits());

  // Set cache invalidation timestamp (to now, so that response date header is
  // in the "past") and load.
  ClearStats();
  int64 now_ms = timer()->NowMs();
  options()->ClearSignatureForTesting();
  options()->UpdateCacheInvalidationTimestampMs(now_ms);
  options()->ComputeSignature();
  EXPECT_TRUE(TryFetchResource(cache_extended_url));
  // We expect: input re-insert, new metadata key
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(1, lru_cache()->num_identical_reinserts());
}

TEST_F(RewriteDriverTest, BaseTags) {
  // Starting the parse, the base-tag will be derived from the html url.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));
  rewrite_driver()->Flush();
  EXPECT_EQ("http://example.com/index.html", BaseUrlSpec());

  // If we then encounter a base tag, that will become the new base.
  rewrite_driver()->ParseText("<base href='http://new.example.com/subdir/'>");
  rewrite_driver()->Flush();
  EXPECT_EQ(0, message_handler()->TotalMessages());
  EXPECT_EQ("http://new.example.com/subdir/", BaseUrlSpec());

  // A second base tag will be ignored, and an info message will be printed.
  rewrite_driver()->ParseText("<base href=http://second.example.com/subdir2>");
  rewrite_driver()->Flush();
  EXPECT_EQ(1, message_handler()->TotalMessages());
  EXPECT_EQ("http://new.example.com/subdir/", BaseUrlSpec());

  // Restart the parse with a new URL and we start fresh.
  rewrite_driver()->FinishParse();
  ASSERT_TRUE(rewrite_driver()->StartParse(
      "http://restart.example.com/index.html"));
  rewrite_driver()->Flush();
  EXPECT_EQ("http://restart.example.com/index.html", BaseUrlSpec());

  // We should be able to reset again.
  rewrite_driver()->ParseText("<base href='http://new.example.com/subdir/'>");
  rewrite_driver()->Flush();
  EXPECT_EQ(1, message_handler()->TotalMessages());
  EXPECT_EQ("http://new.example.com/subdir/", BaseUrlSpec());
}

TEST_F(RewriteDriverTest, RelativeBaseTag) {
  // Starting the parse, the base-tag will be derived from the html url.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));
  rewrite_driver()->ParseText("<base href='subdir/'>");
  rewrite_driver()->Flush();
  EXPECT_EQ(0, message_handler()->TotalMessages());
  EXPECT_EQ("http://example.com/subdir/", BaseUrlSpec());
}

TEST_F(RewriteDriverTest, InvalidBaseTag) {
  // Encountering an invalid base tag should be ignored (except info message).
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // Note: Even nonsensical protocols must be accepted as base URLs.
  rewrite_driver()->ParseText("<base href='slwly:example.com/subdir'>");
  rewrite_driver()->Flush();
  EXPECT_EQ(0, message_handler()->TotalMessages());
  EXPECT_EQ("slwly:example.com/subdir", BaseUrlSpec());

  // Reasonable base URLs following that do not change it.
  rewrite_driver()->ParseText("<base href='http://example.com/absolute/'>");
  rewrite_driver()->Flush();
  EXPECT_EQ("slwly:example.com/subdir", BaseUrlSpec());
}

// The TestUrlNamer produces a url like below which is too long.
// http://cdn.com/http/base.example.com/http/unmapped.example.com/dir/test.jpg.pagespeed.xy.#.     NOLINT
TEST_F(RewriteDriverTest, CreateOutputResourceTooLongSeparateBase) {
  SetUseTestUrlNamer(true);
  OutputResourcePtr resource;
  GoogleString failure_reason;

  options()->set_max_url_size(94);
  resource.reset(rewrite_driver()->CreateOutputResourceWithPath(
      "http://mapped.example.com/dir/",
      "http://unmapped.example.com/dir/",
      "http://base.example.com/dir/",
      "xy",
      "test.jpg",
      kRewrittenResource,
      &failure_reason));
  EXPECT_TRUE(NULL == resource.get());
  EXPECT_EQ("Rewritten URL too long: http://cdn.com/http/base.example.com/"
            "http/unmapped.example.com/dir/test.jpg.pagespeed.xy.#.",
            failure_reason);

  failure_reason = "";
  options()->set_max_url_size(95);
  resource.reset(rewrite_driver()->CreateOutputResourceWithPath(
      "http://mapped.example.com/dir/",
      "http://unmapped.example.com/dir/",
      "http://base.example.com/dir/",
      "xy",
      "test.jpg",
      kRewrittenResource,
      &failure_reason));
  EXPECT_TRUE(NULL != resource.get());
  EXPECT_EQ("", failure_reason);
}

TEST_F(RewriteDriverTest, CreateOutputResourceTooLong) {
  const OutputResourceKind resource_kinds[] = {
    kRewrittenResource,
    kOnTheFlyResource,
    kOutlinedResource,
  };

  // short_path.size() < options()->max_url_size() < long_path.size()
  GoogleString short_path = "http://www.example.com/dir/";
  GoogleString long_path = short_path;
  for (int i = 0; 2 * i < options()->max_url_size(); ++i) {
    long_path += "z/";
  }

  // short_name.size() < options()->max_url_segment_size() < long_name.size()
  GoogleString short_name = "foo.css";
  GoogleString long_name =
      StrCat("foo.css?",
             GoogleString(options()->max_url_segment_size() + 1, 'z'));

  GoogleString dummy_filter_id = "xy";

  OutputResourcePtr resource;
  GoogleString failure_reason;
  for (int k = 0; k < arraysize(resource_kinds); ++k) {
    failure_reason = "";
    // Short name should always succeed at creating new resource.
    resource.reset(rewrite_driver()->CreateOutputResourceWithPath(
        short_path, dummy_filter_id, short_name, resource_kinds[k],
        &failure_reason));
    EXPECT_TRUE(NULL != resource.get());
    EXPECT_EQ("", failure_reason);

    failure_reason = "";
    // Long leaf-name should always fail at creating new resource.
    resource.reset(rewrite_driver()->CreateOutputResourceWithPath(
        short_path, dummy_filter_id, long_name, resource_kinds[k],
        &failure_reason));
    EXPECT_TRUE(NULL == resource.get());
    EXPECT_EQ("Rewritten URL segment too long.", failure_reason);

    failure_reason = "";
    // Long total URL length should always fail at creating new resource.
    resource.reset(rewrite_driver()->CreateOutputResourceWithPath(
        long_path, dummy_filter_id, short_name, resource_kinds[k],
        &failure_reason));
    EXPECT_TRUE(NULL == resource.get());
    EXPECT_EQ(StrCat("Rewritten URL too long: ", long_path, short_name,
                     ".pagespeed.xy.#."),
              failure_reason);
  }
}

TEST_F(RewriteDriverTest, MultipleDomains) {
  rewrite_driver()->AddFilters();

  // Make sure we authorize domains for resources properly. This is a regression
  // test for where loading things from a domain would prevent loads from an
  // another domain from the same RewriteDriver.

  const char kCss[] = "* { display: none; }";
  const char kAltDomain[] = "http://www.example.co.uk/";
  SetResponseWithDefaultHeaders(StrCat(kTestDomain, "a.css"), kContentTypeCss,
                                kCss, 100);
  SetResponseWithDefaultHeaders(StrCat(kAltDomain, "b.css"), kContentTypeCss,
                                kCss, 100);

  GoogleString rewritten1 = Encode(kTestDomain,
                                   RewriteOptions::kCacheExtenderId,
                                   hasher()->Hash(kCss), "a.css", "css");

  GoogleString rewritten2 = Encode(kAltDomain, RewriteOptions::kCacheExtenderId,
                                   hasher()->Hash(kCss), "b.css", "css");

  EXPECT_TRUE(TryFetchResource(rewritten1));
  ClearRewriteDriver();
  EXPECT_TRUE(TryFetchResource(rewritten2));
}

TEST_F(RewriteDriverTest, ResourceCharset) {
  // Make sure we properly pick up the charset into a resource on read.
  const char kUrl[] = "http://www.example.com/foo.css";
  ResponseHeaders resource_headers;
  SetDefaultLongCacheHeaders(&kContentTypeCss, &resource_headers);
  resource_headers.Replace(HttpAttributes::kContentType,
                           "text/css; charset=koi8-r");

  const char kContents[] = "\xF5\xD2\xC1!";  // Ура!
  SetFetchResponse(kUrl, resource_headers, kContents);

  // We do this twice to make sure the cached version is OK, too.
  for (int round = 0; round < 2; ++round) {
    ResourcePtr resource(
        rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
            kUrl));
    MockResourceCallback mock_callback(resource, factory()->thread_system());
    ASSERT_TRUE(resource.get() != NULL);
    resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                        rewrite_driver()->request_context(),
                        &mock_callback);
    EXPECT_TRUE(mock_callback.done());
    EXPECT_TRUE(mock_callback.success());
    EXPECT_EQ(kContents, resource->ExtractUncompressedContents());
    ASSERT_TRUE(resource->type() != NULL);
    EXPECT_EQ(ContentType::kCss, resource->type()->type());
    EXPECT_STREQ("koi8-r", resource->charset());
  }
}

// Test caching behavior for normal UrlInputResources.
// This is the base case that LoadResourcesFromFiles below contrasts with.
TEST_F(RewriteDriverTest, LoadResourcesFromTheWeb) {
  rewrite_driver()->AddFilters();

  const char kStaticUrlPrefix[] = "http://www.example.com/";
  const char kResourceName[ ]= "foo.css";
  GoogleString resource_url = StrCat(kStaticUrlPrefix, kResourceName);
  const char kResourceContents1[] = "body { background: red; }";
  const char kResourceContents2[] = "body { background: blue; }";
  ResponseHeaders resource_headers;
  // This sets 1 year cache lifetime :/ TODO(sligocki): Shorten this.
  SetDefaultLongCacheHeaders(&kContentTypeCss, &resource_headers);
  // Clear the Etag and Last-Modified headers since this
  // SetDefaultLongCacheHeaders sets their value to constants which don't change
  // when their value is updated.
  resource_headers.RemoveAll(HttpAttributes::kEtag);
  resource_headers.RemoveAll(HttpAttributes::kLastModified);

  // Set the fetch value.
  SetFetchResponse(resource_url, resource_headers, kResourceContents1);
  // Make sure file can be loaded. Note this cannot be loaded through the
  // mock_url_fetcher, because it has not been set in that fetcher.
  ResourcePtr resource(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          resource_url));
  MockResourceCallback mock_callback(resource, factory()->thread_system());
  ASSERT_TRUE(resource.get() != NULL);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &mock_callback);
  EXPECT_TRUE(mock_callback.done());
  EXPECT_TRUE(mock_callback.success());
  EXPECT_EQ(kResourceContents1, resource->ExtractUncompressedContents());
  // TODO(sligocki): Check it was cached.

  // Change the fetch value.
  SetFetchResponse(resource_url, resource_headers, kResourceContents2);
  // Check that the resource loads cached.
  ResourcePtr resource2(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          resource_url));
  MockResourceCallback mock_callback2(resource2, factory()->thread_system());
  ASSERT_TRUE(resource2.get() != NULL);
  resource2->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &mock_callback2);
  EXPECT_TRUE(mock_callback2.done());
  EXPECT_TRUE(mock_callback2.success());
  EXPECT_EQ(kResourceContents1, resource2->ExtractUncompressedContents());

  // Advance timer and check that the resource loads updated.
  AdvanceTimeMs(10 * Timer::kYearMs);

  // Check that the resource loads updated.
  ResourcePtr resource3(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          resource_url));
  MockResourceCallback mock_callback3(resource3, factory()->thread_system());
  ASSERT_TRUE(resource3.get() != NULL);
  resource3->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &mock_callback3);
  EXPECT_TRUE(mock_callback3.done());
  EXPECT_EQ(kResourceContents2, resource3->ExtractUncompressedContents());
}

// Test that we successfully load specified resources from files and that
// file resources have the appropriate properties, such as being loaded from
// file every time they are fetched (not being cached).
TEST_F(RewriteDriverTest, LoadResourcesFromFiles) {
  rewrite_driver()->AddFilters();

  const char kStaticUrlPrefix[] = "http://www.example.com/static/";
  const char kStaticFilenamePrefix[] = "/htmlcontent/static/";
  const char kResourceName[ ]= "foo.css";
  GoogleString resource_filename = StrCat(kStaticFilenamePrefix, kResourceName);
  GoogleString resource_url = StrCat(kStaticUrlPrefix, kResourceName);
  const char kResourceContents1[] = "body { background: red; }";
  const char kResourceContents2[] = "body { background: blue; }";

  // Tell RewriteDriver to associate static URLs with filenames.
  options()->file_load_policy()->Associate(kStaticUrlPrefix,
                                           kStaticFilenamePrefix);

  // Write a file.
  WriteFile(resource_filename.c_str(), kResourceContents1);
  // Make sure file can be loaded. Note this cannot be loaded through the
  // mock_url_fetcher, because it has not been set in that fetcher.
  ResourcePtr resource(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          resource_url));
  ASSERT_TRUE(resource.get() != NULL);
  EXPECT_EQ(&kContentTypeCss, resource->type());
  MockResourceCallback mock_callback(resource, factory()->thread_system());
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &mock_callback);
  EXPECT_TRUE(mock_callback.done());
  EXPECT_TRUE(mock_callback.success());
  EXPECT_EQ(kResourceContents1, resource->ExtractUncompressedContents());
  // TODO(sligocki): Check it wasn't cached.

  // Change the file.
  WriteFile(resource_filename.c_str(), kResourceContents2);
  // Make sure the resource loads updated.
  ResourcePtr resource2(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          resource_url));
  ASSERT_TRUE(resource2.get() != NULL);
  EXPECT_EQ(&kContentTypeCss, resource2->type());
  MockResourceCallback mock_callback2(resource2, factory()->thread_system());
  resource2->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &mock_callback2);
  EXPECT_TRUE(mock_callback2.done());
  EXPECT_TRUE(mock_callback2.success());
  EXPECT_EQ(kResourceContents2, resource2->ExtractUncompressedContents());
}

// Make sure the content-type is set correctly, even for URLs with queries.
// http://code.google.com/p/modpagespeed/issues/detail?id=405
TEST_F(RewriteDriverTest, LoadResourcesContentType) {
  rewrite_driver()->AddFilters();

  // Tell RewriteDriver to associate static URLs with filenames.
  options()->file_load_policy()->Associate("http://www.example.com/static/",
                                           "/htmlcontent/static/");

  // Write file with readable extension.
  WriteFile("/htmlcontent/foo.js", "");
  // Load the file with a query param (add .css at the end of the param just
  // for optimal trickyness).
  ResourcePtr resource(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          "http://www.example.com/static/foo.js?version=2.css"));
  EXPECT_TRUE(resource.get() != NULL);
  EXPECT_EQ(&kContentTypeJavascript, resource->type());

  // Write file with bogus extension.
  WriteFile("/htmlcontent/bar.bogus", "");
  // Load it normally.
  ResourcePtr resource2(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          "http://www.example.com/static/bar.bogus"));
  EXPECT_TRUE(resource2.get() != NULL);
  EXPECT_TRUE(NULL == resource2->type());
}

TEST_F(RewriteDriverTest, ResolveAnchorUrl) {
  rewrite_driver()->AddFilters();
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));
  GoogleUrl resolved(rewrite_driver()->base_url(), "#anchor");
  EXPECT_EQ("http://example.com/index.html#anchor", resolved.Spec());
  rewrite_driver()->FinishParse();
}

// A rewrite context that's not actually capable of rewriting -- we just need
// one to pass in to InfoAt in test below.
class MockRewriteContext : public SingleRewriteContext {
 public:
  explicit MockRewriteContext(RewriteDriver* driver) :
      SingleRewriteContext(driver, NULL, NULL) {}

  virtual void RewriteSingle(const ResourcePtr& input,
                             const OutputResourcePtr& output) {}
  virtual const char* id() const { return "mock"; }
  virtual OutputResourceKind kind() const { return kOnTheFlyResource; }
};

TEST_F(RewriteDriverTest, DiagnosticsWithPercent) {
  // Regression test for crash in InfoAt where location has %stuff in it.
  // (make sure it actually shows up first, though).
  int prev_log_level = logging::GetMinLogLevel();
  logging::SetMinLogLevel(logging::LOG_INFO);
  rewrite_driver()->AddFilters();
  MockRewriteContext context(rewrite_driver());
  ResourcePtr resource(
      rewrite_driver()->CreateInputResourceAbsoluteUncheckedForTestsOnly(
          "http://www.example.com/%s%s%s%d%f"));
  ResourceSlotPtr slot(new FetchResourceSlot(resource));
  context.AddSlot(slot);
  rewrite_driver()->InfoAt(&context, "Just a test");
  logging::SetMinLogLevel(prev_log_level);
}

// Tests that we reject https URLs quickly.
TEST_F(RewriteDriverTest, RejectHttpsQuickly) {
  // Need to expressly authorize https even though we don't support it.
  options()->WriteableDomainLawyer()->AddDomain("https://*/",
                                                message_handler());
  AddFilter(RewriteOptions::kRewriteJavascriptExternal);

  // When we don't support https then we fail quickly and cleanly.
  factory()->mock_url_async_fetcher()->set_fetcher_supports_https(false);
  ValidateNoChanges("reject_https_quickly",
                    "<script src='https://example.com/a.js'></script>");
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());

  // When we do support https the fetcher fails to find the resource.
  factory()->mock_url_async_fetcher()->set_fetcher_supports_https(true);
  SetFetchResponse404("https://example.com/a.js");
  ValidateNoChanges("reject_https_quickly",
                    "<script src='https://example.com/a.js'></script>");
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(0, counting_url_async_fetcher()->failure_count());
}

// Test that CreateInputResource doesn't crash when handed a data url.
// This was causing a query of death in some circumstances.
TEST_F(RewriteDriverTest, RejectDataResourceGracefully) {
  MockRewriteContext context(rewrite_driver());
  GoogleUrl dataUrl("data:");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(dataUrl,
                                                             &is_authorized));
  EXPECT_TRUE(resource.get() == NULL);
  EXPECT_TRUE(is_authorized);
}

// Test that when inline_unauthorized_resources is set to false (the default
// case), no resources are created for unauthorized resources, but authorized
// ones are created with the right cache-key.
TEST_F(RewriteDriverTest, NoCreateInputResourceUnauthorized) {
  MockRewriteContext context(rewrite_driver());
  // Call StartParseUrl so that the base_url gets set to a non-empty string.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // Test that an unauthorized resource is not allowed to be created.
  GoogleUrl unauthorized_url("http://unauthorized.domain.com/a.js");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(unauthorized_url,
                                                             &is_authorized));
  EXPECT_TRUE(resource.get() == NULL);
  EXPECT_FALSE(is_authorized);

  // Test that an authorized resource is created with the right cache key even
  // if the filter allows unauthorized domains.
  GoogleUrl authorized_url("http://example.com/a.js");
  ResourcePtr resource2(rewrite_driver()->CreateInputResource(
      authorized_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource2.get() != NULL);
  EXPECT_TRUE(is_authorized);
  EXPECT_STREQ(authorized_url.spec_c_str(), resource2->url());
  EXPECT_STREQ(authorized_url.spec_c_str(), resource2->cache_key());
}

// Test that when inline_unauthorized_resources is set to true, resources
// are created for unauthorized resources with the correctly prefixed keys, and
// the authorized resources continue to get created with the right cache-keys.
TEST_F(RewriteDriverTest, CreateInputResourceUnauthorized) {
  options()->AddInlineUnauthorizedResourceType(semantic_type::kScript);

  MockRewriteContext context(rewrite_driver());
  // Call StartParseUrl so that the base_url gets set to a non-empty string.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // Test that an unauthorized resource is created with the right cache key.
  GoogleUrl unauthorized_url("http://unauthorized.domain.com/a.js");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      unauthorized_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource.get() != NULL);
  EXPECT_FALSE(is_authorized);
  EXPECT_STREQ(unauthorized_url.spec_c_str(), resource->url());
  EXPECT_STREQ("unauth://unauthorized.domain.com/a.js", resource->cache_key());

  // Test that an authorized resource continues to be created with the right
  // cache key.
  GoogleUrl authorized_url("http://example.com/a.js");
  ResourcePtr resource2(rewrite_driver()->CreateInputResource(
      authorized_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource2.get() != NULL);
  EXPECT_TRUE(is_authorized);
  EXPECT_STREQ(authorized_url.spec_c_str(), resource2->url());
  EXPECT_STREQ(authorized_url.spec_c_str(), resource2->cache_key());

  // Test that an unauthorized resource is not created if
  // allow_unauthorized_domain is false.
  ResourcePtr resource3(rewrite_driver()->CreateInputResource(
      unauthorized_url,
      RewriteDriver::kInlineOnlyAuthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource3.get() == NULL);
  EXPECT_FALSE(is_authorized);

  // Test that an unauthorized resource is not created with the default
  // CreateInputResource call.
  ResourcePtr resource4(
      rewrite_driver()->CreateInputResource(unauthorized_url, &is_authorized));
  EXPECT_TRUE(resource4.get() == NULL);
  EXPECT_FALSE(is_authorized);
}

// Test that when inline_unauthorized_resources is set to true, unauthorized
// resources continue to be not created when they match a disallowed pattern.
TEST_F(RewriteDriverTest, CreateInputResourceUnauthorizedWithDisallow) {
  options()->AddInlineUnauthorizedResourceType(semantic_type::kScript);
  options()->Disallow("http://unauthorized.domain.com/*");

  MockRewriteContext context(rewrite_driver());
  // Call StartParseUrl so that the base_url gets set to a non-empty string.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // Test that an unauthorized resource is not created when it is disallowed.
  GoogleUrl unauthorized_url("http://unauthorized.domain.com/a.js");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      unauthorized_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource.get() == NULL);
  EXPECT_FALSE(is_authorized);
}

// Test AllowWhenInlining overrides Disallow when inlining.
TEST_F(RewriteDriverTest, AllowWhenInliningOverridesDisallow) {
  options()->AllowOnlyWhenInlining("*a.js*");

  MockRewriteContext context(rewrite_driver());
  // Call StartParseUrl so that the base_url gets set to a non-empty string.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // This resource would normally not be created because it is disallowed,
  // except that we explicitly allowed it with AllowWhenInlining.
  GoogleUrl js_url("http://example.com/a.js");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      js_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForInlining,
      &is_authorized));
  EXPECT_FALSE(resource.get() == NULL);
  EXPECT_TRUE(is_authorized);
}

// Test AllowWhenInlining fails to overrides Disallow when not inlining.
TEST_F(RewriteDriverTest, AllowWhenInliningDoesntOverrideDisallow) {
  options()->AllowOnlyWhenInlining("*a.js*");

  MockRewriteContext context(rewrite_driver());
  // Call StartParseUrl so that the base_url gets set to a non-empty string.
  ASSERT_TRUE(rewrite_driver()->StartParse("http://example.com/index.html"));

  // This resource would normally not be created because it is disallowed, and
  // AllowWhenInlining doesn't apply because we're not inlining.
  GoogleUrl js_url("http://example.com/a.js");
  bool is_authorized;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      js_url,
      RewriteDriver::kInlineUnauthorizedResources,
      RewriteDriver::kIntendedForGeneral,
      &is_authorized));
  EXPECT_TRUE(resource.get() == NULL);
  EXPECT_FALSE(is_authorized);
}

class ResponseHeadersCheckingFilter : public EmptyHtmlFilter {
 public:
  explicit ResponseHeadersCheckingFilter(RewriteDriver* driver)
      : driver_(driver),
        flush_occurred_(false) {
  }

  void CheckAccess() {
    EXPECT_TRUE(driver_->response_headers() != NULL);
    if (flush_occurred_) {
      EXPECT_TRUE(driver_->mutable_response_headers() == NULL);
    } else {
      EXPECT_EQ(driver_->mutable_response_headers(),
                driver_->response_headers());
    }
  }

  virtual void StartDocument() {
    flush_occurred_ = false;
    CheckAccess();
  }

  virtual void Flush() {
    CheckAccess();  // We still can access the mutable headers during Flush.
    flush_occurred_ = true;
  }

  virtual void StartElement(HtmlElement* element) { CheckAccess(); }
  virtual void EndElement(HtmlElement* element) { CheckAccess(); }
  virtual void EndDocument() { CheckAccess(); }

  virtual const char* Name() const { return "ResponseHeadersCheckingFilter"; }

 private:
  RewriteDriver* driver_;
  bool flush_occurred_;
};

class DetermineEnabledCheckingFilter : public EmptyHtmlFilter {
 public:
  DetermineEnabledCheckingFilter() :
    start_document_called_(false),
    enabled_value_(false) {}

  virtual void StartDocument() {
    start_document_called_ = true;
  }

  virtual void DetermineEnabled(GoogleString* disabled_reason) {
    set_is_enabled(enabled_value_);
  }

  void SetEnabled(bool enabled_value) {
    enabled_value_ = enabled_value;
  }

  bool start_document_called() {
    return start_document_called_;
  }

  virtual const char* Name() const { return "DetermineEnabledCheckingFilter"; }

 private:
  bool start_document_called_;
  bool enabled_value_;
};

TEST_F(RewriteDriverTest, DetermineEnabledTest) {
  RewriteDriver* driver = rewrite_driver();
  DetermineEnabledCheckingFilter* filter =
      new DetermineEnabledCheckingFilter();
  driver->AddOwnedEarlyPreRenderFilter(filter);
  driver->StartParse("http://example.com/index.html");
  rewrite_driver()->ParseText("<div>");
  driver->Flush();
  EXPECT_FALSE(filter->start_document_called());
  rewrite_driver()->ParseText("</div>");
  driver->FinishParse();

  filter = new DetermineEnabledCheckingFilter();
  filter->SetEnabled(true);
  driver->AddOwnedEarlyPreRenderFilter(filter);
  driver->StartParse("http://example.com/index.html");
  rewrite_driver()->ParseText("<div>");
  driver->Flush();
  EXPECT_TRUE(filter->start_document_called());
  rewrite_driver()->ParseText("</div>");
  driver->FinishParse();
}

// Tests that we access driver->response_headers() before/after Flush(),
// and driver->mutable_response_headers() at only before Flush().
TEST_F(RewriteDriverTest, ResponseHeadersAccess) {
  RewriteDriver* driver = rewrite_driver();
  ResponseHeaders headers;
  driver->set_response_headers_ptr(&headers);
  driver->AddOwnedEarlyPreRenderFilter(new ResponseHeadersCheckingFilter(
      driver));
  driver->AddOwnedPostRenderFilter(new ResponseHeadersCheckingFilter(driver));

  // Starting the parse, the base-tag will be derived from the html url.
  ASSERT_TRUE(driver->StartParse("http://example.com/index.html"));
  rewrite_driver()->ParseText("<div>");
  driver->Flush();
  rewrite_driver()->ParseText("</div>");
  driver->FinishParse();
}

TEST_F(RewriteDriverTest, SetSessionFetcherTest) {
  AddFilter(RewriteOptions::kExtendCacheCss);

  const char kFetcher1Css[] = "Fetcher #1";
  const char kFetcher2Css[] = "Fetcher #2";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kFetcher1Css, 100);

  GoogleString url = Encode(kTestDomain, RewriteOptions::kCacheExtenderId,
                            hasher()->Hash(kFetcher1Css), "a.css", "css");

  // Fetch from default.
  GoogleString output;
  ResponseHeaders response_headers;
  EXPECT_TRUE(FetchResourceUrl(url, &output, &response_headers));
  EXPECT_STREQ(kFetcher1Css, output);
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // Load up a different file into a second fetcher.
  // We misappropriate the response_headers from previous fetch for simplicity.
  scoped_ptr<MockUrlFetcher> mock2(new MockUrlFetcher);
  mock2->SetResponse(AbsolutifyUrl("a.css"), response_headers, kFetcher2Css);

  // Switch over to new fetcher, making sure to set two of them to exercise
  // memory management. Note the synchronous mock fetcher we still have to
  // manage ourselves (as the RewriteDriver API is for async ones only).
  RewriteDriver* driver = rewrite_driver();
  driver->SetSessionFetcher(mock2.release());
  CountingUrlAsyncFetcher* counter =
      new CountingUrlAsyncFetcher(driver->async_fetcher());
  driver->SetSessionFetcher(counter);
  EXPECT_EQ(counter, driver->async_fetcher());

  // Note that FetchResourceUrl will call driver->Clear() so we cannot
  // access 'counter' past this point.
  lru_cache()->Clear();  // get rid of cached version of input
  EXPECT_TRUE(FetchResourceUrl(url, &output, &response_headers));
  EXPECT_STREQ(kFetcher2Css, output);
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // As FetchResourceUrl has cleared the driver, further fetcher should
  // grab fetcher 1 version.
  lru_cache()->Clear();  // get rid of cached version of input
  EXPECT_TRUE(FetchResourceUrl(url, &output, &response_headers));
  EXPECT_STREQ(kFetcher1Css, output);
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());
}

class WaitAsyncFetch : public StringAsyncFetch {
 public:
  WaitAsyncFetch(const RequestContextPtr& req, GoogleString* content,
                 ThreadSystem* thread_system)
      : StringAsyncFetch(req, content),
        sync_(thread_system) {
  }
  virtual ~WaitAsyncFetch() {}

  virtual void HandleDone(bool status) {
    StringAsyncFetch::HandleDone(status);
    sync_.Notify();
  }
  void Wait() { sync_.Wait(); }

 private:
  WorkerTestBase::SyncPoint sync_;
};

class InPlaceTest : public RewriteTestBase {
 protected:
  InPlaceTest() {}
  virtual ~InPlaceTest() {}

  bool FetchInPlaceResource(const StringPiece& url,
                            bool proxy_mode,
                            GoogleString* content,
                            ResponseHeaders* response) {
    GoogleUrl gurl(url);
    content->clear();
    WaitAsyncFetch async_fetch(CreateRequestContext(), content,
                               server_context()->thread_system());
    async_fetch.set_response_headers(response);
    rewrite_driver_->SetRequestHeaders(*async_fetch.request_headers());
    rewrite_driver_->FetchInPlaceResource(gurl, proxy_mode,
                                          &async_fetch);
    async_fetch.Wait();

    // Make sure we let the rewrite complete, and also wait for the driver to be
    // idle so we can reuse it safely.
    rewrite_driver_->WaitForShutDown();
    ClearRewriteDriver();  // makes sure to re-create the request context.

    EXPECT_TRUE(async_fetch.done());
    return async_fetch.done() && async_fetch.success();
  }

  bool TryFetchInPlaceResource(const StringPiece& url,
                               bool proxy_mode) {
    GoogleString contents;
    ResponseHeaders response;
    return FetchInPlaceResource(url, proxy_mode, &contents, &response);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(InPlaceTest);
};

TEST_F(InPlaceTest, FetchInPlaceResource) {
  AddFilter(RewriteOptions::kRewriteCss);

  GoogleString url = "http://example.com/foo.css";
  SetResponseWithDefaultHeaders(url, kContentTypeCss,
                                ".a { color: red; }", 100);
  GoogleString html_url = "http://example.com/foo.html";
  SetResponseWithDefaultHeaders(html_url, kContentTypeHtml,
                                "<b>Bold!</b>", 100);

  // This will fail because cache is empty and we are not allowing HTTP fetch.
  EXPECT_FALSE(TryFetchInPlaceResource(url, false /* proxy_mode */));
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(1, http_cache()->cache_misses()->Get());
  EXPECT_EQ(0, http_cache()->cache_inserts()->Get());
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  ClearStats();

  // Now we allow HTTP fetches and we expect success.
  EXPECT_TRUE(TryFetchInPlaceResource(url, true /* proxy_mode */));
  EXPECT_EQ(0, http_cache()->cache_hits()->Get());
  EXPECT_EQ(1, http_cache()->cache_misses()->Get());
  // We insert both original and rewritten resources.
  EXPECT_EQ(2, http_cache()->cache_inserts()->Get());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
  ClearStats();

  // Now that we've loaded the resource into cache, we expect success.
  EXPECT_TRUE(TryFetchInPlaceResource(url, false /* proxy_mode */));
  EXPECT_EQ(1, http_cache()->cache_hits()->Get());
  EXPECT_EQ(0, http_cache()->cache_misses()->Get());
  EXPECT_EQ(0, http_cache()->cache_inserts()->Get());
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  ClearStats();

  // In proxy mode, we should successfully pass through HTML.
  EXPECT_TRUE(TryFetchInPlaceResource(html_url, true /* proxy_mode */));

  // In non-proxy mode producing HTML should fail; it's expected the origin
  // server would produce things we aren't optimizing through its usual
  // code paths. Note that this needs to happen after the previous call so that
  // we get the resource into cache.
  EXPECT_FALSE(TryFetchInPlaceResource(html_url, false /* proxy_mode */));
}

TEST_F(InPlaceTest, InPlaceCssDebug) {
  // Regression test: ipro + debug would crash when a debug message was
  // produced.
  options()->EnableFilter(RewriteOptions::kDebug);
  options()->EnableFilter(RewriteOptions::kFlattenCssImports);
  AddFilter(RewriteOptions::kRewriteCss);

  GoogleString url = "http://example.com/foo.css";
  SetResponseWithDefaultHeaders(url, kContentTypeCss,
                                "@import \"weird://foo\"; .a { color: red; }",
                                100);

  EXPECT_TRUE(TryFetchInPlaceResource(url, true /* proxy_mode */));
}

TEST_F(RewriteDriverTest, DebugModeTest) {
  // Verify that DebugMode() corresponds to RewriteOptions::kDebug as expected

  EXPECT_FALSE(rewrite_driver()->DebugMode());

  options()->EnableFilter(RewriteOptions::kDebug);
  EXPECT_TRUE(rewrite_driver()->DebugMode());

  options()->DisableFilter(RewriteOptions::kDebug);
  EXPECT_FALSE(rewrite_driver()->DebugMode());
}

TEST_F(RewriteDriverTest, CachePollutionWithWrongEncodingCharacter) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("dir/a.css", kContentTypeCss, kCss, 100);

  GoogleString css_wrong_url =
      "http://test.com/dir/B.a.css.pagespeed.cf.0.css";

  GoogleString correct_url = Encode(
      "dir/", RewriteOptions::kCssFilterId, hasher()->Hash(kCss),
      "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_wrong_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  EXPECT_EQ(kFoundResult,
            HttpBlockingFindStatus(StrCat(kTestDomain, correct_url),
                                   http_cache()));

  GoogleString input_html(CssLinkHref("dir/a.css"));
  GoogleString output_html(CssLinkHref(correct_url));
  ValidateExpected("wrong_encoding", input_html, output_html);
}

TEST_F(RewriteDriverTest, CachePollutionWithLowerCasedncodingCharacter) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("dir/a.css", kContentTypeCss, kCss, 100);

  GoogleString css_wrong_url =
      "http://test.com/dir/a.a.css.pagespeed.cf.0.css";

  GoogleString correct_url = Encode(
      "dir/", RewriteOptions::kCssFilterId, hasher()->Hash(kCss),
      "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_wrong_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  EXPECT_EQ(kFoundResult,
            HttpBlockingFindStatus(StrCat(kTestDomain, correct_url),
                                   http_cache()));

  GoogleString input_html(CssLinkHref("dir/a.css"));
  GoogleString output_html(CssLinkHref(correct_url));
  ValidateExpected("wrong_encoding", input_html, output_html);
}

TEST_F(RewriteDriverTest, CachePollutionWithExperimentId) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("dir/a.css", kContentTypeCss, kCss, 100);

  GoogleString css_wrong_url =
      "http://test.com/dir/A.a.css.pagespeed.b.cf.0.css";

  GoogleString correct_url = Encode(
      "dir/", RewriteOptions::kCssFilterId, hasher()->Hash(kCss),
      "a.css", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_wrong_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  EXPECT_EQ(kFoundResult,
            HttpBlockingFindStatus(StrCat(kTestDomain, correct_url),
                                   http_cache()));

  GoogleString input_html(CssLinkHref("dir/a.css"));
  GoogleString output_html(CssLinkHref(correct_url));
  ValidateExpected("wrong_encoding", input_html, output_html);
}

TEST_F(RewriteDriverTest, CachePollutionWithQueryParams) {
  AddFilter(RewriteOptions::kRewriteCss);

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("dir/a.css?ver=3", kContentTypeCss, kCss, 100);

  GoogleString css_wrong_url =
      "http://test.com/dir/A.a.css,qver%3D3.pagespeed.cf.0.css";

  GoogleString correct_url = Encode(
      "dir/", RewriteOptions::kCssFilterId, hasher()->Hash(kCss),
      "a.css?ver=3", "css");

  // Cold load.
  EXPECT_TRUE(TryFetchResource(css_wrong_url));

  // We should have 3 things inserted:
  // 1) the source data
  // 2) the result
  // 3) the rname entry for the result
  int cold_num_inserts = lru_cache()->num_inserts();
  EXPECT_EQ(3, cold_num_inserts);

  EXPECT_EQ(kFoundResult,
            HttpBlockingFindStatus(StrCat(kTestDomain, correct_url),
                                   http_cache()));

  GoogleString input_html(CssLinkHref("dir/a.css?ver=3"));
  GoogleString output_html(CssLinkHref(correct_url));
  ValidateExpected("wrong_encoding", input_html, output_html);
}

TEST_F(RewriteDriverTest, NoLoggingForImagesRewrittenInsideCss) {
  options()->set_image_inline_max_bytes(100000);
  options()->EnableFilter(RewriteOptions::kExtendCacheCss);
  options()->EnableFilter(RewriteOptions::kRewriteCss);
  options()->EnableFilter(RewriteOptions::kExtendCacheImages);
  options()->EnableFilter(RewriteOptions::kRecompressPng);
  options()->set_always_rewrite_css(true);
  rewrite_driver_->AddFilters();

  GoogleString contents = "#a {background:url(1.png) ;}";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, contents, 100);
  AddFileToMockFetcher(StrCat(kTestDomain, "1.png"), kBikePngFile,
                       kContentTypePng, 100);

  GoogleString correct_url = Encode(
        "", RewriteOptions::kCssFilterId, hasher()->Hash(contents),
        "a.css", "css");

  GoogleString input_html(CssLinkHref("a.css"));
  GoogleString output_html(CssLinkHref(correct_url));

  ValidateExpected("no_logging_images_inside_css", input_html, output_html);
  LoggingInfo* logging_info = rewrite_driver_->log_record()->logging_info();
  ASSERT_EQ(1, logging_info->rewriter_info_size());
  EXPECT_EQ("cf", logging_info->rewriter_info(0).id());
}

TEST_F(RewriteDriverTest, DecodeMultiUrlsEncodesCorrectly) {
  options()->EnableFilter(RewriteOptions::kRewriteCss);
  options()->EnableFilter(RewriteOptions::kCombineCss);
  rewrite_driver()->AddFilters();

  const char kCss[] = "* { display: none; }";
  SetResponseWithDefaultHeaders("a.css", kContentTypeCss, kCss, 100);
  SetResponseWithDefaultHeaders("test/b.css", kContentTypeCss, kCss, 100);

  // Combine filters
  GoogleString multi_url = Encode(
      "", RewriteOptions::kCssFilterId, hasher()->Hash(kCss),
      "a.css+test,_b.css.pagespeed.cc.0.css", "css");
  EXPECT_TRUE(TryFetchResource(StrCat(kTestDomain, multi_url)));

  GoogleString input_html(
      StrCat(CssLinkHref("a.css"), CssLinkHref("test/b.css")));
  ParseUrl(kTestDomain, input_html);
  StringVector css_urls;
  CollectCssLinks("multi", output_buffer_, &css_urls);
  EXPECT_EQ(1UL, css_urls.size());
  EXPECT_EQ(multi_url, css_urls[0]);
}

// Records URL of the last img element it sees at point of RenderDone().
class RenderDoneCheckingFilter : public EmptyHtmlFilter {
 public:
  RenderDoneCheckingFilter() : element_(NULL) {}
  virtual ~RenderDoneCheckingFilter() {}
  const GoogleString& src() const { return src_; }

 protected:
  virtual void StartElement(HtmlElement* element) {
    if (element->keyword() == HtmlName::kImg) {
      element_ = element;
    }
  }

  virtual void RenderDone() {
    if (element_ != NULL) {
      const char* val = element_->AttributeValue(HtmlName::kSrc);
      src_ = (val != NULL ? val : "");
    }
  }

  virtual const char* Name() const { return "RenderDoneCheckingFilter"; }

 private:
  HtmlElement* element_;
  GoogleString src_;
  DISALLOW_COPY_AND_ASSIGN(RenderDoneCheckingFilter);
};

TEST_F(RewriteDriverTest, RenderDoneTest) {
  // Test to make sure RenderDone sees output of a pre-render filter.
  RewriteDriver* driver = rewrite_driver();
  RenderDoneCheckingFilter* filter =
      new RenderDoneCheckingFilter();
  driver->AddOwnedEarlyPreRenderFilter(filter);
  SetResponseWithDefaultHeaders("a.png", kContentTypePng, "PNGkinda", 100);
  AddFilter(RewriteOptions::kExtendCacheImages);

  driver->StartParse(kTestDomain);
  rewrite_driver()->ParseText("<img src=\"a.png\">");
  driver->FinishParse();
  EXPECT_EQ(Encode("", RewriteOptions::kCacheExtenderId, "0", "a.png", "png"),
            filter->src());
}

TEST_F(RewriteDriverTest, BlockingRewriteFlagTest) {
  RequestHeaders request_headers;
  RewriteDriver* driver = rewrite_driver();
  options()->ClearSignatureForTesting();
  options()->set_blocking_rewrite_key("blocking");
  options()->ComputeSignature();

  // case 1.
  TestBlockingRewrite(&request_headers, false, true);

  // case 2.
  request_headers.Add(HttpAttributes::kXPsaBlockingRewrite, "not-blocking");
  TestBlockingRewrite(&request_headers, false, true);

  // case 3.
  request_headers.Add(HttpAttributes::kXPsaBlockingRewrite, "blocking");
  TestBlockingRewrite(&request_headers, true, true);

  // case 4.
  request_headers.Add(HttpAttributes::kXPsaBlockingRewrite, "blocking");
  request_headers.Add(HttpAttributes::kXPsaBlockingRewriteMode, "junk");
  TestBlockingRewrite(&request_headers, true, true);

  // case 5.
  request_headers.Add(HttpAttributes::kXPsaBlockingRewrite, "blocking");
  request_headers.Add(HttpAttributes::kXPsaBlockingRewriteMode, "slow");
  TestBlockingRewrite(&request_headers, true, false);

  options()->ClearSignatureForTesting();
  options()->EnableBlockingRewriteForRefererUrlPattern("http://example.com");
  options()->ComputeSignature();

  // case 6.
  request_headers.Add(HttpAttributes::kReferer, "http://junk.com/");
  driver->EnableBlockingRewrite(&request_headers);
  TestBlockingRewrite(&request_headers, false, true);

  // case 7.
  request_headers.RemoveAll(HttpAttributes::kReferer);
  request_headers.Add(HttpAttributes::kReferer, "http://example.com");
  request_headers.Add(HttpAttributes::kXPsaBlockingRewriteMode, "junk");
  TestBlockingRewrite(&request_headers, true, true);

  // case 8.
  request_headers.RemoveAll(HttpAttributes::kReferer);
  request_headers.Add(HttpAttributes::kReferer, "http://example.com");
  request_headers.Add(HttpAttributes::kXPsaBlockingRewriteMode, "slow");
  TestBlockingRewrite(&request_headers, true, false);
}

TEST_F(RewriteDriverTest, PendingAsyncEventsTest) {
  RewriteDriver* driver = rewrite_driver();

  driver->set_fully_rewrite_on_flush(true);
  driver->set_fast_blocking_rewrite(true);
  TestPendingEventsIsDone(true);

  // Only when we are doing a slow blocking rewrite (waiting for async events),
  // IsDone() returns false for kWaitForCompletion.
  driver->set_fully_rewrite_on_flush(true);
  driver->set_fast_blocking_rewrite(false);
  TestPendingEventsIsDone(false);

  driver->set_fully_rewrite_on_flush(false);
  driver->set_fast_blocking_rewrite(true);
  TestPendingEventsIsDone(true);

  driver->set_fully_rewrite_on_flush(false);
  driver->set_fast_blocking_rewrite(false);
  TestPendingEventsIsDone(true);

  // Make sure we properly cleanup as well.
  TestPendingEventsDriverCleanup(false, false);
  TestPendingEventsDriverCleanup(false, true);
  TestPendingEventsDriverCleanup(true, false);
  TestPendingEventsDriverCleanup(true, true);
}

TEST_F(RewriteDriverTest, PendingRenderBlockingAsyncEventsTest) {
  RewriteDriver* driver = rewrite_driver();
  driver->set_fully_rewrite_on_flush(false);

  // Plain async event doesn't prevent completion.
  driver->IncrementAsyncEventsCount();
  EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, false));
  EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, true));

  // Render blocking one does, however.
  driver->IncrementRenderBlockingAsyncEventsCount();
  EXPECT_FALSE(IsDone(RewriteDriver::kWaitForCompletion, false));
  EXPECT_FALSE(IsDone(RewriteDriver::kWaitForCompletion, true));

  driver->DecrementAsyncEventsCount();
  // Still does when regular async removed.
  EXPECT_FALSE(IsDone(RewriteDriver::kWaitForCompletion, false));
  EXPECT_FALSE(IsDone(RewriteDriver::kWaitForCompletion, true));

  // Once all counts are gone it's now Done, though.
  driver->DecrementRenderBlockingAsyncEventsCount();
  EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, false));
  EXPECT_TRUE(IsDone(RewriteDriver::kWaitForCompletion, true));
}

TEST_F(RewriteDriverTest, ValidateCacheResponseRewrittenWebp) {
  const StringPiece kWebpMimeType = kContentTypeWebp.mime_type();
  RequestContextPtr request_context(new RequestContext(
      kDefaultHttpOptionsForTests, new NullMutex, timer()));
  options()->ClearSignatureForTesting();
  ResponseHeaders response_headers;
  response_headers.Add(HttpAttributes::kContentType, kWebpMimeType);
  response_headers.SetDateAndCaching(MockTimer::kApr_5_2010_ms,
                                     300 * Timer::kSecondMs, "");
  response_headers.ComputeCaching();
  const char kOriginUrl[] = "foo.webp";

  // No vary:accept, accepts_webp false.  Note that we ignore the lack of
  // browser capability to display webp and send it anyway.
  request_context->SetAcceptsWebp(false);
  options()->set_serve_rewritten_webp_urls_to_any_agent(true);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));
  options()->set_serve_rewritten_webp_urls_to_any_agent(false);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));

  // no vary:accept, accepts_webp true.
  request_context->SetAcceptsWebp(true);
  options()->set_serve_rewritten_webp_urls_to_any_agent(true);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));
  options()->set_serve_rewritten_webp_urls_to_any_agent(false);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));


  // Now add a Vary: Accept and we'll start paying attention to the
  // browser capabilities.
  response_headers.Add(HttpAttributes::kVary, HttpAttributes::kAccept);
  response_headers.ComputeCaching();
  request_context->SetAcceptsWebp(false);

  // vary:accept, accepts_webp false.
  options()->set_serve_rewritten_webp_urls_to_any_agent(true);
  EXPECT_FALSE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));
  options()->set_serve_rewritten_webp_urls_to_any_agent(false);
  EXPECT_FALSE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));

  // vary:accept, accepts_webp true.
  request_context->SetAcceptsWebp(true);
  options()->set_serve_rewritten_webp_urls_to_any_agent(true);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));
  options()->set_serve_rewritten_webp_urls_to_any_agent(false);
  EXPECT_TRUE(OptionsAwareHTTPCacheCallback::IsCacheValid(
      kOriginUrl, *options(), request_context, response_headers));
}

TEST_F(RewriteDriverTest, SetRequestHeadersPopulatesWebpAccept) {
  RequestHeaders headers;
  headers.Add(HttpAttributes::kAccept, "image/webp");
  headers.Add(HttpAttributes::kUserAgent,
              UserAgentMatcherTestBase::kChrome42UserAgent);
  rewrite_driver()->SetRequestHeaders(headers);
  const RequestProperties* request_properties =
      rewrite_driver()->request_properties();
  EXPECT_TRUE(request_properties->SupportsWebpInPlace());
  EXPECT_TRUE(request_properties->SupportsWebpRewrittenUrls());
  EXPECT_TRUE(request_properties->SupportsWebpLosslessAlpha());
}

TEST_F(RewriteDriverTest, SetRequestHeadersPopulatesWebpNoAccept) {
  RequestHeaders headers;
  headers.Add(HttpAttributes::kUserAgent,
              UserAgentMatcherTestBase::kAndroidICSUserAgent);
  rewrite_driver()->SetRequestHeaders(headers);
  const RequestProperties* request_properties =
      rewrite_driver()->request_properties();
  EXPECT_FALSE(request_properties->SupportsWebpInPlace());
  EXPECT_TRUE(request_properties->SupportsWebpRewrittenUrls());
  EXPECT_FALSE(request_properties->SupportsWebpLosslessAlpha());
}

// Test classes created for using a managed rewrite driver, so that downstream
// caching behavior (especially cache purging) can be tested. Since managed
// rewrite drivers need their filters to be setup before the custom rewrite
// driver is constructed, we need these classes with specific SetUp methods
// for configuring the options.

// This class has ExtendCacheCss filter enabled and has possibility of
// purge requests for the html because of the resources not being
// rewritten in the very first go.
class DownstreamCacheWithPossiblePurgeTest : public RewriteDriverTest {
 protected:
  void SetUp() {
    options()->EnableFilter(RewriteOptions::kExtendCacheCss);
    SetUseManagedRewriteDrivers(true);
    RewriteDriverTest::SetUp();
  }
};

// This class has CollapseWhitespace filter enabled and has no possibility of
// purge requests for the html because the html will always get fully rewritten
// in the very first go.
class DownstreamCacheWithNoPossiblePurgeTest : public RewriteDriverTest {
 protected:
  void SetUp() {
    options()->EnableFilter(RewriteOptions::kCollapseWhitespace);
    SetUseManagedRewriteDrivers(true);
    RewriteDriverTest::SetUp();
  }
};

TEST_F(DownstreamCacheWithPossiblePurgeTest, DownstreamCacheEnabled) {
  SetDownstreamCacheDirectives("GET", "http://localhost:1234/purge", "");
  // Use a wait fetcher so that the response does not get a chance to get
  // rewritten.
  SetupWaitFetcher();
  // Since we want to call both FinishParse() and WaitForCompletion() (it's
  // inside CallFetcherCallbacksForDriver) on a managed rewrite driver,
  // we have to pin it, since otherwise FinishParse will drop our last
  // reference.
  rewrite_driver()->AddUserReference();
  SetupResponsesForDownstreamCacheTesting();
  // Setup request headers since the subsequent purge request needs this.
  RequestHeaders request_headers;
  rewrite_driver()->SetRequestHeaders(request_headers);
  ProcessHtmlForDownstreamCacheTesting();
  EXPECT_STREQ(kNonRewrittenCachableHtml, output_buffer_);
  // Since the response would now have been generated (without any rewriting,
  // because neither of the 2 resource fetches for a.css and b.css
  // would have completed), we allow the fetches to complete now.
  factory()->CallFetcherCallbacksForDriver(rewrite_driver());
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());

  // Now we want to permit fetches to go ahead once we let purge happen
  factory()->wait_url_async_fetcher()->SetPassThroughMode(true);
  rewrite_driver()->Cleanup();  // Drop our ref, to let purge go ahead.

  // We can actually check the result of flush already because
  // our fetcher is immediate.
  EXPECT_EQ(3, counting_url_async_fetcher()->fetch_count());
  EXPECT_STREQ("http://localhost:1234/purge/",
               counting_url_async_fetcher()->most_recent_fetched_url());
  EXPECT_EQ(1, factory()->rewrite_stats()->
                   downstream_cache_purge_attempts()->Get());
}

TEST_F(DownstreamCacheWithPossiblePurgeTest, DownstreamCacheDisabled) {
  SetDownstreamCacheDirectives("GET", "", "");
  // Use a wait fetcher so that the response does not get a chance to get
  // rewritten.
  SetupWaitFetcher();
  // Since we want to call both FinishParse() and WaitForCompletion() (it's
  // inside CallFetcherCallbacksForDriver) on a managed rewrite driver,
  // we have to pin it, since otherwise FinishParse will drop our last
  // reference.
  rewrite_driver()->AddUserReference();
  SetupResponsesForDownstreamCacheTesting();
  // Setup request headers since the subsequent purge request needs this.
  RequestHeaders request_headers;
  rewrite_driver()->SetRequestHeaders(request_headers);
  ProcessHtmlForDownstreamCacheTesting();
  EXPECT_STREQ(kNonRewrittenCachableHtml, output_buffer_);
  // Since the response would now have been generated (without any rewriting,
  // because neither of the 2 resource fetches for a.css and b.css
  // would have completed), we allow the fetches to complete now.
  factory()->CallFetcherCallbacksForDriver(rewrite_driver());
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());

  // The purge-request-fetch can be allowed to complete without any waiting.
  // Hence, we set the pass-through-mode to true.
  factory()->wait_url_async_fetcher()->SetPassThroughMode(true);
  rewrite_driver()->Cleanup();  // Drop our ref, to let any purge go ahead.

  // We expect no purges in this flow.
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());
  EXPECT_STREQ("http://test.com/test/b.css",
               counting_url_async_fetcher()->most_recent_fetched_url());
  EXPECT_EQ(0, factory()->rewrite_stats()->
                   downstream_cache_purge_attempts()->Get());
}

TEST_F(DownstreamCacheWithPossiblePurgeTest,
       DownstreamCache100PercentRewritten) {
  SetDownstreamCacheDirectives("GET", "http://localhost:1234/purge", "");
  // Do not use a wait fetcher here because we want both the fetches (for a.css
  // and b.css) and their rewrites to finish before the response is served out.
  SetupResponsesForDownstreamCacheTesting();
  // Setup request headers since the subsequent purge request needs this.
  RequestHeaders request_headers;
  rewrite_driver()->SetRequestHeaders(request_headers);
  ProcessHtmlForDownstreamCacheTesting();
  EXPECT_STREQ(kRewrittenCachableHtmlWithCacheExtension, output_buffer_);
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());

  // We expect no purges in this flow.
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());
  EXPECT_STREQ("http://test.com/test/b.css",
               counting_url_async_fetcher()->most_recent_fetched_url());
  EXPECT_EQ(0, factory()->rewrite_stats()->
                   downstream_cache_purge_attempts()->Get());
}

TEST_F(DownstreamCacheWithNoPossiblePurgeTest, DownstreamCacheNoInitRewrites) {
  SetDownstreamCacheDirectives("GET", "http://localhost:1234/purge", "");
  // Use a wait fetcher so that the response does not get a chance to get
  // rewritten.
  SetupWaitFetcher();
  rewrite_driver()->AddUserReference();
  SetupResponsesForDownstreamCacheTesting();
  // Setup request headers since the subsequent purge request needs this.
  RequestHeaders request_headers;
  rewrite_driver()->SetRequestHeaders(request_headers);
  ProcessHtmlForDownstreamCacheTesting();
  EXPECT_STREQ(kRewrittenCachableHtmlWithCollapseWhitespace, output_buffer_);

  // Since only collapse-whitespace is enabled in this test, we do not expect
  // any fetches (or fetch callbacks for the wait fetcher) here.
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());

  // Release RewriteDriver and trigger any purge.
  rewrite_driver()->Cleanup();
  EXPECT_EQ(0, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(0, factory()->rewrite_stats()->
                   downstream_cache_purge_attempts()->Get());
}

}  // namespace

}  // namespace net_instaweb
