blob: aca2b4b370a71626414cb1aeb02dc0f956055892 [file] [log] [blame]
/**
* 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: sligocki@google.com (Shawn Ligocki)
#include "net/instaweb/util/fetcher_test.h"
namespace net_instaweb {
const char FetcherTest::kStartDate[] = "Sun, 16 Dec 1979 02:27:45 GMT";
const char FetcherTest::kHtmlContent[] = "<html><body>Nuts!</body></html>";
const char FetcherTest::kErrorMessage[] = "Invalid URL";
const char FetcherTest::kGoodUrl[] = "http://pi.com";
const char FetcherTest::kNotCachedUrl[] = "http://not_cacheable.com";
const char FetcherTest::kBadUrl[] = "http://this_url_will_fail.com";
const char FetcherTest::kHeaderName[] = "header-name";
const char FetcherTest::kHeaderValue[] = "header value";
void FetcherTest::ValidateMockFetcherResponse(
bool success, bool check_error_message,
const std::string& content,
const MetaData& response_headers) {
if (success) {
EXPECT_EQ(std::string(kHtmlContent), content);
CharStarVector values;
EXPECT_TRUE(response_headers.Lookup(kHeaderName, &values));
EXPECT_EQ(1, values.size());
EXPECT_EQ(std::string(kHeaderValue), values[0]);
} else if (check_error_message) {
EXPECT_EQ(std::string(kErrorMessage), content);
}
}
int FetcherTest::CountFetchesSync(const StringPiece& url, bool expect_success,
bool check_error_message) {
CHECK(sync_fetcher() != NULL);
return CountFetchesSync(url, sync_fetcher(),
expect_success, check_error_message);
}
int FetcherTest::CountFetchesSync(
const StringPiece& url, UrlFetcher* fetcher,
bool expect_success, bool check_error_message) {
int starting_fetches = mock_fetcher_.num_fetches();
std::string content;
StringWriter content_writer(&content);
SimpleMetaData request_headers, response_headers;
bool success = fetcher->StreamingFetchUrl(
url.as_string(), request_headers, &response_headers, &content_writer,
&message_handler_);
EXPECT_EQ(expect_success, success);
ValidateMockFetcherResponse(success, check_error_message, content,
response_headers);
return mock_fetcher_.num_fetches() - starting_fetches;
}
int FetcherTest::CountFetchesAsync(const StringPiece& url, bool expect_success,
bool* callback_called) {
CHECK(async_fetcher() != NULL);
*callback_called = false;
int starting_fetches = mock_fetcher_.num_fetches();
SimpleMetaData request_headers;
CheckCallback* fetch = new CheckCallback(expect_success, callback_called);
async_fetcher()->StreamingFetch(
url.as_string(), request_headers, &fetch->response_headers_,
&fetch->content_writer_, &message_handler_, fetch);
return mock_fetcher_.num_fetches() - starting_fetches;
}
void FetcherTest::ValidateOutput(const std::string& content,
const MetaData& response_headers) {
// The detailed header parsing code is tested in
// simple_meta_data_test.cc. But let's check the rseponse code
// and the last header here, and make sure we got the content.
EXPECT_EQ(200, response_headers.status_code());
EXPECT_EQ(15, response_headers.NumAttributes());
EXPECT_EQ(std::string("X-Google-GFE-Response-Body-Transformations"),
std::string(response_headers.Name(14)));
EXPECT_EQ(std::string("gunzipped"),
std::string(response_headers.Value(14)));
// Verifies that after the headers, we see the content. Note that this
// currently assumes 'wget' style output. Wget takes care of any unzipping.
static const char start_of_doc[] = "<!doctype html>";
EXPECT_EQ(0, strncmp(start_of_doc, content.c_str(),
sizeof(start_of_doc) - 1));
}
// MockFetcher
bool FetcherTest::MockFetcher::StreamingFetchUrl(
const std::string& url,
const MetaData& request_headers,
MetaData* response_headers,
Writer* writer,
MessageHandler* message_handler) {
bool ret = false;
if (url == kGoodUrl) {
ret = Populate("public, max-age=300", response_headers, writer,
message_handler);
} else if (url == kNotCachedUrl) {
ret = Populate("no-cache", response_headers, writer,
message_handler);
} else {
writer->Write(kErrorMessage, message_handler);
}
++num_fetches_;
return ret;
}
bool FetcherTest::MockFetcher::Populate(const char* cache_control,
MetaData* response_headers,
Writer* writer,
MessageHandler* message_handler) {
response_headers->SetStatusAndReason(HttpStatus::kOK);
response_headers->Add(HttpAttributes::kCacheControl, cache_control);
response_headers->Add("Date", kStartDate);
response_headers->Add(kHeaderName, kHeaderValue);
response_headers->ComputeCaching();
response_headers->set_headers_complete(true);
writer->Write(kHtmlContent, message_handler);
return true;
}
// MockAsyncFetcher
bool FetcherTest::MockAsyncFetcher::StreamingFetch(
const std::string& url,
const MetaData& request_headers,
MetaData* response_headers,
Writer* writer,
MessageHandler* handler,
Callback* callback) {
bool status = url_fetcher_->StreamingFetchUrl(
url, request_headers, response_headers, writer, handler);
deferred_callbacks_.push_back(std::make_pair(status, callback));
return false;
}
void FetcherTest::MockAsyncFetcher::CallCallbacks() {
for (int i = 0, n = deferred_callbacks_.size(); i < n; ++i) {
bool status = deferred_callbacks_[i].first;
Callback* callback = deferred_callbacks_[i].second;
callback->Done(status);
}
deferred_callbacks_.clear();
}
} // namespace net_isntaweb