DCCL v4
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 <fstream>
26 
27 #include "../../native_protobuf/dccl_native_protobuf.h"
28 #include <google/protobuf/descriptor.pb.h>
29 
30 #include "../../binary.h"
31 #include "../../codec.h"
32 #include "test.pb.h"
33 using namespace dccl::test;
34 
35 dccl::Codec codec;
36 
37 template <typename Msg1, typename Msg2>
38 
39 std::pair<std::size_t, std::size_t> compute_hashes()
40 {
41  std::size_t hash1 = codec.load<Msg1>();
42  codec.unload<Msg1>();
43  std::cout << Msg1::descriptor()->full_name() << ": " << dccl::hash_as_string(hash1)
44  << std::endl;
45  std::size_t hash2 = codec.load<Msg2>();
46  codec.unload<Msg2>();
47  std::cout << Msg2::descriptor()->full_name() << ": " << dccl::hash_as_string(hash2)
48  << std::endl;
49  return std::make_pair(hash1, hash2);
50 }
51 
52 template <typename Msg1, typename Msg2> void expect_same()
53 {
54  auto hashes = compute_hashes<Msg1, Msg2>();
55  assert(hashes.first == hashes.second);
56 }
57 
58 template <typename Msg1, typename Msg2> void expect_different()
59 {
60  auto hashes = compute_hashes<Msg1, Msg2>();
61  assert(hashes.first != hashes.second);
62 }
63 
64 int main(int /*argc*/, char* /*argv*/[])
65 {
66  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
67 
68  expect_same<TestMsg, TestMsgNoHashableChanges>();
69  expect_different<TestMsg, TestMsgNewID>();
70  expect_different<TestMsg, TestMsgNewEnum>();
71  expect_different<TestMsg, TestMsgNewBounds>();
72  expect_different<TestMsgV2, TestMsgV3>();
73  expect_different<TestMsgV3, TestMsgV4>();
74 
75  {
76  std::cout << "TestMsg desc: " << TestMsg::descriptor() << std::endl;
77 
78  auto hash = codec.load<TestMsg>();
79  codec.info<TestMsg>();
80 
81  TestMsg msg_in, msg_out;
82  msg_in.set_e(TestMsg::VALUE1);
83  msg_in.set_hash_req(0x1234); // dummy value - overwritten by dccl.hash codec
84 
85  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
86  std::cout << "Try encode..." << std::endl;
87  std::string bytes;
88  codec.encode(&bytes, msg_in);
89  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
90 
91  std::cout << "Try decode..." << std::endl;
92  std::cout << codec.max_size(msg_in.GetDescriptor()) << std::endl;
93 
94  codec.decode(bytes, &msg_out);
95 
96  std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
97 
98  msg_in.set_hash_opt(hash & 0xFFFF);
99  msg_in.set_hash_req(hash & 0xFFFFFFFF);
100  std::cout << hash << std::endl;
101  std::cout << "Message in (with hash):\n" << msg_in.DebugString() << std::endl;
102 
103  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
104  codec.unload<TestMsg>();
105  }
106 
107  {
108  std::cout << "TestMsg desc: " << TestMsg::descriptor() << std::endl;
109 
110  codec.load<TestMsg>();
111 
112  TestMsg msg_in;
113  TestMsgNewEnum msg_out;
114 
115  msg_in.set_e(TestMsg::VALUE1);
116  msg_in.set_hash_req(0x1234); // dummy value - overwritten by dccl.hash codec
117 
118  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
119  std::cout << "Try encode..." << std::endl;
120  std::string bytes;
121  codec.encode(&bytes, msg_in);
122  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
123 
124  std::cout << "Try decode..." << std::endl;
125  std::cout << codec.max_size(msg_in.GetDescriptor()) << std::endl;
126 
127  codec.unload<TestMsg>();
128  codec.load<TestMsgNewEnum>();
129 
130  try
131  {
132  codec.decode(bytes, &msg_out);
133  assert(false);
134  }
135  catch (const std::exception& e)
136  {
137  // expecting exception
138  std::cout << "Caught expected exception: " << e.what() << std::endl;
139  }
140  }
141 
142  {
143  std::cout << "TestMsgMultiHash desc: " << TestMsgMultiHash::descriptor() << std::endl;
144 
145  auto hash = codec.load<TestMsgMultiHash>();
146  codec.info<TestMsgMultiHash>();
147 
148  TestMsgMultiHash msg_in, msg_out;
149 
150  std::cout << "Message in:\n" << msg_in.DebugString() << std::endl;
151  std::cout << "Try encode..." << std::endl;
152  std::string bytes;
153  codec.encode(&bytes, msg_in);
154  std::cout << "... got bytes (hex): " << dccl::hex_encode(bytes) << std::endl;
155 
156  std::cout << "Try decode..." << std::endl;
157  std::cout << codec.max_size(msg_in.GetDescriptor()) << std::endl;
158 
159  codec.decode(bytes, &msg_out);
160 
161  std::cout << "... got Message out:\n" << msg_out.DebugString() << std::endl;
162 
163  msg_in.set_hash4(hash & ((1 << 4) - 1));
164  msg_in.set_hash6(hash & ((1 << 6) - 1));
165  msg_in.set_hash8(hash & ((1 << 8) - 1));
166  msg_in.set_hash13(hash & ((1 << 13) - 1));
167  msg_in.set_hash26(hash & ((1 << 26) - 1));
168  std::cout << hash << std::endl;
169  std::cout << "Message in (with hash):\n" << msg_in.DebugString() << std::endl;
170 
171  assert(msg_in.SerializeAsString() == msg_out.SerializeAsString());
172  codec.unload<TestMsgMultiHash>();
173  }
174 
175  try
176  {
177  codec.load<TestMsgHashMaxTooLarge>();
178  assert(false);
179  }
180  catch (const std::exception& e)
181  {
182  // expecting exception
183  std::cout << "Caught expected exception: " << e.what() << std::endl;
184  }
185 
186  std::cout << "All tests passed" << std::endl;
187 }
dccl::test
Unit test namespace.
Definition: test.cpp:44
dccl::Codec
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:62
dccl::Logger::connect
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
dccl::hex_encode
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