Page Speed Optimization Libraries  1.3.25.1
net/instaweb/rewriter/public/rewrite_test_base.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http:///www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00018 
00020 
00021 #ifndef NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_TEST_BASE_H_
00022 #define NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_TEST_BASE_H_
00023 
00024 #include <utility>
00025 #include <vector>
00026 
00027 #include "net/instaweb/htmlparse/public/html_parse_test_base.h"
00028 #include "net/instaweb/http/public/mock_url_fetcher.h"
00029 #include "net/instaweb/http/public/http_cache.h"
00030 #include "net/instaweb/http/public/logging_proto.h"
00031 #include "net/instaweb/http/public/response_headers.h"
00033 #include "net/instaweb/rewriter/public/resource.h"
00034 #include "net/instaweb/http/public/request_context.h"
00035 #include "net/instaweb/rewriter/public/rewrite_driver.h"
00036 #include "net/instaweb/rewriter/public/rewrite_options.h"
00037 #include "net/instaweb/rewriter/public/server_context.h"
00038 #include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
00039 #include "net/instaweb/util/public/basictypes.h"
00040 #include "net/instaweb/util/public/md5_hasher.h"
00041 #include "net/instaweb/util/public/mem_file_system.h"
00042 #include "net/instaweb/util/public/mock_hasher.h"
00043 #include "net/instaweb/util/public/mock_message_handler.h"
00044 #include "net/instaweb/util/public/mock_property_page.h"
00046 #include "net/instaweb/util/public/mock_timer.h"
00047 #include "net/instaweb/util/public/scoped_ptr.h"
00048 #include "net/instaweb/util/public/string.h"
00049 #include "net/instaweb/util/public/string_util.h"
00050 #include "net/instaweb/util/public/timer.h"
00051 #include "net/instaweb/util/public/url_segment_encoder.h"
00052 
00053 
00054 namespace net_instaweb {
00055 
00056 class CountingUrlAsyncFetcher;
00057 class DelayCache;
00058 class HTTPValue;
00059 class Hasher;
00060 class HtmlWriterFilter;
00061 class LRUCache;
00062 class MessageHandler;
00063 class MockScheduler;
00064 class PropertyCache;
00065 class ResourceNamer;
00066 class RewriteFilter;
00067 class Statistics;
00068 class WaitUrlAsyncFetcher;
00069 struct ContentType;
00070 
00071 class RewriteOptionsTestBase : public HtmlParseTestBaseNoAlloc {
00072  protected:
00073   RewriteOptionsTestBase() {
00074     RewriteOptions::Initialize();
00075   }
00076   ~RewriteOptionsTestBase() {
00077     RewriteOptions::Terminate();
00078   }
00079 };
00080 
00081 class RewriteTestBase : public RewriteOptionsTestBase {
00082  public:
00083   static const char kTestData[]; 
00084 
00091   enum ActiveServerFlag {
00092     kPrimary,    
00093     kSecondary,  
00094   };
00095 
00096   RewriteTestBase();
00097   explicit RewriteTestBase(Statistics* statistics);
00098 
00104   explicit RewriteTestBase(std::pair<TestRewriteDriverFactory*,
00105                                      TestRewriteDriverFactory*> factories);
00106   virtual ~RewriteTestBase();
00107 
00108   virtual void SetUp();
00109   virtual void TearDown();
00110 
00114   virtual bool AddBody() const { return false; }
00115 
00125   virtual TestRewriteDriverFactory* MakeTestFactory();
00126 
00129   void AddRecompressImageFilters();
00130 
00132   void AddFilter(RewriteOptions::Filter filter);
00133 
00135   void AddOtherFilter(RewriteOptions::Filter filter);
00136 
00139   void AddRewriteFilter(RewriteFilter* filter);
00140 
00143   void AddFetchOnlyRewriteFilter(RewriteFilter* filter);
00144 
00147   void AddOtherRewriteFilter(RewriteFilter* filter);
00148 
00151   void SetBaseUrlForFetch(const StringPiece& url);
00152 
00153   ResourcePtr CreateResource(const StringPiece& base, const StringPiece& url);
00154 
00159   Timer* timer() { return factory()->mock_timer(); }
00160 
00162   void AppendDefaultHeaders(const ContentType& content_type,
00163                             GoogleString* text);
00164 
00167   void AppendDefaultHeaders(const ContentType& content_type,
00168                             int64 original_content_length,
00169                             GoogleString* text);
00170 
00171   void ServeResourceFromManyContexts(const GoogleString& resource_url,
00172                                      const StringPiece& expected_content);
00173 
00174   void ServeResourceFromManyContextsWithUA(
00175       const GoogleString& resource_url,
00176       const StringPiece& expected_content,
00177       const StringPiece& user_agent);
00178 
00181   void ServeResourceFromNewContext(
00182       const GoogleString& resource_url,
00183       const StringPiece& expected_content);
00184 
00188   virtual RewriteDriver* html_parse() { return rewrite_driver_; }
00189 
00191   void DefaultResponseHeaders(const ContentType& content_type, int64 ttl_sec,
00192                               ResponseHeaders* response_headers);
00193 
00197   bool FetchResource(const StringPiece& path, const StringPiece& filter_id,
00198                      const StringPiece& name, const StringPiece& ext,
00199                      GoogleString* content);
00200   bool FetchResource(const StringPiece& path, const StringPiece& filter_id,
00201                      const StringPiece& name, const StringPiece& ext,
00202                      GoogleString* content, ResponseHeaders* response);
00203 
00204   bool FetchResourceUrl(const StringPiece& url, GoogleString* content,
00205                         ResponseHeaders* response);
00206   bool FetchResourceUrl(const StringPiece& url, GoogleString* content);
00207 
00209   bool TryFetchResource(const StringPiece& url);
00210 
00215   void SetUseManagedRewriteDrivers(bool use_managed_rewrite_drivers);
00216 
00217   GoogleString CssLinkHref(const StringPiece& url) {
00218     return StrCat("<link rel=stylesheet href=", url, ">");
00219   }
00220 
00222   class CssLink {
00223    public:
00224     CssLink(const StringPiece& url, const StringPiece& content,
00225             const StringPiece& media, bool supply_mock);
00226 
00228     class Vector : public std::vector<CssLink*> {
00229      public:
00230       ~Vector();
00231       void Add(const StringPiece& url, const StringPiece& content,
00232                const StringPiece& media, bool supply_mock);
00233     };
00234 
00237     bool DecomposeCombinedUrl(GoogleString* base, StringVector* segments,
00238                               MessageHandler* handler);
00239 
00240     GoogleString url_;
00241     GoogleString content_;
00242     GoogleString media_;
00243     bool supply_mock_;
00244   };
00245 
00247   void CollectCssLinks(const StringPiece& id, const StringPiece& html,
00248                        StringVector* css_links);
00249 
00251   void CollectCssLinks(const StringPiece& id, const StringPiece& html,
00252                        CssLink::Vector* css_links);
00253 
00255   void EncodePathAndLeaf(const StringPiece& filter_id,
00256                          const StringPiece& hash,
00257                          const StringVector& name_vector,
00258                          const StringPiece& ext,
00259                          ResourceNamer* namer);
00260 
00261   StringVector MultiUrl(const StringPiece& url1) {
00262     StringVector v;
00263     v.push_back(url1.as_string());
00264     return v;
00265   }
00266 
00267   StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2) {
00268     StringVector v;
00269     v.push_back(url1.as_string());
00270     v.push_back(url2.as_string());
00271     return v;
00272   }
00273 
00274   StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2,
00275                         const StringPiece& url3) {
00276     StringVector v;
00277     v.push_back(url1.as_string());
00278     v.push_back(url2.as_string());
00279     v.push_back(url3.as_string());
00280     return v;
00281   }
00282 
00283   StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2,
00284                         const StringPiece& url3, const StringPiece& url4) {
00285     StringVector v;
00286     v.push_back(url1.as_string());
00287     v.push_back(url2.as_string());
00288     v.push_back(url3.as_string());
00289     v.push_back(url4.as_string());
00290     return v;
00291   }
00292 
00295   GoogleString Encode(const StringPiece& path,
00296                       const StringPiece& filter_id,
00297                       const StringPiece& hash,
00298                       const StringPiece& name,
00299                       const StringPiece& ext) {
00300     return Encode(path, filter_id, hash, MultiUrl(name), ext);
00301   }
00302   GoogleString Encode(const StringPiece& path,
00303                       const StringPiece& filter_id,
00304                       const StringPiece& hash,
00305                       const StringVector& name_vector,
00306                       const StringPiece& ext);
00307 
00309   GoogleString EncodeNormal(const StringPiece& path,
00310                             const StringPiece& filter_id,
00311                             const StringPiece& hash,
00312                             const StringPiece& name,
00313                             const StringPiece& ext) {
00314     return EncodeNormal(path, filter_id, hash, MultiUrl(name), ext);
00315   }
00316   GoogleString EncodeNormal(const StringPiece& path,
00317                             const StringPiece& filter_id,
00318                             const StringPiece& hash,
00319                             const StringVector& name_vector,
00320                             const StringPiece& ext);
00321 
00324   GoogleString EncodeWithBase(const StringPiece& base,
00325                               const StringPiece& path,
00326                               const StringPiece& filter_id,
00327                               const StringPiece& hash,
00328                               const StringPiece& name,
00329                               const StringPiece& ext) {
00330     return EncodeWithBase(base, path, filter_id, hash, MultiUrl(name), ext);
00331   }
00332   GoogleString EncodeWithBase(const StringPiece& base,
00333                               const StringPiece& path,
00334                               const StringPiece& filter_id,
00335                               const StringPiece& hash,
00336                               const StringVector& name_vector,
00337                               const StringPiece& ext);
00338 
00340   GoogleString AddOptionsToEncodedUrl(const StringPiece& url,
00341                                       const StringPiece& options);
00342 
00347   static GoogleString ChangeSuffix(
00348       GoogleString old_url, bool append_new_suffix,
00349       StringPiece old_suffix, StringPiece new_suffix);
00350 
00355   void SetupWaitFetcher();
00356   void CallFetcherCallbacks();
00357 
00358   RewriteOptions* options() { return options_; }
00359   RewriteOptions* other_options() { return other_options_; }
00360 
00362   void TestServeFiles(const ContentType* content_type,
00363                       const StringPiece& filter_id,
00364                       const StringPiece& rewritten_ext,
00365                       const StringPiece& orig_name,
00366                       const StringPiece& orig_content,
00367                       const StringPiece& rewritten_name,
00368                       const StringPiece& rewritten_content);
00369 
00370   TestRewriteDriverFactory* factory() { return factory_.get(); }
00371   TestRewriteDriverFactory* other_factory() { return other_factory_.get(); }
00372 
00373   void UseMd5Hasher() {
00374     server_context_->set_hasher(&md5_hasher_);
00375     server_context_->http_cache()->set_hasher(&md5_hasher_);
00376     other_server_context_->set_hasher(&md5_hasher_);
00377     other_server_context_->http_cache()->set_hasher(&md5_hasher_);
00378   }
00379 
00380 
00381   void SetDefaultLongCacheHeaders(const ContentType* content_type,
00382                                   ResponseHeaders* header) {
00383     server_context_->SetDefaultLongCacheHeaders(content_type, header);
00384   }
00385 
00386   void SetFetchResponse(const StringPiece& url,
00387                         const ResponseHeaders& response_header,
00388                         const StringPiece& response_body) {
00389     mock_url_fetcher()->SetResponse(url, response_header, response_body);
00390   }
00391 
00393   void SetResponseWithDefaultHeaders(const StringPiece& relative_url,
00394                                      const ContentType& content_type,
00395                                      const StringPiece& content,
00396                                      int64 ttl_sec);
00397 
00400   bool LoadFile(const StringPiece& filename, GoogleString* contents);
00401 
00403   void AddFileToMockFetcher(const StringPiece& url,
00404                             const StringPiece& filename,
00405                             const ContentType& content_type, int64 ttl_sec);
00406 
00407   void AddToResponse(const StringPiece& url,
00408                      const StringPiece& name,
00409                      const StringPiece& value) {
00410     mock_url_fetcher()->AddToResponse(url, name, value);
00411   }
00412 
00413   void SetFetchResponse404(const StringPiece& url);
00414 
00415   void SetFetchFailOnUnexpected(bool fail) {
00416     mock_url_fetcher()->set_fail_on_unexpected(fail);
00417   }
00418   void FetcherUpdateDateHeaders() {
00419     mock_url_fetcher()->set_timer(timer());
00420     mock_url_fetcher()->set_update_date_headers(true);
00421   }
00422   void ClearFetcherResponses() { mock_url_fetcher()->Clear(); }
00423 
00424   virtual void ClearStats();
00425 
00428   void ClearRewriteDriver();
00429 
00430   MockUrlFetcher* mock_url_fetcher() {
00431     return &mock_url_fetcher_;
00432   }
00433   Hasher* hasher() { return server_context_->hasher(); }
00434   DelayCache* delay_cache() { return factory_->delay_cache(); }
00435   LRUCache* lru_cache() { return factory_->lru_cache(); }
00436   Statistics* statistics() { return factory_->statistics(); }
00437   MemFileSystem* file_system() { return factory_->mem_file_system(); }
00438   HTTPCache* http_cache() { return server_context_->http_cache(); }
00439   PropertyCache* page_property_cache() {
00440     return server_context_->page_property_cache();
00441   }
00442   MockMessageHandler* message_handler() {
00443     return factory_->mock_message_handler();
00444   }
00445 
00453   RewriteDriver* rewrite_driver() { return rewrite_driver_; }
00454   RewriteDriver* other_rewrite_driver() { return other_rewrite_driver_; }
00455 
00457   MockScheduler* mock_scheduler() { return factory_->mock_scheduler(); }
00458 
00459   int64 start_time_ms() const { return factory_->kStartTimeMs; }
00460 
00461   bool ReadFile(const char* filename, GoogleString* contents) {
00462     return file_system()->ReadFile(filename, contents, message_handler());
00463   }
00464   bool WriteFile(const char* filename, const StringPiece& contents) {
00465     return file_system()->WriteFile(filename, contents, message_handler());
00466   }
00467 
00468   ServerContext* server_context() { return server_context_; }
00469   ServerContext* other_server_context() { return other_server_context_; }
00470   CountingUrlAsyncFetcher* counting_url_async_fetcher() {
00471     return factory_->counting_url_async_fetcher();
00472   }
00473 
00474   void SetMockHashValue(const GoogleString& value) {
00475     factory_->mock_hasher()->set_hash_value(value);
00476   }
00477 
00478   void SetCacheDelayUs(int64 delay_us);
00479 
00484   RewriteDriver* MakeDriver(ServerContext* server_context,
00485                             RewriteOptions* options);
00486 
00488   GoogleString AbsolutifyUrl(const StringPiece& in);
00489 
00494   void TestRetainExtraHeaders(const StringPiece& name,
00495                               const StringPiece& filter_id,
00496                               const StringPiece& ext);
00497 
00501   const UrlSegmentEncoder* FindEncoder(const StringPiece& id) const;
00502 
00504   void SetUseTestUrlNamer(bool use_test_url_namer);
00505 
00508   GoogleString EncodeCssName(const StringPiece& name,
00509                              bool supports_webp,
00510                              bool can_inline);
00511 
00515   bool ReadIfCached(const ResourcePtr& resource);
00516 
00521   void InitiateResourceRead(const ResourcePtr& resource);
00522 
00526   HTTPCache::FindResult HttpBlockingFind(
00527       const GoogleString& key, HTTPCache* http_cache, HTTPValue* value_out,
00528       ResponseHeaders* headers);
00529 
00532   HTTPCache::FindResult HttpBlockingFindStatus(
00533       const GoogleString& key, HTTPCache* http_cache);
00534 
00536   void SetXhtmlMimetype() { SetMimetype("application/xhtml+xml"); }
00537 
00539   void SetHtmlMimetype() { SetMimetype("text/html"); }
00540 
00542   void SetMimetype(const StringPiece& mimetype);
00543 
00546   void CheckFetchFromHttpCache(
00547       StringPiece url,
00548       StringPiece expected_contents,
00549       int64 expected_expiration_ms);
00550 
00552   void SetupCohort(PropertyCache* cache, const GoogleString& cohort) {
00553     factory()->SetupCohort(cache, cohort);
00554   }
00555 
00557   MockPropertyPage* NewMockPage(const StringPiece& key) {
00558     return new MockPropertyPage(
00559         server_context_->thread_system(),
00560         *server_context_->page_property_cache(),
00561         key);
00562   }
00563 
00565   MockPropertyPage* NewMockClientPage(const StringPiece& key) {
00566     return new MockPropertyPage(
00567         server_context_->thread_system(),
00568         *server_context_->client_property_cache(),
00569         key);
00570   }
00571 
00572  protected:
00573   void Init();
00574 
00577   virtual RequestContextPtr CreateRequestContext();
00578 
00581   void CallFetcherCallbacksForDriver(WaitUrlAsyncFetcher* fetcher,
00582                                      RewriteDriver* driver);
00583 
00586   void PopulateDefaultHeaders(const ContentType& content_type,
00587                               int64 original_content_length,
00588                               ResponseHeaders* headers);
00589 
00592   void SetActiveServer(ActiveServerFlag server_to_use);
00593 
00596   void AdvanceTimeUs(int64 delay_ms);
00597   void AdvanceTimeMs(int64 delay_ms) { AdvanceTimeUs(delay_ms * Timer::kMsUs); }
00598   void SetTimeUs(int64 time_us);
00599   void SetTimeMs(int64 time_ms) { SetTimeUs(time_ms * Timer::kMsUs); }
00600 
00602   void AdjustTimeUsWithoutWakingAlarms(int64 time_us);
00603 
00608   LoggingInfo* logging_info();
00609 
00612   GoogleString AppliedRewriterStringFromLog();
00613 
00615   void SetCurrentUserAgent(const StringPiece& user_agent) {
00616     current_user_agent_ = user_agent;
00617   }
00618 
00620   MockUrlFetcher mock_url_fetcher_;
00621   scoped_ptr<Statistics> statistics_;
00622 
00628   scoped_ptr<TestRewriteDriverFactory> factory_;
00629   scoped_ptr<TestRewriteDriverFactory> other_factory_;
00630   ServerContext* server_context_;
00631   RewriteDriver* rewrite_driver_;
00632   ServerContext* other_server_context_;
00633   RewriteDriver* other_rewrite_driver_;
00634   scoped_ptr<HtmlWriterFilter> other_html_writer_filter_;
00635   ActiveServerFlag active_server_;
00636   bool use_managed_rewrite_drivers_;
00637   StringPiece current_user_agent_;
00638   MD5Hasher md5_hasher_;
00639 
00640   RewriteOptions* options_; 
00641   RewriteOptions* other_options_; 
00642   UrlSegmentEncoder default_encoder_;
00643   ResponseHeaders response_headers_;
00644 };
00645 
00646 }  
00647 
00648 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_TEST_BASE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines