Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2017-01-04 20:07:12 +0000
committerHenrik Rentz-Reichert2017-01-09 16:41:16 +0000
commit9b02d5a62ea41136b46b744f7b2c1cf50f30a888 (patch)
treed7473847da1a9e3a470195f384f62322b48057db /tests/org.eclipse.etrice.runtime.cpp.tests
parentb8fd69cd558c0673971bcdaea495131bc4d7cd82 (diff)
downloadorg.eclipse.etrice-9b02d5a62ea41136b46b744f7b2c1cf50f30a888.tar.gz
org.eclipse.etrice-9b02d5a62ea41136b46b744f7b2c1cf50f30a888.tar.xz
org.eclipse.etrice-9b02d5a62ea41136b46b744f7b2c1cf50f30a888.zip
Bug 509875 - [runtime.cpp] replace STL containers with own containers that are more light weight
* replaced streaming code with (s)printf constructs * added String, Vector, Set, Pair and Map with tests * using new String class in * Address * Message * MSCFilter * MSCLogger * RTObject * and affected classes * using new Vector class in * RTObject * MSCLogger * MessageServiceController * ReplicatedActorClassBase * ReplicatedInterfaceItemBase * and affected classes * using new Set class in * MessageDispatcher * using new Map class in * SubSystemClassBase * DebuggingService * adjusted cpp generator Change-Id: I9c91289057185e6e36b9453ecf03f6f6d3834ec6
Diffstat (limited to 'tests/org.eclipse.etrice.runtime.cpp.tests')
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/RunAllTestCases.cpp32
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.cpp53
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.h36
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.cpp61
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.h35
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.cpp106
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.h36
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.cpp121
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.h35
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.cpp86
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.h36
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.cpp50
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.h6
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/MSCLoggerTest.cpp45
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.cpp16
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.h4
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageServiceTest.h2
-rw-r--r--tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/RTObjectTest.cpp18
18 files changed, 715 insertions, 63 deletions
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/RunAllTestCases.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/RunAllTestCases.cpp
index 3a9a7be59..322ca7a2c 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/RunAllTestCases.cpp
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/RunAllTestCases.cpp
@@ -10,9 +10,15 @@
*
*******************************************************************************/
-#include <containers/StaticDequeTest.h>
+#include "common/containers/Set.h"
+#include "containers/SetTest.h"
+#include "containers/StaticDequeTest.h"
#include "containers/StaticArrayTest.h"
#include "containers/StaticStringTest.h"
+#include "containers/StringTest.h"
+#include "containers/VectorTest.h"
+#include "containers/PairTest.h"
+#include "containers/MapTest.h"
#include "debugging/MSCFunctionObjectTest.h"
#include "debugging/MSCFilterTest.h"
#include "debugging/MSCLoggerTest.h"
@@ -41,6 +47,21 @@ int main() {
StaticDequeTest dequeTest;
dequeTest.run();
+ StringTest stringTest;
+ stringTest.run();
+
+ VectorTest vectorTest;
+ vectorTest.run();
+
+ SetTest setTest;
+ setTest.run();
+
+ PairTest pairTest;
+ pairTest.run();
+
+ MapTest mapTest;
+ mapTest.run();
+
// Test debugging
MSCFilterTest filterTest;
filterTest.run();
@@ -81,6 +102,15 @@ int main() {
etUnit_close();
+ printf("String allocations %d and deallocations %d\n", etRuntime::String::getNAllocations(), etRuntime::String::getNDeallocations());
+ printf("String creations %d and destructions %d\n", etRuntime::String::getNCreated(), etRuntime::String::getNDestroyed());
+ printf("Vector allocations %d and deallocations %d\n", etRuntime::VectorStats::getNAllocations(), etRuntime::VectorStats::getNDeallocations());
+ printf("Vector creations %d and destructions %d\n", etRuntime::VectorStats::getNCreated(), etRuntime::VectorStats::getNDestroyed());
+ printf("Set creations %d and destructions %d\n", etRuntime::SetStats::getNCreated(), etRuntime::SetStats::getNDestroyed());
+ printf("Map creations %d and destructions %d\n", etRuntime::MapStats::getNCreated(), etRuntime::MapStats::getNDestroyed());
+
+ fflush(stdout);
+
return 0;
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.cpp
new file mode 100644
index 000000000..21c9cbc89
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.cpp
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "MapTest.h"
+
+#include "common/containers/Map.h"
+#include "common/containers/String.h"
+#include "util/etAssert.h"
+
+using namespace etRuntime;
+
+void MapTest::testConstructors(void) {
+ Map<int, String> m1;
+ EXPECT_TRUE(m_caseId, "map is empty", m1.empty());
+ EXPECT_EQUAL_INT32(m_caseId, "map size is 0", 0, m1.size());
+
+ m1[2] = "two";
+ EXPECT_TRUE(m_caseId, "map is not empty", !m1.empty());
+ EXPECT_EQUAL_INT32(m_caseId, "map size is 1", 1, m1.size());
+
+ // copy constructor
+ Map<int, String> m2(m1);
+ EXPECT_TRUE(m_caseId, "map is not empty", !m2.empty());
+ EXPECT_EQUAL_INT32(m_caseId, "map size is 1", 1, m2.size());
+}
+
+void MapTest::testSettersAndGetters(void) {
+ Map<int, String> m1;
+ m1[2] = "two";
+ m1[1] = "one";
+
+ EXPECT_EQUAL_INT32(m_caseId, "map size is 2", 2, m1.size());
+ EXPECT_TRUE(m_caseId, "map[1]=='one'", m1[1]=="one");
+ EXPECT_TRUE(m_caseId, "map[2]=='two'", m1[2]=="two");
+}
+
+void MapTest::testOperators(void) {
+}
+
+void MapTest::runAllTestCases() {
+ ADD_TESTCASE_CPP(testConstructors)
+ ADD_TESTCASE_CPP(testSettersAndGetters)
+ ADD_TESTCASE_CPP(testOperators)
+}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.h
new file mode 100644
index 000000000..fceac394e
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/MapTest.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef SRC_CONTAINERS_MAPTEST_H_
+#define SRC_CONTAINERS_MAPTEST_H_
+
+#include "etUnit/etUnit.h"
+#include "util/etTestSuite.h"
+
+class MapTest : public etTestSuite {
+
+public:
+ MapTest() :
+ etTestSuite("MapTest"){
+ }
+
+protected:
+ void testConstructors(void);
+ void testSettersAndGetters(void);
+ void testOperators(void);
+
+ virtual void runAllTestCases();
+};
+
+
+
+#endif /* SRC_CONTAINERS_MAPTEST_H_ */
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.cpp
new file mode 100644
index 000000000..453334af2
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.cpp
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "PairTest.h"
+
+#include "common/containers/Pair.h"
+#include "common/containers/String.h"
+#include "util/etAssert.h"
+
+using namespace etRuntime;
+
+void PairTest::testConstructors(void) {
+ Pair<int, int> p1;
+ EXPECT_EQUAL_INT32(m_caseId, "p1.first", 0, p1.first);
+ EXPECT_EQUAL_INT32(m_caseId, "p1.second", 0, p1.second);
+
+ Pair<int, int> p2(1, 2);
+ EXPECT_EQUAL_INT32(m_caseId, "p1.first", 1, p2.first);
+ EXPECT_EQUAL_INT32(m_caseId, "p1.second", 2, p2.second);
+
+ Pair<int, String> p3;
+ EXPECT_EQUAL_INT32(m_caseId, "p1.first", 0, p3.first);
+ EXPECT_TRUE(m_caseId, "p1.second", p3.second=="");
+
+ Pair<int, String> p4(123, "pair");
+ EXPECT_EQUAL_INT32(m_caseId, "p1.first", 123, p4.first);
+ EXPECT_TRUE(m_caseId, "p1.second", p4.second=="pair");
+}
+
+void PairTest::testOperators(void) {
+ Pair<int, int> p1(2,2), p2(1, 1);
+ EXPECT_TRUE(m_caseId, "p1>p2", p1>p2);
+ EXPECT_TRUE(m_caseId, "!p1<p2", !(p1<p2));
+ EXPECT_TRUE(m_caseId, "p1!=p2", p1!=p2);
+
+ p1.first = 1;
+ EXPECT_TRUE(m_caseId, "p1>p2", p1>p2);
+ EXPECT_TRUE(m_caseId, "!p1<p2", !(p1<p2));
+ EXPECT_TRUE(m_caseId, "p1!=p2", p1!=p2);
+
+ p1.second = 1;
+ EXPECT_TRUE(m_caseId, "!p1>p2", !(p1>p2));
+ EXPECT_TRUE(m_caseId, "!p1<p2", !(p1<p2));
+ EXPECT_TRUE(m_caseId, "p1>=p2", p1>=p2);
+ EXPECT_TRUE(m_caseId, "p1<=p2", p1<=p2);
+ EXPECT_TRUE(m_caseId, "p1==p2", p1==p2);
+}
+
+void PairTest::runAllTestCases() {
+ ADD_TESTCASE_CPP(testConstructors)
+ ADD_TESTCASE_CPP(testOperators)
+}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.h
new file mode 100644
index 000000000..145d1cc4a
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/PairTest.h
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef SRC_CONTAINERS_PAIRTEST_H_
+#define SRC_CONTAINERS_PAIRTEST_H_
+
+#include "etUnit/etUnit.h"
+#include "util/etTestSuite.h"
+
+class PairTest : public etTestSuite {
+
+public:
+ PairTest() :
+ etTestSuite("PairTest"){
+ }
+
+protected:
+ void testConstructors(void);
+ void testOperators(void);
+
+ virtual void runAllTestCases();
+};
+
+
+
+#endif /* SRC_CONTAINERS_PAIRTEST_H_ */
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.cpp
new file mode 100644
index 000000000..fbbd1a826
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.cpp
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "SetTest.h"
+
+#include "common/containers/Set.h"
+#include "common/messaging/Address.h"
+#include "util/etAssert.h"
+
+using namespace etRuntime;
+
+void SetTest::testConstructors(void) {
+ Set<int> set;
+ EXPECT_TRUE(m_caseId, "set is empty", set.empty());
+ EXPECT_TRUE(m_caseId, "set is empty", set.size() == 0);
+
+ set.insert(1);
+ set.insert(2);
+ set.insert(3);
+ EXPECT_TRUE(m_caseId, "set is not empty", !set.empty());
+ EXPECT_TRUE(m_caseId, "set has size 3", set.size() == 3);
+
+ // copy constructor
+ Set<int> set2(set);
+ EXPECT_TRUE(m_caseId, "set is not empty", !set2.empty());
+ EXPECT_TRUE(m_caseId, "set has size 3", set2.size() == 3);
+}
+
+void SetTest::testSettersAndGetters(void) {
+ Set<int> set;
+
+ set.insert(1);
+ EXPECT_TRUE(m_caseId, "set is not empty", !set.empty());
+ EXPECT_TRUE(m_caseId, "set size is 1", set.size() == 1);
+
+ set.clear();
+ EXPECT_TRUE(m_caseId, "set is empty", set.empty());
+ EXPECT_TRUE(m_caseId, "set is empty", set.size() == 0);
+}
+
+void SetTest::testOperators(void) {
+ Set<int> set1, set2;
+
+ //
+ // comparison with primitive type
+ //
+ set1.insert(1); set2.insert(3);
+ set1.insert(2); set2.insert(1);
+ set1.insert(3); set2.insert(2);
+ EXPECT_TRUE(m_caseId, "sets are equal", set1 == set2);
+
+ Set<Address> set3, set4;
+
+ //
+ // comparison with class
+ //
+ set3.insert(Address(1,2,3)); set4.insert(Address(7,8,9));
+ set3.insert(Address(4,5,6)); set4.insert(Address(1,2,3));
+ set3.insert(Address(7,8,9)); set4.insert(Address(4,5,6));
+ EXPECT_TRUE(m_caseId, "sets are equal", set3 == set4);
+
+ //
+ // find with primitive type
+ //
+ Set<int>::iterator it1;
+ it1 = set1.find(10);
+ EXPECT_TRUE(m_caseId, "value 10 is not found", it1 == set1.end());
+ it1 = set1.find(2);
+ EXPECT_TRUE(m_caseId, "value 2 is found", it1 != set1.end());
+
+ // remove this occurrence
+ set1.erase(it1);
+
+ it1 = set1.find(2);
+ EXPECT_TRUE(m_caseId, "value 2 is NOT found", it1 == set1.end());
+
+ //
+ // find with class
+ //
+ Set<Address>::iterator it3;
+ it3 = set3.find(Address(3,2,1));
+ EXPECT_TRUE(m_caseId, "value Address(3,2,1) is not found", it3 == set3.end());
+ it3 = set3.find(Address(4,5,6));
+ EXPECT_TRUE(m_caseId, "value Address(4,5,6) is found", it3 != set3.end());
+
+ // remove this occurrence
+ set3.erase(it3);
+
+ it3 = set3.find(Address(4,5,6));
+ EXPECT_TRUE(m_caseId, "value 2 is NOT found", it3 == set3.end());
+}
+
+void SetTest::runAllTestCases() {
+ ADD_TESTCASE_CPP(testConstructors)
+ ADD_TESTCASE_CPP(testSettersAndGetters)
+ ADD_TESTCASE_CPP(testOperators)
+}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.h
new file mode 100644
index 000000000..b76490d58
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/SetTest.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef SRC_CONTAINERS_SETTEST_H_
+#define SRC_CONTAINERS_SETTEST_H_
+
+#include "etUnit/etUnit.h"
+#include "util/etTestSuite.h"
+
+class SetTest : public etTestSuite {
+
+public:
+ SetTest() :
+ etTestSuite("SetTest"){
+ }
+
+protected:
+ void testConstructors(void);
+ void testSettersAndGetters(void);
+ void testOperators(void);
+
+ virtual void runAllTestCases();
+};
+
+
+
+#endif /* SRC_CONTAINERS_SETTEST_H_ */
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.cpp
new file mode 100644
index 000000000..8df849343
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.cpp
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "StringTest.h"
+
+#include "common/containers/String.h"
+#include "util/etAssert.h"
+
+using namespace etRuntime;
+
+void StringTest::testConstructors(void) {
+ // default constructors for simple types
+ String string1; // nothing happens, but should not crash
+ String string2("eTrice");
+ String string3(string2); // copy construction for unequal sizes
+
+ EXPECT_EQUAL_INT8(m_caseId, "default string is not 0 at pos 0", 0,
+ (int8)string1[0]);
+ EXPECT_EQUAL_INT8(m_caseId, "value for string2 at pos 2 is wrong", 'r',
+ (int8)string2[2]);
+ EXPECT_EQUAL_INT8(m_caseId, "value for string2 at pos 4 is wrong", 'c',
+ (int8)string2[4]);
+
+ EXPECT_EQUAL_INT8(m_caseId, "copy constructor for string3 wrong", 'e',
+ (int8)string3[0]);
+ EXPECT_EQUAL_INT8(m_caseId, "copy constructor for string3 wrong", 'r',
+ (int8)string3[2]);
+ EXPECT_EQUAL_INT8(m_caseId, "copy constructor for string3 wrong", 'c',
+ (int8)string3[4]);
+}
+
+void StringTest::testSettersAndGetters(void) {
+ String string1("eTrice"); // nothing happens, but should not crash
+
+ // getSize
+ EXPECT_EQUAL_INT8(m_caseId, "length wrong", 6, string1.length());
+
+ // getData
+ EXPECT_EQUAL_INT8(m_caseId, "getData wrong", 'i', (int8)string1[3]);
+}
+
+void StringTest::testOperators(void) {
+ String string1("eTrice"); // nothing happens, but should not crash
+
+ String string2;
+ string2 = string1;
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp(string1.c_str(), string2.c_str())==0);
+
+ string2 = "ROOM";
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp("ROOM", string2.c_str())==0);
+
+ String string3("ROOM with ");
+ string3 += "eTrice";
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp("ROOM with eTrice", string3.c_str())==0);
+
+ String string4("ROOM with ");
+ String string5("eTrice");
+ string4 += string5;
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp("ROOM with eTrice", string4.c_str())==0);
+
+ String string6("ROOM with ");
+ String string7("eTrice");
+ String string8 = string6 + string7;
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp("ROOM with eTrice", string8.c_str())==0);
+
+ String string9("ROOM with ");
+ String string10 = string9 + "eTrice";
+ EXPECT_TRUE(m_caseId, "strings should be equal", std::strcmp("ROOM with eTrice", string10.c_str())==0);
+
+ String string11("something");
+ EXPECT_TRUE(m_caseId, "strings should be equal", string11=="something");
+
+ String string12("something");
+ EXPECT_TRUE(m_caseId, "strings should be equal", string11==string12);
+
+ String string13("this is a long string");
+ string13 = "short"; // new contents without re-allocation
+ EXPECT_TRUE(m_caseId, "strings should be equal", string13=="short");
+
+ String string14("aaa");
+ String string15("bbb");
+ EXPECT_TRUE(m_caseId, "strings should be equal", string14.compare("aaa")==0);
+ EXPECT_TRUE(m_caseId, "strings should be equal", string14.compare(string15)<0);
+
+ //
+ // find and substr
+ //
+ String str = "We think in generalities, but we live in details.";
+ // (quoting Alfred N. Whitehead)
+
+ String str2 = str.substr(3, 5); // "think"
+ EXPECT_TRUE(m_caseId, "strings should be equal", str2.compare("think")==0);
+
+ size_t pos = str.find("live"); // position of "live" in str
+ EXPECT_EQUAL_INT32(m_caseId, "pos should be 33", 33, pos);
+
+ String str3 = str.substr(pos); // get from "live" to the end
+ EXPECT_TRUE(m_caseId, "strings should be equal", str3.compare("live in details.")==0);
+
+ String str5 = str.substr(pos, 4); // get "live"
+ EXPECT_TRUE(m_caseId, "strings should be equal", str5.compare("live")==0);
+
+ String str4;
+ str4 += 'a';
+ EXPECT_TRUE(m_caseId, "strings should be equal", str4.compare("a")==0);
+}
+
+void StringTest::runAllTestCases() {
+ ADD_TESTCASE_CPP(testConstructors)
+ ADD_TESTCASE_CPP(testSettersAndGetters)
+ ADD_TESTCASE_CPP(testOperators)
+}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.h
new file mode 100644
index 000000000..7a7cb4871
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/StringTest.h
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef SRC_CONTAINERS_STRINGTEST_H_
+#define SRC_CONTAINERS_STRINGTEST_H_
+
+#include "etUnit/etUnit.h"
+#include "util/etTestSuite.h"
+
+class StringTest : public etTestSuite {
+
+public:
+ StringTest() :
+ etTestSuite("StringTest"){
+ }
+
+protected:
+ void testConstructors(void);
+ void testSettersAndGetters(void);
+ void testOperators(void);
+
+ virtual void runAllTestCases();
+};
+
+
+#endif /* SRC_CONTAINERS_STRINGTEST_H_ */
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.cpp
new file mode 100644
index 000000000..fb272cf45
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.cpp
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "VectorTest.h"
+
+#include "common/containers/Vector.h"
+#include "common/messaging/Address.h"
+#include "util/etAssert.h"
+
+using namespace etRuntime;
+
+void VectorTest::testConstructors(void) {
+ Vector<int> vec;
+ EXPECT_TRUE(m_caseId, "vector is empty", vec.empty());
+ EXPECT_TRUE(m_caseId, "vector is empty", vec.size() == 0);
+
+ Vector<Address> vec2(3);
+ EXPECT_TRUE(m_caseId, "vector is not empty", !vec2.empty());
+ EXPECT_TRUE(m_caseId, "vector has size 3", vec2.size() == 3);
+}
+
+void VectorTest::testSettersAndGetters(void) {
+ Vector<int> vec;
+
+ vec.push_back(1);
+ EXPECT_TRUE(m_caseId, "vector is not empty", !vec.empty());
+ EXPECT_TRUE(m_caseId, "vector size is 1", vec.size() == 1);
+ EXPECT_TRUE(m_caseId, "element 0 is 1", vec[0] == 1);
+
+ vec[0] = 2;
+ EXPECT_TRUE(m_caseId, "element 0 is 2", vec[0] == 2);
+
+ vec[0] = 1;
+ EXPECT_TRUE(m_caseId, "element 0 is 1", vec[0] == 1);
+ vec.push_back(2);
+ EXPECT_TRUE(m_caseId, "vector is not empty", !vec.empty());
+ EXPECT_TRUE(m_caseId, "vector size is 2", vec.size() == 2);
+ EXPECT_TRUE(m_caseId, "element 1 is 2", vec[1] == 2);
+}
+
+void VectorTest::testOperators(void) {
+ Vector<int> vec1, vec2;
+
+ //
+ // comparison
+ //
+ vec1.push_back(1); vec2.push_back(1);
+ vec1.push_back(2); vec2.push_back(2);
+ vec1.push_back(3); vec2.push_back(3);
+ EXPECT_TRUE(m_caseId, "vectors are equal", vec1 == vec2);
+
+ //
+ // iterators
+ //
+ Vector<int>::iterator it1 = vec1.begin();
+ EXPECT_TRUE(m_caseId, "element at iterator position is 1", *it1 == 1);
+ EXPECT_TRUE(m_caseId, "element at iterator position is 2", *(++it1) == 2);
+
+ it1 = vec1.erase(it1);
+ EXPECT_EQUAL_INT32(m_caseId, "new vector size is 2", 2, vec1.size());
+ EXPECT_EQUAL_INT32(m_caseId, "element at iterator position is 3", 3, *it1);
+ EXPECT_TRUE(m_caseId, "incremented iterator is at end", ++it1 == vec1.end());
+
+ EXPECT_TRUE(m_caseId, "vectors are not equal", vec1 != vec2);
+
+ //
+ // front and back
+ //
+ EXPECT_EQUAL_INT32(m_caseId, "element at front is 1", 1, vec2.front());
+ EXPECT_EQUAL_INT32(m_caseId, "element at front is 3", 3, vec2.back());
+}
+
+void VectorTest::runAllTestCases() {
+ ADD_TESTCASE_CPP(testConstructors)
+ ADD_TESTCASE_CPP(testSettersAndGetters)
+ ADD_TESTCASE_CPP(testOperators)
+}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.h
new file mode 100644
index 000000000..d997a9cc3
--- /dev/null
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/containers/VectorTest.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef SRC_CONTAINERS_VECTORTEST_H_
+#define SRC_CONTAINERS_VECTORTEST_H_
+
+#include "etUnit/etUnit.h"
+#include "util/etTestSuite.h"
+
+class VectorTest : public etTestSuite {
+
+public:
+ VectorTest() :
+ etTestSuite("VectorTest"){
+ }
+
+protected:
+ void testConstructors(void);
+ void testSettersAndGetters(void);
+ void testOperators(void);
+
+ virtual void runAllTestCases();
+};
+
+
+
+#endif /* SRC_CONTAINERS_VECTORTEST_H_ */
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.cpp
index 7a53e2fc9..b04d03034 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.cpp
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.cpp
@@ -16,6 +16,7 @@
#include "common/messaging/RTServices.h"
#include "common/messaging/StaticMessageMemory.h"
#include "etUnit/etUnit.h"
+#include <iostream>
using namespace etRuntime;
@@ -61,47 +62,54 @@ void DebuggingServiceTest::testLogging() {
RTServices::getInstance().getMsgSvcCtrl().stop();
const char* failMsg = "DebuggingServiceTest failed";
- std::list<std::string>& result = dbgSvc.getAsyncLogger().getCommandList();
+ Vector<String>& result = dbgSvc.getAsyncLogger().getCommandList();
+
+ typedef Vector<String> CmdList;
+ for (CmdList::iterator it=result.begin(); it!=result.end(); ++it) {
+ std::cout << (*it).c_str() << std::endl;
+ }
+
+ Vector<String>::iterator it = result.begin();
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem (!) /TestSubSystem/TestActor1 "));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem (!) /TestSubSystem/TestActor2 "));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 (!) /TestSubSystem/TestActor1/SubActor "));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 >-- /TestSubSystem/TestActor2 MessageAsync"));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 --> /TestSubSystem/TestActor2 MessageAsync"));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 ==> /TestSubSystem/TestActor2 MessageSyncCall"));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 <== /TestSubSystem/TestActor2 MessageSyncReturn"));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem/TestActor1 >>> TestState"));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare(
+ 0==(*it).compare(
"\t/TestSubSystem (X) /TestSubSystem/TestActor1 "));
- result.pop_front();
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("# This is a comment"));
- result.pop_front();
+ 0==(*it).compare("# This is a comment"));
+ ++it;
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.h
index 44f19d517..212d38e8f 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.h
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/DebuggingServiceTest.h
@@ -34,7 +34,7 @@ protected:
class ActorClass: public ActorClassBase {
public:
- ActorClass(IRTObject* parent, const std::string& name) :
+ ActorClass(IRTObject* parent, const String& name) :
ActorClassBase(parent, name) {
}
@@ -46,7 +46,7 @@ public:
class SubSystemClass: public SubSystemClassBase {
public:
- SubSystemClass(IRTObject* parent, std::string name) :
+ SubSystemClass(IRTObject* parent, String name) :
SubSystemClassBase(parent, name) {
}
@@ -63,7 +63,7 @@ public:
class Port: public PortBase {
public:
- Port(IInterfaceItemOwner* owner, const std::string& name) :
+ Port(IInterfaceItemOwner* owner, const String& name) :
PortBase(owner, name, 0) {
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/MSCLoggerTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/MSCLoggerTest.cpp
index ea1ae065b..01be8e936 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/MSCLoggerTest.cpp
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/debugging/MSCLoggerTest.cpp
@@ -13,8 +13,6 @@
#include "MSCLoggerTest.h"
#include "common/debugging/MSCLogger.h"
#include "etUnit/etUnit.h"
-#include <stdio.h>
-#include <string.h>
using namespace etRuntime;
@@ -36,38 +34,39 @@ void MSCLoggerTest::testLogger() {
logger.close();
const char* failMsg = "MSCLoggerTest failed";
- std::list<std::string>& result = logger.getCommandList();
+ Vector<String>& result = logger.getCommandList();
+ Vector<String>::iterator it = result.begin();
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource >-- Target MessageAsync"));
- result.pop_front();
+ !(*it).compare("\tSource >-- Target MessageAsync"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource --> Target MessageAsync"));
- result.pop_front();
+ !(*it).compare("\tSource --> Target MessageAsync"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource ==> Target MessageSyncCall"));
- result.pop_front();
+ !(*it).compare("\tSource ==> Target MessageSyncCall"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource <== Target MessageSyncReturn"));
- result.pop_front();
+ !(*it).compare("\tSource <== Target MessageSyncReturn"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource (!) Target "));
- result.pop_front();
+ !(*it).compare("\tSource (!) Target "));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource (X) Target "));
- result.pop_front();
+ !(*it).compare("\tSource (X) Target "));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tActor note: Note"));
- result.pop_front();
+ !(*it).compare("\tActor note: Note"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tSource (!) Target "));
- result.pop_front();
+ !(*it).compare("\tSource (!) Target "));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("\tActor >>> State"));
- result.pop_front();
+ !(*it).compare("\tActor >>> State"));
+ ++it;
EXPECT_TRUE(m_caseId, failMsg,
- !result.front().compare("# This is a comment"));
- result.pop_front();
+ !(*it).compare("# This is a comment"));
+ ++it;
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.cpp
index 730a3a7d9..0c04fd125 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.cpp
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.cpp
@@ -22,7 +22,7 @@ void MessageDispatcherTest::testConstructors() {
const char *failMsg = "MessageDispatcher constructor test failed";
- // Test constructor MessageDispatcher(IRTObject* parent, const Address& addr, const std::string& name)
+ // Test constructor MessageDispatcher(IRTObject* parent, const Address& addr, const String& name)
Address addr(1, 2, 3);
MessageDispatcher msgDisp(NULL, addr, "TestMessageDispatcher");
EXPECT_TRUE(m_caseId, failMsg, addr == msgDisp.getAddress());
@@ -41,16 +41,26 @@ void MessageDispatcherTest::testFreeAddresses() {
Address(1, 2, 5) == msgDisp.getFreeAddress());
EXPECT_TRUE(m_caseId, failMsg,
Address(1, 2, 6) == msgDisp.getFreeAddress());
+
+ // free one address
msgDisp.freeAddress(Address(1, 2, 5));
+
+ // get it as next address
EXPECT_TRUE(m_caseId, failMsg,
Address(1, 2, 5) == msgDisp.getFreeAddress());
+
+ // free two addresses
msgDisp.freeAddress(Address(1, 2, 4));
msgDisp.freeAddress(Address(1, 2, 6));
- EXPECT_TRUE(m_caseId, failMsg,
- Address(1, 2, 4) == msgDisp.getFreeAddress());
+
+ // get them in reverse order
EXPECT_TRUE(m_caseId, failMsg,
Address(1, 2, 6) == msgDisp.getFreeAddress());
EXPECT_TRUE(m_caseId, failMsg,
+ Address(1, 2, 4) == msgDisp.getFreeAddress());
+
+ // no freed address left: get a fresh one
+ EXPECT_TRUE(m_caseId, failMsg,
Address(1, 2, 7) == msgDisp.getFreeAddress());
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.h
index 072eb4f35..beab56e2a 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.h
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageDispatcherTest.h
@@ -34,9 +34,9 @@ protected:
class SimpleMessageReceiver: public etRuntime::RTObject,
public etRuntime::IMessageReceiver {
public:
- SimpleMessageReceiver(IRTObject *parent, const std::string& name,
+ SimpleMessageReceiver(IRTObject *parent, const etRuntime::String& name,
const etRuntime::Address& address) :
- RTObject(parent, name), m_address(address), m_lastMessage(NULL) {
+ RTObject(parent, name), m_address(address), m_lastMessage(NULL) {
}
void receive(const etRuntime::Message* msg) {
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageServiceTest.h b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageServiceTest.h
index cccf480b7..57e00d7b8 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageServiceTest.h
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/MessageServiceTest.h
@@ -54,7 +54,7 @@ private:
class MessageCounter: public etRuntime::RTObject,
public etRuntime::IMessageReceiver {
public:
- MessageCounter(IRTObject *parent, const std::string &name,
+ MessageCounter(IRTObject *parent, const etRuntime::String &name,
const etRuntime::Address &address) :
RTObject(parent, name), m_counter(0), m_address(address) {
}
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/RTObjectTest.cpp b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/RTObjectTest.cpp
index f84456fc5..51ef8bf0e 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/RTObjectTest.cpp
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/src/messaging/RTObjectTest.cpp
@@ -22,7 +22,7 @@ void RTObjectTest::testConstructors() {
const char* failMsg = "RTObject constructor test failed";
- // Test constructor RTObject(IRTObject* parent, const std::string& name)
+ // Test constructor RTObject(IRTObject* parent, const String& name)
RTObject* rto1 = new RTObject(NULL, "grandparent");
RTObject* rto2 = new RTObject(rto1, "parent");
RTObject* rto3 = new RTObject(rto2, "child1");
@@ -35,7 +35,7 @@ void RTObjectTest::testConstructors() {
EXPECT_TRUE(m_caseId, failMsg,
!rto1->getInstancePath().compare(
- IRTObject::PATH_DELIM + std::string("grandparent")));
+ IRTObject::PATH_DELIM + String("grandparent")));
EXPECT_TRUE(m_caseId, failMsg,
!rto2->getInstancePath().compare(
rto1->getInstancePath() + IRTObject::PATH_DELIM + "parent"));
@@ -48,7 +48,7 @@ void RTObjectTest::testConstructors() {
EXPECT_TRUE(m_caseId, failMsg,
!rto1->getInstancePathName().compare(
- IRTObject::PATHNAME_DELIM + std::string("grandparent")));
+ IRTObject::PATHNAME_DELIM + String("grandparent")));
EXPECT_TRUE(m_caseId, failMsg,
!rto2->getInstancePathName().compare(
rto1->getInstancePathName() + IRTObject::PATHNAME_DELIM
@@ -62,10 +62,10 @@ void RTObjectTest::testConstructors() {
rto2->getInstancePathName() + IRTObject::PATHNAME_DELIM
+ "child2"));
- std::vector<IRTObject*> children1 = rto1->getChildren();
- std::vector<IRTObject*> children2 = rto2->getChildren();
- std::vector<IRTObject*> children3 = rto3->getChildren();
- std::vector<IRTObject*> children4 = rto4->getChildren();
+ IRTObject::ChildList children1 = rto1->getChildren();
+ IRTObject::ChildList children2 = rto2->getChildren();
+ IRTObject::ChildList children3 = rto3->getChildren();
+ IRTObject::ChildList children4 = rto4->getChildren();
IRTObject *child1 = children2.front();
IRTObject *child2 = children2.back();
EXPECT_EQUAL_PTR(m_caseId, failMsg, rto2, children1.back());
@@ -115,10 +115,10 @@ void RTObjectTest::testGetters() {
EXPECT_TRUE(m_caseId, failMsg, !rto.getName().compare("test"));
EXPECT_TRUE(m_caseId, failMsg,
!rto.getInstancePath().compare(
- IRTObject::PATH_DELIM + std::string("test")));
+ IRTObject::PATH_DELIM + String("test")));
EXPECT_TRUE(m_caseId, failMsg,
!rto.getInstancePathName().compare(
- IRTObject::PATHNAME_DELIM + std::string("test")));
+ IRTObject::PATHNAME_DELIM + String("test")));
EXPECT_EQUAL_INT16(m_caseId, failMsg, 0, rto.getChildren().size());
EXPECT_EQUAL_PTR(m_caseId, failMsg, NULL, rto.getParent());
EXPECT_EQUAL_PTR(m_caseId, failMsg, &rto, rto.getRoot());

Back to the top