libutil++  1.9.3
 All Classes Functions Variables
test.cpp
1 /*
2 ** libutil++
3 ** $Id: test.cpp 1889 2017-05-29 22:13:33Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: test.cpp 1889 2017-05-29 22:13:33Z sella $";
10 
11 #include "test.h"
12 
13 #include <stdio.h>
14 #include <signal.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <pthread.h>
18 #include <syscall.h>
19 
20 #include <iostream>
21 #include <string>
22 #include <vector>
23 
24 #include "alias.h"
25 #include "version.h"
26 #include "sella/net/IPAddressPort.h"
27 #include "sella/net/IPPrefix.h"
28 #include "sella/net/SocketMux.h"
29 #include "sella/net/EtherSocket.h"
30 #include "sella/net/DNS.h"
31 #include "sella/net/DNSCallback.h"
32 #include "sella/net/Pipe.h"
33 #include "sella/net/SocketPair.h"
34 #include "sella/net/SocketTrigger.h"
35 #include "sella/util/Log.h"
36 #include "sella/util/SimpleLogFormat.h"
37 #include "sella/util/MixedLogFormat.h"
38 #include "sella/util/VerboseLogFormat.h"
39 #include "sella/util/Log.h"
40 #include "sella/util/String.h"
41 #include "sella/util/Process.h"
42 #include "sella/util/File.h"
43 #include "sella/util/Path.h"
44 #include "sella/util/LockFile.h"
45 #include "sella/util/Interface.h"
46 #include "sella/util/Packet.h"
47 #include "sella/util/UUID.h"
48 #include "sella/variant/Variant.h"
49 #include "sella/util/ThreadPool.h"
50 #include "sella/util/Time.h"
51 #include "sella/util/MessagePack.h"
52 #include "sella/container/radix_tree.h"
53 #define USE_REDUCED_TRIE
54 #include "sella/container/CedarTrie.h"
55 
56 #include <linux/if_packet.h>
57 #include <netinet/ip_icmp.h>
58 
59 using namespace sella::util;
60 using namespace sella::net;
61 using namespace sella::container;
62 
63 /* Global Variables */
64 
65 int main(int argc, char **argv) {
66  printf("Using %s v%s\n\n", libutilxx__package(), libutilxx__version());
67 
68  SET_FORMAT(SimpleLogFormat());
69  SET_IDENTIFIER("test");
70  SET_OPTION(Log::WithStderrOption);
71  SET_LOGMASK(LOG_UPTO(LOG_DEBUG));
72 
73 #if 1
74  testLog();
75  testString();
76  testProcess();
77  testFile();
78  testPath();
79  testLockFile();
80  testInterface();
81  testSocket();
82  testIPPrefix();
83  testIPAddress();
84  testIPAddressPort();
85  testException();
86  testDNS();
87  testThreadPool();
88  testSocketPair();
89  testSocketTrigger();
90  testPipe();
91  testRadixTree();
92  testCedarTrie();
93  testUUID();
94  testMessagePack();
95  testIPAddress();
96  testVariant();
97  testUUID();
98  testString();
99  testPath();
100  testDNS();
101 #endif
102 
103 #if 0
104  try {
105  std::string buf = "This is a test ${foo}. Time to make the ${donuts}[bob=1] ${bar} and ${front}[${sub}[jack=1]]. Yawn.";
106 
107  std::vector<std::string> v;
108  su::String::regex_search(buf, "(\\$\\{[^{}]+\\}(?:\\[[^\\]]*\\]+)?)", v, true, false);
109 
110  for (auto it = v.begin(); it != v.end(); ++it) {
111  INFO("MATCH: %s", it->c_str());
112  }
113  } catch (sella::Exception &e) {
114  WARNING("Got: %s", e.what());
115  }
116 #endif
117 
118 #if 0
119  sv::Variant n;
120  sv::Variant a("string-a", sv::Variant::TypeString);
121  sv::Variant s(6);
122 
123  printf("---- operator== ---\n");
124  printf("n == a: %s\n", (n == a) ? "true" : "false");
125  printf("n == string-a: %s\n", (n == "string-a") ? "true" : "false");
126  printf("s == string-a: %s\n", (s == "string-a") ? "true" : "false");
127  printf("s == 6: %s\n", (s == 6) ? "true" : "false");
128  printf("a == string-a: %s\n", (a == "string-a") ? "true" : "false");
129  printf("a == string-a: %s\n", (a == std::string("string-a")) ? "true" : "false");
130  printf("a == xxxxxxxx: %s\n", (a == "xxx") ? "true" : "false");
131  printf("a == xxxxxxxx: %s\n", (a == std::string("xxx")) ? "true" : "false");
132 
133  printf("---- operator!= ---\n");
134  printf("n != a: %s\n", (n != a) ? "true" : "false");
135  printf("n != string-a: %s\n", (n != "string-a") ? "true" : "false");
136  printf("s != string-a: %s\n", (s != "string-a") ? "true" : "false");
137  printf("s != 6: %s\n", (s != 6) ? "true" : "false");
138  printf("a != string-a: %s\n", (a != "string-a") ? "true" : "false");
139  printf("a != string-a: %s\n", (a != std::string("string-a")) ? "true" : "false");
140  printf("a != xxxxxxxx: %s\n", (a != "xxx") ? "true" : "false");
141  printf("a != xxxxxxxx: %s\n", (a != std::string("xxx")) ? "true" : "false");
142 #endif
143 
144  return EXIT_SUCCESS;
145 }
146 
147 void testLog(void) {
148  printf("--------------------\n");
149  printf("- sella/util/Log.h -\n");
150  printf("--------------------\n");
151 
152  DLOG("Debug message which only shows with ./configure --enable-debug");
153 
154  sella::Exception e(false, __func__, __FILE__, __LINE__, 100, "exception message");
155  SET_TRACE("foo");
156 
157  DTRACE("foo", "Debug is on and foo is set") || INFO("Debug is off or foo is not set");
158 
159  {
160  printf("Using SimpleLogFormat:\n");
161  SET_FORMAT(SimpleLogFormat());
162  SET_IDENTIFIER("test");
163  SET_OPTION(Log::WithStderrOption);
164 
165  INFO("Informational message");
166  WARNING("Warning message");
167  ERROR("Error message");
168  EXCEPTION(e, NULL);
169 
170  SET_TRACE("test-trace");
171  TRACE_IF(true, "test-trace", "Display when 'test-trace' is set and first argument is true");
172 
173  TRACE("test-trace", "#1: Display when 'test-trace' is set") || INFO("#1: Display when 'test-trace' is not set");
174  UNSET_TRACE("test-trace");
175  TRACE("test-trace", "#2: Display when 'test-trace' is set") || INFO("#2: Display when 'test-trace' is not set");
176 
177  if (IS_TRACE("test-trace")) {
178  printf("Perform action only when 'test-trace' is set\n");
179  }
180  }
181 
182  {
183  printf("Using MixedLogFormat:\n");
184  SET_FORMAT(MixedLogFormat());
185 
186  INFO("Informational message");
187  WARNING("Warning message");
188  ERROR("Error message");
189  TRACE("foo", "Trace message");
190  EXCEPTION(e, NULL);
191  }
192 
193  {
194  printf("Using VerboseLogFormat:\n");
195  SET_FORMAT(VerboseLogFormat());
196 
197  INFO("Informational message");
198  WARNING("Warning message");
199  ERROR("Error message");
200  TRACE("foo", "Trace message");
201  EXCEPTION(e, NULL);
202  }
203 
204  SET_FORMAT(SimpleLogFormat());
205 
206  if (IS_TRACE(std::vector<std::string>({ "foo", "bar" }))) {
207  TRACE(std::vector<std::string>({ "foo", "bar" }), "Multiple options message");
208  }
209 
210  printf("\n");
211 }
212 
213 void testString(void) {
214  using namespace sella::util;
215 
216  char buf[1024];
217  size_t len = sizeof(buf);
218  boost::cmatch m;
219  std::string in, match;
220  std::vector<std::string> matches;
221 
222  printf("-----------------------\n");
223  printf("- sella/util/String.h -\n");
224  printf("-----------------------\n");
225 
226  printf("String::sprintf(): %s\n", String::sprintf("Dulce et %s est pro %s mori", "decorum", "patria").c_str());
227 
228  in = "Dulce Et Decorum Est Pro Patria Mori";
229  printf("\nString::substr_replace(): %s\n", String::substr_replace((const std::string) in, "e", "X", false).c_str());
230  printf("String::substr_ireplace(): %s\n", String::substr_ireplace((const std::string) in, "MORI", "VITA").c_str());
231 
232  String::substr_ireplace(in, "D", "XXX");
233  printf("String::substr_ireplace(): %s\n", in.c_str());
234  String::substr_ireplace(in, "XXX", "D");
235 
236  printf("\nString::regex_replace(): %s\n", String::regex_replace((const std::string) in, "e", "X", String::DefaultREFlags(), boost::regex_constants::format_first_only).c_str());
237  printf("String::regex_ireplace(): %s\n", String::regex_ireplace((const std::string) in, "(M.RI)", "(was: $1, now: VITA)").c_str());
238 
239  in = "Dulce Et Decorum Est Pro Patria Mori";
240  printf("\nString::regex_match(): %s\n", (String::regex_match(in, ".*Dulce.*", m)) ? "MATCH" : "no match");
241  printf("String::regex_imatch(): %s\n", (String::regex_imatch(in, ".*DULCE.*")) ? "MATCH" : "no match");
242 
243  printf("\nString::regex_search(): %s\n", (String::regex_search(in, "D.lce", m)) ? "MATCH" : "no match");
244  printf("String::regex_isearch(): %s\n", (String::regex_isearch(in, "D.LCE")) ? "MATCH" : "no match");
245 
246  in = "Dulce Et Decorum Est Pro Patria Mori";
247  if (String::regex_match(in, ".*Decorum.*Patria.*", match)) {
248  printf("\nString::regex_match(): %s\n", match.c_str());
249  } else {
250  printf("\nString::regex_match(): no match\n");
251  }
252 
253  if (String::regex_imatch(in, ".*DECORUM.*PATRIA.*", match)) {
254  printf("String::regex_imatch(): %s\n", match.c_str());
255  } else {
256  printf("String::regex_imatch(): no match\n");
257  }
258 
259  if (String::regex_search(in, "([DP][^ ]+|Dul)(ce)?", matches, true, false)) {
260  printf("\nString::regex_search(): ");
261 
262  for (auto it = matches.begin(); it != matches.end(); ++it) {
263  printf("%s, ", it->c_str());
264  }
265  matches.clear();
266 
267  printf("\b\b \n");
268  } else {
269  printf("\nString::regex_search(): no match\n");
270  }
271 
272  if (String::regex_isearch(in, "([dp][^ ]+|dul)(ce)?", matches, true, false)) {
273  printf("String::regex_isearch(): ");
274 
275  for (auto it = matches.begin(); it != matches.end(); ++it) {
276  printf("%s, ", it->c_str());
277  }
278  matches.clear();
279 
280  printf("\b\b \n");
281  } else {
282  printf("String::regex_isearch(): no match\n");
283  }
284 
285  try {
286  String::regex_isearch("foobar", "^bad-regex [a-z]{");
287  } catch (RegexException &e) {
288  printf("RegexException Test: %s\n", e.what());
289  }
290 
291  in = " dulce et DECORUM est pro pAtRiA mori ";
292  printf("\nString::rtrim(): |%s|\n", String::rtrim(in).c_str());
293  printf("String::ltrim(): |%s|\n", String::ltrim(in).c_str());
294  printf("String::rtrim(): |%s|\n", String::rtrim("/var/tmp/", '/').c_str());
295 
296  printf("String::lower(): %s\n", String::lower(in).c_str());
297  printf("String::upper(): %s\n", String::upper(in).c_str());
298  printf("String::ucfirst(): %s\n", String::ucfirst(in).c_str());
299  printf("String::ucword(): %s\n", String::ucword(in).c_str());
300  printf("String::itoa(): 123 == %s\n", String::itoa(123).c_str());
301  printf("String::itoa(): -77 == %s\n", String::itoa(-77).c_str());
302  printf("String::itoa(): 456 == %s\n", String::itoa(456, buf, len));
303  printf("String::itoa(): %" PRIu64 " == %s\n", (uint64_t) -1, String::itoa((uint64_t) -1).c_str());
304  printf("String::itoa(): 0xdead == 0x%s\n", String::itoa(57005, 16).c_str());
305 
306  std::vector<std::string> v;
307  in = "first,second,,forth,";
308  in = "first::second::::forth::";
309  v = String::split(in, "::", true, true);
310  printf("\n");
311  for (auto it = v.begin(); it != v.end(); ++it) {
312  printf("String::split(): '%s'\n", it->c_str());
313  }
314 
315  in = "jack=jill=olaf";
316  v = String::split(in, '=', false, 2);
317  printf("\n");
318  for (auto it = v.begin(); it != v.end(); ++it) {
319  printf("String::split(): '%s'\n", it->c_str());
320  }
321 
322  in = ".jack.jill..olaf.";
323  v = String::split(in, '.', false);
324  printf("\n");
325  for (auto it = v.begin(); it != v.end(); ++it) {
326  printf("String::split(): '%s'\n", it->c_str());
327  }
328 
329  printf("\nString::join(): %s\n", String::join(v, ", ", '\0', "", "[ ", " ]", 1).c_str());
330 
331  std::list<std::string> l = { "foo", "bar" };
332  printf("String::join(): %s\n", String::join(l, ", ").c_str());
333 
334  std::set<std::string> s = { "Sucker", "Punch" };
335  printf("String::join(): %s\n", String::join(s, ", ", '"').c_str());
336 
337  s.clear();
338  printf("String::join(): %s\n", String::join(s, ", ", '\0', "(empty)").c_str());
339 
340  printf("\nString::bandwidth(): %s\n", String::bandwidth(1250000000LL).c_str());
341  printf("String::bandwidth(): %s\n", String::bandwidth(1250000000LL, 2).c_str());
342  printf("String::dataRate(): %s\n", String::dataRate(1250000000LL).c_str());
343  printf("String::dataRate(): %s\n", String::dataRate(1250000000LL, 2).c_str());
344  printf("String::dataRate(): %" PRIu64 " (uint64_t)\n", String::dataRate("1k"));
345  printf("String::dataSize(): %s\n", String::dataSize(5772800LL).c_str());
346  printf("String::dataSize(): %s\n", String::dataSize(5772800LL, 1).c_str());
347  printf("String::dataSize(): %" PRIu64 " (uint64_t)\n", String::dataSize("1KB"));
348  printf("String::duration(): %s == 1250ms\n", String::duration(1250000LL).c_str());
349  printf("String::duration(): %s == 1.25s\n", String::duration(1250000LL, 3).c_str());
350  printf("String::duration(): %s == 20.25w\n", String::duration(12247200000000LL, 2).c_str());
351  printf("String::duration(): %s == 3.1h\n", String::duration(360000000LL + 3 * 3600 * 1000000LL, 1).c_str());
352  printf("String::duration(): %s == 1.5min\n", String::duration(1 * 60 * 1000000LLU + (30 * 1000000LLU), 1).c_str());
353  printf("String::duration(): %s == 1.5h\n", String::duration(1 * 3600 * 1000000LLU + (3600/2 * 1000000LLU), 1).c_str());
354  printf("String::duration(): %s == 43.3min\n", String::duration(2598000000LL, 3).c_str());
355 
356  printf("String::scale(): %s == 1.25m\n", String::scale(1250000LL, 2).c_str());
357  printf("String::scale(): %s == 1.5k\n", String::scale(1500, 1).c_str());
358  printf("String::scale(): %s == 1b\n", String::scale(1000000000LL).c_str());
359 
360  printf("String::str_imatch(): %s (true)\n", (String::str_imatch("aaa", "AAA")) ? "true" : "false");
361  printf("String::str_imatch(): %s (false)\n", (String::str_imatch("aaa", "bbb")) ? "true" : "false");
362  printf("String::strcmp(): %d (0)\n", String::strcmp("aaa", "aaa"));
363  printf("String::strcmp(): %d (>0)\n", String::strcmp("bbb", "aaa"));
364  printf("String::strcmp(): %d (<0)\n", String::strcmp("aaa", "bbb"));
365  printf("String::strcasecmp(): %d (0)\n", String::strcasecmp("aaa", "AAA"));
366  printf("String::strcasecmp(): %d (>0)\n", String::strcasecmp("bbb", "aaaaaaa"));
367  printf("String::strcasecmp(): %d (<0)\n", String::strcasecmp("aaaaaaa", "bbb"));
368  printf("String::strncmp(): %d (0)\n", String::strncmp("aaa", "aaaaaaa", 3));
369  printf("String::strncmp(): %d (>0)\n", String::strncmp("aaaaaa", "aaa", 5));
370  printf("String::strncmp(): %d (<0)\n", String::strncmp("aaa", "aaaaaaa", 5));
371  printf("String::strncasecmp(): %d (0)\n", String::strncasecmp("aaa", "AAAAAA", 3));
372  printf("String::strncasecmp(): %d (>0)\n", String::strncasecmp("AAAAAA", "aaa", 5));
373  printf("String::strncasecmp(): %d (<0)\n", String::strncasecmp("aaa", "AAAAAA", 5));
374 
375  try {
376  std::string org("It's a trick, get an axe.", 16384);
377 
378  std::string zip = String::deflate(org, String::Zlib, 1);
379  printf("\nString::deflate(std::string, String::Zlib): %zd char (org: %zd char)\n", zip.size(), org.size());
380  std::string unzip = String::inflate(zip);
381  printf("String::inflate(std::string, String::Zlib): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
382  } catch (CompressionException &e) {
383  printf("Exception: %s\n", e.what());
384  }
385 
386  try {
387  std::string org("It's a trick, get an axe.", 16384);
388 
389  std::string zip = String::deflate(org, String::LZ4, 1);
390  printf("\nString::deflate(std::string, String::LZ4): %zd char (org: %zd char)\n", zip.size(), org.size());
391  std::string unzip = String::inflate(zip);
392  printf("String::inflate(std::string, String::LZ4): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
393  } catch (CompressionException &e) {
394  printf("Exception: %s\n", e.what());
395  }
396 
397  try {
398  std::string org("It's a trick, get an axe.", 16384);
399 
400  std::string zip = String::deflate(org, String::Gzip, 1);
401  printf("\nString::deflate(std::string, String::Gzip): %zd char (org: %zd char)\n", zip.size(), org.size());
402  std::string unzip = String::inflate(zip);
403  printf("String::inflate(std::string, String::Gzip): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
404  } catch (CompressionException &e) {
405  printf("Exception: %s\n", e.what());
406  }
407 
408  try {
409  std::vector<char> org;
410  for (size_t i = 0; i < 16384; i++) { org.push_back(97 + (i % 26)); }
411 
412  std::vector<char> zip = String::deflate(org, String::Zlib, 1);
413  printf("\nString::deflate(std::vector<char>, String::Zlib): %zd char (org: %zd char)\n", zip.size(), org.size());
414  std::vector<char> unzip = String::inflate(zip);
415  printf("String::inflate(std::vector<char>, String::Zlib): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
416  } catch (CompressionException &e) {
417  printf("Exception: %s\n", e.what());
418  }
419 
420  try {
421  std::vector<char> org;
422  for (size_t i = 0; i < 16384; i++) { org.push_back(97 + (i % 26)); }
423 
424  std::vector<char> zip = String::deflate(org, String::LZ4, 1);
425  printf("\nString::deflate(std::vector<char>, String::LZ4): %zd char (org: %zd char)\n", zip.size(), org.size());
426  std::vector<char> unzip = String::inflate(zip);
427  printf("String::inflate(std::vector<char>, String::LZ4): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
428  } catch (CompressionException &e) {
429  printf("Exception: %s\n", e.what());
430  }
431 
432  try {
433  std::vector<char> org;
434  for (size_t i = 0; i < 16384; i++) { org.push_back(97 + (i % 26)); }
435 
436  std::vector<char> zip = String::deflate(org, String::Gzip, 1);
437  printf("\nString::deflate(std::vector<char>, String::Gzip): %zd char (org: %zd char)\n", zip.size(), org.size());
438  std::vector<char> unzip = String::inflate(zip);
439  printf("String::inflate(std::vector<char>, String::Gzip): %zd char (match: %s)\n", unzip.size(), (org == unzip) ? "true" : "false");
440  } catch (CompressionException &e) {
441  printf("Exception: %s\n", e.what());
442  }
443 
444  try {
445  const std::string org("It's a trick, get an axe.");
446  std::string buf = String::encrypt(org, "RickAndMorty", "salty");
447  printf("\nString::encrypt(std::string): %s\n", org.c_str());
448  String::decrypt(buf, "RickAndMorty", "salty");
449  printf("String::inflate(std::string): %s (match: %s)\n", buf.c_str(), (buf == org) ? "true" : "false");
450  } catch (CryptException &e) {
451  printf("Exception: %s\n", e.what());
452  }
453 
454  printf("\nString::random(10): %s\n", String::random(10).c_str());
455 
456  try {
457  std::string org("It's a trick, get an axe.");
458 
459  std::string b64 = String::base64_encode(org);
460  printf("\nString::base64_encode(%s): %s\n", org.c_str(), b64.c_str());
461  printf("String::base64_dencode(%s): %s\n", b64.c_str(), String::base64_decode(b64).c_str());
462  } catch (sella::Exception &e) {
463  printf("Exception: %s\n", e.what());
464  }
465 
466  printf("\n");
467 
468  try {
469  std::vector<std::string> matches;
470  std::string org("xxx:one xxx:two xxx:three");
471  std::string re("(?:xxx):([a-z]+)");
472 
473  if (String::regex_search(org, re, matches, true, true)) {
474  printf("String::regex_search(\"%s\", \"%s\"): %s\n", org.c_str(), re.c_str(), String::join(matches).c_str());
475  } else {
476  printf("String::regex_search(\"%s\", \"%s\"): <no-match>\n", org.c_str(), re.c_str());
477  }
478  } catch (sella::Exception &e) {
479  printf("Exception: %s\n", e.what());
480  }
481 
482  try {
483  std::set<std::string> matches;
484  std::string org("xxx:one xxx:two xxx:three");
485  std::string re("(?:xxx):([a-z]+)");
486 
487  if (String::regex_search_sub(org, re, matches, true)) {
488  printf("String::regex_search_sub(\"%s\", \"%s\"): %s\n", org.c_str(), re.c_str(), String::join(matches).c_str());
489  } else {
490  printf("String::regex_search_sub(\"%s\", \"%s\"): <no-match>\n", org.c_str(), re.c_str());
491  }
492  } catch (sella::Exception &e) {
493  printf("Exception: %s\n", e.what());
494  }
495  printf("\n");
496 }
497 
498 void testProcess(void) {
499  printf("------------------------\n");
500  printf("- sella/util/Process.h -\n");
501  printf("------------------------\n");
502 
503  printf("Process::getBaseName(): %s\n", Process::getBaseName().c_str());
504  printf("Process::getDirName(): %s\n", Process::getDirName().c_str());
505  printf("Process::getPath(): %s\n", Process::getPath().c_str());
506 
507  {
508  Process p;
509 
510  { /* Waste some CPU cycles */
511  for (volatile size_t i = 0, x = 5; i < 500000LL; i++) {
512  x *= i;
513  x += i;
514  x /= 2.2;
515  }
516 
517  usleep(15000); /* Short cool down period. */
518  }
519 
520  p.update(); /* Update CPU and process statistics */
521 
522  printf("Process::getStartTime(): %" PRIu64 "\n", p.getStartTime());
523  printf("Process::getUptime(): %" PRIu64 " (sec)\n", p.getUptime());
524  printf("Process::getUpdateIntervalUsec(): %" PRIu64 " (usec)\n", p.getUpdateIntervalUsec());
525  printf("Process::getState(): %c\n", p.getState());
526  printf("Process::getCpu(): %d%%\n", p.getCPU());
527  printf("Process::getUserCPU(): %d%%\n", p.getUserCPU());
528  printf("Process::getSystemCPU(): %d%%\n", p.getSystemCPU());
529 
530  printf("Process::getMemory(): %d%%\n", p.getMemory());
531  printf("Process::getBytesRead(): %s\n", su::String::dataSize(p.getBytesRead()).c_str());
532  printf("Process::getBytesWrite(): %s\n", su::String::dataSize(p.getBytesWrite()).c_str());
533  printf("Process::getReadSyscall(): %" PRIu64 "\n", p.getReadSyscall());
534  printf("Process::getWriteSyscall(): %" PRIu64 "\n", p.getWriteSyscall());
535  printf("Process::getBytesReadStorage(): %s\n", su::String::dataSize(p.getBytesReadStorage()).c_str());
536  printf("Process::getBytesWriteStorage(): %s\n", su::String::dataSize(p.getBytesWriteStorage()).c_str());
537  printf("Process::getCancelledBytesWrite(): %s\n", su::String::dataSize(p.getCancelledBytesWrite()).c_str());
538  printf("Process::getBlockIOWait(): %" PRIu64 " (msec)\n", p.getBlockIOWait());
539 
540  printf("Process::getFDs(): %" PRIu64 "\n", p.getFDs());
541  printf("Process::getFDSize(): %" PRIu64 "\n", p.getFDSize());
542  printf("Process::getVMPeak(): %s\n", su::String::dataSize(p.getVMPeak()).c_str());
543  printf("Process::getVMSize(): %s\n", su::String::dataSize(p.getVMSize()).c_str());
544  printf("Process::getLocked(): %s\n", su::String::dataSize(p.getLocked()).c_str());
545  printf("Process::getRSSHighWaterMark(): %s\n", su::String::dataSize(p.getRSSHighWaterMark()).c_str());
546  printf("Process::getRSS(): %s\n", su::String::dataSize(p.getRSS()).c_str());
547  printf("Process::getData(): %s\n", su::String::dataSize(p.getData()).c_str());
548  printf("Process::getStack(): %s\n", su::String::dataSize(p.getStack()).c_str());
549  printf("Process::getEXE(): %s\n", su::String::dataSize(p.getEXE()).c_str());
550  printf("Process::getLib(): %s\n", su::String::dataSize(p.getLib()).c_str());
551  printf("Process::getPTE(): %s\n", su::String::dataSize(p.getPTE()).c_str());
552  printf("Process::getSwap(): %s\n", su::String::dataSize(p.getSwap()).c_str());
553  printf("Process::getThreads(): %" PRIu64 "\n", p.getThreads());
554  printf("Process::getVoluntaryContextSwitch(): %" PRIu64 "\n", p.getVoluntaryContextSwitch());
555  printf("Process::getNonVoluntaryContextSwitch(): %" PRIu64 "\n", p.getNonVoluntaryContextSwitch());
556 
557  printf("Process::getSystemUptime(): %" PRIu64 "\n", p.getSystemUptime());
558  printf("Process::getSystemLoadAverage(): %" PRIu64 "\n", p.getSystemLoadAverage());
559  printf("Process::getSystemMemory(): %s\n", su::String::dataSize(p.getSystemMemory()).c_str());
560  printf("Process::getSystemFree(): %s\n", su::String::dataSize(p.getSystemFree()).c_str());
561  printf("Process::getSystemShared(): %s\n", su::String::dataSize(p.getSystemShared()).c_str());
562  printf("Process::getSystemBuffer(): %s\n", su::String::dataSize(p.getSystemBuffer()).c_str());
563  printf("Process::getSystemSwap(): %s\n", su::String::dataSize(p.getSystemSwap()).c_str());
564  printf("Process::getSystemProcesses(): %" PRIu64 "\n", p.getSystemProcesses());
565  printf("Process::getSystemTotalHigh(): %s\n", su::String::dataSize(p.getSystemTotalHigh()).c_str());
566  printf("Process::getSystemFreeHigh(): %s\n", su::String::dataSize(p.getSystemFreeHigh()).c_str());
567  printf("Process::getSystemMemUnitSize(): %s\n", su::String::dataSize(p.getSystemMemUnitSize()).c_str());
568 
569  std::string org = Process::getName();
570 
571  Process::setName("new-name");
572  printf("Process::setName(): %s\n", Process::getName().c_str());
573  Process::setName(org);
574  printf("Process::getName(): %s\n", Process::getName().c_str());
575 
576  }
577 
578  printf("Process::runCommand(): %s\n", Process::runCommand("echo -n \"it works\" 2> /dev/null").c_str());
579  printf("Process::stackTrace(): Output below:\n%s\n", Process::stackTrace(Process::getPath()).c_str());
580 
581  printf("\n");
582 }
583 
584 void testLockFile(void) {
585  printf("-------------------------\n");
586  printf("- sella/util/LockFile.h -\n");
587  printf("-------------------------\n");
588 
589  try {
590  LockFile lockfile("/var/tmp/test.lock");
591 
592  if (lockfile.isLocked() && !lockfile.ownLock()) {
593  lockfile.remove();
594  }
595 
596  printf("LockFile::tryLock(): %s == true\n", (lockfile.tryLock()) ? "true" : "false");
597  printf("LockFile::ownLock(): %s == true\n", (lockfile.ownLock()) ? "true" : "false");
598  printf("LockFile::isLocked(): %s == true\n", (lockfile.isLocked()) ? "true" : "false");
599  printf("LockFile::isStale(): %s == false\n", (lockfile.isStale()) ? "true" : "false");
600 
601  if (lockfile.ownLock()) {
602  printf("LockFile::unlock(): %s == true\n", (lockfile.unlock()) ? "true" : "false");
603  }
604 
605  printf("LockFile::ownLock(): %s == false\n", (lockfile.ownLock()) ? "true" : "false");
606  printf("LockFile::isLocked(): %s == false\n", (lockfile.isLocked()) ? "true" : "false");
607  } catch (FileException &e) {
608  ERROR(e);
609  }
610 
611  printf("\n");
612 }
613 
614 void testFile(void) {
615  printf("---------------------\n");
616  printf("- sella/util/File.h -\n");
617  printf("---------------------\n");
618 
619  printf("File::getBaseName(): %s\n", File::getBaseName("/proc/cpuinfo").c_str());
620  printf("File::getDirName(): %s\n", File::getDirName("/proc/cpuinfo").c_str());
621  printf("File::getRealPath(): %s\n", File::getRealPath("/proc/./self").c_str());
622  printf("File::exists(): %s\n", (File::exists("/proc/cpuinfo")) ? "true" : "false");
623  printf("File::isRegularFile(): %s\n", (File::isRegularFile("/proc/cpuinfo")) ? "true" : "false");
624  printf("File::isDirectory(): %s\n", (File::isDirectory("/proc/self")) ? "true" : "false");
625  printf("File::isSymLink(): %s\n", (File::isSymLink("/proc/self")) ? "true" : "false");
626  printf("File::getSize(): %" PRId64 "B (%s)\n", File::getSize("/proc/self/exe"), String::dataSize(File::getSize("/proc/self/exe"), 1).c_str());
627 
628  printf("File::getDirectory(): %s\n", String::join(File::getDirectory("/proc/self/attr/", ".*create$")).c_str());
629 
630  printf("File::read(): %s\n", File::read("/proc/timer_stats", 10).c_str());
631  printf("File::readline(): %s\n", File::readline("/proc/timer_stats").c_str());
632  printf("File::readlines(): %s\n", su::String::join(File::readlines("/proc/timer_stats", 3), '|').c_str());
633 
634  printf("\n");
635 }
636 
637 void testPath(void) {
638  printf("---------------------\n");
639  printf("- sella/util/Path.h -\n");
640  printf("---------------------\n");
641 
642  try {
643  printf("Path::getPartitionSize(): %" PRIu64 "\n", Path::getPartitionSize("/var"));
644  printf("Path::getPartitionUsed(): %" PRIu64 "\n", Path::getPartitionUsed("/var"));
645  printf("Path::getPartitionFree(): %" PRIu64 "\n", Path::getPartitionFree("/var"));
646  printf("Path::getPartitionFull(): %.1f%%\n", Path::getPartitionFull("/var"));
647  } catch (PathException &e) {
648  ERROR(e);
649  }
650 
651  printf("\n");
652 }
653 
654 void testInterface(void) {
655  printf("--------------------------\n");
656  printf("- sella/util/Interface.h -\n");
657  printf("--------------------------\n");
658 
659  printf("Interface::getNames():\n");
660  auto names = Interface::getNames(0);
661 
662  for (auto it = names.begin(); it != names.end(); ++it) {
663  printf("name: %s\n", it->c_str());
664  }
665 
666 
667  printf("Interface::getInterface():\n");
668  std::string iface = Interface::getInterface(IPAddress("127.0.0.1"), IFF_UP, 0);
669  printf("interface: %s\n", iface.c_str());
670 
671 
672  printf("\nInterface::getEthernetNames():\n");
673  auto enames = Interface::getEthernetNames(0);
674 
675  for (auto it = enames.begin(); it != enames.end(); ++it) {
676  printf("name: %s\n", it->c_str());
677  }
678 
679 
680  printf("\nInterface::getIPAddresses(\"%s\"):\n", names.front().c_str());
681  auto addresses = Interface::getIPAddresses(names.front());
682 
683  for (auto it = addresses.begin(); it != addresses.end(); ++it) {
684  printf("address: %s\n", (*it)->c_str());
685  }
686 
687 
688  printf("\nInterface::getIPAddresses():\n");
689  addresses = Interface::getIPAddresses();
690 
691  for (auto it = addresses.begin(); it != addresses.end(); ++it) {
692  printf("address: %s\n", (*it)->c_str());
693  }
694 
695 
696  printf("\nInterface::getMAC(\"%s\"):\n", names.front().c_str());
697  std::string mac = Interface::getMAC(names.front());
698  printf("mac: %s\n", mac.c_str());
699 
700 
701  printf("\nInterface::getMACs():\n");
702  auto macs = Interface::getMACs();
703 
704  for (auto it = macs.begin(); it != macs.end(); ++it) {
705  printf("mac: %s\n", it->c_str());
706  }
707 
708 
709  printf("\nInterface::getIndex():\n");
710 
711  for (auto it = names.begin(); it != names.end(); ++it) {
712  int idx = Interface::getIndex(*it);
713  printf("%s: %d (reverse: %s)\n", it->c_str(), idx, Interface::getName(idx).c_str());
714  }
715 
716  {
717  printf("\nInterface::convertMAC():\n");
718 
719  unsigned char addr[6] = { 0, 1, 2, 3, 4, 5 };
720  uint64_t mac1, mac2;
721  std::string buf1, buf2;
722 
723  Interface::convertMAC(mac1, (const unsigned char*) addr);
724  Interface::convertMAC(addr, mac1);
725  Interface::convertMAC(mac2, (const unsigned char*) addr);
726  printf("%" PRIu64 " == %" PRIu64 "\n", mac1, mac2);
727  printf("%s == %s\n", Interface::convertMAC(buf1, mac1).c_str(), Interface::convertMAC(buf2, mac2).c_str());
728  Interface::convertMAC(buf1, mac1);
729  Interface::convertMAC(mac2, buf1);
730  Interface::convertMAC(buf2, mac2);
731  printf("%s == %s\n", buf1.c_str(), buf2.c_str());
732  }
733 
734  printf("\n");
735 }
736 
737 void testSocket(void) {
738  size_t c;
739  unsigned char buf[9216] = { 0 };
740  size_t ethhdr_size = 18; // 14 without VLAN
741  struct ethhdr *eh = (struct ethhdr*) buf;
742  struct ip *iphdr = (struct ip*) (buf + ethhdr_size);
743  struct icmphdr *ich = (struct icmphdr*) (buf + ethhdr_size + sizeof(struct ip));
744  size_t pktlen = ethhdr_size + sizeof(struct ip) + sizeof(struct icmphdr);
745 
746  printf("--------------------------\n");
747  printf("- sella/net/Socket.h -\n");
748  printf("--------------------------\n");
749 
750  auto names = Interface::getNames();
751 
752  /* View outgoiong packets with:
753  # tcpdump -v -nettti eth2 '(ether dst host 00:11:22:33:44:55)'
754  */
755 
756  try {
757  std::string destination = "00:11:22:33:44:55";
758  std::string name = names.front();
759  name = "eth2";
760 
761  printf("EtherSocket(): %s\n", name.c_str());
762  EtherSocket::shared s = std::make_shared<EtherSocket>(ETH_P_ALL, name, true);
763  SocketMux mux;
764 
765  s->setPromiscous();
766  s->setSoReuseAddr();
767  s->bindInterface();
768  s->setSoBindToDevice();
769 
770 //#define ZEROCOPY
771 #ifdef ZEROCOPY
772  size_t ring_frames = 256;
773  //#define PKT_OFFSET (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + TPACKET_ALIGN(sizeof(struct sockaddr_ll)))
774 
775  struct tpacket_req req;
776  req.tp_block_size = ring_frames * getpagesize();
777  req.tp_block_nr = 1;
778  req.tp_frame_size = getpagesize();
779  req.tp_frame_nr = ring_frames;
780 
781  unsigned char *tx, *rx;
782  s->mmapRingBuffer(&tx, req);
783  s->mmapRingBuffer(&rx, req);
784 
785  s->setPacketRxRing(req);
786  s->setPacketTxRing(req);
787 
788  s->munmapRingBuffer(&tx, req);
789  s->munmapRingBuffer(&rx, req);
790 #endif
791 
792  unsigned char dst_mac[6], src_mac[6];
793 
794  su::Interface::convertMAC(dst_mac, destination);
795  su::Interface::convertMAC(src_mac, su::Interface::getMAC(name));
796 
797  memset(&buf, 0, sizeof(buf));
798  memcpy((void*) (buf), (void*) &dst_mac, 6);
799  memcpy((void*) (buf + 6), (void*) &src_mac, 6);
800 
801  eh->h_proto = htons(0x8100);
802  unsigned short int vid = htons(200);
803  memcpy((void*) (buf + 14), (void*) &vid, 2);
804 
805  unsigned short int vlanproto = htons(0x0800);
806  memcpy((void*) (buf + 16), (void*) &vlanproto, 2);
807 
808  iphdr->ip_hl = 5;
809  iphdr->ip_v = 4;
810  iphdr->ip_tos = 0;
811  iphdr->ip_len = htons(pktlen - ethhdr_size);
812  iphdr->ip_id = 0;
813  iphdr->ip_off = 0;
814  iphdr->ip_ttl = 64;
815  iphdr->ip_p = 1; /* ICMP */
816  iphdr->ip_sum = 0;
817  iphdr->ip_src.s_addr = inet_addr(su::Interface::getIPAddress(name).c_str());
818  iphdr->ip_dst.s_addr = inet_addr(destination.c_str());
819 
820  ich->type = 8;
821  ich->code = 0;
822  ich->checksum = 0;
823  ich->un.echo.id = 0;
824  ich->un.echo.sequence = htons(11);
825 
826  ich->checksum = su::Packet::csum((unsigned short*) (buf + ethhdr_size + sizeof(struct ip)), 4);
827  iphdr->ip_sum = su::Packet::csum((unsigned short*) (buf + ethhdr_size), iphdr->ip_hl << 1);
828 
829  printf("Sending packet on vlan %d to %s (size: %zd)...\n", ntohs(vid), su::Interface::getMAC(name).c_str(), pktlen);
830  for (size_t i = 0; i < pktlen; i++) {
831  printf("%02X", buf[i]);
832  }
833  printf("\n");
834 
835  s->sendto(&buf, pktlen, destination);
836 
837  mux.insertRead(s);
838 
839  struct timeval delay = { 0, 5000 };
840 
841  if (mux.select(&delay) > 0) {
842  const auto &list = mux.getReadList();
843 
844  for (auto it = list.begin(); it != list.end(); ++it) {
845  s = std::static_pointer_cast<EtherSocket>(*it);
846  std::string mac;
847 
848  if ((c = s->recvfrom(&buf, sizeof(buf), mac)) > 0) {
849 
850  printf("Received packet on from %s.\n", mac.c_str());
851  for (size_t i = 0; i < c; i++) {
852  printf("%X", buf[i]);
853  }
854  printf("\n");
855 
856  } else {
857  printf("Received no packet.\n");
858  }
859  }
860  } else {
861  printf("Receive timed out (nothing to receive)\n");
862  }
863  } catch (sella::Exception &e) {
864  printf("Exception: %s\n", e.what());
865  }
866 
867 #if 0
868  try {
869  printf("\nEtherSocket(): %s\n", names.front().c_str());
870  EtherSocket s(ETH_P_MPLS_UC, "eth2");
871  SocketMux mux;
872 
873  s.setSoReuseAddr(true);
874  //s.setSoBindToDevice(names.front());
875  s.setSoBindToDevice("eth2");
876 // s.bindInterface(names.front());
877 // Interface::setPromiscous(names.front());
878 
879  printf("sendto...\n");
880 
881  struct header_8021q {
882  uint32_t vid:12;
883  } __attribute__((packed));
884 
885  union mpls_shim {
886  uint32_t shim;
887  struct mpls_label {
888  uint32_t label:20;
889  uint8_t exp:3;
890  uint8_t s:1;
891  uint8_t ttl:8;
892  } __attribute__((__packed__)) bits;
893  };
894 
895  mpls_shim *h = (mpls_shim*) buf;
896 
897  h->bits.label = htons(500);
898  h->bits.exp = 0;
899  h->bits.s = 1;
900  h->bits.ttl = 10;
901 
902  h->shim = htonl(h->shim);
903 
904  s.sendto(&buf, 4, "68:05:CA:0F:C5:FF");
905 
906 #if 0
907  printf("GET GET\n");
908  read(s.getFD(), buf, sizeof(buf));
909 #endif
910 
911  printf("recvfrom()...\n");
912  if (s.recvfrom(&buf, sizeof(buf)) > 0) {
913  printf("Got some packets\n");
914  } else {
915  printf("Got no packets\n");
916  }
917  } catch (sella::Exception &e) {
918  printf("Exception: %s\n", e.what());
919  }
920 #endif
921 
922  printf("\n");
923 }
924 
925 void testIPAddress(void) {
926  printf("------------------------\n");
927  printf("- sella/net/IPAddress.h -\n");
928  printf("------------------------\n");
929 
930  try {
931  printf("IPAddress Constructors\n");
932  IPAddress a("192.168.0.0");
933  IPAddress b("192.168.0.25");
934  IPAddress c("192.168.0.75");
935  IPAddress e("fe80::6a05:caff:fe0f:0000");
936  IPAddress f("fe80::6a05:caff:fe0f:5555");
937  IPAddress g("ffff::ffff:ffff:ffff:ffff");
938  IPAddress m("0.0.0.255");
939  IPAddress j("::FFFF");
940 
941  printf("a: %s\n", a.c_str());
942  printf("b: %s\n", b.c_str());
943  printf("c: %s\n", c.c_str());
944  printf("e: %s\n", e.c_str());
945  printf("f: %s\n", f.c_str());
946  printf("g: %s\n", g.c_str());
947  printf("m: %s\n", m.c_str());
948  printf("j: %s\n", j.c_str());
949 
950  printf("\nIPAddress::operator==()\n");
951  printf("(%s == %s) == %s\n", a.c_str(), b.c_str(), (a == b) ? "true" : "false");
952  printf("(%s == %s) == %s\n", b.c_str(), c.c_str(), (b == c) ? "true" : "false");
953  printf("(%s == %s) == %s\n", b.c_str(), b.c_str(), (b == b) ? "true" : "false");
954  printf("(%s == %s) == %s\n", e.c_str(), f.c_str(), (e == f) ? "true" : "false");
955  printf("(%s == %s) == %s\n", f.c_str(), g.c_str(), (f == g) ? "true" : "false");
956  printf("(%s == %s) == %s\n", f.c_str(), f.c_str(), (f == f) ? "true" : "false");
957 
958  printf("\nIPAddress::operator>()\n");
959  printf("(%s > %s) == %s\n", a.c_str(), b.c_str(), (a > b) ? "true" : "false");
960  printf("(%s > %s) == %s\n", c.c_str(), b.c_str(), (c > b) ? "true" : "false");
961  printf("(%s > %s) == %s\n", f.c_str(), e.c_str(), (f > e) ? "true" : "false");
962  printf("(%s > %s) == %s\n", f.c_str(), g.c_str(), (f > g) ? "true" : "false");
963 
964  printf("\nIPAddress::operator<()\n");
965  printf("(%s < %s) == %s\n", a.c_str(), b.c_str(), (a < b) ? "true" : "false");
966  printf("(%s < %s) == %s\n", b.c_str(), c.c_str(), (b < c) ? "true" : "false");
967  printf("(%s < %s) == %s\n", f.c_str(), e.c_str(), (f < e) ? "true" : "false");
968  printf("(%s < %s) == %s\n", f.c_str(), g.c_str(), (f < g) ? "true" : "false");
969 
970  printf("\nIPAddress::operator>=()\n");
971  printf("(%s >= %s) == %s\n", a.c_str(), b.c_str(), (a >= b) ? "true" : "false");
972  printf("(%s >= %s) == %s\n", c.c_str(), b.c_str(), (c >= b) ? "true" : "false");
973  printf("(%s >= %s) == %s\n", f.c_str(), e.c_str(), (f >= e) ? "true" : "false");
974  printf("(%s >= %s) == %s\n", f.c_str(), g.c_str(), (f >= g) ? "true" : "false");
975 
976  printf("\nIPAddress::operator<=()\n");
977  printf("(%s <= %s) == %s\n", a.c_str(), b.c_str(), (a <= b) ? "true" : "false");
978  printf("(%s <= %s) == %s\n", b.c_str(), c.c_str(), (b <= c) ? "true" : "false");
979  printf("(%s <= %s) == %s\n", f.c_str(), e.c_str(), (f <= e) ? "true" : "false");
980  printf("(%s <= %s) == %s\n", f.c_str(), g.c_str(), (f <= g) ? "true" : "false");
981 
982  printf("\nIPAddress::operator&()\n");
983  printf("(%s & %s) == %s\n", a.c_str(), m.c_str(), (a & m).str().c_str());
984  printf("(%s & %s) == %s\n", b.c_str(), m.c_str(), (b & m).str().c_str());
985  printf("(%s & %s) == %s\n", e.c_str(), j.c_str(), (e & j).str().c_str());
986  printf("(%s & %s) == %s\n", f.c_str(), j.c_str(), (f & j).str().c_str());
987 
988  printf("\nIPAddress::operator|()\n");
989  printf("(%s | %s) == %s\n", a.c_str(), m.c_str(), (a | m).str().c_str());
990  printf("(%s | %s) == %s\n", b.c_str(), m.c_str(), (b | m).str().c_str());
991  printf("(%s | %s) == %s\n", e.c_str(), j.c_str(), (e | j).str().c_str());
992  printf("(%s | %s) == %s\n", f.c_str(), j.c_str(), (f | j).str().c_str());
993 
994  printf("\nIPAddress::operator^()\n");
995  printf("(%s ^ %s) == %s\n", a.c_str(), m.c_str(), (a ^ m).str().c_str());
996  printf("(%s ^ %s) == %s\n", b.c_str(), m.c_str(), (b ^ m).str().c_str());
997  printf("(%s ^ %s) == %s\n", e.c_str(), j.c_str(), (e ^ j).str().c_str());
998  printf("(%s ^ %s) == %s\n", f.c_str(), j.c_str(), (f ^ j).str().c_str());
999 
1000  printf("\nIPAddress::operator~()\n");
1001  printf("(~ %s) == %s\n", a.c_str(), (~a).str().c_str());
1002  printf("(~ %s) == %s\n", b.c_str(), (~b).str().c_str());
1003  printf("(~ %s) == %s\n", e.c_str(), (~e).str().c_str());
1004  printf("(~ %s) == %s\n", f.c_str(), (~f).str().c_str());
1005 
1006  printf("\nIPAddress::getU32()\n");
1007  printf("%s => %u\n", a.c_str(), a.getU32());
1008  printf("%s => %u\n", b.c_str(), b.getU32());
1009  printf("%s => %u\n", e.c_str(), e.getU32());
1010  printf("%s => %u\n", f.c_str(), f.getU32());
1011 
1012  printf("\nIPAddress::getHash()\n");
1013  printf("%s => %u\n", a.c_str(), a.getHash());
1014  printf("%s => %u\n", b.c_str(), b.getHash());
1015  printf("%s => %u\n", e.c_str(), e.getHash());
1016  printf("%s => %u\n", f.c_str(), f.getHash());
1017 
1018  printf("\nIPAddress::operator++()\n");
1019  printf("%s++ == %s\n", a.c_str(), (a++).c_str());
1020  printf("%s++ == %s\n", e.c_str(), (e++).c_str());
1021  g = IPAddress("::ffff:ffff:ffff:ffff");
1022  printf("%s++ == %s\n", g.c_str(), (g++).c_str());
1023  g = IPAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
1024  printf("%s++ == %s\n", g.c_str(), (g++).c_str());
1025 
1026  printf("\nIPAddress::operator+()\n");
1027  printf("%s++ == %s\n", a.c_str(), (a++).c_str());
1028  printf("%s++ == %s\n", e.c_str(), (e++).c_str());
1029  g = IPAddress("::ffff:ffff:ffff:ffff");
1030  printf("%s + 256 == %s\n", g.c_str(), (g + 256).c_str());
1031  g = IPAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
1032  printf("%s + 256 == %s\n", g.c_str(), (g + 256).c_str());
1033 
1034  printf("\nIPAddress::operator--()\n");
1035  printf("%s-- == %s\n", a.c_str(), (a--).c_str());
1036  printf("%s-- == %s\n", e.c_str(), (e--).c_str());
1037  g = IPAddress("::1");
1038  printf("%s-- == %s\n", g.c_str(), (g--).c_str());
1039  g = IPAddress("::ffff:ffff:ffff:ffff");
1040  printf("%s-- == %s\n", g.c_str(), (g--).c_str());
1041  g = IPAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
1042  printf("%s-- == %s\n", g.c_str(), (g--).c_str());
1043 
1044  printf("\nIPAddress::operator-()\n");
1045  printf("%s-- == %s\n", a.c_str(), (a--).c_str());
1046  printf("%s-- == %s\n", e.c_str(), (e--).c_str());
1047  g = IPAddress("::ffff:ffff:ffff:ffff");
1048  printf("%s - 1 == %s\n", g.c_str(), (g - 1).c_str());
1049  g = IPAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
1050  printf("%s - 1 == %s\n", g.c_str(), (g - 1).c_str());
1051  g = IPAddress("::");
1052  printf("%s - 1 == %s\n", g.c_str(), (g - 1).c_str());
1053  g = IPAddress("::1:ffff:ffff:ffff:ffff");
1054  printf("%s - 2 == %s\n", g.c_str(), (g - 2).c_str());
1055  g = IPAddress("ffff:ffff:ffff:ffff::");
1056  printf("%s - 1 == %s\n", g.c_str(), (g - 1).c_str());
1057  g = IPAddress("0:0:0:1::");
1058  printf("%s - 1 == %s\n", g.c_str(), (g - 1).c_str());
1059 
1060  printf("\nIPAddress::operator+=()\n");
1061  a = IPAddress("10.0.0.5") += 1;
1062  printf("%s += 1 == %s\n", IPAddress("10.0.0.5").c_str(), a.c_str());
1063  a = IPAddress("::ffff:ffff:ffff:ffff") += 2;
1064  printf("%s += 2 == %s\n", IPAddress("::ffff:ffff:ffff:ffff").c_str(), a.c_str());
1065 
1066  printf("\nIPAddress::operator-=()\n");
1067  a = IPAddress("10.0.0.6") -= 1;
1068  printf("%s -= 1 == %s\n", IPAddress("10.0.0.6").c_str(), a.c_str());
1069  a = IPAddress("0:0:0:2::") -= 2;
1070  printf("%s -= 2 == %s\n", IPAddress("0:0:0:2::").c_str(), a.c_str());
1071 
1072  IPAddress ipv4("192.168.1.50"); a = ipv4;
1073  printf("\nIPAddress::applyCIDR()\n");
1074  a.applyCIDR(24);
1075  printf("(%s).applyCIDR(24) == %s\n", ipv4.c_str(), a.c_str());
1076  a.applyCIDR(16);
1077  printf("(%s).applyCIDR(16) == %s\n", ipv4.c_str(), a.c_str());
1078  a.applyCIDR(8);
1079  printf("(%s).applyCIDR(8) == %s\n", ipv4.c_str(), a.c_str());
1080  a.applyCIDR(0);
1081  printf("(%s).applyCIDR(0) == %s\n", ipv4.c_str(), a.c_str());
1082 
1083  IPAddress ipv6("cafe:ffff:ffff:ffff:ffff:ffff:ffff:babe"); a = ipv6;
1084  printf("\nIPAddress::applyCIDR()\n");
1085  a.applyCIDR(128);
1086  printf("(%s).applyCIDR(128) == %s\n", ipv6.c_str(), a.c_str());
1087  a.applyCIDR(64);
1088  printf("(%s).applyCIDR(64) == %s\n", ipv6.c_str(), a.c_str());
1089  a.applyCIDR(56);
1090  printf("(%s).applyCIDR(56) == %s\n", ipv6.c_str(), a.c_str());
1091  a.applyCIDR(48);
1092  printf("(%s).applyCIDR(48) == %s\n", ipv6.c_str(), a.c_str());
1093  a.applyCIDR(32);
1094  printf("(%s).applyCIDR(30) == %s\n", ipv6.c_str(), a.c_str());
1095  a.applyCIDR(0);
1096  printf("(%s).applyCIDR(0) == %s\n", ipv6.c_str(), a.c_str());
1097  } catch (AddressException &e) {
1098  printf("AddressException: %s\n", e.what());
1099 
1100  exit(1);
1101  }
1102 
1103  try {
1104  printf("\nIPAddress Comparison Tests:\n");
1105  sn::IPAddress::vector v = { sn::IPAddress("1.1.1.1"), sn::IPAddress("cafe::babe"), sn::IPAddress("2.2.2.2"), sn::IPAddress("cafe::babe"), sn::IPAddress("1.1.1.1") };
1106 
1107  printf("Original: ");
1108  for (auto i = v.begin(); i != v.end(); ++i) {
1109  printf("%s, ", i->c_str());
1110  }
1111  printf("\b\b \n");
1112 
1113  std::sort(v.begin(), v.end());
1114 
1115  printf("Sorted: ");
1116  for (auto i = v.begin(); i != v.end(); ++i) {
1117  printf("%s, ", i->c_str());
1118  }
1119  printf("\b\b \n");
1120 
1121  v.erase(std::unique(v.begin(), v.end()), v.end());
1122 
1123  printf("Uniqued: ");
1124  for (auto i = v.begin(); i != v.end(); ++i) {
1125  printf("%s, ", i->c_str());
1126  }
1127  printf("\b\b \n");
1128  } catch (AddressException &e) {
1129  printf("AddressException: %s\n", e.what());
1130 
1131  exit(1);
1132  }
1133 
1134  printf("\n");
1135 }
1136 
1137 void testIPAddressPort(void) {
1138  printf("-----------------------------\n");
1139  printf("- sella/net/IPAddressPort.h -\n");
1140  printf("-----------------------------\n");
1141 
1142  try {
1143  printf("\nIPAddressPort Constructors\n");
1144  IPAddressPort a("192.168.0.0");
1145  IPAddressPort b("[192.168.0.25]:80");
1146  IPAddressPort c("192.168.0.75:8080", 9999);
1147  IPAddressPort e("fe80::6a05:caff:fe0f:5151");
1148  IPAddressPort f("[fe80::6a05:caff:fe0f:5555]:8080", 9999);
1149  IPAddressPort g("ffff::ffff:ffff:ffff:ffff", 9999);
1150  IPAddressPort h("[::]:0");
1151  IPAddressPort m("[0.0.0.255]");
1152  IPAddressPort j("[::FFFF]");
1153 
1154  printf("a: %s\n", a.c_str());
1155  printf("b: %s\n", b.c_str());
1156  printf("c: %s\n", c.c_str());
1157  printf("e: %s\n", e.c_str());
1158  printf("f: %s\n", f.c_str());
1159  printf("g: %s\n", g.c_str());
1160  printf("h: %s\n", h.c_str());
1161  printf("m: %s\n", m.c_str());
1162  printf("j: %s\n", j.c_str());
1163 
1164  printf("\nIPAddressPort::operator==()\n");
1165  printf("(%s == %s) == %s\n", a.c_str(), b.c_str(), (a == b) ? "true" : "false");
1166  printf("(%s == %s) == %s\n", b.c_str(), c.c_str(), (b == c) ? "true" : "false");
1167  printf("(%s == %s) == %s\n", b.c_str(), b.c_str(), (b == b) ? "true" : "false");
1168  printf("(%s == %s) == %s\n", e.c_str(), f.c_str(), (e == f) ? "true" : "false");
1169  printf("(%s == %s) == %s\n", f.c_str(), g.c_str(), (f == g) ? "true" : "false");
1170  printf("(%s == %s) == %s\n", f.c_str(), f.c_str(), (f == f) ? "true" : "false");
1171 
1172  printf("\nIPAddressPort::operator>()\n");
1173  printf("(%s > %s) == %s\n", a.c_str(), b.c_str(), (a > b) ? "true" : "false");
1174  printf("(%s > %s) == %s\n", c.c_str(), b.c_str(), (c > b) ? "true" : "false");
1175  printf("(%s > %s) == %s\n", f.c_str(), e.c_str(), (f > e) ? "true" : "false");
1176  printf("(%s > %s) == %s\n", f.c_str(), g.c_str(), (f > g) ? "true" : "false");
1177 
1178  printf("\nIPAddressPort::operator<()\n");
1179  printf("(%s < %s) == %s\n", a.c_str(), b.c_str(), (a < b) ? "true" : "false");
1180  printf("(%s < %s) == %s\n", b.c_str(), c.c_str(), (b < c) ? "true" : "false");
1181  printf("(%s < %s) == %s\n", f.c_str(), e.c_str(), (f < e) ? "true" : "false");
1182  printf("(%s < %s) == %s\n", f.c_str(), g.c_str(), (f < g) ? "true" : "false");
1183 
1184  printf("\nIPAddressPort::operator>=()\n");
1185  printf("(%s >= %s) == %s\n", a.c_str(), b.c_str(), (a >= b) ? "true" : "false");
1186  printf("(%s >= %s) == %s\n", c.c_str(), b.c_str(), (c >= b) ? "true" : "false");
1187  printf("(%s >= %s) == %s\n", f.c_str(), e.c_str(), (f >= e) ? "true" : "false");
1188  printf("(%s >= %s) == %s\n", f.c_str(), g.c_str(), (f >= g) ? "true" : "false");
1189 
1190  printf("\nIPAddressPort::operator<=()\n");
1191  printf("(%s <= %s) == %s\n", a.c_str(), b.c_str(), (a <= b) ? "true" : "false");
1192  printf("(%s <= %s) == %s\n", b.c_str(), c.c_str(), (b <= c) ? "true" : "false");
1193  printf("(%s <= %s) == %s\n", f.c_str(), e.c_str(), (f <= e) ? "true" : "false");
1194  printf("(%s <= %s) == %s\n", f.c_str(), g.c_str(), (f <= g) ? "true" : "false");
1195 
1196  printf("\nIPAddressPort::getU32()\n");
1197  printf("%s => %u\n", b.c_str(), b.getU32());
1198  printf("%s => %u\n", e.c_str(), e.getU32());
1199 
1200  printf("\nIPAddressPort::getHash()\n");
1201  printf("%s => %u\n", b.c_str(), b.getHash());
1202  printf("%s => %u\n", e.c_str(), e.getHash());
1203  } catch (AddressException &e) {
1204  printf("AddressException: %s\n", e.what());
1205 
1206  exit(1);
1207  }
1208 
1209  try {
1210  printf("\nIPAddressPort Comparison Tests:\n");
1211  sn::IPAddressPort::vector v = { sn::IPAddressPort("1.1.1.1:80"), sn::IPAddressPort("[cafe::babe]:80"), sn::IPAddressPort("2.2.2.2:80"), sn::IPAddressPort("[cafe::babe]:80"), sn::IPAddressPort("1.1.1.1:80") };
1212 
1213  printf("Original: ");
1214  for (auto i = v.begin(); i != v.end(); ++i) {
1215  printf("%s, ", i->c_str());
1216  }
1217  printf("\b\b \n");
1218 
1219  std::sort(v.begin(), v.end());
1220 
1221  printf("Sorted: ");
1222  for (auto i = v.begin(); i != v.end(); ++i) {
1223  printf("%s, ", i->c_str());
1224  }
1225  printf("\b\b \n");
1226 
1227  v.erase(std::unique(v.begin(), v.end()), v.end());
1228 
1229  printf("Uniqued: ");
1230  for (auto i = v.begin(); i != v.end(); ++i) {
1231  printf("%s, ", i->c_str());
1232  }
1233  printf("\b\b \n");
1234  } catch (AddressException &e) {
1235  printf("AddressException: %s\n", e.what());
1236 
1237  exit(1);
1238  } catch (PortException &e) {
1239  printf("PortException: %s\n", e.what());
1240 
1241  exit(1);
1242  }
1243 
1244  printf("\n");
1245 }
1246 
1247 void testIPPrefix(void) {
1248  printf("------------------------\n");
1249  printf("- sella/net/IPPrefix.h -\n");
1250  printf("------------------------\n");
1251 
1252  try {
1253  printf("IPPrefix Constructors\n");
1254  IPPrefix a("192.168.50.25");
1255  IPPrefix b("192.168.50.1/24");
1256  IPPrefix c("192.168.50.25", 24);
1257  IPPrefix d(IPAddress("192.168.50.25"), 16);
1258  IPPrefix e("fe80::6a05:caff:fe0f:c55f", 128);
1259  IPPrefix f("fe80::6a05:caff:fe0f:c55f");
1260  IPPrefix g("fe80::6a05:caff:fe0f:dead/128");
1261  IPPrefix h("fe80::6a05:caff/64");
1262  IPPrefix m("0.0.0.255");
1263  IPPrefix j("::FFFF");
1264  IPPrefix t("1.0.0.0/24");
1265  IPPrefix w("200.0.0.0/24");
1266  IPPrefix y("fe80::6a05:caff:fe0f:dead/36");
1267  IPPrefix z("fe80::6a05:caff:fe0f:dead/56");
1268  IPAddress aa("192.168.50.1");
1269 
1270  printf("a: %s\n", a.c_str());
1271  printf("b: %s\n", b.c_str());
1272  printf("c: %s\n", c.c_str());
1273  printf("d: %s\n", d.c_str());
1274  printf("e: %s\n", e.c_str());
1275  printf("f: %s\n", f.c_str());
1276  printf("g: %s\n", g.c_str());
1277  printf("h: %s\n", h.c_str());
1278 
1279  printf("\nIPPrefix::operator==()\n");
1280  printf("(%s == %s) == %s\n", a.c_str(), b.c_str(), (a == b) ? "true" : "false");
1281  printf("(%s == %s) == %s\n", b.c_str(), c.c_str(), (b == c) ? "true" : "false");
1282  printf("(%s == %s) == %s\n", e.c_str(), f.c_str(), (e == f) ? "true" : "false");
1283  printf("(%s == %s) == %s\n", f.c_str(), g.c_str(), (f == g) ? "true" : "false");
1284 
1285  printf("\nIPPrefix::operator>()\n");
1286  printf("(%s > %s) == %s\n", a.c_str(), b.c_str(), (a > b) ? "true" : "false");
1287  printf("(%s > %s) == %s\n", b.c_str(), a.c_str(), (b > a) ? "true" : "false");
1288  printf("(%s > %s) == %s\n", b.c_str(), c.c_str(), (b > c) ? "true" : "false");
1289  printf("(%s > %s) == %s\n", t.c_str(), c.c_str(), (t > c) ? "true" : "false");
1290  printf("(%s > %s) == %s\n", w.c_str(), c.c_str(), (w > c) ? "true" : "false");
1291  printf("(%s > %s) == %s\n", e.c_str(), f.c_str(), (e > f) ? "true" : "false");
1292  printf("(%s > %s) == %s\n", f.c_str(), g.c_str(), (f > g) ? "true" : "false");
1293 
1294  printf("\nIPPrefix::operator<()\n");
1295  printf("(%s < %s) == %s\n", a.c_str(), b.c_str(), (a < b) ? "true" : "false");
1296  printf("(%s < %s) == %s\n", b.c_str(), a.c_str(), (b < a) ? "true" : "false");
1297  printf("(%s < %s) == %s\n", b.c_str(), c.c_str(), (b < c) ? "true" : "false");
1298  printf("(%s < %s) == %s\n", c.c_str(), t.c_str(), (c < t) ? "true" : "false");
1299  printf("(%s < %s) == %s\n", t.c_str(), c.c_str(), (t < c) ? "true" : "false");
1300  printf("(%s < %s) == %s\n", w.c_str(), c.c_str(), (w < c) ? "true" : "false");
1301  printf("(%s < %s) == %s\n", e.c_str(), f.c_str(), (e < f) ? "true" : "false");
1302  printf("(%s < %s) == %s\n", f.c_str(), g.c_str(), (f < g) ? "true" : "false");
1303 
1304  printf("\nIPPrefix::operator>=()\n");
1305  printf("(%s >= %s) == %s\n", a.c_str(), b.c_str(), (a >= b) ? "true" : "false");
1306  printf("(%s >= %s) == %s\n", b.c_str(), a.c_str(), (b >= a) ? "true" : "false");
1307  printf("(%s >= %s) == %s\n", b.c_str(), c.c_str(), (b >= c) ? "true" : "false");
1308  printf("(%s >= %s) == %s\n", e.c_str(), f.c_str(), (e >= f) ? "true" : "false");
1309  printf("(%s >= %s) == %s\n", f.c_str(), g.c_str(), (f >= g) ? "true" : "false");
1310 
1311  printf("\nIPPrefix::operator<=()\n");
1312  printf("(%s <= %s) == %s\n", a.c_str(), b.c_str(), (a <= b) ? "true" : "false");
1313  printf("(%s <= %s) == %s\n", b.c_str(), a.c_str(), (b <= a) ? "true" : "false");
1314  printf("(%s <= %s) == %s\n", b.c_str(), c.c_str(), (b <= c) ? "true" : "false");
1315  printf("(%s <= %s) == %s\n", e.c_str(), f.c_str(), (e <= f) ? "true" : "false");
1316  printf("(%s <= %s) == %s\n", f.c_str(), g.c_str(), (f <= g) ? "true" : "false");
1317 
1318  printf("\nIPPrefix::contains()\n");
1319  printf("(%s contains %s) == %s\n", a.c_str(), b.c_str(), (a.contains(b)) ? "true" : "false");
1320  printf("(%s contains %s) == %s\n", b.c_str(), a.c_str(), (b.contains(a)) ? "true" : "false");
1321  printf("(%s contains %s) == %s\n", b.c_str(), c.c_str(), (b.contains(c)) ? "true" : "false");
1322  printf("(%s contains %s) == %s\n", g.c_str(), h.c_str(), (g.contains(h)) ? "true" : "false");
1323  printf("(%s contains %s) == %s\n", h.c_str(), g.c_str(), (h.contains(g)) ? "true" : "false");
1324  printf("(%s contains %s) == %s\n", b.c_str(), aa.c_str(), (b.contains(aa)) ? "true" : "false");
1325 
1326  printf("\nIPPrefix::operator>>=()\n");
1327  printf("(%s >>= %s) == %s\n", a.c_str(), b.c_str(), (a >>= b) ? "true" : "false");
1328  printf("(%s >>= %s) == %s\n", b.c_str(), a.c_str(), (b >>= a) ? "true" : "false");
1329  printf("(%s >>= %s) == %s\n", b.c_str(), c.c_str(), (b >>= c) ? "true" : "false");
1330  printf("(%s >>= %s) == %s\n", g.c_str(), h.c_str(), (g >>= h) ? "true" : "false");
1331  printf("(%s >>= %s) == %s\n", h.c_str(), g.c_str(), (h >>= g) ? "true" : "false");
1332  printf("(%s >>= %s) == %s\n", b.c_str(), aa.c_str(), (b >>= aa) ? "true" : "false");
1333 
1334  printf("\nIPPrefix::operator>>()\n");
1335  printf("(%s >> %s) == %s\n", a.c_str(), b.c_str(), (a >> b) ? "true" : "false");
1336  printf("(%s >> %s) == %s\n", b.c_str(), a.c_str(), (b >> a) ? "true" : "false");
1337  printf("(%s >> %s) == %s\n", b.c_str(), c.c_str(), (b >> c) ? "true" : "false");
1338  printf("(%s >> %s) == %s\n", g.c_str(), h.c_str(), (g >> h) ? "true" : "false");
1339  printf("(%s >> %s) == %s\n", h.c_str(), g.c_str(), (h >> g) ? "true" : "false");
1340  printf("(%s >> %s) == %s\n", b.c_str(), aa.c_str(), (b >> aa) ? "true" : "false");
1341 
1342  printf("\nIPPrefix::operator<<=()\n");
1343  printf("(%s <<= %s) == %s\n", a.c_str(), b.c_str(), (a <<= b) ? "true" : "false");
1344  printf("(%s <<= %s) == %s\n", b.c_str(), a.c_str(), (b <<= a) ? "true" : "false");
1345  printf("(%s <<= %s) == %s\n", b.c_str(), c.c_str(), (b <<= c) ? "true" : "false");
1346  printf("(%s <<= %s) == %s\n", g.c_str(), h.c_str(), (g <<= h) ? "true" : "false");
1347  printf("(%s <<= %s) == %s\n", h.c_str(), g.c_str(), (h <<= g) ? "true" : "false");
1348  printf("(%s <<= %s) == %s\n", b.c_str(), aa.c_str(), (b <<= aa) ? "true" : "false");
1349 
1350  printf("\nIPPrefix::operator<<()\n");
1351  printf("(%s << %s) == %s\n", a.c_str(), b.c_str(), (a << b) ? "true" : "false");
1352  printf("(%s << %s) == %s\n", b.c_str(), a.c_str(), (b << a) ? "true" : "false");
1353  printf("(%s << %s) == %s\n", b.c_str(), c.c_str(), (b << c) ? "true" : "false");
1354  printf("(%s << %s) == %s\n", g.c_str(), h.c_str(), (g << h) ? "true" : "false");
1355  printf("(%s << %s) == %s\n", h.c_str(), g.c_str(), (h << g) ? "true" : "false");
1356  printf("(%s << %s) == %s\n", b.c_str(), aa.c_str(), (b << aa) ? "true" : "false");
1357 
1358  printf("\nIPPrefix::getU32()\n");
1359  printf("%s => %u\n", a.c_str(), a.getU32());
1360  printf("%s => %u\n", b.c_str(), b.getU32());
1361  printf("%s => %u\n", e.c_str(), e.getU32());
1362  printf("%s => %u\n", h.c_str(), h.getU32());
1363 
1364  printf("\nIPPrefix::getHash()\n");
1365  printf("%s => %u\n", a.c_str(), a.getHash());
1366  printf("%s => %u\n", b.c_str(), b.getHash());
1367  printf("%s => %u\n", e.c_str(), e.getHash());
1368  printf("%s => %u\n", h.c_str(), h.getHash());
1369 
1370  printf("\nIPPrefix::getNetmask()\n");
1371  printf("%s => %s\n", a.c_str(), a.getNetmask().c_str());
1372  printf("%s => %s\n", b.c_str(), b.getNetmask().c_str());
1373  printf("%s => %s\n", d.c_str(), d.getNetmask().c_str());
1374  printf("%s => %s\n", e.c_str(), e.getNetmask().c_str());
1375  printf("%s => %s\n", h.c_str(), h.getNetmask().c_str());
1376 
1377  printf("\nIPPrefix::getInverseMask()\n");
1378  printf("%s => %s\n", a.c_str(), a.getInverseMask().c_str());
1379  printf("%s => %s\n", b.c_str(), b.getInverseMask().c_str());
1380  printf("%s => %s\n", d.c_str(), d.getInverseMask().c_str());
1381  printf("%s => %s\n", e.c_str(), e.getInverseMask().c_str());
1382  printf("%s => %s\n", h.c_str(), h.getInverseMask().c_str());
1383 
1384  printf("\nIPPrefix::getIPAddresses()\n");
1385  a = IPPrefix("192.168.50.0/29");
1386  auto addresses = a.getIPAddresses(true);
1387 
1388  for (auto ip = addresses.begin(); ip != addresses.end(); ++ip) {
1389  printf("%s => %s\n", a.c_str(), ip->c_str());
1390  }
1391 
1392  } catch (AddressException &e) {
1393  printf("AddressException: %s\n", e.what());
1394 
1395  exit(1);
1396  }
1397 
1398  printf("\n");
1399 }
1400 
1401 void testVariant(void) {
1402  using namespace sella::variant;
1403 
1404  printf("---------------------------\n");
1405  printf("- sella/variant/Variant.h -\n");
1406  printf("---------------------------\n");
1407 
1408  try {
1409  Variant vvv(std::make_shared<sv::Null>());
1410  printf("Variant:null => null: %s (%s)\n", vvv.c_str(), vvv.getTypeName());
1411 
1412  Variant n;
1413  Variant a(true);
1414  Variant b; b = false;
1415  Variant c; c = 1.23;
1416  Variant c2(1.23);
1417  Variant d("abc");
1418  Variant d2; d2 = "bogus"; d2 = std::string("bogusx");
1419  Variant e(-100);
1420  Variant e2 = e;
1421  Variant f(100);
1422  Variant v("[ 100, [ 200, \"str\" ], 300 ]", Variant::TypeAuto);
1423  Variant o("{ \"foo\": \"bar\", \"100\": 200 }", Variant::TypeAuto);
1424  Variant vv("[{ \"a\": 100, \"b\": { \"c\": [100,200] } }, 50.1,[ 200, \"aa\\\"bb\", [0,\f\r\n1, [ 2, \t3]]] ]", Variant::TypeAuto);
1425  Variant u(sella::util::UUID("35898CBD-BAC6-468b-a0cb-efa700954925"));
1426  Variant m;
1427 
1428  printf("Variant:cast<const std::string&> => null: %s (%s)\n", static_cast<const std::string &>(n).c_str(), n.getTypeName());
1429  printf("Variant:(const char*) => true: %s (%s)\n", (const char*) a, a.getTypeName());
1430  printf("Variant:c_str() => false: %s (%s)\n", b.c_str(), b.getTypeName());
1431  printf("Variant:operator+ => 2.25: %s (%s)\n", (++c + 0.02).c_str(), c.getTypeName());
1432  printf("Variant:contains() => true: %s\n", (d.contains("abc")) ? "true" : "false");
1433  printf("Variant:contains() => false: %s\n", (d.contains("zozo")) ? "true" : "false");
1434  printf("Variant:operator+ => abcabc: %s (%s)\n", (d + d).c_str(), d.getTypeName());
1435  printf("Variant:operator+ => abcxxx: %s (%s)\n", (d + "xxx").c_str(), d.getTypeName());
1436  printf("Variant:operator+ => abc100: %s (%s)\n", (d + 100).c_str(), d.getTypeName());
1437  printf("Variant:cast<int64_t> => -100: %" PRId64 " (%s)\n", e.cast<int64_t>(), e.getTypeName());
1438  printf("Variant:contains() => true: %s\n", (e.contains(-100)) ? "true" : "false");
1439  printf("Variant:contains() => false: %s\n", (e.contains(919)) ? "true" : "false");
1440  printf("Variant:cast<uint64_t> => 100: %" PRIu64 " (%s)\n", f.cast<uint64_t>(), f.getTypeName());
1441  printf("Variant:operator+ => 200: %" PRId64 " (%s)\n", static_cast<int64_t>(f + f), f.getTypeName());
1442  printf("Variant:operator+,/%%^ => 25: %" PRId64 " (%s)\n", static_cast<int64_t>((400 + f) / 100 % 10 ^ 2), f.getTypeName());
1443  printf("Variant:(int64_t) => 100: %" PRId64 " (%s)\n", (int64_t) f, f.getTypeName());
1444  printf("Variant:operator- => 99.0: %.1f (%s)\n", static_cast<double>(f - true), f.getTypeName());
1445  printf("Variant:c_str() => [ 100, [ 200, \"str\" ], 300 ]: %s (%s)\n", v.c_str(), v.getTypeName());
1446  printf("Variant:c_str() => { \"foo\": \"bar\", \"100\": 200 }: %s (%s)\n", o.c_str(), o.getTypeName());
1447  printf("Variant:c_str() => [ { messy } ]: %s (%s)\n", vv.c_str(), vv.getTypeName());
1448  printf("Variant:(const char*) => 35898cbd-bac6-468b-a0cb-efa700954925: %s (%s)\n", (const char*) u, u.getTypeName());
1449  u.shrink_to_fit();
1450  printf("Variant:contains() => true: %s\n", (u.contains(u)) ? "true" : "false");
1451  printf("Variant:contains() => false: %s\n", (u.contains("bogus")) ? "true" : "false");
1452  f.parse("216.136.9.22", Variant::TypeString);
1453  printf("Variant:(IPAddress) => 216.136.9.22: %s\n", f.cast<sella::net::IPAddress>().c_str());
1454  printf("Variant:(IPPrefix) => 216.136.9.22/32: %s\n", f.cast<sella::net::IPPrefix>().c_str());
1455  f = "150";
1456  f.setType(Variant::TypeDouble);
1457  printf("Variant:c_str() => 150.0: %s (%s)\n", f.c_str(), f.getTypeName());
1458  f.setType(Variant::TypeUnsigned);
1459  std::cout << "Variant:operator<< => 150: " << f << " (" << f.getTypeName() << ")" << std::endl;
1460 
1461  vv.clear();
1462  printf("Variant:clear() => null: %s (%s)\n", vv.c_str(), vv.getTypeName());
1463 
1464  printf("Variant:operator== => false: %s (%s == %s)\n", (c == c2) ? "true" : "false", c.c_str(), c2.c_str());
1465  printf("Variant:operator== => true: %s\n", (e == e2) ? "true" : "false");
1466  printf("Variant:operator!= => true: %s\n", (d != d2) ? "true" : "false");
1467  printf("Variant:operator== => false: %s\n", (b == c) ? "true" : "false");
1468  printf("Variant:operator!= => true: %s\n", (b != c) ? "true" : "false");
1469  printf("Variant:operator! => false: %s\n", (!c) ? "true" : "false");
1470  printf("Variant:operator>= => false: %s\n", (b >= a) ? "true" : "false");
1471  printf("Variant:operator<= => false: %s\n", (c <= c2) ? "true" : "false");
1472  printf("Variant:operator>= => true: %s\n", (b >= false) ? "true" : "false");
1473 
1474  m["foo"] = 100;
1475  m["bar"] = "zoo";
1476  m["nullptr"].clear();
1477 
1478  printf("Variant:c_str() => { \"bar\": \"zoo\", \"foo\": 100, \"nullptr\": null }: %s\n", m.c_str());
1479  printf("Variant:operator[] => 100: %s\n", m["foo"].c_str());
1480  printf("Variant:contains() => true: %s\n", (m.contains("foo")) ? "true" : "false");
1481  printf("Variant:contains() => false: %s\n", (m.contains("zzz")) ? "true" : "false");
1482 
1483  for (auto it = m.begin(); it != m.end(); ++it) {
1484  printf("Variant::iterator => Key: %s, value: %s\n", it.key().c_str(), it->c_str());
1485  }
1486 
1487  for (auto it = m.asMap().begin(); it != m.asMap().end(); ++it) {
1488  printf("Variant::asMap()::iterator => Key: %s, value: %s\n", it->first.c_str(), it->second.c_str());
1489  }
1490 
1491  v.clear();
1492  v[(size_t) 0] = 100;
1493  v[2] = 300;
1494  v[3] = 350;
1495  v.erase(3);
1496  v.push_back(400);
1497  v.erase("400"); /* pure virtual? */
1498  v += 500;
1499 
1500  for (Variant::iterator it = v.begin(); it != v.end(); ++it) {
1501  printf("Variant::iterator => value: %s\n", it->c_str());
1502  }
1503 
1504  for (auto it = v.asVector().begin(); it != v.asVector().end(); ++it) {
1505  printf("Variant::asVector()::iterator => value: %s\n", it->c_str());
1506  }
1507 
1508  printf("Variant:c_str() => [ 100, null, 300, 500 ]: %s\n", v.c_str());
1509  printf("Variant[2]:c_str() => 300: %s\n", v[2].c_str());
1510  printf("Variant:contains() => true: %s\n", (v.contains(100)) ? "true" : "false");
1511  printf("Variant:contains() => false: %s\n", (v.contains(919)) ? "true" : "false");
1512 
1513  Variant x("[ 1 2 3 ]", Variant::TypeJSON);
1514  Variant y("[ 4 5 6 ]", Variant::TypeJSON);
1515  Variant zz(std::move(std::string("string")));
1516  std::string z("string");
1517 
1518  x.push_back(std::move(y));
1519  x.push_back(std::move(z));
1520 
1521 // x.msgpack_buffer();
1522 
1523  const std::shared_ptr<Nullable> &xxx = x.get();
1524 
1525  printf("Variant::push_back(std::move()) => value: %s\n", xxx->str(Variant::JSON).c_str());
1526 
1527  c.clear();
1528  printf("Variant:empty() => true: %s\n", (c.empty()) ? "true" : "false");
1529  printf("Variant:empty() => false: %s\n", (m.empty()) ? "true" : "false");
1530 
1531  m.clear();
1532  m["test"] = 100; m.erase("test");
1533  printf("Variant:empty() => true: %s\n", (m.empty()) ? "true" : "false");
1534 
1535  f = 100;
1536  printf("Variant:c_str() => 101: %" PRIu64 " (%s)\n", (int64_t) ++f, f.getTypeName());
1537 
1538  f = 65535;
1539  printf("Variant:>> => 3: %" PRIu64 " (%s)\n", (int64_t) (f >> 14), f.getTypeName());
1540 
1541  printf("Variant:&& => true: %s\n", (m && f && true) ? "true" : "false");
1542 
1543  f = (void*) NULL;
1544  printf("Variant:NULL => null: %s (%s)\n", f.c_str(), f.getTypeName());
1545 
1546  std::string in("{ \"ipaddress\": \"216.136.9.22\", \"signed\": 10, \"string\": \"bob\", \"ipprefix\": \"216.136.9.0/24\", \"uuid\": \"35898CBD-BAC6-468b-a0cb-efa700954925\" }");
1547  f.parse(in, Variant::TypeAuto);
1548  printf("Variant:parse() => input: %s\n", in.c_str());
1549  printf("Variant:parse() => ipaddress: %s\n", f["ipaddress"].getTypeName());
1550  printf("Variant:parse() => ipprefix: %s\n", f["ipprefix"].getTypeName());
1551  printf("Variant:parse() => signed: %s\n", f["signed"].getTypeName());
1552  printf("Variant:parse() => string: %s\n", f["string"].getTypeName());
1553  printf("Variant:parse() => uuid: %s\n", f["uuid"].getTypeName());
1554  printf("Variant:parse() => output: %s\n", f.c_json());
1555 
1556  b.clear();
1557 
1558 #if 0 /* Does not work correctly. Need std::nullptr to make this work. */
1559  printf("Variant:operator== NULL => true: %s\n", (b == NULL) ? "true" : "false");
1560 #endif
1561  printf("Variant:isNull => true: %s\n", (b.isNull()) ? "true" : "false");
1562 
1563  Variant bin("0x01AABBCCEEFF");
1564 
1565  printf("Variant:c_str() => binary: %s (%s)\n", bin.c_str(), bin.getTypeName());
1566 
1567  Variant str2("{ \"x\": \"35898CBD-BAC6-468b-a0cb-efa700954925\" }", Variant::TypeAuto);
1568 
1569  str2["x"] = u;
1570 
1571  printf("str2: %s\n", str2.c_str());
1572 
1573  Variant ip("192.168.0.2");
1574  printf("ip: %s (%s)\n", ip.c_str(), ip.getTypeName());
1575 
1576  Variant ip2("2601:1:af00:28f:6a05:caff:fe0f:c55f");
1577  printf("ip2: %s (%s)\n", ip2.c_str(), ip2.getTypeName());
1578 
1579  Variant prefix("2601:1:af00:28f:6a05:caff:fe0f:c55f/64");
1580  printf("prefix: %s (%s)\n", prefix.c_str(), prefix.getTypeName());
1581 
1582  Variant prefix2("192.168.0.2/24");
1583  printf("prefix2: %s (%s)\n", prefix2.c_str(), prefix2.getTypeName());
1584 
1585  {
1586  Variant data("[ { \"foo\": \"bar\", \"yes\": true, \"nullptr\": null, \"sub\": { \"pi\": 3.14 }, \"zempty\": {} }, [ 1, null, 3 ]]", Variant::TypeJSON);
1587 
1588  printf("data.json(): %s\n", data.c_json());
1589  printf("data.cjson(): %s\n", data.c_cjson());
1590  printf("data.xml(): %s\n", data.c_xml());
1591  printf("data.csv(): %s\n", data.c_csv());
1592 
1593  data.unjson("[ {\"a\": 1, \"b\": 2}, {\"a\": 10, \"b\": 11} ]");
1594 
1595  printf("data.json(): %s\n", data.c_json());
1596  printf("data.cjson(): %s\n", data.c_cjson());
1597  printf("data.xml(): %s\n", data.c_xml());
1598  printf("data.csv(): %s\n", data.c_csv());
1599 
1600  {
1601  std::string buf, msg = data.msgpack();
1602  printf("data.unmsgpack(): %s\n", data.unmsgpack(msg).c_json());
1603 
1604  for (size_t i = 0; i < msg.size(); i++) {
1605  buf.append(su::String::sprintf("%02x ", (uint8_t) msg[i]));
1606  }
1607 
1608  printf("data.msgpack(): 0x %s\n", buf.c_str()); /* Use output with: http://msgpack-json-editor.com/ (offline as of 1/23/16) */
1609  printf("data.msgpack(): %zd bytes (vs json %zd bytes, vs cjson %zd bytes)\n", msg.size(), data.json().size(), data.cjson().size());
1610  printf("data.msgpackBufferSize(): %zd bytes\n", data.msgpackBufferSize());
1611 
1612  printf("data.unmsgpack(): %s\n", data.unmsgpack(msg).c_json());
1613  }
1614  }
1615 
1616  {
1617  uint8_t buffer[16384];
1618  uint32_t size = sizeof(buffer);
1619 
1620  Variant mpack(R"([ -500000, -44000, -3000, -2000, -1000, -300, -250, -160, -128, -127, -105, -90, -75, -60, -33, -10, -5, -1, 0, 1, 5, 33, 60, 75, 90, 105, 127, 128, 160, 250, 300, 1000, 2000, 3000, 44000, 500000 ])");
1621  //Variant mpack(R"([9999, { "foo": "bar", "pi": 3.14, "foofoo": [ 1, 2, 3.14, "ass" ] }])");
1622  //Variant mpack(R"([ { "a": 100, "b": { "c": [ 100, 200 ] } }, 50.100000, [ 200, "aa\"bb", [ 0, 1, [ 2, 3 ] ] ] ])");
1623 
1624  size_t len = mpack.msgpack(buffer, size);
1625 
1626  std::string buf((const char*) buffer, len);
1627  Variant out;
1628 
1629  out.unmsgpack(buf);
1630 
1631  printf("out: %s\n", out.c_str());
1632 
1633  Variant in;
1634 
1635  in.unmsgpack(buffer, len);
1636 
1637  printf("in-: %s\n", in.c_str());
1638 
1639  mpack.parse(R"([{ "version": 1, "action": "subscribe", "data": { "match": { "object": { "type": "ip-protocol", "value": "*" } }, "output": { "attributes": [ "ip", "protocol", "port", "bytes-tx", "bytes-rx", "packets-rx", "packets-tx" ] } }, "uuid": "53bdcadc-4258-4541-bbce-85afc8f18d6d" }])", Variant::TypeJSON);
1640  printf("test<: %s\n", mpack.c_json());
1641 
1642  len = mpack.msgpack(buffer, size);
1643  buf.assign((const char*) buffer, len);
1644 
1645  out.unmsgpack(buf);
1646  printf("test>: %s\n", out.c_json());
1647  }
1648  } catch (su::UUIDException &e) {
1649  printf("UUIDException: %s\n", e.what());
1650 
1651  exit(1);
1652  } catch (TypeCastException &e) {
1653  printf("TypeCastException: %s\n", e.what());
1654 
1655  exit(1);
1656  } catch (sella::Exception &e) {
1657  printf("sella::Exception: %s\n", e.what());
1658 
1659  exit(1);
1660  } catch (...) {
1661  printf("Unknown Exception\n");
1662 
1663  exit(1);
1664  }
1665 
1666  try {
1667  {
1668  std::string good = "216.136.9.0";
1669  std::string bad = "1.1.1.350";
1670 
1671  if (sv::IPAddress::isType(good) != boost::regex_match(good, sv::IPAddress::Pattern())) {
1672  printf("IPAddress::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::IPAddress::isType(good), boost::regex_match(good, sv::IPAddress::Pattern()), good.c_str());
1673  } else if (sv::IPAddress::isType(bad) != boost::regex_match(bad, sv::IPAddress::Pattern())) {
1674  printf("IPAddress::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::IPAddress::isType(good), boost::regex_match(good, sv::IPAddress::Pattern()), bad.c_str());
1675  }
1676  }
1677 
1678  {
1679  std::string good = "216.136.9.0/24";
1680  std::string bad = "1.1.1.350/24";
1681 
1682  if (sv::IPPrefix::isType(good) != boost::regex_match(good, sv::IPPrefix::Pattern())) {
1683  printf("IPPrefix::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::IPPrefix::isType(good), boost::regex_match(good, sv::IPPrefix::Pattern()), good.c_str());
1684  } else if (sv::IPPrefix::isType(bad) != boost::regex_match(bad, sv::IPPrefix::Pattern())) {
1685  printf("IPPrefix::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::IPPrefix::isType(good), boost::regex_match(good, sv::IPPrefix::Pattern()), bad.c_str());
1686  }
1687  }
1688 
1689  {
1690  std::string good = "+123456";
1691  std::string bad = "654foo";
1692 
1693  if (sv::Signed::isType(good) != boost::regex_match(good, sv::Signed::Pattern())) {
1694  printf("Signed::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Signed::isType(good), boost::regex_match(good, sv::Signed::Pattern()), good.c_str());
1695  } else if (sv::Signed::isType(bad) != boost::regex_match(bad, sv::Signed::Pattern())) {
1696  printf("Signed::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Signed::isType(good), boost::regex_match(good, sv::Signed::Pattern()), bad.c_str());
1697  }
1698  }
1699 
1700  {
1701  std::string good = "-1.1";
1702  std::string bad = "1.x";
1703 
1704  if (sv::Double::isType(good) != boost::regex_match(good, sv::Double::Pattern())) {
1705  printf("Double::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Double::isType(good), boost::regex_match(good, sv::Double::Pattern()), good.c_str());
1706  } else if (sv::Double::isType(bad) != boost::regex_match(bad, sv::Double::Pattern())) {
1707  printf("Double::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Double::isType(good), boost::regex_match(good, sv::Double::Pattern()), bad.c_str());
1708  }
1709  }
1710 
1711  {
1712  std::string good = "[ true ]";
1713  std::string bad = "[ 123 x";
1714 
1715  if (sv::Vector::isType(good) != boost::regex_match(good, sv::Vector::Pattern())) {
1716  printf("Vector::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Vector::isType(good), boost::regex_match(good, sv::Vector::Pattern()), good.c_str());
1717  } else if (sv::Vector::isType(bad) != boost::regex_match(bad, sv::Vector::Pattern())) {
1718  printf("Vector::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Vector::isType(good), boost::regex_match(good, sv::Vector::Pattern()), bad.c_str());
1719  }
1720  }
1721 
1722  {
1723  std::string good = "{ true }";
1724  std::string bad = "{ 123 }";
1725 
1726  if (sv::Object::isType(good) != boost::regex_match(good, sv::Object::Pattern())) {
1727  printf("Object::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Object::isType(good), boost::regex_match(good, sv::Object::Pattern()), good.c_str());
1728  } else if (sv::Object::isType(bad) != boost::regex_match(bad, sv::Object::Pattern())) {
1729  printf("Object::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Object::isType(good), boost::regex_match(good, sv::Object::Pattern()), bad.c_str());
1730  }
1731  }
1732 
1733  {
1734  std::string good = "false";
1735  std::string bad = "truX";
1736 
1737  if (sv::Boolean::isType(good) != boost::regex_match(good, sv::Boolean::Pattern())) {
1738  printf("Boolean::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Boolean::isType(good), boost::regex_match(good, sv::Boolean::Pattern()), good.c_str());
1739  } else if (sv::Boolean::isType(bad) != boost::regex_match(bad, sv::Boolean::Pattern())) {
1740  printf("Boolean::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Boolean::isType(good), boost::regex_match(good, sv::Boolean::Pattern()), bad.c_str());
1741  }
1742  }
1743 
1744  {
1745  std::string good = "\"str\"";
1746  std::string bad = "123";
1747 
1748  if (sv::String::isType(good) != boost::regex_match(good, sv::String::Pattern())) {
1749  printf("String::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::String::isType(good), boost::regex_match(good, sv::String::Pattern()), good.c_str());
1750  } else if (sv::String::isType(bad) != boost::regex_match(bad, sv::String::Pattern())) {
1751  printf("String::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::String::isType(good), boost::regex_match(good, sv::String::Pattern()), bad.c_str());
1752  }
1753  }
1754 
1755  {
1756  std::string good = "35898cbd-bac6-468b-a0cb-efa700954925";
1757  std::string bad = "cafe-babe";
1758 
1759  if (sv::UUID::isType(good) != boost::regex_match(good, sv::UUID::Pattern())) {
1760  printf("UUID::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::UUID::isType(good), boost::regex_match(good, sv::UUID::Pattern()), good.c_str());
1761  } else if (sv::UUID::isType(bad) != boost::regex_match(bad, sv::UUID::Pattern())) {
1762  printf("UUID::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::UUID::isType(good), boost::regex_match(good, sv::UUID::Pattern()), bad.c_str());
1763  }
1764  }
1765 
1766  {
1767  std::string good = "0xCAFEBABE";
1768  std::string bad = "donkey";
1769 
1770  if (sv::Binary::isType(good) != boost::regex_match(good, sv::Binary::Pattern())) {
1771  printf("Binary::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Binary::isType(good), boost::regex_match(good, sv::Binary::Pattern()), good.c_str());
1772  } else if (sv::Binary::isType(bad) != boost::regex_match(bad, sv::Binary::Pattern())) {
1773  printf("Binary::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Binary::isType(good), boost::regex_match(good, sv::Binary::Pattern()), bad.c_str());
1774  }
1775  }
1776 
1777  {
1778  std::string good = "null";
1779  std::string bad = "not";
1780 
1781  if (sv::Null::isType(good) != boost::regex_match(good, sv::Null::Pattern())) {
1782  printf("Null::isType() (%d) doesn't agree with pattern match (%d) on good value: %s\n", sv::Null::isType(good), boost::regex_match(good, sv::Null::Pattern()), good.c_str());
1783  } else if (sv::Null::isType(bad) != boost::regex_match(bad, sv::Null::Pattern())) {
1784  printf("Null::isType() (%d) doesn't agree with pattern match (%d) on bad value: %s\n", sv::Null::isType(good), boost::regex_match(good, sv::Null::Pattern()), bad.c_str());
1785  }
1786  }
1787 
1788  } catch (...) {
1789  printf("Unknown Exception\n");
1790 
1791  exit(1);
1792  }
1793 
1794  printf("\n");
1795 }
1796 
1797 namespace sella {
1798  namespace test {
1799  BUILD_EXCEPTION(TestException);
1800  }
1801 }
1802 
1803 void testException(void) {
1804  printf("---------------------\n");
1805  printf("- sella/Exception.h -\n");
1806  printf("---------------------\n");
1807 
1808  SET_FORMAT(MixedLogFormat());
1809 
1810  try {
1811  THROW(sella::test::TestException, "TestException test!");
1812  } catch (sella::test::TestException &e) {
1813  ERROR(e);
1814  WARNING(e);
1815 
1816  /* SWIG PERL functions. */
1817  INFO("code: %d, what: %s", e.getCode(), e.what());
1818 
1819  try {
1820  RETHROW2_CODE(sella::test::TestException, 200, e, "Added rethrow text.");
1821  } catch (sella::test::TestException &e) {
1822  ERROR(e);
1823  }
1824  }
1825 
1826  try {
1827  std::string x = "bobert";
1828  std::string y = "janert";
1829  THROW(sella::test::TestException, "TestException with Bob %s and Jane %s", x.c_str(), y.c_str());
1830  } catch (sella::test::TestException &e) {
1831  INFO("ExceptionName: %s", e.getName().c_str());
1832  ERROR(e);
1833  }
1834 
1835  SET_FORMAT(SimpleLogFormat());
1836 
1837  try {
1838  printf("\n");
1839  INFO("throwing...");
1840  THROW(sella::Exception, "Important message text!");
1841  } catch (sella::Exception &e) {
1842  INFO("caught...");
1843  try {
1844  RETHROW(sella::Exception, e);
1845  } catch (sella::Exception &e) {
1846  WARNING(e);
1847  }
1848  }
1849 
1850  try {
1851  printf("\n");
1852  INFO("throwing with code...");
1853  THROW_CODE(sella::Exception, 100, "Important message text!");
1854  } catch (sella::Exception &e) {
1855  INFO("caught...");
1856  try {
1857  RETHROW(sella::Exception, e);
1858  } catch (sella::Exception &e) {
1859  INFO("found code: %d", e.getCode());
1860  WARNING(e);
1861  }
1862  }
1863 
1864  printf("\n");
1865 }
1866 
1868  virtual void success(const std::string &qname, const std::string &cname, int ttl, const std::vector<std::string> &responses) throw () {
1869  if (cname.empty()) {
1870  INFO("DNS::resolve[async/success]: %s [ttl: %d]", this->qname.c_str(), ttl);
1871  } else {
1872  INFO("DNS::resolve[async/success]: %s <- %s [ttl: %d]", this->qname.c_str(), cname.c_str(), ttl);
1873  }
1874 
1875  for (auto r = responses.begin(); r != responses.end(); ++r) {
1876  INFO(" - response: %s", r->c_str());
1877  }
1878  }
1879 
1880  virtual void failure(const std::string &qname, Error error) throw () {
1881  INFO("DNS::resolve[async/failure](%s): %s => %s", qname.c_str(), getErrorName(error), getErrorDetail(error));
1882  }
1883 };
1884 
1885 void testDNS(void) {
1886  using namespace sella::net;
1887 
1888  printf("-------------------\n");
1889  printf("- sella/net/DNS.h -\n");
1890  printf("-------------------\n");
1891 
1892 // SET_TRACE(PACKAGE);
1893 // SET_TRACE(PACKAGE "-detail");
1894 
1895  try {
1896  if (1) { /* Sync */
1897  INFO("[Sync]");
1898  INFO("");
1899 
1900  DNS dns({ "127.0.0.1", "8.8.8.8" }, { "digital-genesis.com", "google.com" });
1901 
1902  INFO("DNS::resolve(www.google.com, DNS::AnyProtocol):");
1903  auto ipvx = dns.resolve("www.google.com", DNS::A, DNS::AnyProtocol);
1904  for (auto ip = ipvx.begin(); ip != ipvx.end(); ++ip) {
1905  INFO(" - response: %s", ip->c_str());
1906  }
1907 
1908  INFO("DNS::resolve(www.digital-genesis.com, DNS::IPv4Required):");
1909  auto ipv4a = dns.resolve("www.digital-genesis.com", DNS::A, DNS::IPv4Required);
1910  for (auto ip = ipv4a.begin(); ip != ipv4a.end(); ++ip) {
1911  INFO(" - response: %s", ip->c_str());
1912  }
1913 
1914  INFO("DNS::resolve(www, DNS::IPv4Preferred):");
1915  auto ipv4b = dns.resolve("www", DNS::A, DNS::IPv4Preferred);
1916  for (auto ip = ipv4b.begin(); ip != ipv4b.end(); ++ip) {
1917  INFO(" - response: %s", ip->c_str());
1918  }
1919 
1920  INFO("DNS::resolve(www.digital-genesis.com, DNS::IPv6Required):");
1921  auto ipv6a = dns.resolve("www.digital-genesis.com", DNS::A, DNS::IPv6Required);
1922  for (auto ip = ipv6a.begin(); ip != ipv6a.end(); ++ip) {
1923  INFO(" - response: %s", ip->c_str());
1924  }
1925 
1926  INFO("DNS::resolve(www.digital-genesis.com, DNS::IPv6Preferred):");
1927  auto ipv6b = dns.resolve("www.digital-genesis.com", DNS::A, DNS::IPv6Preferred);
1928  for (auto ip = ipv6b.begin(); ip != ipv6b.end(); ++ip) {
1929  INFO(" - response: %s", ip->c_str());
1930  }
1931 
1932  INFO("DNS::resolve(bogus.digital-genesis.com, DNS::AnyProtocol):");
1933  auto bogus = dns.resolve("bogus.digital-genesis.com", DNS::A, DNS::AnyProtocol);
1934  if (!bogus.empty()) {
1935  INFO(" - response: %s", bogus.front().c_str());
1936  } else {
1937  INFO(" - response: none");
1938  }
1939 
1940  INFO("");
1941  }
1942 
1943  if (1) {
1944  INFO("[Async - Callback]");
1945  INFO("");
1946 
1947  DNS dns({ "127.0.0.1", "8.8.8.8" }, { "digital-genesis.com", "google.com" });
1948  std::vector<TestCallback> callbacks(10);
1949 
1950  dns.setTimeout(1);
1951  dns.setNoSearch(true);
1952  dns.setAuthoritativeOnly(true);
1953 
1954  dns.resolve(&callbacks[0], "www.google.com", DNS::A, DNS::IPv4Preferred);
1955  dns.resolve(&callbacks[1], "bogus", DNS::A, DNS::IPv4Required);
1956  dns.resolve(&callbacks[2], "www.digital-genesis.com", DNS::A, DNS::IPv4Required);
1957  dns.resolve(&callbacks[3], "www.digital-genesis.com", DNS::A, DNS::IPv4Preferred);
1958  dns.resolve(&callbacks[4], "www.digital-genesis.com", DNS::A, DNS::IPv6Required);
1959  dns.resolve(&callbacks[5], "www.digital-genesis.com", DNS::A, DNS::IPv6Preferred);
1960  dns.resolve(&callbacks[6], "216.136.9.5", DNS::PTR);
1961  dns.resolve(&callbacks[7], "2607:fc88:100:9::33", DNS::PTR);
1962 
1963  while (dns.getActive() > 0) {
1964  dns.receive(250000);
1965  }
1966 
1967  INFO("");
1968  }
1969 
1970  if (1) {
1971  INFO("[Async - BulkResolve]");
1972  INFO("");
1973 
1974  DNS dns({ "127.0.0.1", "8.8.8.8" });
1975 
1976  INFO("DNS::resolve(ipv4.google.com, ipv6.google.com, www.google.com, DNS::AnyProtocol):");
1977  auto ipvx = dns.bulkResolve({ "ipv4.google.com", "ipv6.google.com", "www.google.com" }, DNS::A, DNS::AnyProtocol);
1978  for (auto ip = ipvx.begin(); ip != ipvx.end(); ++ip) {
1979  INFO(" - response: %s", ip->c_str());
1980  }
1981 
1982  INFO("");
1983  INFO("DNS::resolve(ipv4.google.com, ipv6.google.com, www.google.com, DNS::AnyProtocol):");
1984  auto v = dns.resolve({ "ipv4.google.com", "ipv6.google.com", "www.google.com" }, DNS::A, DNS::AnyProtocol);
1985 // auto v = dns.resolve(std::vector<std::string>({ "ipv6.google.com", "ipv4.google.com" }), DNS::AnyProtocol);
1986  for (auto i = v.begin(); i != v.end(); ++i) {
1987  INFO(" %s: [ttl: %d]", i.key().c_str(), (*i)["ttl"].cast<int>());
1988  for (auto ip = (*i)["response"].begin(); ip != (*i)["response"].end(); ++ip) {
1989  INFO(" - response: %s", ip->c_str());
1990  }
1991  }
1992  INFO(" raw: %s", v.c_json());
1993 
1994  INFO("");
1995  }
1996 
1997  if (1) {
1998  INFO("[Async - AnyProtocol]");
1999  INFO("");
2000 
2001  DNS dns({ "127.0.0.1", "8.8.8.8" });
2002 
2003  INFO("DNS::resolve(ipv4.google.com, DNS::AnyProtocol):");
2004  auto ipvx = dns.resolve("ipv4.google.com", DNS::A, DNS::AnyProtocol);
2005  for (auto ip = ipvx.begin(); ip != ipvx.end(); ++ip) {
2006  INFO(" - response: %s", ip->c_str());
2007  }
2008 
2009  INFO("DNS::resolve(ipv6.google.com, DNS::AnyProtocol):");
2010  auto ipvx2 = dns.resolve("ipv6.google.com", DNS::A, DNS::AnyProtocol);
2011  for (auto ip = ipvx2.begin(); ip != ipvx2.end(); ++ip) {
2012  INFO(" - response: %s", ip->c_str());
2013  }
2014 
2015  INFO("DNS::resolve(www.google.com, DNS::AnyProtocol):");
2016  auto ipvx3 = dns.resolve("www.google.com", DNS::A, DNS::AnyProtocol);
2017  for (auto ip = ipvx3.begin(); ip != ipvx3.end(); ++ip) {
2018  INFO(" - response: %s", ip->c_str());
2019  }
2020 
2021  INFO("");
2022  }
2023 
2024  if (1) { /* Async ThreadPool */
2025  using namespace sella::util;
2026 
2027  INFO("[Async - ThreadPool]");
2028  INFO("");
2029 
2030  ThreadPool pool(10);
2031  DNS dns(&pool, { "127.0.0.1", "8.8.8.8" }, { "digital-genesis.com" });
2032  std::vector<TestCallback> callbacks(10);
2033 
2034  dns.setTimeout(1);
2035 
2036  dns.resolve(&callbacks[0], "www.google.com", DNS::A, DNS::IPv4Preferred);
2037  dns.resolve(&callbacks[1], "bogus", DNS::A, DNS::IPv4Required);
2038  dns.resolve(&callbacks[2], "www.digital-genesis.com", DNS::A, DNS::IPv4Required);
2039  dns.resolve(&callbacks[3], "www.digital-genesis.com", DNS::A, DNS::IPv4Preferred);
2040  dns.resolve(&callbacks[4], "www.digital-genesis.com", DNS::A, DNS::IPv6Required);
2041  dns.resolve(&callbacks[5], "www.digital-genesis.com", DNS::A, DNS::IPv6Preferred);
2042  dns.resolve(&callbacks[6], "216.136.9.5", DNS::PTR);
2043  dns.resolve(&callbacks[7], "2607:fc88:100:9::33", DNS::PTR);
2044 
2045  INFO("Waiting for ThreadPool to complete all tasks.");
2046  pool.wait();
2047  INFO("ThreadPool has no remaining tasks");
2048  INFO("");
2049  }
2050 
2051  if (1) {
2052  INFO("[Async - SharedStore Callback]");
2053  INFO("");
2054 
2055  DNS dns({ "127.0.0.1", "8.8.8.8" }, { "digital-genesis.com", "google.com" });
2056 
2057  dns.setTimeout(1);
2058  dns.setNoSearch(true);
2059  dns.setAuthoritativeOnly(true);
2060 
2061  std::map<std::string, SharedStoreDNSCallback::result_t> results;
2062  std::vector<SharedStoreDNSCallback> callbacks(10, results);
2063 
2064  dns.resolve(&callbacks[0], "www.google.com", DNS::A, DNS::IPv4Preferred);
2065  dns.resolve(&callbacks[1], "bogus", DNS::A, DNS::IPv4Required);
2066  dns.resolve(&callbacks[2], "www.digital-genesis.com", DNS::A, DNS::IPv4Required);
2067  dns.resolve(&callbacks[3], "www.digital-genesis.com", DNS::A, DNS::IPv4Preferred);
2068  dns.resolve(&callbacks[4], "www.digital-genesis.com", DNS::A, DNS::IPv6Required);
2069  dns.resolve(&callbacks[5], "www.digital-genesis.com", DNS::A, DNS::IPv6Preferred);
2070  dns.resolve(&callbacks[6], "216.136.9.5", DNS::PTR);
2071  dns.resolve(&callbacks[7], "2607:fc88:100:9::33", DNS::PTR);
2072 
2073  while (dns.getActive() > 0) {
2074  dns.receive(250000);
2075  }
2076 
2077  for (auto r = results.begin(); r != results.end(); ++r) {
2078  const std::string &qname = r->first;
2079  const SharedStoreDNSCallback::result_t &result = r->second;
2080 
2081  if (result.error) {
2082  INFO("DNS::resolve[async/failure](%s): %s => %s", qname.c_str(), DNSCallback::getErrorName(result.error), DNSCallback::getErrorDetail(result.error));
2083  } else {
2084  if (result.cname.empty()) {
2085  INFO("DNS::resolve[async/success]: %s [ttl: %d]", qname.c_str(), result.ttl);
2086  } else {
2087  INFO("DNS::resolve[async/success]: %s <- %s [ttl: %d]", qname.c_str(), result.cname.c_str(), result.ttl);
2088  }
2089 
2090  for (auto r = result.responses.begin(); r != result.responses.end(); ++r) {
2091  INFO(" - response: %s", r->c_str());
2092  }
2093  }
2094  }
2095 
2096  INFO("");
2097  }
2098 
2099  } catch (DNSException &e) {
2100  WARNING(e);
2101  }
2102 
2103  printf("\n");
2104 }
2105 
2106 void example(int &s) {
2107 #if 0
2108  sleep(s);
2109 #else
2110  long i = 0; double res = 0;
2111  while (i < (s * 30000000LL)) { i++; res += sqrt(i); }
2112 #endif
2113 
2114  //INFO("task example(%d) - exiting", syscall(SYS_gettid));
2115 }
2116 
2117 void testThreadPool(void) {
2118  using namespace sella::util;
2119 
2120  printf("--------------------------\n");
2121  printf("- sella/util/ThreadPool.h -\n");
2122  printf("--------------------------\n");
2123 
2124  SET_TRACE(PACKAGE);
2125  SET_TRACE(PACKAGE "-detail");
2126 
2127  {
2128 #if 1
2129  ThreadPool pool(8, 2, 2); /* Scaling ThreadPool */
2130 #else
2131  ThreadPool pool(8); /* Simple non-scaling ThreadPool */
2132 #endif
2133  Task::shared task;
2134  Task::callback function;
2135 
2136  INFO("Setting ThreadPool CPU Affinity");
2137  pool.addCPUAffinity({2,99}); /* CPU 99 unlikely to exist on system */
2138 
2139  INFO("Pausing ThreadPool");
2140  pool.pause();
2141 
2142  /* Priority based tasks */
2143  for (size_t i = 0; i < 15; i++) {
2144  task = Task::shared_ptr();
2145  function = std::bind(&example, 2);
2146  task->setCallback(function);
2147 
2148  pool.schedule(task, 10 * i);
2149  }
2150 
2151  /* Delay based task */
2152  task = Task::shared_ptr();
2153  function = std::bind(&example, 1);
2154  task->setCallback(function);
2155 
2156  pool.schedule(task, std::chrono::seconds(2), 64);
2157 
2158  /* Timer based task */
2159  task = Task::shared_ptr();
2160  function = std::bind(&example, 1);
2161  task->setCallback(function);
2162 
2163  pool.schedule(task, std::chrono::system_clock::now(), 32);
2164 
2165  pool.print();
2166  usleep(10000);
2167 
2168  /* Resume pool workers */
2169  INFO("Resuming ThreadPool");
2170  pool.resume();
2171 
2172  sleep(2);
2173  pool.clearCPUAffinity({1,2});
2174 
2175  INFO("Waiting for ThreadPool to complete all tasks.");
2176  pool.wait();
2177  INFO("ThreadPool has no remaining tasks");
2178  }
2179 
2180  printf("\n");
2181 }
2182 
2183 void testSocketPair(void) {
2184  using namespace sella::net;
2185 
2186  printf("--------------------------\n");
2187  printf("- sella/net/SocketPair.h -\n");
2188  printf("--------------------------\n");
2189 
2190  SET_TRACE(PACKAGE);
2191  SET_TRACE(PACKAGE "-detail");
2192 
2193  try {
2194  SocketPair pair;
2195  UnixSocket::shared first = pair.getFirst();
2196  UnixSocket::shared second = pair.getSecond();
2197 
2198  printf("Send: test\n");
2199  first->send("test");
2200 
2201  std::string data;
2202  if (second->recv(data) > 0) {
2203  printf("Recv: %s\n", data.c_str());
2204  } else {
2205  printf("Recv: <empty>\n");
2206  }
2207 
2208  } catch (SocketException &e) {
2209  ERROR(e);
2210  }
2211 
2212  printf("\n");
2213 }
2214 
2215 void testSocketTrigger(void) {
2216  using namespace sella::net;
2217 
2218  printf("-----------------------------\n");
2219  printf("- sella/net/SocketTrigger.h -\n");
2220  printf("-----------------------------\n");
2221 
2222  SET_TRACE(PACKAGE);
2223  SET_TRACE(PACKAGE "-detail");
2224 
2225  try {
2226  SocketTrigger trigger;
2227 
2228  printf("trigger::isSet(): %d\n", trigger.isSet());
2229 
2230  printf("trigger::set() [2x]\n");
2231  trigger.set();
2232  trigger.set();
2233  printf("trigger::isSet(): %d\n", trigger.isSet());
2234 
2235  printf("trigger::clear()\n");
2236  trigger.clear();
2237  printf("trigger::isSet(): %d\n", trigger.isSet());
2238  } catch (SocketException &e) {
2239  ERROR(e);
2240  }
2241 
2242  printf("\n");
2243 }
2244 
2245 void testPipe(void) {
2246  using namespace sella::net;
2247 
2248  printf("--------------------\n");
2249  printf("- sella/net/Pipe.h -\n");
2250  printf("--------------------\n");
2251 
2252  SET_TRACE(PACKAGE);
2253  SET_TRACE(PACKAGE "-detail");
2254 
2255  try {
2256  std::string buf;
2257  Pipe pipe;
2258 
2259  printf("Write: test\n");
2260  pipe.write("test");
2261 
2262  if (pipe.read(buf) > 0) {
2263  printf("Read: %s\n", buf.c_str());
2264  } else {
2265  printf("Read: <empty>\n");
2266  }
2267  } catch (SocketException &e) {
2268  ERROR(e);
2269  }
2270 
2271  printf("\n");
2272 }
2273 
2274 void testRadixTree(void) {
2275  printf("--------------------------------\n");
2276  printf("- sella/container/radix_tree.h -\n");
2277  printf("--------------------------------\n");
2278 
2279  try {
2281 
2282  tree["sally"] = 7;
2283  tree["sally-joe"] = 9;
2284  tree["sally-may"] = 8;
2285  tree["jenny"] = 10;
2286  tree["susie"] = 6;
2287 
2288  printf("[tree]\n");
2289  for (auto t = tree.begin(), end = tree.end(); t != end; ++t) {
2290  printf(" %s => %d\n", t->first.c_str(), t->second);
2291  }
2292  printf("\n");
2293 
2294  printf("tree::contains(sally): %s ==> true\n", (tree.contains("sally")) ? "true" : "false");
2295  printf("tree::contains(veronica): %s ==> false\n", (tree.contains("veronica")) ? "true" : "false");
2296  printf("tree::contains(sally-joe): %s ==> true\n", (tree.contains("sally-joe")) ? "true" : "false");
2297 
2298  printf("tree::longest_match(sally-x): %d ==> 7\n", tree.longest_match("sally-x")->second);
2299  printf("tree::operator[](sally-joe): %d ==> 9\n", tree["sally-joe"]);
2300  printf("tree::at(jenny): %d ==> 10\n", tree.at("jenny"));
2301 
2302  try {
2303  printf("tree::at(veronica): %d ==> X\n", tree.at("veronica"));
2304  } catch (std::out_of_range &e) {
2305  printf("tree::at(veronica): std::out_of_range (not in tree)\n");
2306  }
2307  } catch (std::exception &e) {
2308  ERROR("%s", e.what());
2309  }
2310 
2311  printf("\n");
2312 }
2313 
2314 void testCedarTrie(void) {
2315  printf("-------------------------------\n");
2316  printf("- sella/container/CedarTrie.h -\n");
2317  printf("-------------------------------\n");
2318 
2319  try {
2321  int32_t v;
2322 
2323  trie.insert("sally", ::strlen("sally"), 7);
2324  trie.insert("sally-joe", 9);
2325  trie.insert(std::string("jenny"), 10);
2326 
2327  printf("trie::contains(sally): %s ==> true\n", (trie.contains("sally", strlen("sally"))) ? "true" : "false");
2328  printf("trie::contains(veronica): %s ==> false\n", (trie.contains("veronica")) ? "true" : "false");
2329  printf("trie::contains(sally-joe): %s ==> true\n", (trie.contains(std::string("sally-joe"))) ? "true" : "false");
2330 
2331  if (trie.lookup("sally", v)) {
2332  printf("trie::lookup(sally): %d ==> 7\n", v);
2333  }
2334  printf("trie::at(jenny): %d ==> 10\n", trie.at("jenny"));
2335 
2336  trie["emily"] = 8;
2337  printf("trie::operator[emily]: %d ==> 8\n", trie["emily"]);
2338 
2339  try {
2340  trie.insert("veronica", 2);
2341  trie.remove("veronica");
2342  printf("trie::at(veronica): %d ==> X\n", trie.at("veronica"));
2343  } catch (std::out_of_range &e) {
2344  printf("trie::at(veronica): std::out_of_range (not in trie)\n");
2345  }
2346  } catch (sella::Exception &e) {
2347  ERROR("%s", e.what());
2348  }
2349 
2350  printf("\n");
2351 }
2352 
2353 void testMessagePack(void) {
2354  printf("----------------------------\n");
2355  printf("- sella/util/MessagePack.h -\n");
2356  printf("----------------------------\n");
2357 
2358  try {
2359  uint8_t buf[64];
2360  uint32_t o = 0, len = sizeof(buf);
2361  uint8_t *b = buf;
2362 
2363  memset(b, 0, len);
2364 
2365  su::MessagePack mpack(b, len);
2366 
2367  o += mpack.append_object(o, 1);
2368 
2369  o += mpack.append(o, "key");
2370  o += mpack.append_vector(o, 0);
2371 
2372  printf("MessagePack::append(): %s\n", mpack.json().c_str());
2373 
2374  mpack.print(true);
2375  } catch (sella::Exception &e) {
2376  ERROR("%s", e.what());
2377  }
2378 
2379  printf("\n");
2380 }
2381 
2382 void testUUID(void) {
2383  printf("----------------------------\n");
2384  printf("- sella/util/UUID.h -\n");
2385  printf("----------------------------\n");
2386 
2387  try {
2388  su::UUID uuid;
2389 
2390  printf("UUID::c_str(): %s\n", uuid.c_str());
2391  printf("UUID::c_base64(true): %s\n", uuid.c_base64(true));
2392  printf("UUID::c_base64(false): %s\n", uuid.c_base64(false));
2393  } catch (sella::Exception &e) {
2394  ERROR("%s", e.what());
2395  }
2396 
2397  printf("\n");
2398 }
2399 
2400 /*
2401 ** vim: noet ts=3 sw=3
2402 */