David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 1 | /* |
David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
| 18 | */ |
| 19 | |
David Reiss | 3cc9dab | 2010-10-06 17:10:21 +0000 | [diff] [blame] | 20 | #define __STDC_LIMIT_MACROS |
| 21 | #define __STDC_FORMAT_MACROS |
| 22 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 23 | #ifndef _GNU_SOURCE |
| 24 | #define _GNU_SOURCE // needed for getopt_long |
| 25 | #endif |
| 26 | |
David Reiss | 3cc9dab | 2010-10-06 17:10:21 +0000 | [diff] [blame] | 27 | #include <stdint.h> |
| 28 | #include <inttypes.h> |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 29 | #include <getopt.h> |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 30 | #include <cstddef> |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 31 | #include <fstream> |
| 32 | #include <iostream> |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 33 | #include <tr1/functional> |
David Reiss | 3cc9dab | 2010-10-06 17:10:21 +0000 | [diff] [blame] | 34 | |
| 35 | #include <boost/random.hpp> |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 36 | #include <boost/shared_array.hpp> |
| 37 | #include <boost/test/unit_test.hpp> |
David Reiss | 3cc9dab | 2010-10-06 17:10:21 +0000 | [diff] [blame] | 38 | |
David Reiss | 28f298d | 2008-05-01 06:17:36 +0000 | [diff] [blame] | 39 | #include <transport/TBufferTransports.h> |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 40 | #include <transport/TZlibTransport.h> |
| 41 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 42 | using namespace std; |
| 43 | using namespace boost; |
| 44 | using namespace apache::thrift::transport; |
| 45 | |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 46 | |
| 47 | // Distributions of reads and writes meant to approximate a real load, |
| 48 | // mixing up small and large while also hitting various boundary conditions. |
| 49 | // Generated by Python: int(random.lognormvariate(2.5, 1)) |
| 50 | unsigned int dist[][5000] = { |
| 51 | { 1<<15 }, |
| 52 | |
| 53 | { |
| 54 | 5,13,9,1,8,9,11,13,18,48,24,13,21,13,5,11,35,2,4,20,17,72,27,14,15,4,7,26, |
| 55 | 12,1,14,9,2,16,29,41,7,24,4,27,14,4,1,4,25,3,6,34,10,8,50,2,14,13,55,29,3, |
| 56 | 43,53,49,14,4,10,32,27,48,1,3,1,11,5,17,16,51,17,30,15,11,9,2,2,11,52,12,2, |
| 57 | 13,94,1,19,1,38,2,8,43,8,33,7,30,8,17,22,2,15,14,12,34,2,12,6,37,29,74,3, |
| 58 | 165,16,11,17,5,14,3,10,7,37,11,24,7,1,3,12,37,8,9,34,17,12,8,21,13,37,1,4, |
| 59 | 30,14,78,4,15,2,40,37,17,12,36,82,14,4,1,4,7,17,11,16,88,77,2,3,15,3,34,11, |
| 60 | 5,79,22,34,8,4,4,40,22,24,28,9,13,3,34,27,9,16,39,16,39,13,2,4,3,41,26,10,4, |
| 61 | 33,4,7,12,5,6,3,10,30,8,21,16,58,19,9,0,47,7,13,11,19,15,7,53,57,2,13,28,22, |
| 62 | 3,16,9,25,33,12,40,7,12,64,7,14,24,44,9,2,14,11,2,58,1,26,30,11,9,5,24,7,9, |
| 63 | 94,2,10,21,5,5,4,5,6,179,9,18,2,7,13,31,41,17,4,36,3,21,6,26,8,15,18,44,27, |
| 64 | 11,9,25,7,0,14,2,12,20,23,13,2,163,9,5,15,65,2,14,6,8,98,11,15,14,34,2,3,10, |
| 65 | 22,9,92,7,10,32,67,13,3,4,35,8,2,1,5,0,26,381,7,27,8,2,16,93,4,19,5,8,25,9, |
| 66 | 31,14,4,21,5,3,9,22,56,4,18,3,11,18,6,4,3,40,12,16,110,8,35,14,1,18,40,9,12, |
| 67 | 14,3,11,7,57,13,18,116,53,19,22,7,16,11,5,8,21,16,1,75,21,20,1,28,2,6,1,7, |
| 68 | 19,38,5,6,9,9,4,1,7,55,36,62,5,4,4,24,15,1,12,35,48,20,5,17,1,5,26,15,4,54, |
| 69 | 13,5,5,15,5,19,32,29,31,7,6,40,7,80,11,18,8,128,48,6,12,84,13,4,7,2,13,9,16, |
| 70 | 17,3,254,1,4,181,8,44,7,6,24,27,9,23,14,34,16,22,25,10,3,3,4,4,12,2,12,6,7, |
| 71 | 13,58,13,6,11,19,53,11,66,18,19,10,4,13,2,5,49,58,1,67,7,21,64,14,11,14,8,3, |
| 72 | 26,33,91,31,20,7,9,42,39,4,3,55,11,10,0,7,4,75,8,12,0,27,3,8,9,0,12,12,23, |
| 73 | 28,23,20,4,13,30,2,22,20,19,30,6,22,2,6,4,24,7,19,55,86,5,33,2,161,6,7,1,62, |
| 74 | 13,3,72,12,12,9,7,12,10,5,10,29,1,5,22,13,13,5,2,12,3,7,14,18,2,3,46,21,17, |
| 75 | 15,19,3,27,5,16,45,31,10,8,17,18,18,3,7,24,6,55,9,3,6,12,10,12,8,91,9,4,4,4, |
| 76 | 27,29,16,5,7,22,43,28,11,14,8,11,28,109,55,71,40,3,8,22,26,15,44,3,25,29,5, |
| 77 | 3,32,17,12,3,29,27,25,15,11,8,40,39,38,17,3,9,11,2,32,11,6,20,48,75,27,3,7, |
| 78 | 54,12,95,12,7,24,23,2,13,8,15,16,5,12,4,17,7,19,88,2,6,13,115,45,12,21,2,86, |
| 79 | 74,9,7,5,16,32,16,2,21,18,6,34,5,18,260,7,12,16,44,19,92,31,7,8,2,9,0,0,15, |
| 80 | 8,38,4,8,20,18,2,83,3,3,4,9,5,3,10,3,5,29,15,7,11,8,48,17,23,2,17,4,11,22, |
| 81 | 21,64,8,8,4,19,95,0,17,28,9,11,20,71,5,11,18,12,13,45,49,4,1,33,32,23,13,5, |
| 82 | 52,2,2,16,3,4,7,12,2,1,12,6,24,1,22,155,21,3,45,4,12,44,26,5,40,36,9,9,8,20, |
| 83 | 35,31,3,2,32,50,10,8,37,2,75,35,22,15,192,8,11,23,1,4,29,6,8,8,5,12,18,32,4, |
| 84 | 7,12,2,0,0,9,5,48,11,35,3,1,123,6,29,8,11,8,23,51,16,6,63,12,2,5,4,14,2,15, |
| 85 | 7,14,3,2,7,17,32,8,8,10,1,23,62,2,49,6,49,47,23,3,20,7,11,39,10,24,6,15,5,5, |
| 86 | 11,8,16,36,8,13,20,3,10,44,7,52,7,10,36,6,15,10,5,11,4,14,19,17,10,12,3,6, |
| 87 | 23,4,13,94,70,7,36,7,38,7,28,8,4,15,3,19,4,33,39,21,109,4,80,6,40,4,432,4,4, |
| 88 | 7,8,3,31,8,28,37,34,10,2,21,5,22,0,7,36,14,12,6,24,1,21,5,9,2,29,20,54,113, |
| 89 | 13,31,39,27,6,0,27,4,5,2,43,7,8,57,8,62,7,9,12,22,90,30,6,19,7,10,20,6,5,58, |
| 90 | 32,30,41,4,10,25,13,3,8,7,10,2,9,6,151,44,16,12,16,20,8,3,18,11,17,4,10,45, |
| 91 | 15,8,56,38,52,25,40,14,4,17,15,8,2,19,7,8,26,30,2,3,180,8,26,17,38,35,5,16, |
| 92 | 28,5,15,56,13,14,18,9,15,83,27,3,9,4,11,8,27,27,44,10,12,8,3,48,14,7,9,4,4, |
| 93 | 8,4,5,9,122,8,14,12,19,17,21,4,29,63,21,17,10,12,18,47,10,10,53,4,18,16,4,8, |
| 94 | 118,9,5,12,9,11,9,3,12,32,3,23,2,15,3,3,30,3,17,235,15,22,9,299,14,17,1,5, |
| 95 | 16,8,3,7,3,13,2,7,6,4,8,66,2,13,6,15,16,47,3,36,5,7,10,24,1,9,9,8,13,16,26, |
| 96 | 12,7,24,21,18,49,23,39,10,41,4,13,4,27,11,12,12,19,4,147,8,10,9,40,21,2,83, |
| 97 | 10,5,6,11,25,9,50,57,40,12,12,21,1,3,24,23,9,3,9,13,2,3,12,57,8,11,13,15,26, |
| 98 | 15,10,47,36,4,25,1,5,8,5,4,0,12,49,5,19,4,6,16,14,6,10,69,10,33,29,7,8,61, |
| 99 | 12,4,0,3,7,6,3,16,29,27,38,4,21,0,24,3,2,1,19,16,22,2,8,138,11,7,7,3,12,22, |
| 100 | 3,16,5,7,3,53,9,10,32,14,5,7,3,6,22,9,59,26,8,7,58,5,16,11,55,7,4,11,146,91, |
| 101 | 8,13,18,14,6,8,8,31,26,22,6,11,30,11,30,15,18,31,3,48,17,7,6,4,9,2,25,3,35, |
| 102 | 13,13,7,8,4,31,10,8,10,4,3,45,10,23,2,7,259,17,21,13,14,3,26,3,8,27,4,18,9, |
| 103 | 66,7,12,5,8,17,4,23,55,41,51,2,32,26,66,4,21,14,12,65,16,22,17,5,14,2,29,24, |
| 104 | 7,3,36,2,43,53,86,5,28,4,58,13,49,121,6,2,73,2,1,47,4,2,27,10,35,28,27,10, |
| 105 | 17,10,56,7,10,14,28,20,24,40,7,4,7,3,10,11,32,6,6,3,15,11,54,573,2,3,6,2,3, |
| 106 | 14,64,4,16,12,16,42,10,26,4,6,11,69,18,27,2,2,17,22,9,13,22,11,6,1,15,49,3, |
| 107 | 14,1 |
| 108 | }, |
| 109 | |
| 110 | { |
| 111 | 11,11,11,15,47,1,3,1,23,5,8,18,3,23,15,21,1,7,19,10,26,1,17,11,31,21,41,18, |
| 112 | 34,4,9,58,19,3,3,36,5,18,13,3,14,4,9,10,4,19,56,15,3,5,3,11,27,9,4,10,13,4, |
| 113 | 11,6,9,2,18,3,10,19,11,4,53,4,2,2,3,4,58,16,3,0,5,30,2,11,93,10,2,14,10,6,2, |
| 114 | 115,2,25,16,22,38,101,4,18,13,2,145,51,45,15,14,15,13,20,7,24,5,13,14,30,40, |
| 115 | 10,4,107,12,24,14,39,12,6,13,20,7,7,11,5,18,18,45,22,6,39,3,2,1,51,9,11,4, |
| 116 | 13,9,38,44,8,11,9,15,19,9,23,17,17,17,13,9,9,1,10,4,18,6,2,9,5,27,32,72,8, |
| 117 | 37,9,4,10,30,17,20,15,17,66,10,4,73,35,37,6,4,16,117,45,13,4,75,5,24,65,10, |
| 118 | 4,9,4,13,46,5,26,29,10,4,4,52,3,13,18,63,6,14,9,24,277,9,88,2,48,27,123,14, |
| 119 | 61,7,5,10,8,7,90,3,10,3,3,48,17,13,10,18,33,2,19,36,6,21,1,16,12,5,6,2,16, |
| 120 | 15,29,88,28,2,15,6,11,4,6,11,3,3,4,18,9,53,5,4,3,33,8,9,8,6,7,36,9,62,14,2, |
| 121 | 1,10,1,16,7,32,7,23,20,11,10,23,2,1,0,9,16,40,2,81,5,22,8,5,4,37,51,37,10, |
| 122 | 19,57,11,2,92,31,6,39,10,13,16,8,20,6,9,3,10,18,25,23,12,30,6,2,26,7,64,18, |
| 123 | 6,30,12,13,27,7,10,5,3,33,24,99,4,23,4,1,27,7,27,49,8,20,16,3,4,13,9,22,67, |
| 124 | 28,3,10,16,3,2,10,4,8,1,8,19,3,85,6,21,1,9,16,2,30,10,33,12,4,9,3,1,60,38,6, |
| 125 | 24,32,3,14,3,40,8,34,115,5,9,27,5,96,3,40,6,15,5,8,22,112,5,5,25,17,58,2,7, |
| 126 | 36,21,52,1,3,95,12,21,4,11,8,59,24,5,21,4,9,15,8,7,21,3,26,5,11,6,7,17,65, |
| 127 | 14,11,10,2,17,5,12,22,4,4,2,21,8,112,3,34,63,35,2,25,1,2,15,65,23,0,3,5,15, |
| 128 | 26,27,9,5,48,11,15,4,9,5,33,20,15,1,18,19,11,24,40,10,21,74,6,6,32,30,40,5, |
| 129 | 4,7,44,10,25,46,16,12,5,40,7,18,5,18,9,12,8,4,25,5,6,36,4,43,8,9,12,35,17,4, |
| 130 | 8,9,11,27,5,10,17,40,8,12,4,18,9,18,12,20,25,39,42,1,24,13,22,15,7,112,35,3, |
| 131 | 7,17,33,2,5,5,19,8,4,12,24,14,13,2,1,13,6,5,19,11,7,57,0,19,6,117,48,14,8, |
| 132 | 10,51,17,12,14,2,5,8,9,15,4,48,53,13,22,4,25,12,11,19,45,5,2,6,54,22,9,15,9, |
| 133 | 13,2,7,11,29,82,16,46,4,26,14,26,40,22,4,26,6,18,13,4,4,20,3,3,7,12,17,8,9, |
| 134 | 23,6,20,7,25,23,19,5,15,6,23,15,11,19,11,3,17,59,8,18,41,4,54,23,44,75,13, |
| 135 | 20,6,11,2,3,1,13,10,3,7,12,3,4,7,8,30,6,6,7,3,32,9,5,28,6,114,42,13,36,27, |
| 136 | 59,6,93,13,74,8,69,140,3,1,17,48,105,6,11,5,15,1,10,10,14,8,53,0,8,24,60,2, |
| 137 | 6,35,2,12,32,47,16,17,75,2,5,4,37,28,10,5,9,57,4,59,5,12,13,7,90,5,11,5,24, |
| 138 | 22,13,30,1,2,10,9,6,19,3,18,47,2,5,7,9,35,15,3,6,1,21,14,14,18,14,9,12,8,73, |
| 139 | 6,19,3,32,9,14,17,17,5,55,23,6,16,28,3,11,48,4,6,6,6,12,16,30,10,30,27,51, |
| 140 | 18,29,2,3,15,1,76,0,16,33,4,27,3,62,4,10,2,4,8,15,9,41,26,22,2,4,20,4,49,0, |
| 141 | 8,1,57,13,12,39,3,63,10,19,34,35,2,7,8,29,72,4,10,0,77,8,6,7,9,15,21,9,4,1, |
| 142 | 20,23,1,9,18,9,15,36,4,7,6,15,5,7,7,40,2,9,22,2,3,20,4,12,34,13,6,18,15,1, |
| 143 | 38,20,12,7,16,3,19,85,12,16,18,16,2,17,1,13,8,6,12,15,97,17,12,9,3,21,15,12, |
| 144 | 23,44,81,26,30,2,5,17,6,6,0,22,42,19,6,19,41,14,36,7,3,56,7,9,3,2,6,9,69,3, |
| 145 | 15,4,30,28,29,7,9,15,17,17,6,1,6,153,9,33,5,12,14,16,28,3,8,7,14,12,4,6,36, |
| 146 | 9,24,13,13,4,2,9,15,19,9,53,7,13,4,150,17,9,2,6,12,7,3,5,58,19,58,28,8,14,3, |
| 147 | 20,3,0,32,56,7,5,4,27,1,68,4,29,13,5,58,2,9,65,41,27,16,15,12,14,2,10,9,24, |
| 148 | 3,2,9,2,2,3,14,32,10,22,3,13,11,4,6,39,17,0,10,5,5,10,35,16,19,14,1,8,63,19, |
| 149 | 14,8,56,10,2,12,6,12,6,7,16,2,9,9,12,20,73,25,13,21,17,24,5,32,8,12,25,8,14, |
| 150 | 16,5,23,3,7,6,3,11,24,6,30,4,21,13,28,4,6,29,15,5,17,6,26,8,15,8,3,7,7,50, |
| 151 | 11,30,6,2,28,56,16,24,25,23,24,89,31,31,12,7,22,4,10,17,3,3,8,11,13,5,3,27, |
| 152 | 1,12,1,14,8,10,29,2,5,2,2,20,10,0,31,10,21,1,48,3,5,43,4,5,18,13,5,18,25,34, |
| 153 | 18,3,5,22,16,3,4,20,3,9,3,25,6,6,44,21,3,12,7,5,42,3,2,14,4,36,5,3,45,51,15, |
| 154 | 9,11,28,9,7,6,6,12,26,5,14,10,11,42,55,13,21,4,28,6,7,23,27,11,1,41,36,0,32, |
| 155 | 15,26,2,3,23,32,11,2,15,7,29,26,144,33,20,12,7,21,10,7,11,65,46,10,13,20,32, |
| 156 | 4,4,5,19,2,19,15,49,41,1,75,10,11,25,1,2,45,11,8,27,18,10,60,28,29,12,30,19, |
| 157 | 16,4,24,11,19,27,17,49,18,7,40,13,19,22,8,55,12,11,3,6,5,11,8,10,22,5,9,9, |
| 158 | 25,7,17,7,64,1,24,2,12,17,44,4,12,27,21,11,10,7,47,5,9,13,12,38,27,21,7,29, |
| 159 | 7,1,17,3,3,5,48,62,10,3,11,17,15,15,6,3,8,10,8,18,19,13,3,9,7,6,44,9,10,4, |
| 160 | 43,8,6,6,14,20,38,24,2,4,5,5,7,5,9,39,8,44,40,9,19,7,3,15,25,2,37,18,15,9,5, |
| 161 | 8,32,10,5,18,4,7,46,20,17,23,4,11,16,18,31,11,3,11,1,14,1,25,4,27,13,13,39, |
| 162 | 14,6,6,35,6,16,13,11,122,21,15,20,24,10,5,152,15,39,5,20,16,9,14,7,53,6,3,8, |
| 163 | 19,63,32,6,2,3,20,1,19,5,13,42,15,4,6,68,31,46,11,38,10,24,5,5,8,9,12,3,35, |
| 164 | 46,26,16,2,8,4,74,16,44,4,5,1,16,4,14,23,16,69,15,42,31,14,7,7,6,97,14,40,1, |
| 165 | 8,7,34,9,39,19,13,15,10,21,18,10,5,15,38,7,5,12,7,20,15,4,11,6,14,5,17,7,39, |
| 166 | 35,36,18,20,26,22,4,2,36,21,64,0,5,9,10,6,4,1,7,3,1,3,3,4,10,20,90,2,22,48, |
| 167 | 16,23,2,33,40,1,21,21,17,20,8,8,12,4,83,14,48,4,21,3,9,27,5,11,40,15,9,3,16, |
| 168 | 17,9,11,4,24,31,17,3,4,2,11,1,8,4,8,6,41,17,4,13,3,7,17,8,27,5,13,6,10,7,13, |
| 169 | 12,18,13,60,18,3,8,1,12,125,2,7,16,2,11,2,4,7,26,5,9,14,14,16,8,14,7,14,6,9, |
| 170 | 13,9,6,4,26,35,49,36,55,3,9,6,40,26,23,31,19,41,2,10,31,6,54,5,69,16,7,8,16, |
| 171 | 1,5,7,4,22,7,7,5,4,48,11,13,3,98,4,11,19,4,2,14,7,34,7,10,3,2,12,7,6,2,5,118 |
| 172 | }, |
| 173 | }; |
| 174 | |
David Reiss | 3cc9dab | 2010-10-06 17:10:21 +0000 | [diff] [blame] | 175 | boost::mt19937 rng; |
| 176 | |
| 177 | uint8_t* gen_uniform_buffer(uint32_t buf_len, uint8_t c) { |
| 178 | uint8_t* buf = new uint8_t[buf_len]; |
| 179 | memset(buf, c, buf_len); |
| 180 | return buf; |
| 181 | } |
| 182 | |
| 183 | uint8_t* gen_compressible_buffer(uint32_t buf_len) { |
| 184 | uint8_t* buf = new uint8_t[buf_len]; |
| 185 | |
| 186 | // Generate small runs of alternately increasing and decreasing bytes |
| 187 | boost::uniform_smallint<uint32_t> run_length_distribution(1, 64); |
| 188 | boost::uniform_smallint<uint8_t> byte_distribution(0, UINT8_MAX); |
| 189 | boost::variate_generator< boost::mt19937, boost::uniform_smallint<uint8_t> > |
| 190 | byte_generator(rng, byte_distribution); |
| 191 | boost::variate_generator< boost::mt19937, boost::uniform_smallint<uint32_t> > |
| 192 | run_len_generator(rng, run_length_distribution); |
| 193 | |
| 194 | uint32_t idx = 0; |
| 195 | int8_t step = 1; |
| 196 | while (idx < buf_len) { |
| 197 | uint32_t run_length = run_len_generator(); |
| 198 | if (idx + run_length > buf_len) { |
| 199 | run_length = buf_len - idx; |
| 200 | } |
| 201 | |
| 202 | uint8_t byte = byte_generator(); |
| 203 | for (uint32_t n = 0; n < run_length; ++n) { |
| 204 | buf[idx] = byte; |
| 205 | ++idx; |
| 206 | byte += step; |
| 207 | } |
| 208 | |
| 209 | step *= -1; |
| 210 | } |
| 211 | |
| 212 | return buf; |
| 213 | } |
| 214 | |
| 215 | uint8_t* gen_random_buffer(uint32_t buf_len) { |
| 216 | uint8_t* buf = new uint8_t[buf_len]; |
| 217 | |
| 218 | boost::uniform_smallint<uint8_t> distribution(0, UINT8_MAX); |
| 219 | boost::variate_generator< boost::mt19937, boost::uniform_smallint<uint8_t> > |
| 220 | generator(rng, distribution); |
| 221 | |
| 222 | for (uint32_t n = 0; n < buf_len; ++n) { |
| 223 | buf[n] = generator(); |
| 224 | } |
| 225 | |
| 226 | return buf; |
| 227 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 228 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 229 | void test_write_then_read(const uint8_t* buf, uint32_t buf_len) { |
| 230 | shared_ptr<TMemoryBuffer> membuf(new TMemoryBuffer()); |
| 231 | shared_ptr<TZlibTransport> zlib_trans(new TZlibTransport(membuf, false)); |
| 232 | zlib_trans->write(buf, buf_len); |
| 233 | zlib_trans->flush(); |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 234 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 235 | boost::shared_array<uint8_t> mirror(new uint8_t[buf_len]); |
| 236 | uint32_t got = zlib_trans->read(mirror.get(), buf_len); |
| 237 | BOOST_REQUIRE_EQUAL(got, buf_len); |
| 238 | BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf, buf_len), 0); |
| 239 | zlib_trans->verifyChecksum(); |
| 240 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 241 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 242 | void test_separate_checksum(const uint8_t* buf, uint32_t buf_len) { |
| 243 | // This one is tricky. I separate the last byte of the stream out |
| 244 | // into a separate crbuf_. The last byte is part of the checksum, |
| 245 | // so the entire read goes fine, but when I go to verify the checksum |
| 246 | // it isn't there. The original implementation complained that |
| 247 | // the stream was not complete. I'm about to go fix that. |
| 248 | // It worked. Awesome. |
| 249 | shared_ptr<TMemoryBuffer> membuf(new TMemoryBuffer()); |
| 250 | shared_ptr<TZlibTransport> zlib_trans(new TZlibTransport(membuf, false)); |
| 251 | zlib_trans->write(buf, buf_len); |
| 252 | zlib_trans->flush(); |
| 253 | string tmp_buf; |
| 254 | membuf->appendBufferToString(tmp_buf); |
| 255 | zlib_trans.reset(new TZlibTransport(membuf, false, |
| 256 | TZlibTransport::DEFAULT_URBUF_SIZE, |
| 257 | tmp_buf.length()-1)); |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 258 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 259 | boost::shared_array<uint8_t> mirror(new uint8_t[buf_len]); |
| 260 | uint32_t got = zlib_trans->read(mirror.get(), buf_len); |
| 261 | BOOST_REQUIRE_EQUAL(got, buf_len); |
| 262 | BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf, buf_len), 0); |
| 263 | zlib_trans->verifyChecksum(); |
| 264 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 265 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 266 | void test_incomplete_checksum(const uint8_t* buf, uint32_t buf_len) { |
| 267 | // Make sure we still get that "not complete" error if |
| 268 | // it really isn't complete. |
| 269 | shared_ptr<TMemoryBuffer> membuf(new TMemoryBuffer()); |
| 270 | shared_ptr<TZlibTransport> zlib_trans(new TZlibTransport(membuf, false)); |
| 271 | zlib_trans->write(buf, buf_len); |
| 272 | zlib_trans->flush(); |
| 273 | string tmp_buf; |
| 274 | membuf->appendBufferToString(tmp_buf); |
| 275 | tmp_buf.erase(tmp_buf.length() - 1); |
| 276 | membuf->resetBuffer(const_cast<uint8_t*>( |
| 277 | reinterpret_cast<const uint8_t*>(tmp_buf.data())), |
| 278 | tmp_buf.length()); |
| 279 | |
| 280 | boost::shared_array<uint8_t> mirror(new uint8_t[buf_len]); |
| 281 | uint32_t got = zlib_trans->read(mirror.get(), buf_len); |
| 282 | BOOST_REQUIRE_EQUAL(got, buf_len); |
| 283 | BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf, buf_len), 0); |
| 284 | try { |
| 285 | zlib_trans->verifyChecksum(); |
| 286 | BOOST_ERROR("verifyChecksum() did not report an error"); |
| 287 | } catch (TTransportException& ex) { |
| 288 | BOOST_CHECK_EQUAL(ex.getType(), TTransportException::CORRUPTED_DATA); |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | void test_read_write_mix(const uint8_t* buf, uint32_t buf_len, |
| 293 | unsigned int* write_dist, unsigned int* read_dist) { |
| 294 | // Try it with a mix of read/write sizes. |
| 295 | shared_ptr<TMemoryBuffer> membuf(new TMemoryBuffer()); |
| 296 | shared_ptr<TZlibTransport> zlib_trans(new TZlibTransport(membuf, false)); |
| 297 | int idx; |
| 298 | unsigned int tot; |
| 299 | |
| 300 | idx = 0; |
| 301 | tot = 0; |
| 302 | while (tot < buf_len) { |
| 303 | uint32_t write_len = write_dist[idx]; |
| 304 | if (tot + write_len > buf_len) { |
| 305 | write_len = buf_len - tot; |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 306 | } |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 307 | zlib_trans->write(buf + tot, write_len); |
| 308 | tot += write_len; |
| 309 | idx++; |
| 310 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 311 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 312 | zlib_trans->flush(); |
| 313 | |
| 314 | idx = 0; |
| 315 | tot = 0; |
| 316 | boost::shared_array<uint8_t> mirror(new uint8_t[buf_len]); |
| 317 | while (tot < buf_len) { |
| 318 | uint32_t read_len = read_dist[idx]; |
| 319 | uint32_t expected_read_len = read_len; |
| 320 | if (tot + read_len > buf_len) { |
| 321 | expected_read_len = buf_len - tot; |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 322 | } |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 323 | uint32_t got = zlib_trans->read(mirror.get() + tot, read_len); |
| 324 | BOOST_REQUIRE_EQUAL(got, expected_read_len); |
| 325 | tot += got; |
| 326 | idx++; |
| 327 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 328 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 329 | BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf, buf_len), 0); |
| 330 | zlib_trans->verifyChecksum(); |
| 331 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 332 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 333 | void test_invalid_checksum(const uint8_t* buf, uint32_t buf_len) { |
| 334 | // Verify checksum checking. |
| 335 | shared_ptr<TMemoryBuffer> membuf(new TMemoryBuffer()); |
| 336 | shared_ptr<TZlibTransport> zlib_trans(new TZlibTransport(membuf, false)); |
| 337 | zlib_trans->write(buf, buf_len); |
| 338 | zlib_trans->flush(); |
| 339 | string tmp_buf; |
| 340 | membuf->appendBufferToString(tmp_buf); |
| 341 | // Modify a byte at the end of the buffer (part of the checksum). |
| 342 | // On rare occasions, modifying a byte in the middle of the buffer |
| 343 | // isn't caught by the checksum. |
| 344 | // |
| 345 | // (This happens especially often for the uniform buffer. The |
| 346 | // re-inflated data is correct, however. I suspect in this case that |
| 347 | // we're more likely to modify bytes that are part of zlib metadata |
| 348 | // instead of the actual compressed data.) |
| 349 | // |
| 350 | // I've also seen some failure scenarios where a checksum failure isn't |
| 351 | // reported, but zlib keeps trying to decode past the end of the data. |
| 352 | // (When this occurs, verifyChecksum() throws an exception indicating |
| 353 | // that the end of the data hasn't been reached.) I haven't seen this |
| 354 | // error when only modifying checksum bytes. |
| 355 | int index = tmp_buf.size() - 1; |
| 356 | tmp_buf[index]++; |
| 357 | membuf->resetBuffer(const_cast<uint8_t*>( |
| 358 | reinterpret_cast<const uint8_t*>(tmp_buf.data())), |
| 359 | tmp_buf.length()); |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 360 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 361 | boost::shared_array<uint8_t> mirror(new uint8_t[buf_len]); |
| 362 | try { |
| 363 | zlib_trans->read(mirror.get(), buf_len); |
| 364 | zlib_trans->verifyChecksum(); |
| 365 | BOOST_ERROR("verifyChecksum() did not report an error"); |
| 366 | } catch (TZlibTransportException& ex) { |
| 367 | BOOST_CHECK_EQUAL(ex.getType(), TTransportException::INTERNAL_ERROR); |
| 368 | } |
| 369 | } |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 370 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 371 | #define ADD_TEST_CASE(suite, name, function, ...) \ |
| 372 | do { \ |
| 373 | ::std::ostringstream name_ss; \ |
| 374 | name_ss << name << "-" << BOOST_STRINGIZE(function); \ |
| 375 | ::boost::unit_test::test_case* tc = ::boost::unit_test::make_test_case( \ |
| 376 | ::std::tr1::bind(function, ## __VA_ARGS__), \ |
| 377 | name_ss.str()); \ |
| 378 | (suite)->add(tc); \ |
| 379 | } while (0) |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 380 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 381 | void add_tests(unit_test::test_suite* suite, |
| 382 | const uint8_t* buf, |
| 383 | uint32_t buf_len, |
| 384 | const char* name) { |
| 385 | ADD_TEST_CASE(suite, name, test_write_then_read, buf, buf_len); |
| 386 | ADD_TEST_CASE(suite, name, test_separate_checksum, buf, buf_len); |
| 387 | ADD_TEST_CASE(suite, name, test_incomplete_checksum, buf, buf_len); |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 388 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 389 | for (int d1 = 0; d1 < 3; d1++) { |
| 390 | for (int d2 = 0; d2 < 3; d2++) { |
| 391 | ADD_TEST_CASE(suite, name << "_w" << d1 << "_r" << d2, |
| 392 | test_read_write_mix, buf, buf_len, dist[d1], dist[d2]); |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 393 | } |
| 394 | } |
| 395 | |
David Reiss | 9a961e7 | 2010-10-06 17:10:23 +0000 | [diff] [blame^] | 396 | ADD_TEST_CASE(suite, name, test_invalid_checksum, buf, buf_len); |
| 397 | } |
| 398 | |
| 399 | void print_usage(FILE* f, const char* argv0) { |
| 400 | fprintf(f, "Usage: %s [boost_options] [options]\n", argv0); |
| 401 | fprintf(f, "Options:\n"); |
| 402 | fprintf(f, " --seed=<N>, -s <N>\n"); |
| 403 | fprintf(f, " --help\n"); |
| 404 | } |
| 405 | |
| 406 | void parse_args(int argc, char* argv[]) { |
| 407 | uint32_t seed = 0; |
| 408 | bool has_seed = false; |
| 409 | |
| 410 | struct option long_opts[] = { |
| 411 | { "help", false, NULL, 'h' }, |
| 412 | { "seed", true, NULL, 's' }, |
| 413 | { NULL, 0, NULL, 0 } |
| 414 | }; |
| 415 | |
| 416 | while (true) { |
| 417 | optopt = 1; |
| 418 | int optchar = getopt_long(argc, argv, "hs:", long_opts, NULL); |
| 419 | if (optchar == -1) { |
| 420 | break; |
| 421 | } |
| 422 | |
| 423 | switch (optchar) { |
| 424 | case 's': { |
| 425 | char *endptr; |
| 426 | seed = strtol(optarg, &endptr, 0); |
| 427 | if (endptr == optarg || *endptr != '\0') { |
| 428 | fprintf(stderr, "invalid seed value \"%s\": must be a positive " |
| 429 | "integer\n", optarg); |
| 430 | exit(1); |
| 431 | } |
| 432 | has_seed = true; |
| 433 | break; |
| 434 | } |
| 435 | case 'h': |
| 436 | print_usage(stdout, argv[0]); |
| 437 | exit(0); |
| 438 | case '?': |
| 439 | exit(1); |
| 440 | default: |
| 441 | // Only happens if someone adds another option to the optarg string, |
| 442 | // but doesn't update the switch statement to handle it. |
| 443 | fprintf(stderr, "unknown option \"-%c\"\n", optchar); |
| 444 | exit(1); |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | if (!has_seed) { |
| 449 | seed = time(NULL); |
| 450 | } |
| 451 | |
| 452 | printf("seed: %" PRIu32 "\n", seed); |
| 453 | rng.seed(seed); |
| 454 | } |
| 455 | |
| 456 | unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { |
| 457 | parse_args(argc, argv); |
| 458 | |
| 459 | unit_test::test_suite* suite = BOOST_TEST_SUITE("ZlibTests"); |
| 460 | |
| 461 | uint32_t buf_len = 1024*32; |
| 462 | add_tests(suite, gen_uniform_buffer(buf_len, 'a'), buf_len, "uniform"); |
| 463 | add_tests(suite, gen_compressible_buffer(buf_len), buf_len, "compressible"); |
| 464 | add_tests(suite, gen_random_buffer(buf_len), buf_len, "random"); |
| 465 | |
| 466 | return suite; |
David Reiss | faebedd | 2007-09-17 23:20:38 +0000 | [diff] [blame] | 467 | } |