blob: c93a7a0754ed63f151a36a8c1af64b5613b7bfe8 [file] [log] [blame]
/*
* Copyright 2014 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: morlovich@google.com (Maksim Orlovich)
#include "net/instaweb/http/public/simulated_delay_fetcher.h"
#include "base/logging.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/request_context.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mem_file_system.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/thread/mock_scheduler.h"
#include "pagespeed/kernel/util/platform.h"
namespace net_instaweb {
namespace {
const char kConfigPath[] = "hosts.txt";
const char kLogPath[] = "request_log.txt";
const char kHostA[] = "foo.com";
const int kDelayMsA = 200;
const char kHostB[] = "bar.com";
const int kDelayMsB = 100;
class SimulatedDelayFetcherTest : public ::testing::Test {
protected:
SimulatedDelayFetcherTest()
: thread_system_(Platform::CreateThreadSystem()),
timer_(thread_system_->NewMutex(), MockTimer::kApr_5_2010_ms),
scheduler_(thread_system_.get(), &timer_),
file_system_(thread_system_.get(), &timer_) {
// Write out configuration.
GoogleString config;
StrAppend(&config, kHostA, "= ", IntegerToString(kDelayMsA), ";\n");
StrAppend(&config, kHostB, "= ", IntegerToString(kDelayMsB), ";\n");
file_system_.WriteFile(kConfigPath, config, &handler_);
fetcher_.reset(
new SimulatedDelayFetcher(thread_system_.get(), &timer_, &scheduler_,
&handler_, &file_system_, kConfigPath,
kLogPath, 2 /* flush after 2 requests */));
}
virtual ~SimulatedDelayFetcherTest() {}
scoped_ptr<ThreadSystem> thread_system_;
GoogleMessageHandler handler_;
MockTimer timer_;
MockScheduler scheduler_;
MemFileSystem file_system_;
scoped_ptr<SimulatedDelayFetcher> fetcher_;
};
TEST_F(SimulatedDelayFetcherTest, BasicOperation) {
GoogleString result_a;
StringAsyncFetch fetch_a(
RequestContext::NewTestRequestContext(thread_system_.get()),
&result_a);
GoogleString result_b;
StringAsyncFetch fetch_b(
RequestContext::NewTestRequestContext(thread_system_.get()),
&result_b);
fetcher_->Fetch(StrCat("http://", kHostA), &handler_, &fetch_a);
GoogleString log1;
file_system_.ReadFile(kLogPath, &log1, &handler_);
// Nothing should be in log yet, as flush after 2 requests.
EXPECT_TRUE(log1.empty()) << log1;
fetcher_->Fetch(StrCat("http://", kHostB), &handler_, &fetch_b);
// Now we should have flushed stuff.
GoogleString log2;
file_system_.ReadFile(kLogPath, &log2, &handler_);
EXPECT_EQ(
"Mon, 05 Apr 2010 18:51:26 GMT http://foo.com\n"
"Mon, 05 Apr 2010 18:51:26 GMT http://bar.com\n",
log2);
// Fetch results aren't returned at first.
EXPECT_FALSE(fetch_a.done());
EXPECT_FALSE(fetch_b.done());
// Fetch B is supposed to fire earlier, since kDelayMsB < kDelayMsA
CHECK_LT(kDelayMsB, kDelayMsA);
scheduler_.AdvanceTimeMs(kDelayMsB);
EXPECT_FALSE(fetch_a.done());
EXPECT_TRUE(fetch_b.done());
EXPECT_TRUE(fetch_b.success());
EXPECT_EQ(SimulatedDelayFetcher::kPayload, result_b);
// Next fetch A files.
scheduler_.AdvanceTimeMs(kDelayMsA - kDelayMsB);
EXPECT_TRUE(fetch_a.done());
EXPECT_TRUE(fetch_a.success());
EXPECT_EQ(SimulatedDelayFetcher::kPayload, result_a);
}
} // namespace
} // namespace net_instaweb