00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00018
00020
00021 #ifndef NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_MANAGER_TEST_BASE_H_
00022 #define NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_MANAGER_TEST_BASE_H_
00023
00024 #include <vector>
00025
00026 #include "base/scoped_ptr.h"
00027 #include "net/instaweb/htmlparse/public/html_parse_test_base.h"
00028 #include "net/instaweb/http/public/http_cache.h"
00029 #include "net/instaweb/http/public/mock_url_fetcher.h"
00030 #include "net/instaweb/rewriter/public/resource.h"
00031 #include "net/instaweb/rewriter/public/resource_manager.h"
00033 #include "net/instaweb/rewriter/public/rewrite_driver.h"
00034 #include "net/instaweb/rewriter/public/rewrite_options.h"
00035 #include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
00036 #include "net/instaweb/util/public/basictypes.h"
00037 #include "net/instaweb/util/public/md5_hasher.h"
00038 #include "net/instaweb/util/public/mem_file_system.h"
00039 #include "net/instaweb/util/public/mock_hasher.h"
00040 #include "net/instaweb/util/public/mock_message_handler.h"
00041 #include "net/instaweb/util/public/string.h"
00042 #include "net/instaweb/util/public/string_util.h"
00043 #include "net/instaweb/util/public/url_segment_encoder.h"
00044
00045
00046 namespace net_instaweb {
00047
00048 class CountingUrlAsyncFetcher;
00049 class DelayCache;
00050 class HTTPValue;
00051 class Hasher;
00052 class LRUCache;
00053 class MessageHandler;
00054 class MockScheduler;
00055 class MockTimer;
00056 class ResourceNamer;
00057 class ResponseHeaders;
00058 class RewriteFilter;
00059 class Statistics;
00060 class UrlNamer;
00061 class WaitUrlAsyncFetcher;
00062 struct ContentType;
00063
00064 class ResourceManagerTestBase : public HtmlParseTestBaseNoAlloc {
00065 public:
00066 static const char kTestData[];
00067
00068 ResourceManagerTestBase();
00069 explicit ResourceManagerTestBase(Statistics* statistics);
00070 ResourceManagerTestBase(TestRewriteDriverFactory* factory,
00071 TestRewriteDriverFactory* other_factory);
00072 virtual ~ResourceManagerTestBase();
00073
00074 virtual void SetUp();
00075 virtual void TearDown();
00076
00080 virtual bool AddBody() const { return false; }
00081
00083 void AddFilter(RewriteOptions::Filter filter);
00084
00086 void AddOtherFilter(RewriteOptions::Filter filter);
00087
00090 void AddRewriteFilter(RewriteFilter* filter);
00091
00094 void AddFetchOnlyRewriteFilter(RewriteFilter* filter);
00095
00098 void AddOtherRewriteFilter(RewriteFilter* filter);
00099
00102 void SetBaseUrlForFetch(const StringPiece& url);
00103
00104 ResourcePtr CreateResource(const StringPiece& base, const StringPiece& url);
00105
00106 MockTimer* mock_timer() { return factory_->mock_timer(); }
00107
00108 void AppendDefaultHeaders(const ContentType& content_type,
00109 GoogleString* text);
00110
00111 void ServeResourceFromManyContexts(const GoogleString& resource_url,
00112 const StringPiece& expected_content,
00113 UrlNamer* new_rms_url_namer = NULL);
00114
00117 void ServeResourceFromNewContext(
00118 const GoogleString& resource_url,
00119 const StringPiece& expected_content,
00120 UrlNamer* new_rms_url_namer = NULL);
00121
00125 virtual RewriteDriver* html_parse() { return rewrite_driver_; }
00126
00128 void DefaultResponseHeaders(const ContentType& content_type, int64 ttl_sec,
00129 ResponseHeaders* response_headers);
00130
00132 void SetResponseWithDefaultHeaders(const StringPiece& relative_url,
00133 const ContentType& content_type,
00134 const StringPiece& content,
00135 int64 ttl_sec);
00136
00138 void AddFileToMockFetcher(const StringPiece& url,
00139 const StringPiece& filename,
00140 const ContentType& content_type, int64 ttl_sec);
00141
00145 bool FetchResource(const StringPiece& path, const StringPiece& filter_id,
00146 const StringPiece& name, const StringPiece& ext,
00147 GoogleString* content);
00148 bool FetchResource(const StringPiece& path, const StringPiece& filter_id,
00149 const StringPiece& name, const StringPiece& ext,
00150 GoogleString* content, ResponseHeaders* response);
00151
00152 bool FetchResourceUrl(const StringPiece& url, GoogleString* content,
00153 ResponseHeaders* response);
00154 bool FetchResourceUrl(const StringPiece& url, GoogleString* content);
00155
00157 bool TryFetchResource(const StringPiece& url);
00158
00163 void SetUseManagedRewriteDrivers(bool use_managed_rewrite_drivers);
00164
00165 GoogleString CssLinkHref(const StringPiece& url) {
00166 return StrCat("<link rel=stylesheet href=", url, ">");
00167 }
00168
00170 class CssLink {
00171 public:
00172 CssLink(const StringPiece& url, const StringPiece& content,
00173 const StringPiece& media, bool supply_mock);
00174
00176 class Vector : public std::vector<CssLink*> {
00177 public:
00178 ~Vector();
00179 void Add(const StringPiece& url, const StringPiece& content,
00180 const StringPiece& media, bool supply_mock);
00181 };
00182
00185 bool DecomposeCombinedUrl(GoogleString* base, StringVector* segments,
00186 MessageHandler* handler);
00187
00188 GoogleString url_;
00189 GoogleString content_;
00190 GoogleString media_;
00191 bool supply_mock_;
00192 };
00193
00195 void CollectCssLinks(const StringPiece& id, const StringPiece& html,
00196 StringVector* css_links);
00197
00199 void CollectCssLinks(const StringPiece& id, const StringPiece& html,
00200 CssLink::Vector* css_links);
00201
00203 void EncodePathAndLeaf(const StringPiece& filter_id,
00204 const StringPiece& hash,
00205 const StringVector& name_vector,
00206 const StringPiece& ext,
00207 ResourceNamer* namer);
00208
00209 StringVector MultiUrl(const StringPiece& url1) {
00210 StringVector v;
00211 v.push_back(url1.as_string());
00212 return v;
00213 }
00214
00215 StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2) {
00216 StringVector v;
00217 v.push_back(url1.as_string());
00218 v.push_back(url2.as_string());
00219 return v;
00220 }
00221
00222 StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2,
00223 const StringPiece& url3) {
00224 StringVector v;
00225 v.push_back(url1.as_string());
00226 v.push_back(url2.as_string());
00227 v.push_back(url3.as_string());
00228 return v;
00229 }
00230
00231 StringVector MultiUrl(const StringPiece& url1, const StringPiece& url2,
00232 const StringPiece& url3, const StringPiece& url4) {
00233 StringVector v;
00234 v.push_back(url1.as_string());
00235 v.push_back(url2.as_string());
00236 v.push_back(url3.as_string());
00237 v.push_back(url4.as_string());
00238 return v;
00239 }
00240
00243 GoogleString Encode(const StringPiece& path,
00244 const StringPiece& filter_id,
00245 const StringPiece& hash,
00246 const StringPiece& name,
00247 const StringPiece& ext) {
00248 return Encode(path, filter_id, hash, MultiUrl(name), ext);
00249 }
00250 GoogleString Encode(const StringPiece& path,
00251 const StringPiece& filter_id,
00252 const StringPiece& hash,
00253 const StringVector& name_vector,
00254 const StringPiece& ext);
00255
00257 GoogleString EncodeNormal(const StringPiece& path,
00258 const StringPiece& filter_id,
00259 const StringPiece& hash,
00260 const StringPiece& name,
00261 const StringPiece& ext) {
00262 return EncodeNormal(path, filter_id, hash, MultiUrl(name), ext);
00263 }
00264 GoogleString EncodeNormal(const StringPiece& path,
00265 const StringPiece& filter_id,
00266 const StringPiece& hash,
00267 const StringVector& name_vector,
00268 const StringPiece& ext);
00269
00272 GoogleString EncodeWithBase(const StringPiece& base,
00273 const StringPiece& path,
00274 const StringPiece& filter_id,
00275 const StringPiece& hash,
00276 const StringPiece& name,
00277 const StringPiece& ext) {
00278 return EncodeWithBase(base, path, filter_id, hash, MultiUrl(name), ext);
00279 }
00280 GoogleString EncodeWithBase(const StringPiece& base,
00281 const StringPiece& path,
00282 const StringPiece& filter_id,
00283 const StringPiece& hash,
00284 const StringVector& name_vector,
00285 const StringPiece& ext);
00286
00291 static GoogleString ChangeSuffix(
00292 GoogleString old_url, bool append_new_suffix,
00293 StringPiece old_suffix, StringPiece new_suffix);
00294
00299 void SetupWaitFetcher();
00300 void CallFetcherCallbacks();
00301
00302 RewriteOptions* options() { return options_; }
00303 RewriteOptions* other_options() { return other_options_; }
00304
00306 void TestServeFiles(const ContentType* content_type,
00307 const StringPiece& filter_id,
00308 const StringPiece& rewritten_ext,
00309 const StringPiece& orig_name,
00310 const StringPiece& orig_content,
00311 const StringPiece& rewritten_name,
00312 const StringPiece& rewritten_content);
00313
00314 TestRewriteDriverFactory* factory() { return factory_.get(); }
00315 TestRewriteDriverFactory* other_factory() { return other_factory_.get(); }
00316
00317 void UseMd5Hasher() {
00318 resource_manager_->set_hasher(&md5_hasher_);
00319 other_resource_manager_->set_hasher(&md5_hasher_);
00320 }
00321
00322
00323 void SetDefaultLongCacheHeaders(const ContentType* content_type,
00324 ResponseHeaders* header) {
00325 resource_manager_->SetDefaultLongCacheHeaders(content_type, header);
00326 }
00327
00328 void SetFetchResponse(const StringPiece& url,
00329 const ResponseHeaders& response_header,
00330 const StringPiece& response_body) {
00331 mock_url_fetcher()->SetResponse(url, response_header, response_body);
00332 }
00333
00334 void AddToResponse(const StringPiece& url,
00335 const StringPiece& name,
00336 const StringPiece& value) {
00337 mock_url_fetcher()->AddToResponse(url, name, value);
00338 }
00339
00340 void SetFetchResponse404(const StringPiece& url);
00341
00342 void SetFetchFailOnUnexpected(bool fail) {
00343 mock_url_fetcher()->set_fail_on_unexpected(fail);
00344 }
00345 void FetcherUpdateDateHeaders() {
00346 mock_url_fetcher()->set_timer(mock_timer());
00347 mock_url_fetcher()->set_update_date_headers(true);
00348 }
00349 void ClearFetcherResponses() { mock_url_fetcher()->Clear(); }
00350
00351 virtual void ClearStats();
00352
00353 MockUrlFetcher* mock_url_fetcher() {
00354 return &mock_url_fetcher_;
00355 }
00356 Hasher* hasher() { return resource_manager_->hasher(); }
00357 DelayCache* delay_cache() { return factory_->delay_cache(); }
00358 LRUCache* lru_cache() { return factory_->lru_cache(); }
00359 Statistics* statistics() { return factory_->statistics(); }
00360 MemFileSystem* file_system() { return factory_->mem_file_system(); }
00361 HTTPCache* http_cache() { return factory_->http_cache(); }
00362 MockMessageHandler* message_handler() {
00363 return factory_->mock_message_handler();
00364 }
00365
00373 RewriteDriver* rewrite_driver() { return rewrite_driver_; }
00374 RewriteDriver* other_rewrite_driver() { return other_rewrite_driver_; }
00375
00377 MockScheduler* mock_scheduler() { return factory_->mock_scheduler(); }
00378
00379 int64 start_time_ms() const { return factory_->kStartTimeMs; }
00380
00381 bool ReadFile(const char* filename, GoogleString* contents) {
00382 return file_system()->ReadFile(filename, contents, message_handler());
00383 }
00384 bool WriteFile(const char* filename, const StringPiece& contents) {
00385 return file_system()->WriteFile(filename, contents, message_handler());
00386 }
00387
00388 ResourceManager* resource_manager() { return resource_manager_; }
00389 ResourceManager* other_resource_manager() { return other_resource_manager_; }
00390 CountingUrlAsyncFetcher* counting_url_async_fetcher() {
00391 return factory_->counting_url_async_fetcher();
00392 }
00393
00394 void SetMockHashValue(const GoogleString& value) {
00395 factory_->mock_hasher()->set_hash_value(value);
00396 }
00397
00398 void SetCacheDelayUs(int64 delay_us);
00399
00404 RewriteDriver* MakeDriver(ResourceManager* resource_manager,
00405 RewriteOptions* options);
00406
00408 GoogleString AbsolutifyUrl(const StringPiece& in);
00409
00414 void TestRetainExtraHeaders(const StringPiece& name,
00415 const StringPiece& filter_id,
00416 const StringPiece& ext);
00417
00421 const UrlSegmentEncoder* FindEncoder(const StringPiece& id) const;
00422
00424 void SetUseTestUrlNamer(bool use_test_url_namer);
00425
00428 GoogleString EncodeCssName(const StringPiece& name,
00429 bool supports_webp,
00430 bool can_inline);
00431
00435 bool ReadIfCached(const ResourcePtr& resource);
00436
00441 void InitiateResourceRead(const ResourcePtr& resource);
00442
00446 HTTPCache::FindResult HttpBlockingFind(
00447 const GoogleString& key, HTTPCache* http_cache, HTTPValue* value_out,
00448 ResponseHeaders* headers);
00449
00450 protected:
00451 void Init();
00452
00455 void CallFetcherCallbacksForDriver(WaitUrlAsyncFetcher* fetcher,
00456 RewriteDriver* driver);
00457
00459 MockUrlFetcher mock_url_fetcher_;
00460 scoped_ptr<Statistics> statistics_;
00461
00467 scoped_ptr<TestRewriteDriverFactory> factory_;
00468 scoped_ptr<TestRewriteDriverFactory> other_factory_;
00469 ResourceManager* resource_manager_;
00470 RewriteDriver* rewrite_driver_;
00471 ResourceManager* other_resource_manager_;
00472 RewriteDriver* other_rewrite_driver_;
00473 bool use_managed_rewrite_drivers_;
00474
00475 MD5Hasher md5_hasher_;
00476
00477 RewriteOptions* options_;
00478 RewriteOptions* other_options_;
00479 UrlSegmentEncoder default_encoder_;
00480 };
00481
00482 }
00483
00484 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_MANAGER_TEST_BASE_H_