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