xref: /trafficserver/iocore/cache/test/main.cc (revision fa6e5731)
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 CATCH_CONFIG_MAIN
25 #include "main.h"
26 
27 #define THREADS 1
28 #define DIAGS_LOG_FILE "diags.log"
29 
30 void
test_done()31 test_done()
32 {
33   TSSystemState::shut_down_event_system();
34 }
35 
36 const char *GLOBAL_DATA = static_cast<char *>(ats_malloc(10 * 1024 * 1024 + 3)); // 10M
37 
38 struct EventProcessorListener : Catch::TestEventListenerBase {
39   using TestEventListenerBase::TestEventListenerBase; // inherit constructor
40 
41   void
testRunStartingEventProcessorListener42   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
43   {
44     BaseLogFile *base_log_file = new BaseLogFile("stderr");
45     diags                      = new Diags(testRunInfo.name, "*" /* tags */, "" /* actions */, base_log_file);
46     diags->activate_taglist("cache.*|agg.*|locks", DiagsTagType_Debug);
47     diags->config.enabled[DiagsTagType_Debug] = true;
48     diags->show_location                      = SHOW_LOCATION_DEBUG;
49 
50     mime_init();
51     Layout::create();
52     RecProcessInit(RECM_STAND_ALONE);
53     LibRecordsConfigInit();
54     ink_net_init(ts::ModuleVersion(1, 0, ts::ModuleVersion::PRIVATE));
55     ink_assert(GLOBAL_DATA != nullptr);
56 
57     statPagesManager.init(); // mutex needs to be initialized before calling netProcessor.init
58     netProcessor.init();
59     eventProcessor.start(THREADS);
60 
61     ink_aio_init(AIO_MODULE_PUBLIC_VERSION);
62 
63     EThread *thread = new EThread();
64     thread->set_specific();
65     init_buffer_allocators(0);
66 
67     std::string src_dir       = std::string(TS_ABS_TOP_SRCDIR) + "/iocore/cache/test";
68     Layout::get()->sysconfdir = src_dir;
69     Layout::get()->prefix     = src_dir;
70     ::remove("./test/var/trafficserver/cache.db");
71   }
72 };
73 CATCH_REGISTER_LISTENER(EventProcessorListener);
74 
75 extern Store theCacheStore;
76 
77 void
init_cache(size_t size,const char * name)78 init_cache(size_t size, const char *name)
79 {
80   ink_cache_init(ts::ModuleVersion(1, 0, ts::ModuleVersion::PRIVATE));
81   cacheProcessor.start();
82 }
83 
84 void
build_hdrs(HTTPInfo & info,const char * url,const char * content_type)85 build_hdrs(HTTPInfo &info, const char *url, const char *content_type)
86 {
87   HTTPHdr req;
88   HTTPHdr resp;
89   HTTPParser parser;
90   int err           = -1;
91   char buf[1024]    = {0};
92   const char *start = buf;
93   char *p           = buf;
94 
95   REQUIRE(url != nullptr);
96 
97   p += sprintf(p, "GET %s HTTP/1.1\n", url);
98   p += sprintf(p, "User-Agent: curl/7.47.0\n");
99   p += sprintf(p, "Accept: %s\n", content_type);
100   p += sprintf(p, "Vary: Content-type\n");
101   p += sprintf(p, "Proxy-Connection: Keep-Alive\n\n");
102 
103   req.create(HTTP_TYPE_REQUEST);
104   http_parser_init(&parser);
105 
106   while (true) {
107     err = req.parse_req(&parser, &start, p, true);
108     if (err != PARSE_RESULT_CONT) {
109       break;
110     }
111   }
112 
113   ink_assert(err == PARSE_RESULT_DONE);
114 
115   memset(buf, 0, sizeof(buf));
116   p = buf;
117 
118   if (content_type == nullptr) {
119     content_type = "application/octet-stream";
120   }
121 
122   p = buf;
123   p += sprintf(p, "HTTP/1.1 200 OK\n");
124   p += sprintf(p, "Content-Type: %s\n", content_type);
125   p += sprintf(p, "Expires: Fri, 15 Mar 2219 08:55:45 GMT\n");
126   p += sprintf(p, "Last-Modified: Thu, 14 Mar 2019 08:47:40 GMT\n\n");
127 
128   resp.create(HTTP_TYPE_RESPONSE);
129   http_parser_init(&parser);
130   start = buf;
131 
132   while (true) {
133     err = resp.parse_resp(&parser, &start, p, true);
134     if (err != PARSE_RESULT_CONT) {
135       break;
136     }
137   }
138   ink_assert(err == PARSE_RESULT_DONE);
139 
140   info.request_set(&req);
141   info.response_set(&resp);
142 
143   req.destroy();
144   resp.destroy();
145 }
146 
147 HttpCacheKey
generate_key(HTTPInfo & info)148 generate_key(HTTPInfo &info)
149 {
150   HttpCacheKey key;
151   Cache::generate_key(&key, info.request_get()->url_get(), 1);
152   return key;
153 }
154 
155 void
fill_data()156 CacheWriteTest::fill_data()
157 {
158   size_t size = std::min(WRITE_LIMIT, this->_size);
159   auto n      = this->_write_buffer->write(this->_cursor, size);
160   this->_size -= n;
161   this->_cursor += n;
162 }
163 
164 int
write_event(int event,void * e)165 CacheWriteTest::write_event(int event, void *e)
166 {
167   switch (event) {
168   case CACHE_EVENT_OPEN_WRITE:
169     this->vc = static_cast<CacheVC *>(e);
170     /* fall through */
171   case CACHE_EVENT_OPEN_WRITE_FAILED:
172     this->process_event(event);
173     break;
174   case VC_EVENT_WRITE_READY:
175     this->process_event(event);
176     this->fill_data();
177     break;
178   case VC_EVENT_WRITE_COMPLETE:
179     this->process_event(event);
180     break;
181   default:
182     this->close();
183     CHECK(false);
184     break;
185   }
186   return 0;
187 }
188 
189 void
do_io_write(size_t size)190 CacheWriteTest::do_io_write(size_t size)
191 {
192   if (size == 0) {
193     size = this->_size;
194   }
195   this->vc->set_http_info(&this->info);
196   this->vio = this->vc->do_io_write(this, size, this->_write_buffer->alloc_reader());
197 }
198 
199 int
start_test(int event,void * e)200 CacheWriteTest::start_test(int event, void *e)
201 {
202   Debug("cache test", "start write test");
203 
204   HttpCacheKey key;
205   key = generate_key(this->info);
206 
207   HTTPInfo *old_info = &this->old_info;
208   if (!old_info->valid()) {
209     old_info = nullptr;
210   }
211 
212   SET_HANDLER(&CacheWriteTest::write_event);
213   cacheProcessor.open_write(this, 0, &key, (CacheHTTPHdr *)this->info.request_get(), old_info);
214   return 0;
215 }
216 
217 int
read_event(int event,void * e)218 CacheReadTest::read_event(int event, void *e)
219 {
220   switch (event) {
221   case CACHE_EVENT_OPEN_READ:
222     this->vc = static_cast<CacheVC *>(e);
223     /* fall through */
224   case CACHE_EVENT_OPEN_READ_FAILED:
225     this->process_event(event);
226     break;
227   case VC_EVENT_READ_READY: {
228     while (this->_reader->block_read_avail()) {
229       auto str = this->_reader->block_read_view();
230       if (memcmp(str.data(), this->_cursor, str.size()) == 0) {
231         this->_reader->consume(str.size());
232         this->_cursor += str.size();
233         this->process_event(event);
234       } else {
235         CHECK(false);
236         this->close();
237         TEST_DONE();
238         break;
239       }
240     }
241     break;
242   }
243   case VC_EVENT_ERROR:
244   case VC_EVENT_EOS:
245   case VC_EVENT_READ_COMPLETE:
246     this->process_event(event);
247     break;
248   default:
249     CHECK(false);
250     this->close();
251     break;
252   }
253   return 0;
254 }
255 
256 void
do_io_read(size_t size)257 CacheReadTest::do_io_read(size_t size)
258 {
259   if (size == 0) {
260     size = this->_size;
261   }
262   this->vc->get_http_info(&this->read_http_info);
263   this->vio = this->vc->do_io_read(this, size, this->_read_buffer);
264 }
265 
266 int
start_test(int event,void * e)267 CacheReadTest::start_test(int event, void *e)
268 {
269   Debug("cache test", "start read test");
270   HttpCacheKey key;
271   key = generate_key(this->info);
272 
273   SET_HANDLER(&CacheReadTest::read_event);
274   cacheProcessor.open_read(this, &key, (CacheHTTPHdr *)this->info.request_get(), &this->params);
275   return 0;
276 }
277 
278 constexpr size_t WRITE_LIMIT = 1024 * 3;
279