• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

NetVCTest.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026    NetVCTest.cc
00027 
00028    Description:
00029        Unit test for infastructure for VConnections implementing the
00030          NetVConnection interface
00031 
00032 
00033 
00034 
00035  ****************************************************************************/
00036 
00037 #include "P_Net.h"
00038 
00039 // Each test requires two definition entries.  One for the passive
00040 //   side of the connection and one for the active side
00041 //
00042 //  test fields:
00043 //
00044 //  name bytes_to_send nbytes_write bytes_to_read nbytes_read write_per timeout read_term write_term
00045 //
00046 NVC_test_def netvc_tests_def[] = {
00047 
00048   {"basic", 2000, 2000, 2000, 2000, 50, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00049   ,
00050   {"basic", 2000, 2000, 2000, 2000, 50, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00051   ,
00052 
00053   {"basic2", 10001, 10001, 5001, 5001, 1024, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00054   ,
00055   {"basic2", 5001, 5001, 10001, 10001, 1024, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00056   ,
00057 
00058   {"large", 1000000, 1000000, 500000, 500000, 8192, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00059   ,
00060   {"large", 500000, 500000, 1000000, 1000000, 8192, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00061   ,
00062 
00063   // Test large block transfers
00064   {"larget", 1000000, 1000000, 500000, 500000, 40000, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00065   ,
00066   {"larget", 500000, 500000, 1000000, 1000000, 40000, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00067   ,
00068 
00069   {"eos", 4000, 4000, 10, 10, 8192, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00070   ,
00071   {"eos", 10, 10, 6000, 6000, 8192, 10, VC_EVENT_EOS, VC_EVENT_WRITE_COMPLETE}
00072   ,
00073 
00074   {"werr", 4000, 4000, 10, 10, 129, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_ERROR}
00075   ,
00076   {"werr", 10, 10, 10, 10, 129, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00077   ,
00078 
00079   {"itimeout", 6000, 8000, 10, 10, 512, 10, VC_EVENT_READ_COMPLETE, VC_EVENT_INACTIVITY_TIMEOUT}
00080   ,
00081   {"itimeout", 10, 10, 6000, 8000, 512, 20, VC_EVENT_EOS, VC_EVENT_WRITE_COMPLETE}
00082   ,
00083 
00084   // Test the small transfer code one byts at a time
00085   {"smallt", 400, 400, 500, 500, 1, 15, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00086   ,
00087   {"smallt", 500, 500, 400, 400, 1, 15, VC_EVENT_READ_COMPLETE, VC_EVENT_WRITE_COMPLETE}
00088   ,
00089 
00090   // The purpose of this test is show that stack can over flow if we move too
00091   //   small of blocks between the buffers.  EVENT_NONE is wild card error event
00092   //   since which side gets the timeout is unpredictable
00093   {"overflow", 1000000, 1000000, 50, 50, 1, 20, VC_EVENT_READ_COMPLETE, EVENT_NONE}
00094   ,
00095   {"overflow", 50, 50, 0, 35000, 1024, 35, EVENT_NONE, VC_EVENT_WRITE_COMPLETE}
00096 
00097 };
00098 const unsigned num_netvc_tests = countof(netvc_tests_def);
00099 
00100 
00101 NetVCTest::NetVCTest():
00102 Continuation(NULL),
00103 test_cont_type(NET_VC_TEST_ACTIVE),
00104 test_vc(NULL), regress(NULL), driver(NULL), read_vio(NULL),
00105 write_vio(NULL), read_buffer(NULL), write_buffer(NULL),
00106 reader_for_rbuf(NULL), reader_for_wbuf(NULL), write_bytes_to_add_per(0),
00107 timeout(0),
00108 actual_bytes_read(0), actual_bytes_sent(0), write_done(false), read_done(false),
00109 read_seed(0), write_seed(0), bytes_to_send(0), bytes_to_read(0),
00110 nbytes_read(0), nbytes_write(0), expected_read_term(0),
00111 expected_write_term(0), test_name(NULL), module_name(NULL), debug_tag(NULL)
00112 {
00113 }
00114 
00115 NetVCTest::~NetVCTest()
00116 {
00117   mutex = NULL;
00118 
00119   if (read_buffer) {
00120     Debug(debug_tag, "Freeing read MIOBuffer with %d blocks on %s",
00121           read_buffer->max_block_count(), (test_cont_type == NET_VC_TEST_ACTIVE) ? "Active" : "Passive");
00122     free_MIOBuffer(read_buffer);
00123     read_buffer = NULL;
00124   }
00125 
00126   if (write_buffer) {
00127     Debug(debug_tag, "Freeing write MIOBuffer with %d blocks on %s",
00128           write_buffer->max_block_count(), (test_cont_type == NET_VC_TEST_ACTIVE) ? "Active" : "Passive");
00129     free_MIOBuffer(write_buffer);
00130     write_buffer = NULL;
00131   }
00132 }
00133 
00134 void
00135 NetVCTest::init_test(NetVcTestType_t c_type, NetTestDriver * driver_arg,
00136                      NetVConnection * nvc, RegressionTest * robj,
00137                      NVC_test_def * my_def, const char *module_name_arg, const char *debug_tag_arg)
00138 {
00139 
00140   test_cont_type = c_type;
00141   driver = driver_arg;
00142   test_vc = nvc;
00143   regress = robj;
00144   module_name = module_name_arg;
00145   debug_tag = debug_tag_arg;
00146 
00147   bytes_to_send = my_def->bytes_to_send;
00148   bytes_to_read = my_def->bytes_to_read;
00149 
00150   nbytes_read = my_def->nbytes_read;
00151   nbytes_write = my_def->nbytes_write;
00152 
00153   write_bytes_to_add_per = my_def->write_bytes_per;
00154   timeout = my_def->timeout;
00155   expected_read_term = my_def->expected_read_term;
00156   expected_write_term = my_def->expected_write_term;
00157   test_name = my_def->test_name;
00158 
00159   mutex = new_ProxyMutex();
00160   SET_HANDLER(&NetVCTest::main_handler);
00161 
00162   if (c_type == NET_VC_TEST_ACTIVE) {
00163     start_test();
00164   }
00165 }
00166 
00167 void
00168 NetVCTest::start_test()
00169 {
00170 
00171   test_vc->set_inactivity_timeout(HRTIME_SECONDS(timeout));
00172   test_vc->set_active_timeout(HRTIME_SECONDS(timeout + 5));
00173 
00174   read_buffer = new_MIOBuffer();
00175   write_buffer = new_MIOBuffer();
00176 
00177   reader_for_rbuf = read_buffer->alloc_reader();
00178   reader_for_wbuf = write_buffer->alloc_reader();
00179 
00180   if (nbytes_read > 0) {
00181     read_vio = test_vc->do_io_read(this, nbytes_read, read_buffer);
00182   } else {
00183     read_done = true;
00184   }
00185 
00186   if (nbytes_write > 0) {
00187     write_vio = test_vc->do_io_write(this, nbytes_write, reader_for_wbuf);
00188   } else {
00189     write_done = true;
00190   }
00191 }
00192 
00193 
00194 int
00195 NetVCTest::fill_buffer(MIOBuffer * buf, uint8_t * seed, int bytes)
00196 {
00197 
00198   char *space = (char *)ats_malloc(bytes);
00199   char *tmp = space;
00200   int to_add = bytes;
00201 
00202   while (bytes > 0) {
00203     *tmp = *seed;
00204     (*seed)++;
00205     bytes--;
00206     tmp++;
00207   }
00208 
00209   buf->write(space, to_add);
00210   ats_free(space);
00211 
00212   return to_add;
00213 }
00214 
00215 int
00216 NetVCTest::consume_and_check_bytes(IOBufferReader * r, uint8_t * seed)
00217 {
00218 
00219   uint8_t *tmp, *end;
00220   int b_consumed = 0;
00221 
00222   if (actual_bytes_read >= bytes_to_read) {
00223     return 1;
00224   }
00225 
00226   while (r->read_avail() > 0) {
00227     int64_t b_avail = r->block_read_avail();
00228 
00229     tmp = (uint8_t *) r->start();
00230     end = tmp + b_avail;
00231     b_consumed = 0;
00232 
00233     while (tmp < end && actual_bytes_read < bytes_to_read) {
00234       actual_bytes_read++;
00235       b_consumed++;
00236       if (*tmp != *seed) {
00237         r->consume(b_consumed);
00238         return 0;
00239 
00240       } else {
00241         tmp++;
00242         (*seed)++;
00243       }
00244     }
00245 
00246     Debug(debug_tag, "consume_&_check: read %d, to_read %d", actual_bytes_read, bytes_to_read);
00247     r->consume(b_consumed);
00248   }
00249 
00250   return 1;
00251 }
00252 
00253 void
00254 NetVCTest::write_finished()
00255 {
00256   if (nbytes_write != write_vio->ndone && expected_write_term == VC_EVENT_WRITE_COMPLETE) {
00257     record_error("write: bad ndone value");
00258     return;
00259   }
00260 
00261   write_done = true;
00262 
00263   if (read_done) {
00264     test_vc->do_io_close();
00265     finished();
00266   } else {
00267     test_vc->do_io_shutdown(IO_SHUTDOWN_WRITE);
00268   }
00269 }
00270 
00271 void
00272 NetVCTest::read_finished()
00273 {
00274   if (nbytes_read != read_vio->ndone && expected_read_term != VC_EVENT_EOS && expected_read_term != VC_EVENT_NONE) {
00275     record_error("read: bad ndone value");
00276     return;
00277   }
00278 
00279   read_done = true;
00280 
00281   if (write_done) {
00282     test_vc->do_io_close();
00283     finished();
00284   } else {
00285     test_vc->do_io_shutdown(IO_SHUTDOWN_READ);
00286   }
00287 }
00288 
00289 void
00290 NetVCTest::record_error(const char *msg)
00291 {
00292 
00293   rprintf(regress, "  %s test: %s failed : %s : on %s\n",
00294           module_name, test_name, msg, (test_cont_type == NET_VC_TEST_ACTIVE) ? "Active" : "Passive");
00295   ink_atomic_increment(&driver->errors, 1);
00296 
00297   test_vc->do_io_close();
00298   finished();
00299 }
00300 
00301 void
00302 NetVCTest::finished()
00303 {
00304   eventProcessor.schedule_imm(driver);
00305   delete this;
00306 }
00307 
00308 void
00309 NetVCTest::write_handler(int event)
00310 {
00311 
00312   Debug(debug_tag, "write_handler received event %d on %s",
00313         event, (test_cont_type == NET_VC_TEST_ACTIVE) ? "Active" : "Passive");
00314 
00315   switch (event) {
00316   case VC_EVENT_WRITE_READY:
00317     if (write_vio->ndone < bytes_to_send) {
00318       int left_to_send = bytes_to_send - actual_bytes_sent;
00319       ink_assert(left_to_send >= 0);
00320       int to_fill = MIN(left_to_send, write_bytes_to_add_per);
00321       actual_bytes_sent += fill_buffer(write_buffer, &write_seed, to_fill);
00322       write_vio->reenable();
00323     }
00324     break;
00325   case VC_EVENT_WRITE_COMPLETE:
00326     write_finished();
00327     break;
00328   case VC_EVENT_INACTIVITY_TIMEOUT:
00329   case VC_EVENT_ACTIVE_TIMEOUT:
00330   case VC_EVENT_ERROR:
00331     if (expected_write_term != event && expected_write_term != VC_EVENT_NONE) {
00332       record_error("write: Unexpected error or timeout");
00333     } else {
00334       write_finished();
00335     }
00336     break;
00337   default:
00338     record_error("write: Unknown event");
00339     break;
00340   }
00341 }
00342 
00343 void
00344 NetVCTest::read_handler(int event)
00345 {
00346 
00347   Debug(debug_tag, "read_handler received event %d on %s",
00348         event, (test_cont_type == NET_VC_TEST_ACTIVE) ? "Active" : "Passive");
00349 
00350   switch (event) {
00351   case VC_EVENT_READ_READY:
00352     if (consume_and_check_bytes(reader_for_rbuf, &read_seed) == 0) {
00353       record_error("Read content corrupt");
00354       return;
00355     } else {
00356       read_vio->reenable();
00357     }
00358     break;
00359   case VC_EVENT_READ_COMPLETE:
00360     if (consume_and_check_bytes(reader_for_rbuf, &read_seed) == 0) {
00361       record_error("Read content corrupt");
00362       return;
00363     } else {
00364       read_finished();
00365     }
00366     break;
00367   case VC_EVENT_EOS:
00368     if (expected_read_term != VC_EVENT_EOS && expected_read_term != VC_EVENT_NONE) {
00369       record_error("read: Unexpected EOS Event");
00370     } else {
00371       read_finished();
00372     }
00373     break;
00374   case VC_EVENT_INACTIVITY_TIMEOUT:
00375   case VC_EVENT_ACTIVE_TIMEOUT:
00376   case VC_EVENT_ERROR:
00377     if (expected_read_term != event && expected_read_term != VC_EVENT_NONE) {
00378       record_error("read: Unexpected error or timeout");
00379     } else {
00380       read_finished();
00381     }
00382     break;
00383   default:
00384     record_error("read: Unknown event");
00385     break;
00386   }
00387 }
00388 
00389 int
00390 NetVCTest::main_handler(int event, void *data)
00391 {
00392 
00393   if (event == NET_EVENT_ACCEPT) {
00394     test_vc = (NetVConnection *) data;
00395     start_test();
00396     return 0;
00397   }
00398 
00399   if (data == read_vio) {
00400     read_handler(event);
00401   } else if (data == write_vio) {
00402     write_handler(event);
00403   } else {
00404     record_error("main: unknown event");
00405   }
00406 
00407   return 0;
00408 }
00409 
00410 
00411 NetTestDriver::NetTestDriver():
00412 Continuation(NULL), errors(0), r(NULL), pstatus(NULL)
00413 {
00414 }
00415 
00416 NetTestDriver::~NetTestDriver()
00417 {
00418 }

Generated by  doxygen 1.7.1