1//
2// CoreTest.cpp
3//
4// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "CoreTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Bugcheck.h"
15#include "Poco/Exception.h"
16#include "Poco/Environment.h"
17#include "Poco/Thread.h"
18#include "Poco/Runnable.h"
19#include "Poco/Buffer.h"
20#include "Poco/FIFOBuffer.h"
21#include "Poco/AtomicCounter.h"
22#include "Poco/AtomicFlag.h"
23#include "Poco/Nullable.h"
24#include "Poco/Ascii.h"
25#include "Poco/BasicEvent.h"
26#include "Poco/Delegate.h"
27#include "Poco/Checksum.h"
28#include "Poco/MakeUnique.h"
29#include "Poco/Exception.h"
30#include <iostream>
31#include <sstream>
32#include <vector>
33#include <cstring>
34
35
36using Poco::Bugcheck;
37using Poco::Exception;
38using Poco::Environment;
39using Poco::Thread;
40using Poco::Runnable;
41using Poco::Buffer;
42using Poco::AtomicCounter;
43using Poco::AtomicFlag;
44using Poco::Nullable;
45using Poco::Ascii;
46using Poco::BasicEvent;
47using Poco::delegate;
48using Poco::NullType;
49using Poco::InvalidAccessException;
50using Poco::Checksum;
51using Poco::makeUnique;
52
53
54namespace
55{
56 class ACTRunnable: public Poco::Runnable
57 {
58 public:
59 ACTRunnable(AtomicCounter& counter):
60 _counter(counter)
61 {
62 }
63
64 void run()
65 {
66 for (int i = 0; i < 100000; ++i)
67 {
68 _counter++;
69 _counter--;
70 ++_counter;
71 --_counter;
72 }
73 }
74
75 private:
76 AtomicCounter& _counter;
77 };
78
79 class NonDefaultConstructible
80 {
81 public:
82 NonDefaultConstructible(int val) : _val(val)
83 {
84 }
85
86 NonDefaultConstructible& operator=(int val)
87 {
88 _val = val;
89 return *this;
90 }
91
92 bool operator == (const NonDefaultConstructible& other) const
93 {
94 return (_val == other._val);
95 }
96
97 bool operator < (const NonDefaultConstructible& other) const
98 {
99 return (_val < other._val);
100 }
101
102 int value() const
103 {
104 return _val;
105 }
106
107 private:
108 NonDefaultConstructible();
109 int _val;
110 };
111}
112
113
114class Small
115{
116};
117
118
119struct Parent
120{
121 Parent() { i = -1; }
122 virtual ~Parent() { i= -2; }
123
124 static int i;
125};
126
127
128int Parent::i = 0;
129
130
131struct Medium : public Parent
132{
133};
134
135
136struct Large
137{
138 Large() : i(1), j(2), k(3), l(4) { }
139 long i,j,k;
140 const long l;
141};
142
143
144//
145// The bugcheck test is normally disabled, as it
146// causes a break into the debugger.
147//
148#define ENABLE_BUGCHECK_TEST 0
149
150
151CoreTest::CoreTest(const std::string& rName): CppUnit::TestCase(rName)
152{
153}
154
155
156CoreTest::~CoreTest()
157{
158}
159
160
161void CoreTest::testPlatform()
162{
163 std::cout << "POCO_OS: " << POCO_OS << std::endl;
164 std::cout << "POCO_ARCH: " << POCO_ARCH << std::endl;
165}
166
167
168void CoreTest::testFixedLength()
169{
170 assertTrue (sizeof(Poco::Int8) == 1);
171 assertTrue (sizeof(Poco::UInt8) == 1);
172 assertTrue (sizeof(Poco::Int16) == 2);
173 assertTrue (sizeof(Poco::UInt16) == 2);
174 assertTrue (sizeof(Poco::Int32) == 4);
175 assertTrue (sizeof(Poco::UInt32) == 4);
176#if defined(POCO_HAVE_INT64)
177 assertTrue (sizeof(Poco::Int64) == 8);
178 assertTrue (sizeof(Poco::UInt64) == 8);
179#endif
180 assertTrue (sizeof(Poco::IntPtr) == sizeof(void*));
181 assertTrue (sizeof(Poco::UIntPtr) == sizeof(void*));
182}
183
184
185void CoreTest::testBugcheck()
186{
187#if ENABLE_BUGCHECK_TEST
188 try
189 {
190 Bugcheck::assertion("test", __FILE__, __LINE__);
191 failmsg("must throw exception");
192 }
193 catch (Exception&)
194 {
195 }
196
197 try
198 {
199 Bugcheck::nullPointer("test", __FILE__, __LINE__);
200 failmsg("must throw exception");
201 }
202 catch (Exception&)
203 {
204 }
205
206 try
207 {
208 Bugcheck::bugcheck("test", __FILE__, __LINE__);
209 failmsg("must throw exception");
210 }
211 catch (Exception&)
212 {
213 }
214#endif
215}
216
217
218void CoreTest::testEnvironment()
219{
220#if !defined(_WIN32_WCE)
221 Environment::set("FOO", "BAR");
222 assertTrue (Environment::has("FOO"));
223 assertTrue (Environment::get("FOO") == "BAR");
224#endif
225 try
226 {
227 std::string v = Environment::get("THISONEDOESNOTEXIST123");
228 failmsg("Environment variable does not exist - must throw exception");
229 }
230 catch (Exception&)
231 {
232 }
233 std::cout << std::endl;
234 std::cout << "OS Name: " << Environment::osName() << std::endl;
235 std::cout << "OS Display Name: " << Environment::osDisplayName() << std::endl;
236 std::cout << "OS Version: " << Environment::osVersion() << std::endl;
237 std::cout << "OS Architecture: " << Environment::osArchitecture() << std::endl;
238 std::cout << "Node Name: " << Environment::nodeName() << std::endl;
239 std::cout << "Node ID: " << Environment::nodeId() << std::endl;
240 std::cout << "Number of CPUs: " << Environment::processorCount() << std::endl;
241}
242
243
244void CoreTest::testBuffer()
245{
246 std::size_t s = 10;
247 Buffer<int> b(s);
248 assertTrue (b.size() == s);
249 assertTrue (b.sizeBytes() == s * sizeof(int));
250 assertTrue (b.capacity() == s);
251 assertTrue (b.capacityBytes() == s * sizeof(int));
252 std::vector<int> v;
253 for (int i = 0; i < s; ++i)
254 v.push_back(i);
255
256 std::memcpy(b.begin(), &v[0], sizeof(int) * v.size());
257
258 assertTrue (s == b.size());
259 for (int i = 0; i < s; ++i)
260 assertTrue (b[i] == i);
261
262 b.resize(s/2);
263 for (int i = 0; i < s/2; ++i)
264 assertTrue (b[i] == i);
265
266 assertTrue (b.size() == s/2);
267 assertTrue (b.capacity() == s);
268
269 b.resize(s*2);
270 v.clear();
271 for (int i = 0; i < s*2; ++i)
272 v.push_back(i);
273
274 std::memcpy(b.begin(), &v[0], sizeof(int) * v.size());
275
276 for (int i = 0; i < s*2; ++i)
277 assertTrue (b[i] == i);
278
279 assertTrue (b.size() == s*2);
280 assertTrue (b.capacity() == s*2);
281
282 b.setCapacity(s * 4);
283 assertTrue (b.size() == s*2);
284 assertTrue (b.capacity() == s*4);
285
286 b.setCapacity(s);
287 assertTrue (b.size() == s);
288 assertTrue (b.capacity() == s);
289
290#if ENABLE_BUGCHECK_TEST
291 try { int i = b[s]; fail ("must fail"); }
292 catch (Exception&) { }
293#endif
294
295 Buffer<int> c(s);
296 Buffer<int> d(c);
297 assertTrue (c == d);
298
299 c[1] = -1;
300 assertTrue (c[1] == -1);
301 c.clear();
302 assertTrue (c[1] == 0);
303
304 Buffer<int> e(0);
305 assertTrue (e.empty());
306
307 assertTrue (c != e);
308
309 Buffer<int> f = e;
310 assertTrue (f == e);
311
312 Buffer<char> g(0);
313 g.append("hello", 5);
314 assertTrue (g.size() == 5);
315
316 g.append("hello", 5);
317 assertTrue (g.size() == 10);
318 assertTrue ( !std::memcmp(g.begin(), "hellohello", 10) );
319
320 char h[10];
321 Buffer<char> buf(h, 10);
322 try
323 {
324 buf.append("hello", 5);
325 fail ("must fail");
326 }
327 catch (InvalidAccessException&) { }
328
329 buf.assign("hello", 5);
330 assertTrue ( !std::memcmp(&h[0], "hello", 5) );
331
332 const char j[10] = "hello";
333 Buffer<char> k(j, 5);
334 k.append("hello", 5);
335 assertTrue ( !std::memcmp(&j[0], "hello", 5) );
336 assertTrue ( !std::memcmp(k.begin(), "hellohello", 10) );
337 k.append('w');
338 assertTrue (k.size() == 11);
339 assertTrue ( !std::memcmp(k.begin(), "hellohellow", k.size()) );
340 k.append('o');
341 assertTrue (k.size() == 12);
342 assertTrue ( !std::memcmp(k.begin(), "hellohellowo", k.size()) );
343 k.append('r');
344 assertTrue (k.size() == 13);
345 assertTrue ( !std::memcmp(k.begin(), "hellohellowor", k.size()) );
346 k.append('l');
347 assertTrue (k.size() == 14);
348 assertTrue ( !std::memcmp(k.begin(), "hellohelloworl", k.size()) );
349 k.append('d');
350 assertTrue (k.size() == 15);
351 assertTrue ( !std::memcmp(k.begin(), "hellohelloworld", k.size()) );
352
353 char my[16];
354 Poco::Buffer<char> buffer(16);
355 Poco::Buffer<char> wrapper(my, sizeof(my));
356 buffer.swap(wrapper);
357}
358
359
360void CoreTest::testAtomicCounter()
361{
362 AtomicCounter ac(0);
363
364 assertTrue (ac.value() == 0);
365 assertTrue (ac++ == 0);
366 assertTrue (ac-- == 1);
367 assertTrue (++ac == 1);
368 assertTrue (--ac == 0);
369
370 ac = 2;
371 assertTrue (ac.value() == 2);
372
373 ac = 0;
374 assertTrue (ac.value() == 0);
375
376 AtomicCounter ac2(2);
377 assertTrue (ac2.value() == 2);
378
379 ACTRunnable act(ac);
380 Thread t1;
381 Thread t2;
382 Thread t3;
383 Thread t4;
384 Thread t5;
385
386 t1.start(act);
387 t2.start(act);
388 t3.start(act);
389 t4.start(act);
390 t5.start(act);
391
392 t1.join();
393 t2.join();
394 t3.join();
395 t4.join();
396 t5.join();
397
398 assertTrue (ac.value() == 0);
399}
400
401
402void CoreTest::testAtomicFlag()
403{
404 AtomicFlag f;
405 assertTrue(!f);
406 assertFalse(!f);
407 assertTrue(f);
408 f.reset();
409 assertFalse(f);
410 assertTrue(f);
411 assertFalse(!f);
412}
413
414
415void CoreTest::testNullable()
416{
417 Nullable<NonDefaultConstructible> ndc1;
418 Nullable<NonDefaultConstructible> ndc2;
419 assertTrue (ndc1.isNull());
420 assertTrue (ndc2.isNull());
421 assertTrue (ndc1 == ndc2);
422 assertTrue (!(ndc1 != ndc2));
423 assertTrue (!(ndc1 > ndc2));
424 bool ge = (ndc1 >= ndc2);
425 assertTrue (ndc1 >= ndc2);
426 assertTrue (!(ndc1 < ndc2));
427 assertTrue (ndc1 <= ndc2);
428 ndc1 = 42;
429 assertTrue (!ndc1.isNull());
430 assertTrue (ndc1.value() == 42);
431
432 Nullable<int> i;
433 Nullable<double> f;
434 Nullable<std::string> s;
435
436 assertTrue (i.isNull());
437 assertTrue (f.isNull());
438 assertTrue (s.isNull());
439
440 i = 1;
441 f = 1.5;
442 s = "abc";
443
444 assertTrue (!i.isNull());
445 assertTrue (!f.isNull());
446 assertTrue (!s.isNull());
447
448 assertTrue (i == 1);
449 assertTrue (f == 1.5);
450 assertTrue (s == "abc");
451
452 i.clear();
453 f.clear();
454 s.clear();
455
456 assertTrue (i.isNull());
457 assertTrue (f.isNull());
458 assertTrue (s.isNull());
459
460 Nullable<int> n1;
461 assertTrue (n1.isNull());
462
463 assertTrue (n1.value(42) == 42);
464 assertTrue (n1.isNull());
465 assertTrue (!(0 == n1));
466 assertTrue (0 != n1);
467 assertTrue (!(n1 == 0));
468 assertTrue (n1 != 0);
469
470 try
471 {
472 int tmp = n1.value();
473 fail("null value, must throw");
474 }
475 catch (Poco::NullValueException&)
476 {
477 }
478
479 n1 = 1;
480 assertTrue (!n1.isNull());
481 assertTrue (n1.value() == 1);
482
483 Nullable<int> n2(42);
484 assertTrue (!n2.isNull());
485 assertTrue (n2.value() == 42);
486 assertTrue (n2.value(99) == 42);
487
488 assertTrue (!(0 == n2));
489 assertTrue (0 != n2);
490 assertTrue (!(n2 == 0));
491 assertTrue (n2 != 0);
492
493 n1 = n2;
494 assertTrue (!n1.isNull());
495 assertTrue (n1.value() == 42);
496
497 std::ostringstream str;
498 str << n1;
499 assertTrue (str.str() == "42");
500
501 n1.clear();
502 assertTrue (n1.isNull());
503
504 str.str(""); str << n1;
505 assertTrue (str.str().empty());
506
507 n2.clear();
508 assertTrue (n1 == n2);
509 n1 = 1; n2 = 1;
510 assertTrue (n1 == n2);
511 n1.clear();
512 assertTrue (n1 < n2);
513 assertTrue (n2 > n1);
514 n2 = -1; n1 = 0;
515 assertTrue (n2 < n1);
516 assertTrue (n2 != n1);
517 assertTrue (n1 > n2);
518
519 NullType nd;
520 assertTrue (n1 != nd);
521 assertTrue (nd != n1);
522 n1.clear();
523 assertTrue (n1 == nd);
524 assertTrue (nd == n1);
525}
526
527
528void CoreTest::testAscii()
529{
530 assertTrue (Ascii::isAscii('A'));
531 assertTrue (!Ascii::isAscii(-1));
532 assertTrue (!Ascii::isAscii(128));
533 assertTrue (!Ascii::isAscii(222));
534
535 assertTrue (Ascii::isSpace(' '));
536 assertTrue (Ascii::isSpace('\t'));
537 assertTrue (Ascii::isSpace('\r'));
538 assertTrue (Ascii::isSpace('\n'));
539 assertTrue (!Ascii::isSpace('A'));
540 assertTrue (!Ascii::isSpace(-1));
541 assertTrue (!Ascii::isSpace(222));
542
543 assertTrue (Ascii::isDigit('0'));
544 assertTrue (Ascii::isDigit('1'));
545 assertTrue (Ascii::isDigit('2'));
546 assertTrue (Ascii::isDigit('3'));
547 assertTrue (Ascii::isDigit('4'));
548 assertTrue (Ascii::isDigit('5'));
549 assertTrue (Ascii::isDigit('6'));
550 assertTrue (Ascii::isDigit('7'));
551 assertTrue (Ascii::isDigit('8'));
552 assertTrue (Ascii::isDigit('9'));
553 assertTrue (!Ascii::isDigit('a'));
554
555 assertTrue (Ascii::isHexDigit('0'));
556 assertTrue (Ascii::isHexDigit('1'));
557 assertTrue (Ascii::isHexDigit('2'));
558 assertTrue (Ascii::isHexDigit('3'));
559 assertTrue (Ascii::isHexDigit('4'));
560 assertTrue (Ascii::isHexDigit('5'));
561 assertTrue (Ascii::isHexDigit('6'));
562 assertTrue (Ascii::isHexDigit('7'));
563 assertTrue (Ascii::isHexDigit('8'));
564 assertTrue (Ascii::isHexDigit('9'));
565 assertTrue (Ascii::isHexDigit('a'));
566 assertTrue (Ascii::isHexDigit('b'));
567 assertTrue (Ascii::isHexDigit('c'));
568 assertTrue (Ascii::isHexDigit('d'));
569 assertTrue (Ascii::isHexDigit('e'));
570 assertTrue (Ascii::isHexDigit('f'));
571 assertTrue (Ascii::isHexDigit('A'));
572 assertTrue (Ascii::isHexDigit('B'));
573 assertTrue (Ascii::isHexDigit('C'));
574 assertTrue (Ascii::isHexDigit('D'));
575 assertTrue (Ascii::isHexDigit('E'));
576 assertTrue (Ascii::isHexDigit('F'));
577 assertTrue (!Ascii::isHexDigit('G'));
578
579 assertTrue (Ascii::isPunct('.'));
580 assertTrue (Ascii::isPunct(','));
581 assertTrue (!Ascii::isPunct('A'));
582
583 assertTrue (Ascii::isAlpha('a'));
584 assertTrue (Ascii::isAlpha('Z'));
585 assertTrue (!Ascii::isAlpha('0'));
586
587 assertTrue (Ascii::isLower('a'));
588 assertTrue (!Ascii::isLower('A'));
589
590 assertTrue (Ascii::isUpper('A'));
591 assertTrue (!Ascii::isUpper('a'));
592
593 assertTrue (Ascii::toLower('A') == 'a');
594 assertTrue (Ascii::toLower('z') == 'z');
595 assertTrue (Ascii::toLower('0') == '0');
596
597 assertTrue (Ascii::toUpper('a') == 'A');
598 assertTrue (Ascii::toUpper('0') == '0');
599 assertTrue (Ascii::toUpper('Z') == 'Z');
600}
601
602
603void CoreTest::testChecksum64()
604{
605 Poco::Checksum checksum64_0(Checksum::TYPE_CRC64);
606 Poco::Checksum checksum64_1(Checksum::TYPE_CRC64);
607 Poco::UInt64 crc64_0 = 0;
608 Poco::UInt64 crc64_1 = 0;
609 Poco::UInt64 crc64_2 = 0;
610 Poco::UInt64 crc64_3 = 0;
611 Poco::UInt64 crc64_4 = 0;
612 Poco::UInt64 crc64_5 = 0;
613 Poco::UInt64 crc64_6 = 0;
614 Poco::UInt64 crc64_7 = 0;
615 std::string str = "Hello world!!!";
616 const char c_str[] = "Hello People!!!";
617 const char c_str1[] = "Hello world!!!";
618 const char c_str2[] = "b";
619 const char c_str3[] = "c";
620 char ch = 'c';
621
622 checksum64_0.update(str);
623 crc64_0 = checksum64_0.checksum(); // crc64 of "Hello world!!!"
624 checksum64_0.update(c_str, (int)strlen(c_str));
625 crc64_1 = checksum64_0.checksum(); // crc64 of "Hello People!!!"
626 assertTrue (crc64_0 != crc64_1);
627
628 checksum64_0.update(ch);
629 crc64_2 = checksum64_0.checksum(); // crc64 of 'c'
630 assertTrue (crc64_0 != crc64_2);
631
632 assertTrue (crc64_1 != crc64_2);
633
634 checksum64_0.update(c_str1);
635 crc64_3 = checksum64_0.checksum(); // crc64 of "Hello world!!!"
636 assertTrue (crc64_0 == crc64_3);
637
638 str = "c";
639 checksum64_0.update(str);
640 crc64_4 = checksum64_0.checksum(); // crc64 of "c", fetching from checksum64_0 object
641 checksum64_1.update(ch);
642 crc64_5 = checksum64_1.checksum(); // crc64 of 'c', fetching from checksum64_1 object
643 assertTrue (crc64_4 == crc64_5);
644
645 checksum64_0.update(c_str2, (int)strlen(c_str2));
646 crc64_6 = checksum64_0.checksum(); // crc64 of "b", fetching from checksum64_0 object
647 assertTrue (crc64_5 != crc64_6);
648
649 checksum64_0.update(c_str3, (int)strlen(c_str3));
650 crc64_7 = checksum64_0.checksum(); // crc64 of "c", fetching from checksum64_0 object
651 assertTrue (crc64_5 == crc64_7);
652}
653
654
655void CoreTest::testMakeUnique()
656{
657 assertTrue (*makeUnique<int>() == 0);
658 assertTrue (*makeUnique<int>(1729) == 1729);
659 assertTrue (*makeUnique<std::string>() == "");
660 assertTrue (*makeUnique<std::string>("meow") == "meow");
661 assertTrue (*makeUnique<std::string>(6, 'z') == "zzzzzz");
662
663 auto up = makeUnique<int[]>(5);
664
665 for (int i = 0; i < 5; ++i) up[i] = i;
666 for (int i = 0; i < 5; ++i) assertTrue (up[i] == i);
667}
668
669
670void CoreTest::setUp()
671{
672 _readableToNot = 0;
673 _notToReadable = 0;
674 _writableToNot = 0;
675 _notToWritable = 0;
676}
677
678
679void CoreTest::tearDown()
680{
681}
682
683
684CppUnit::Test* CoreTest::suite()
685{
686 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("CoreTest");
687
688 CppUnit_addTest(pSuite, CoreTest, testPlatform);
689 CppUnit_addTest(pSuite, CoreTest, testFixedLength);
690 CppUnit_addTest(pSuite, CoreTest, testBugcheck);
691 CppUnit_addTest(pSuite, CoreTest, testEnvironment);
692 CppUnit_addTest(pSuite, CoreTest, testBuffer);
693 CppUnit_addTest(pSuite, CoreTest, testAtomicCounter);
694 CppUnit_addTest(pSuite, CoreTest, testAtomicFlag);
695 CppUnit_addTest(pSuite, CoreTest, testNullable);
696 CppUnit_addTest(pSuite, CoreTest, testAscii);
697 CppUnit_addTest(pSuite, CoreTest, testChecksum64);
698 CppUnit_addTest(pSuite, CoreTest, testMakeUnique);
699
700 return pSuite;
701}
702