1 /*
2 * Copyright (C) 2009-2020 Codership Oy <info@codership.com>
3 */
4
5 #include "gcomm/util.hpp"
6 #include "gcomm/protonet.hpp"
7 #include "gcomm/datagram.hpp"
8 #include "gcomm/conf.hpp"
9
10 #include "check_gcomm.hpp"
11
12 #include "gu_logger.hpp"
13
14 #include <vector>
15 #include <fstream>
16 #include <limits>
17 #include <cstdlib>
18 #include <check.h>
19
20 using std::vector;
21 using std::numeric_limits;
22 using std::string;
23
24 using namespace gcomm;
25 using gu::Exception;
26 using gu::byte_t;
27 using gu::Buffer;
28
START_TEST(test_datagram)29 START_TEST(test_datagram)
30 {
31
32 // Header check
33 gcomm::NetHeader hdr(42, 0);
34 ck_assert(hdr.len() == 42);
35 ck_assert(hdr.has_crc32() == false);
36 ck_assert(hdr.version() == 0);
37
38 hdr.set_crc32(1234, NetHeader::CS_CRC32);
39 ck_assert(hdr.has_crc32() == true);
40 ck_assert(hdr.len() == 42);
41
42 gcomm::NetHeader hdr1(42, 1);
43 ck_assert(hdr1.len() == 42);
44 ck_assert(hdr1.has_crc32() == false);
45 ck_assert(hdr1.version() == 1);
46
47 gu::byte_t hdrbuf[NetHeader::serial_size_];
48 ck_assert(serialize(hdr1, hdrbuf, sizeof(hdrbuf), 0) ==
49 NetHeader::serial_size_);
50 try
51 {
52 unserialize(hdrbuf, sizeof(hdrbuf), 0, hdr);
53 ck_abort();
54 }
55 catch (Exception& e)
56 {
57 // ok
58 }
59
60
61 gu::byte_t b[128];
62 for (gu::byte_t i = 0; i < sizeof(b); ++i)
63 {
64 b[i] = i;
65 }
66 gu::Buffer buf(b, b + sizeof(b));
67
68 gcomm::Datagram dg(buf);
69 ck_assert(dg.len() == sizeof(b));
70
71 // Normal copy construction
72 gcomm::Datagram dgcopy(buf);
73 ck_assert(dgcopy.len() == sizeof(b));
74 ck_assert(memcmp(dgcopy.header() + dgcopy.header_offset(),
75 dg.header() + dg.header_offset(),
76 dg.header_len()) == 0);
77 ck_assert(dgcopy.payload() == dg.payload());
78
79 // Copy construction from offset of 16
80 gcomm::Datagram dg16(dg, 16);
81 log_info << dg16.len();
82 ck_assert(dg16.len() - dg16.offset() == sizeof(b) - 16);
83 for (gu::byte_t i = 0; i < sizeof(b) - 16; ++i)
84 {
85 ck_assert(dg16.payload()[i + dg16.offset()] == i + 16);
86 }
87
88 #if 0
89 // Normalize datagram, all data is moved into payload, data from
90 // beginning to offset is discarded. Normalization must not change
91 // dg
92 dg16.normalize();
93
94 ck_assert(dg16.len() == sizeof(b) - 16);
95 for (byte_t i = 0; i < sizeof(b) - 16; ++i)
96 {
97 ck_assert(dg16.payload()[i] == i + 16);
98 }
99
100 ck_assert(dg.len() == sizeof(b));
101 for (byte_t i = 0; i < sizeof(b); ++i)
102 {
103 ck_assert(dg.payload()[i] == i);
104 }
105
106 Datagram dgoff(buf, 16);
107 dgoff.header().resize(8);
108 dgoff.set_header_offset(4);
109 ck_assert(dgoff.len() == buf.size() + 4);
110 ck_assert(dgoff.header_offset() == 4);
111 ck_assert(dgoff.header().size() == 8);
112 for (byte_t i = 0; i < 4; ++i)
113 {
114 *(&dgoff.header()[0] + i) = i;
115 }
116
117 dgoff.normalize();
118
119 ck_assert(dgoff.len() == sizeof(b) - 16 + 4);
120 ck_assert(dgoff.header_offset() == 0);
121 ck_assert(dgoff.header().size() == 0);
122 #endif // 0
123 }
124 END_TEST
125
126
127
128
START_TEST(test_view_state)129 START_TEST(test_view_state)
130 {
131 // compare view.
132 UUID view_uuid(NULL, 0);
133 ViewId view_id(V_TRANS, view_uuid, 789);
134 UUID m1(NULL, 0);
135 UUID m2(NULL, 0);
136 View view(0, view_id, true);
137 view.add_member(m1, 0);
138 view.add_member(m2, 1);
139 View view2;
140
141 {
142 std::ostringstream os;
143 view.write_stream(os);
144
145 std::istringstream is(os.str());
146 view2.read_stream(is);
147
148 ck_assert(view == view2);
149 }
150
151 // Create configuration to set file name.
152 gu::Config conf;
153
154 // compare view state.
155 UUID my_uuid(NULL, 0);
156 ViewState vst(my_uuid, view, conf);
157 UUID my_uuid_2;
158 View view_2;
159 ViewState vst2(my_uuid_2, view_2, conf);
160
161 {
162 std::ostringstream os;
163 vst.write_stream(os);
164
165 std::istringstream is(os.str());
166 vst2.read_stream(is);
167
168 ck_assert(vst == vst2);
169 }
170
171 // test write file and read file.
172 vst.write_file();
173 UUID my_uuid_3;
174 View view_3;
175 ViewState vst3(my_uuid_3, view_3, conf);
176 vst3.read_file();
177 ck_assert(vst == vst3);
178 ViewState::remove_file(conf);
179 }
180 END_TEST
181
182
util_suite()183 Suite* util_suite()
184 {
185 Suite* s = suite_create("util");
186 TCase* tc;
187
188 tc = tcase_create("test_datagram");
189 tcase_add_test(tc, test_datagram);
190 suite_add_tcase(s, tc);
191
192 tc = tcase_create("test_view_state");
193 tcase_add_test(tc, test_view_state);
194 suite_add_tcase(s, tc);
195
196 return s;
197 }
198