DCCL v4
test.cpp
1 // Copyright 2011-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 // Chris Murphy <cmurphy@aphysci.com>
8 //
9 //
10 // This file is part of the Dynamic Compact Control Language Library
11 // ("DCCL").
12 //
13 // DCCL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU Lesser General Public License as published by
15 // the Free Software Foundation, either version 2.1 of the License, or
16 // (at your option) any later version.
17 //
18 // DCCL is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Lesser General Public License for more details.
22 //
23 // You should have received a copy of the GNU Lesser General Public License
24 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
25 // tests all protobuf types with _default codecs, repeat and non repeat
26 
27 #include <thread>
28 
29 #include "../../arithmetic/field_codec_arithmetic.h"
30 #include "../../codec.h"
31 #include "test.pb.h"
32 #include "test_arithmetic.pb.h"
33 
34 using namespace dccl::test;
35 
36 void arithmetic_run_test(dccl::Codec& codec, dccl::arith::protobuf::ArithmeticModel& model,
37  const google::protobuf::Message& msg_in, bool set_model = true)
38 {
39  if (set_model)
40  {
41  model.set_name("model");
42  dccl::arith::ModelManager::set_model(codec, model);
43  }
44 
45  codec.load(msg_in.GetDescriptor());
46  codec.info(msg_in.GetDescriptor());
47 
48  // std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
49 
50  // std::cout << "Try encode..." << std::endl;
51  std::string bytes;
52  codec.encode(&bytes, msg_in);
53  // std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
54 
55  // std::cout << "Try decode..." << std::endl;
56 
57  std::shared_ptr<google::protobuf::Message> msg_out(msg_in.New());
58  codec.decode(bytes, msg_out.get());
59 
60  // std::cout << "... got Message out:\n" << msg_out->DebugString() << std::endl;
61 
62  assert(msg_in.SerializeAsString() == msg_out->SerializeAsString());
63 }
64 
65 void decode_check(dccl::Codec& codec, const std::string& encoded, TestMsg msg_in);
66 void run(int thread, int num_iterations);
67 int main(int /*argc*/, char* /*argv*/ [])
68 {
69  {
70  std::thread t1([]() { run(1, 100); });
71  std::thread t2([]() { run(2, 100); });
72  std::thread t3([]() { run(3, 100); });
73  std::thread t4([]() { run(4, 100); });
74  std::thread t5([]() { run(5, 100); });
75  std::thread t6([]() { run(6, 100); });
76  std::thread t7([]() { run(7, 100); });
77  std::thread t8([]() { run(8, 100); });
78  std::thread t9([]() { run(9, 100); });
79  std::thread t10([]() { run(10, 100); });
80  t1.join();
81  t2.join();
82  t3.join();
83  t4.join();
84  t5.join();
85  t6.join();
86  t7.join();
87  t8.join();
88  t9.join();
89  t10.join();
90  }
91 
92  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
93  {
94  std::thread t1([]() { run(1, 10); });
95  std::thread t2([]() { run(2, 10); });
96  std::thread t3([]() { run(3, 10); });
97  std::thread t4([]() { run(4, 10); });
98  std::thread t5([]() { run(5, 10); });
99  std::thread t6([]() { run(6, 10); });
100  std::thread t7([]() { run(7, 10); });
101  std::thread t8([]() { run(8, 10); });
102  std::thread t9([]() { run(9, 10); });
103  std::thread t10([]() { run(10, 10); });
104  t1.join();
105  t2.join();
106  t3.join();
107  t4.join();
108  t5.join();
109  t6.join();
110  t7.join();
111  t8.join();
112  t9.join();
113  t10.join();
114  }
115 
116  std::cout << "all tests passed" << std::endl;
117 }
118 
119 void run(int thread, int num_iterations)
120 {
121  dccl::Codec codec;
122  codec.load_library(DCCL_ARITHMETIC_NAME);
123  codec.load<TestMsg>();
124  for (int m = 0; m < num_iterations; ++m)
125  {
126  std::cout << "Thread " << thread << ", it: " << m << std::endl;
127  codec.info<TestMsg>();
128  TestMsg msg_in;
129  int i = 0;
130  msg_in.set_double_default_optional(++i + 0.1);
131  msg_in.set_float_default_optional(++i + 0.2);
132 
133  msg_in.set_int32_default_optional(++i);
134  msg_in.set_int64_default_optional(-++i);
135  msg_in.set_uint32_default_optional(++i);
136  msg_in.set_uint64_default_optional(++i);
137  msg_in.set_sint32_default_optional(-++i);
138  msg_in.set_sint64_default_optional(++i);
139  msg_in.set_fixed32_default_optional(++i);
140  msg_in.set_fixed64_default_optional(++i);
141  msg_in.set_sfixed32_default_optional(++i);
142  msg_in.set_sfixed64_default_optional(-++i);
143 
144  msg_in.set_bool_default_optional(true);
145 
146  msg_in.set_string_default_optional("abc123");
147  msg_in.set_bytes_default_optional(dccl::hex_decode("00112233aabbcc1234"));
148 
149  msg_in.set_enum_default_optional(ENUM_C);
150  msg_in.mutable_msg_default_optional()->set_val(++i + 0.3);
151  msg_in.mutable_msg_default_optional()->mutable_msg()->set_val(++i);
152 
153  msg_in.set_double_default_required(++i + 0.1);
154  msg_in.set_float_default_required(++i + 0.2);
155 
156  msg_in.set_int32_default_required(++i);
157  msg_in.set_int64_default_required(-++i);
158  msg_in.set_uint32_default_required(++i);
159  msg_in.set_uint64_default_required(++i);
160  msg_in.set_sint32_default_required(-++i);
161  msg_in.set_sint64_default_required(++i);
162  msg_in.set_fixed32_default_required(++i);
163  msg_in.set_fixed64_default_required(++i);
164  msg_in.set_sfixed32_default_required(++i);
165  msg_in.set_sfixed64_default_required(-++i);
166 
167  msg_in.set_bool_default_required(true);
168 
169  msg_in.set_string_default_required("abc123");
170  msg_in.set_bytes_default_required(dccl::hex_decode("00112233aabbcc1234"));
171 
172  msg_in.set_enum_default_required(ENUM_C);
173  msg_in.mutable_msg_default_required()->set_val(++i + 0.3);
174  msg_in.mutable_msg_default_required()->mutable_msg()->set_val(++i);
175 
176  for (int j = 0; j < 2; ++j)
177  {
178  msg_in.add_double_default_repeat(++i + 0.1);
179  msg_in.add_float_default_repeat(++i + 0.2);
180 
181  msg_in.add_int32_default_repeat(++i);
182  msg_in.add_int64_default_repeat(-++i);
183  msg_in.add_uint32_default_repeat(++i);
184  msg_in.add_uint64_default_repeat(++i);
185  msg_in.add_sint32_default_repeat(-++i);
186  msg_in.add_sint64_default_repeat(++i);
187  msg_in.add_fixed32_default_repeat(++i);
188  msg_in.add_fixed64_default_repeat(++i);
189  msg_in.add_sfixed32_default_repeat(++i);
190  msg_in.add_sfixed64_default_repeat(-++i);
191 
192  msg_in.add_bool_default_repeat(true);
193 
194  msg_in.add_string_default_repeat("abc123");
195 
196  if (j)
197  msg_in.add_bytes_default_repeat(dccl::hex_decode("00aabbcc"));
198  else
199  msg_in.add_bytes_default_repeat(dccl::hex_decode("ffeedd12"));
200 
201  msg_in.add_enum_default_repeat(static_cast<Enum1>((++i % 3) + 1));
202  EmbeddedMsg1* em_msg = msg_in.add_msg_default_repeat();
203  em_msg->set_val(++i + 0.3);
204  em_msg->mutable_msg()->set_val(++i);
205  }
206 
207  std::string bytes;
208  codec.encode(&bytes, msg_in);
209 
210  decode_check(codec, bytes, msg_in);
211 
212  // test case from Practical Implementations of Arithmetic Coding by Paul G. Howard and Je rey Scott Vitter
213  {
214  dccl::arith::protobuf::ArithmeticModel model;
215 
216  model.set_eof_frequency(4); // "a"
217 
218  model.add_value_bound(0);
219  model.add_frequency(5); // "b"
220 
221  model.add_value_bound(1);
222  model.add_frequency(1); // "EOF"
223 
224  model.add_value_bound(2);
225 
226  model.set_out_of_range_frequency(0);
227 
228  dccl::test::arith::ArithmeticDoubleTestMsg msg_in;
229 
230  msg_in.add_value(0); // b
231  msg_in.add_value(0); // b
232  msg_in.add_value(0); // b
233  msg_in.add_value(1); // "EOF"
234 
235  arithmetic_run_test(codec, model, msg_in);
236  }
237  }
238 }
239 
240 void decode_check(dccl::Codec& codec, const std::string& encoded, TestMsg msg_in)
241 {
242  TestMsg msg_out;
243  codec.decode(encoded, &msg_out);
244 
245  // std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
246 
247  // truncate to "max_length" as codec should do
248  msg_in.set_string_default_repeat(0, "abc1");
249  msg_in.set_string_default_repeat(1, "abc1");
250 
251  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
252 }
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:63
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:214
Unit test namespace.
Definition: test.cpp:46
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition: binary.h:51