1 /** @file 2 3 A brief file description 4 5 @section license License 6 7 Licensed to the Apache Software Foundation (ASF) under one 8 or more contributor license agreements. See the NOTICE file 9 distributed with this work for additional information 10 regarding copyright ownership. The ASF licenses this file 11 to you under the Apache License, Version 2.0 (the 12 "License"); you may not use this file except in compliance 13 with the License. You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 */ 23 24 #define LARGE_FILE 10 * 1024 * 1024 25 #define SMALL_FILE 10 * 1024 26 27 #include "main.h" 28 29 class CacheUpdateReadAgain : public CacheTestHandler 30 { 31 public: CacheUpdateReadAgain(size_t size,const char * url)32 CacheUpdateReadAgain(size_t size, const char *url) : CacheTestHandler() 33 { 34 auto rt = new CacheReadTest(size, this, url); 35 rt->mutex = this->mutex; 36 37 rt->info.destroy(); 38 rt->info.create(); 39 build_hdrs(rt->info, url, "application/x-javascript"); 40 41 this->_rt = rt; 42 43 SET_HANDLER(&CacheUpdateReadAgain::start_test); 44 } 45 46 int start_test(int event,void * e)47 start_test(int event, void *e) 48 { 49 REQUIRE(event == EVENT_IMMEDIATE); 50 this_ethread()->schedule_imm(this->_rt); 51 return 0; 52 } 53 54 void handle_cache_event(int event,CacheTestBase * base)55 handle_cache_event(int event, CacheTestBase *base) override 56 { 57 switch (event) { 58 case CACHE_EVENT_OPEN_READ: 59 base->do_io_read(); 60 this->validate_content_type(base); 61 this->check_fragment_table(base); 62 break; 63 case VC_EVENT_READ_READY: 64 base->reenable(); 65 break; 66 case VC_EVENT_READ_COMPLETE: 67 base->close(); 68 delete this; 69 break; 70 default: 71 REQUIRE(false); 72 break; 73 } 74 } 75 76 void validate_content_type(CacheTestBase * base)77 validate_content_type(CacheTestBase *base) 78 { 79 auto rt = dynamic_cast<CacheReadTest *>(base); 80 REQUIRE(rt); 81 MIMEField *field = rt->read_http_info->m_alt->m_response_hdr.field_find(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE); 82 REQUIRE(field); 83 int len; 84 const char *value = field->value_get(&len); 85 REQUIRE(memcmp(value, "application/x-javascript", len) == 0); 86 } 87 88 void check_fragment_table(CacheTestBase * base)89 check_fragment_table(CacheTestBase *base) 90 { 91 REQUIRE(base->vc->alternate.get_frag_table() != nullptr); 92 REQUIRE(base->vc->alternate.get_frag_offset_count() != 0); 93 } 94 }; 95 96 class CacheUpdateHeader : public CacheTestHandler 97 { 98 public: CacheUpdateHeader(size_t read_size,const char * url)99 CacheUpdateHeader(size_t read_size, const char *url) 100 { 101 auto rt = new CacheReadTest(read_size, this, url); 102 auto wt = new CacheWriteTest(read_size, this, url); 103 104 wt->info.destroy(); 105 wt->info.create(); 106 build_hdrs(wt->info, url, "application/x-javascript"); 107 108 this->_rt = rt; 109 this->_wt = wt; 110 111 this->_rt->mutex = this->mutex; 112 this->_wt->mutex = this->mutex; 113 114 SET_HANDLER(&CacheUpdateHeader::start_test); 115 } 116 117 int start_test(int event,void * e)118 start_test(int event, void *e) 119 { 120 REQUIRE(event == EVENT_IMMEDIATE); 121 this_ethread()->schedule_imm(this->_rt); 122 return 0; 123 } 124 125 void handle_cache_event(int event,CacheTestBase * base)126 handle_cache_event(int event, CacheTestBase *base) override 127 { 128 CacheWriteTest *wt = static_cast<CacheWriteTest *>(this->_wt); 129 switch (event) { 130 case CACHE_EVENT_OPEN_WRITE: 131 base->do_io_write(); 132 // commit the header change 133 this->_wt->close(); 134 this->_wt = nullptr; 135 delete this; 136 break; 137 case CACHE_EVENT_OPEN_READ: 138 base->do_io_read(); 139 wt->old_info.copy(static_cast<HTTPInfo *>(&base->vc->alternate)); 140 break; 141 case VC_EVENT_READ_READY: 142 base->reenable(); 143 break; 144 case VC_EVENT_READ_COMPLETE: 145 this->_rt->close(); 146 this->_rt = nullptr; 147 this_ethread()->schedule_imm(this->_wt); 148 break; 149 default: 150 REQUIRE(false); 151 break; 152 } 153 } 154 }; 155 156 class CacheUpdateInit : public CacheInit 157 { 158 public: CacheUpdateInit()159 CacheUpdateInit() {} 160 int cache_init_success_callback(int event,void * e)161 cache_init_success_callback(int event, void *e) override 162 { 163 CacheTestHandler *h = new CacheTestHandler(LARGE_FILE, "http://www.scw11.com"); 164 CacheUpdateHeader *update = new CacheUpdateHeader(LARGE_FILE, "http://www.scw11.com"); 165 CacheUpdateReadAgain *read = new CacheUpdateReadAgain(LARGE_FILE, "http://www.scw11.com"); 166 TerminalTest *tt = new TerminalTest; 167 168 h->add(update); 169 h->add(read); // read again 170 h->add(tt); 171 this_ethread()->schedule_imm(h); 172 delete this; 173 return 0; 174 } 175 }; 176 177 TEST_CASE("cache write -> read", "cache") 178 { 179 init_cache(256 * 1024 * 1024); 180 // large write test 181 CacheUpdateInit *init = new CacheUpdateInit; 182 183 this_ethread()->schedule_imm(init); 184 this_thread()->execute(); 185 } 186