| /* |
| * 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 |