Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 1
/*
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
 
20
#ifndef _THRIFT_TEST_GENERICPROTOCOLTEST_TCC_
21
#define _THRIFT_TEST_GENERICPROTOCOLTEST_TCC_ 1
22
 
23
#include <limits>
24
 
25
#include <protocol/TBinaryProtocol.h>
26
#include <transport/TBufferTransports.h>
27
#include <Thrift.h>
28
 
29
#include "GenericHelpers.h"
30
 
31
using boost::shared_ptr;
32
using namespace apache::thrift;
33
using namespace apache::thrift::protocol;
34
using namespace apache::thrift::transport;
35
 
36
#define ERR_LEN 512
37
extern char errorMessage[ERR_LEN];
38
 
39
template <typename TProto, typename Val>
40
void testNaked(Val val) {
41
  shared_ptr<TTransport> transport(new TMemoryBuffer());
42
  shared_ptr<TProtocol> protocol(new TProto(transport));
43
 
44
  GenericIO::write(protocol, val);
45
  Val out;
46
  GenericIO::read(protocol, out);
47
  if (out != val) {
48
    snprintf(errorMessage, ERR_LEN, "Invalid naked test (type: %s)", ClassNames::getName<Val>());
49
    throw TException(errorMessage);
50
  }
51
}
52
 
53
template <typename TProto, TType type, typename Val>
54
void testField(const Val val) {
55
  shared_ptr<TTransport> transport(new TMemoryBuffer());
56
  shared_ptr<TProtocol> protocol(new TProto(transport));
57
 
58
  protocol->writeStructBegin("test_struct");
59
  protocol->writeFieldBegin("test_field", type, (int16_t)15);
60
 
61
  GenericIO::write(protocol, val);
62
 
63
  protocol->writeFieldEnd();
64
  protocol->writeStructEnd();
65
 
66
  std::string name;
67
  TType fieldType;
68
  int16_t fieldId;
69
 
70
  protocol->readStructBegin(name);
71
  protocol->readFieldBegin(name, fieldType, fieldId);
72
 
73
  if (fieldId != 15) {
74
    snprintf(errorMessage, ERR_LEN, "Invalid ID (type: %s)", typeid(val).name());
75
    throw TException(errorMessage);
76
  }
77
  if (fieldType != type) {
78
    snprintf(errorMessage, ERR_LEN, "Invalid Field Type (type: %s)", typeid(val).name());
79
    throw TException(errorMessage);
80
  }
81
 
82
  Val out;
83
  GenericIO::read(protocol, out);
84
 
85
  if (out != val) {
86
    snprintf(errorMessage, ERR_LEN, "Invalid value read (type: %s)", typeid(val).name());
87
    throw TException(errorMessage);
88
  }
89
 
90
  protocol->readFieldEnd();
91
  protocol->readStructEnd();
92
}
93
 
94
template <typename TProto>
95
void testMessage() {
96
  struct TMessage {
97
    const char* name;
98
    TMessageType type;
99
    int32_t seqid;
100
  } messages[4] = {
101
    {"short message name", T_CALL, 0},
102
    {"1", T_REPLY, 12345},
103
    {"loooooooooooooooooooooooooooooooooong", T_EXCEPTION, 1 << 16},
104
    {"Janky", T_CALL, 0}
105
  };
106
 
107
  for (int i = 0; i < 4; i++) {
108
    shared_ptr<TTransport> transport(new TMemoryBuffer());
109
    shared_ptr<TProtocol> protocol(new TProto(transport));
110
 
111
    protocol->writeMessageBegin(messages[i].name,
112
                                messages[i].type,
113
                                messages[i].seqid);
114
    protocol->writeMessageEnd();
115
 
116
    std::string name;
117
    TMessageType type;
118
    int32_t seqid;
119
 
120
    protocol->readMessageBegin(name, type, seqid);
121
    if (name != messages[i].name ||
122
        type != messages[i].type ||
123
        seqid != messages[i].seqid) {
124
      throw TException("readMessageBegin failed.");
125
    }
126
  }
127
}
128
 
129
template <typename TProto>
130
void testProtocol(const char* protoname) {
131
  try {
132
    testNaked<TProto, int8_t>((int8_t)123);
133
 
134
    for (int32_t i = 0; i < 128; i++) {
135
      testField<TProto, T_BYTE, int8_t>((int8_t)i);
136
      testField<TProto, T_BYTE, int8_t>((int8_t)-i);
137
    }
138
 
139
    testNaked<TProto, int16_t>((int16_t)0);
140
    testNaked<TProto, int16_t>((int16_t)1);
141
    testNaked<TProto, int16_t>((int16_t)15000);
142
    testNaked<TProto, int16_t>((int16_t)0x7fff);
143
    testNaked<TProto, int16_t>((int16_t)-1);
144
    testNaked<TProto, int16_t>((int16_t)-15000);
145
    testNaked<TProto, int16_t>((int16_t)-0x7fff);
146
    testNaked<TProto, int16_t>(std::numeric_limits<int16_t>::min());
147
    testNaked<TProto, int16_t>(std::numeric_limits<int16_t>::max());
148
 
149
    testField<TProto, T_I16, int16_t>((int16_t)0);
150
    testField<TProto, T_I16, int16_t>((int16_t)1);
151
    testField<TProto, T_I16, int16_t>((int16_t)7);
152
    testField<TProto, T_I16, int16_t>((int16_t)150);
153
    testField<TProto, T_I16, int16_t>((int16_t)15000);
154
    testField<TProto, T_I16, int16_t>((int16_t)0x7fff);
155
    testField<TProto, T_I16, int16_t>((int16_t)-1);
156
    testField<TProto, T_I16, int16_t>((int16_t)-7);
157
    testField<TProto, T_I16, int16_t>((int16_t)-150);
158
    testField<TProto, T_I16, int16_t>((int16_t)-15000);
159
    testField<TProto, T_I16, int16_t>((int16_t)-0x7fff);
160
 
161
    testNaked<TProto, int32_t>(0);
162
    testNaked<TProto, int32_t>(1);
163
    testNaked<TProto, int32_t>(15000);
164
    testNaked<TProto, int32_t>(0xffff);
165
    testNaked<TProto, int32_t>(-1);
166
    testNaked<TProto, int32_t>(-15000);
167
    testNaked<TProto, int32_t>(-0xffff);
168
    testNaked<TProto, int32_t>(std::numeric_limits<int32_t>::min());
169
    testNaked<TProto, int32_t>(std::numeric_limits<int32_t>::max());
170
 
171
    testField<TProto, T_I32, int32_t>(0);
172
    testField<TProto, T_I32, int32_t>(1);
173
    testField<TProto, T_I32, int32_t>(7);
174
    testField<TProto, T_I32, int32_t>(150);
175
    testField<TProto, T_I32, int32_t>(15000);
176
    testField<TProto, T_I32, int32_t>(31337);
177
    testField<TProto, T_I32, int32_t>(0xffff);
178
    testField<TProto, T_I32, int32_t>(0xffffff);
179
    testField<TProto, T_I32, int32_t>(-1);
180
    testField<TProto, T_I32, int32_t>(-7);
181
    testField<TProto, T_I32, int32_t>(-150);
182
    testField<TProto, T_I32, int32_t>(-15000);
183
    testField<TProto, T_I32, int32_t>(-0xffff);
184
    testField<TProto, T_I32, int32_t>(-0xffffff);
185
    testNaked<TProto, int64_t>(std::numeric_limits<int32_t>::min());
186
    testNaked<TProto, int64_t>(std::numeric_limits<int32_t>::max());
187
    testNaked<TProto, int64_t>(std::numeric_limits<int32_t>::min() + 10);
188
    testNaked<TProto, int64_t>(std::numeric_limits<int32_t>::max() - 16);
189
    testNaked<TProto, int64_t>(std::numeric_limits<int64_t>::min());
190
    testNaked<TProto, int64_t>(std::numeric_limits<int64_t>::max());
191
 
192
 
193
    testNaked<TProto, int64_t>(0);
194
    for (int64_t i = 0; i < 62; i++) {
195
      testNaked<TProto, int64_t>(1L << i);
196
      testNaked<TProto, int64_t>(-(1L << i));
197
    }
198
 
199
    testField<TProto, T_I64, int64_t>(0);
200
    for (int i = 0; i < 62; i++) {
201
      testField<TProto, T_I64, int64_t>(1L << i);
202
      testField<TProto, T_I64, int64_t>(-(1L << i));
203
    }
204
 
205
    testNaked<TProto, double>(123.456);
206
 
207
    testNaked<TProto, std::string>("");
208
    testNaked<TProto, std::string>("short");
209
    testNaked<TProto, std::string>("borderlinetiny");
210
    testNaked<TProto, std::string>("a bit longer than the smallest possible");
211
    testNaked<TProto, std::string>("\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA"); //kinda binary test
212
 
213
    testField<TProto, T_STRING, std::string>("");
214
    testField<TProto, T_STRING, std::string>("short");
215
    testField<TProto, T_STRING, std::string>("borderlinetiny");
216
    testField<TProto, T_STRING, std::string>("a bit longer than the smallest possible");
217
 
218
    testMessage<TProto>();
219
 
220
    printf("%s => OK\n", protoname);
221
  } catch (TException e) {
222
    snprintf(errorMessage, ERR_LEN, "%s => Test FAILED: %s", protoname, e.what());
223
    throw TException(errorMessage);
224
  }
225
}
226
 
227
#endif