DCCL v3
test.cpp
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 // tests all protobuf types with _default codecs, repeat and non repeat
23 
24 #include <fstream>
25 
26 #include <google/protobuf/descriptor.pb.h>
27 
28 #include "dccl/codec.h"
29 #include "test.pb.h"
30 #include "dccl/binary.h"
31 using namespace dccl::test;
32 
33 void decode_check(const TestMsg& msg_in);
34 dccl::Codec codec;
35 
36 int main(int argc, char* argv[])
37 {
38  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
39 
40  codec.info<TestMsg>();
41  codec.load<TestMsg>();
42 
43  // enable strict mode
44  codec.set_strict(true);
45 
46  {
47  TestMsg msg_in;
48  msg_in.set_d(10.0);
49  msg_in.set_i(1000);
50  msg_in.set_s("foo");
51  msg_in.set_b(std::string(9, '1'));
52  msg_in.add_ri(1);
53  msg_in.add_ri(2);
54  msg_in.add_ri(3);
55 
56  decode_check(msg_in);
57  }
58 
59 
60  // double out of range
61  try
62  {
63  TestMsg msg_in;
64  msg_in.set_d(150);
65  msg_in.set_i(1000);
66  msg_in.set_s("foo");
67  msg_in.set_b(std::string(9, '1'));
68 
69  decode_check(msg_in);
70  bool expected_out_of_range_exception = false;
71  assert(expected_out_of_range_exception);
72  }
74  {
75  assert(e.field() == TestMsg::descriptor()->FindFieldByName("d"));
76  std::cout << "Caught (as expected) " << e.what() << std::endl;
77  }
78 
79  // int out of range
80  try
81  {
82  TestMsg msg_in;
83  msg_in.set_d(10.0);
84  msg_in.set_i(-30);
85  msg_in.set_s("foo");
86  msg_in.set_b(std::string(9, '1'));
87 
88  decode_check(msg_in);
89  bool expected_out_of_range_exception = false;
90  assert(expected_out_of_range_exception);
91  }
93  {
94  assert(e.field() == TestMsg::descriptor()->FindFieldByName("i"));
95  std::cout << "Caught (as expected) " << e.what() << std::endl;
96  }
97 
98  // string (version 2) out of range
99  try
100  {
101  TestMsg msg_in;
102  msg_in.set_d(10.0);
103  msg_in.set_i(1000);
104  msg_in.set_s2("foobar1234546789");
105  msg_in.set_b(std::string(9, '1'));
106 
107  decode_check(msg_in);
108  bool expected_out_of_range_exception = false;
109  assert(expected_out_of_range_exception);
110  }
111  catch(dccl::OutOfRangeException& e)
112  {
113  assert(e.field() == TestMsg::descriptor()->FindFieldByName("s2"));
114  std::cout << "Caught (as expected) " << e.what() << std::endl;
115  }
116 
117  // string (version 3) out of range
118  try
119  {
120  TestMsg msg_in;
121  msg_in.set_d(10.0);
122  msg_in.set_i(1000);
123  msg_in.set_s("foobar1234546789");
124  msg_in.set_b(std::string(9, '1'));
125 
126  decode_check(msg_in);
127  bool expected_out_of_range_exception = false;
128  assert(expected_out_of_range_exception);
129  }
130  catch(dccl::OutOfRangeException& e)
131  {
132  assert(e.field() == TestMsg::descriptor()->FindFieldByName("s"));
133  std::cout << "Caught (as expected) " << e.what() << std::endl;
134  }
135 
136  // bytes out of range
137  try
138  {
139  TestMsg msg_in;
140  msg_in.set_d(10.0);
141  msg_in.set_i(1000);
142  msg_in.set_s("foo");
143  msg_in.set_b(std::string(12, '1'));
144 
145  decode_check(msg_in);
146  bool expected_out_of_range_exception = false;
147  assert(expected_out_of_range_exception);
148  }
149  catch(dccl::OutOfRangeException& e)
150  {
151  assert(e.field() == TestMsg::descriptor()->FindFieldByName("b"));
152  std::cout << "Caught (as expected) " << e.what() << std::endl;
153  }
154 
155  // var bytes out of range
156  try
157  {
158  TestMsg msg_in;
159  msg_in.set_d(10.0);
160  msg_in.set_i(1000);
161  msg_in.set_s("foo");
162  msg_in.set_vb(std::string(12, '1'));
163 
164  decode_check(msg_in);
165  bool expected_out_of_range_exception = false;
166  assert(expected_out_of_range_exception);
167  }
168  catch(dccl::OutOfRangeException& e)
169  {
170  assert(e.field() == TestMsg::descriptor()->FindFieldByName("vb"));
171  std::cout << "Caught (as expected) " << e.what() << std::endl;
172  }
173 
174 
175  // repeat size out of range
176  try
177  {
178  TestMsg msg_in;
179  msg_in.set_d(10.0);
180  msg_in.set_i(1000);
181  msg_in.set_s("foo");
182  msg_in.set_b(std::string(9, '1'));
183  msg_in.add_ri(1);
184  msg_in.add_ri(2);
185  msg_in.add_ri(3);
186  msg_in.add_ri(4);
187 
188  decode_check(msg_in);
189  }
190  catch(dccl::OutOfRangeException& e)
191  {
192  assert(e.field() == TestMsg::descriptor()->FindFieldByName("ri"));
193  std::cout << "Caught (as expected) " << e.what() << std::endl;
194  }
195 
196 
197  std::cout << "all tests passed" << std::endl;
198 }
199 
200 
201 void decode_check(const TestMsg& msg_in)
202 {
203 
204  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
205 
206  std::cout << "Try encode (in bounds)..." << std::endl;
207  std::string bytes;
208  codec.encode(&bytes, msg_in);
209  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
210 
211  std::cout << "Try decode..." << std::endl;
212 
213  TestMsg msg_out;
214  codec.decode(bytes, &msg_out);
215 
216  std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
217 
218  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
219 }
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:56
void info(std::ostream *os=0, int user_id=-1) const
Writes a human readable summary (including field sizes) of the provided DCCL type to the stream provi...
Definition: codec.h:155
void load()
All messages must be explicited loaded and validated (size checks, option extensions checks...
Definition: codec.h:96
void encode(std::string *bytes, const google::protobuf::Message &msg, bool header_only=false, int user_id=-1)
Encodes a DCCL message.
Definition: codec.cpp:283
void set_strict(bool mode)
Set "strict" mode where a dccl::OutOfRangeException will be thrown for encode if the value(s) provide...
Definition: codec.h:139
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar) ...
Definition: logger.h:161
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
Definition: binary.h:100
Unit test namespace.
Definition: test.cpp:44
CharIterator decode(CharIterator begin, CharIterator end, google::protobuf::Message *msg, bool header_only=false)
Decode a DCCL message when the type is known at compile time.
Definition: codec.h:439