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 // delete dir
30 Dir dir = {};
31 
32 class CacheAltReadAgain2 : public CacheTestHandler
33 {
34 public:
CacheAltReadAgain2(size_t size,const char * url)35   CacheAltReadAgain2(size_t size, const char *url) : CacheTestHandler()
36   {
37     auto rt = new CacheReadTest(size, this, url);
38 
39     rt->mutex = this->mutex;
40 
41     rt->info.destroy();
42 
43     rt->info.create();
44     build_hdrs(rt->info, url, "application/x-javascript");
45 
46     this->_rt = rt;
47 
48     SET_HANDLER(&CacheAltReadAgain2::start_test);
49   }
50 
51   int
start_test(int event,void * e)52   start_test(int event, void *e)
53   {
54     REQUIRE(event == EVENT_IMMEDIATE);
55     this_ethread()->schedule_imm(this->_rt);
56     return 0;
57   }
58 
59   void
handle_cache_event(int event,CacheTestBase * base)60   handle_cache_event(int event, CacheTestBase *base) override
61   {
62     switch (event) {
63     case CACHE_EVENT_OPEN_READ:
64       base->do_io_read();
65       validate_content_type(base);
66       break;
67     case VC_EVENT_READ_READY:
68       base->reenable();
69       break;
70     case VC_EVENT_READ_COMPLETE:
71       base->close();
72       delete this;
73       break;
74     default:
75       REQUIRE(false);
76       break;
77     }
78   }
79 
80   void
validate_content_type(CacheTestBase * base)81   validate_content_type(CacheTestBase *base)
82   {
83     auto rt = dynamic_cast<CacheReadTest *>(base);
84     REQUIRE(rt);
85     MIMEField *field = rt->read_http_info->m_alt->m_response_hdr.field_find(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE);
86     REQUIRE(field);
87     int len;
88     const char *value = field->value_get(&len);
89     REQUIRE(memcmp(value, "application/x-javascript", len) == 0);
90   }
91 };
92 
93 class CacheAltReadAgain : public CacheTestHandler
94 {
95 public:
CacheAltReadAgain(size_t size,const char * url)96   CacheAltReadAgain(size_t size, const char *url) : CacheTestHandler()
97   {
98     this->_rt        = new CacheReadTest(size, this, url);
99     this->_rt->mutex = this->mutex;
100 
101     SET_HANDLER(&CacheAltReadAgain::start_test);
102   }
103 
104   int
start_test(int event,void * e)105   start_test(int event, void *e)
106   {
107     REQUIRE(event == EVENT_IMMEDIATE);
108     this_ethread()->schedule_imm(this->_rt);
109     return 0;
110   }
111 
112   void
handle_cache_event(int event,CacheTestBase * base)113   handle_cache_event(int event, CacheTestBase *base) override
114   {
115     switch (event) {
116     case CACHE_EVENT_OPEN_READ_FAILED:
117       delete this;
118       break;
119     default:
120       REQUIRE(false);
121       break;
122     }
123   }
124 
125   void
validate_content_type(CacheTestBase * base)126   validate_content_type(CacheTestBase *base)
127   {
128     auto rt = dynamic_cast<CacheReadTest *>(base);
129     REQUIRE(rt);
130     MIMEField *field = rt->read_http_info->m_alt->m_response_hdr.field_find(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE);
131     REQUIRE(field);
132     int len;
133     const char *value = field->value_get(&len);
134     REQUIRE(memcmp(value, "text/html;charset=utf-8", len) == 0);
135   }
136 };
137 
138 class CacheAltTest_L_to_S_remove_L : public CacheTestHandler
139 {
140 public:
CacheAltTest_L_to_S_remove_L(size_t size,const char * url)141   CacheAltTest_L_to_S_remove_L(size_t size, const char *url) : CacheTestHandler()
142   {
143     auto rt = new CacheReadTest(size, this, url);
144     auto wt = new CacheWriteTest(size, this, url);
145 
146     rt->info.destroy();
147     wt->info.destroy();
148 
149     rt->info.create();
150     wt->info.create();
151 
152     build_hdrs(rt->info, url, "application/x-javascript");
153     build_hdrs(wt->info, url, "application/x-javascript");
154 
155     this->_rt = rt;
156     this->_wt = wt;
157 
158     this->_rt->mutex = this->mutex;
159     this->_wt->mutex = this->mutex;
160 
161     SET_HANDLER(&CacheAltTest_L_to_S_remove_L::start_test);
162   }
163 
164   int
start_test(int event,void * e)165   start_test(int event, void *e)
166   {
167     REQUIRE(event == EVENT_IMMEDIATE);
168     this_ethread()->schedule_imm(this->_wt);
169     return 0;
170   }
171 
172   void
handle_cache_event(int event,CacheTestBase * base)173   handle_cache_event(int event, CacheTestBase *base) override
174   {
175     switch (event) {
176     case CACHE_EVENT_OPEN_WRITE:
177       base->do_io_write();
178       break;
179     case VC_EVENT_WRITE_READY:
180       base->reenable();
181       break;
182     case VC_EVENT_WRITE_COMPLETE:
183       this->_wt->close();
184       this->_wt = nullptr;
185       this_ethread()->schedule_imm(this->_rt);
186       break;
187     case CACHE_EVENT_OPEN_READ:
188       base->do_io_read();
189       validate_content_type(base);
190       break;
191     case VC_EVENT_READ_READY:
192       base->reenable();
193       break;
194     case VC_EVENT_READ_COMPLETE:
195       delete_earliest_dir(base->vc);
196       base->close();
197       delete this;
198       break;
199     default:
200       REQUIRE(false);
201       break;
202     }
203   }
204 
205   void
validate_content_type(CacheTestBase * base)206   validate_content_type(CacheTestBase *base)
207   {
208     auto rt = dynamic_cast<CacheReadTest *>(base);
209     REQUIRE(rt);
210     MIMEField *field = rt->read_http_info->m_alt->m_response_hdr.field_find(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE);
211     REQUIRE(field);
212     int len;
213     const char *value = field->value_get(&len);
214     REQUIRE(memcmp(value, "application/x-javascript", len) == 0);
215   }
216 
217   void
delete_earliest_dir(CacheVC * vc)218   delete_earliest_dir(CacheVC *vc)
219   {
220     CacheKey key        = {};
221     Dir *last_collision = nullptr;
222     SCOPED_MUTEX_LOCK(lock, vc->vol->mutex, this->mutex->thread_holding);
223     vc->vector.data[0].alternate.object_key_get(&key);
224     REQUIRE(dir_probe(&key, vc->vol, &dir, &last_collision) != 0);
225     REQUIRE(dir_delete(&key, vc->vol, &dir));
226   }
227 };
228 
229 class CacheAltInit : public CacheInit
230 {
231 public:
CacheAltInit()232   CacheAltInit() {}
233   int
cache_init_success_callback(int event,void * e)234   cache_init_success_callback(int event, void *e) override
235   {
236     CacheTestHandler *h              = new CacheTestHandler(LARGE_FILE, "http://www.scw11.com");
237     CacheAltTest_L_to_S_remove_L *ls = new CacheAltTest_L_to_S_remove_L(SMALL_FILE, "http://www.scw11.com");
238     CacheAltReadAgain *read          = new CacheAltReadAgain(LARGE_FILE, "http://www.scw11.com");
239     CacheAltReadAgain2 *read2        = new CacheAltReadAgain2(SMALL_FILE, "http://www.scw11.com");
240     TerminalTest *tt                 = new TerminalTest;
241 
242     h->add(ls);
243     h->add(read); // read again
244     h->add(read2);
245     h->add(tt);
246     this_ethread()->schedule_imm(h);
247     delete this;
248     return 0;
249   }
250 };
251 
252 TEST_CASE("cache write -> read", "cache")
253 {
254   init_cache(256 * 1024 * 1024);
255   // large write test
256   CacheAltInit *init = new CacheAltInit;
257 
258   this_ethread()->schedule_imm(init);
259   this_thread()->execute();
260 }
261