Update README.md
[nemesis.git] / Platform / PlatformTest.cpp
1 /*
2  Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
3
4  Governed by the TrueCrypt License 3.0 the full text of which is contained in
5  the file License.txt included in TrueCrypt binary and source code distribution
6  packages.
7 */
8
9 #include "PlatformTest.h"
10 #include "Exception.h"
11 #include "FileStream.h"
12 #include "Finally.h"
13 #include "ForEach.h"
14 #include "MemoryStream.h"
15 #include "Mutex.h"
16 #include "Serializable.h"
17 #include "SharedPtr.h"
18 #include "StringConverter.h"
19 #include "SyncEvent.h"
20 #include "Thread.h"
21 #include "Common/Tcdefs.h"
22
23 namespace TrueCrypt
24 {
25         // make_shared_auto, File, Stream, MemoryStream, Endian, Serializer, Serializable
26         void PlatformTest::SerializerTest ()
27         {
28                 shared_ptr <Stream> stream (new MemoryStream);
29
30 #if 0
31                 make_shared_auto (File, file);
32                 finally_do_arg (File&, *file, { if (finally_arg.IsOpen()) finally_arg.Delete(); });
33
34                 try
35                 {
36                         file->Open ("truecrypt-serializer-test.tmp", File::CreateReadWrite);
37                         stream = shared_ptr <Stream> (new FileStream (file));
38                 }
39                 catch (...) { }
40 #endif
41
42                 Serializer ser (stream);
43
44                 uint32 i32 = 0x12345678;
45                 uint64 i64 = 0x0123456789abcdefULL;
46                 string str = "string test";
47                 wstring wstr = L"wstring test";
48
49                 string convStr = "test";
50                 StringConverter::ToSingle (wstr, convStr);
51                 if (convStr != "wstring test")
52                         throw TestFailed (SRC_POS);
53
54                 StringConverter::Erase (convStr);
55                 if (convStr != "            ")
56                         throw TestFailed (SRC_POS);
57
58                 wstring wEraseTest = L"erase test";
59                 StringConverter::Erase (wEraseTest);
60                 if (wEraseTest != L"          ")
61                         throw TestFailed (SRC_POS);
62
63                 list <string> stringList;
64                 stringList.push_back (str + "1");
65                 stringList.push_back (str + "2");
66                 stringList.push_back (str + "3");
67
68                 list <wstring> wstringList;
69                 wstringList.push_back (wstr + L"1");
70                 wstringList.push_back (wstr + L"2");
71                 wstringList.push_back (wstr + L"3");
72
73                 Buffer buffer (10);
74                 for (size_t i = 0; i < buffer.Size(); i++)
75                         buffer[i] = (byte) i;
76
77                 ser.Serialize ("int32", i32);
78                 ser.Serialize ("int64", i64);
79                 ser.Serialize ("string", str);
80                 ser.Serialize ("wstring", wstr);
81                 ser.Serialize ("stringList", stringList);
82                 ser.Serialize ("wstringList", wstringList);
83                 ser.Serialize ("buffer", ConstBufferPtr (buffer));
84
85                 ExecutedProcessFailed ex (SRC_POS, "cmd", -123, "error output");
86                 ex.Serialize (stream);
87
88                 list < shared_ptr <ExecutedProcessFailed> > exList;
89                 exList.push_back (make_shared <ExecutedProcessFailed> (ExecutedProcessFailed (SRC_POS, "cmd", -123, "error output1")));
90                 exList.push_back (make_shared <ExecutedProcessFailed> (ExecutedProcessFailed (SRC_POS, "cmd", -234, "error output2")));
91                 exList.push_back (make_shared <ExecutedProcessFailed> (ExecutedProcessFailed (SRC_POS, "cmd", -567, "error output3")));
92                 Serializable::SerializeList (stream, exList);
93
94 #if 0
95                 if (file->IsOpen())
96                         file->SeekAt (0);
97 #endif
98
99                 uint32 di32;
100                 ser.Deserialize ("int32", di32);
101                 if (i32 != di32)
102                         throw TestFailed (SRC_POS);
103
104                 uint64 di64;
105                 ser.Deserialize ("int64", di64);
106                 if (i64 != di64)
107                         throw TestFailed (SRC_POS);
108
109                 string dstr;
110                 ser.Deserialize ("string", dstr);
111                 if (str != dstr)
112                         throw TestFailed (SRC_POS);
113
114                 wstring dwstr;
115                 ser.Deserialize ("wstring", dwstr);
116                 if (str != dstr)
117                         throw TestFailed (SRC_POS);
118
119                 int i = 1;
120                 foreach (string item, ser.DeserializeStringList ("stringList"))
121                 {
122                         stringstream s;
123                         s << str << i++;
124                         if (item != s.str())
125                                 throw TestFailed (SRC_POS);
126                 }
127
128                 i = 1;
129                 foreach (wstring item, ser.DeserializeWStringList ("wstringList"))
130                 {
131                         wstringstream s;
132                         s << wstr << i++;
133                         if (item != s.str())
134                                 throw TestFailed (SRC_POS);
135                 }
136
137                 Buffer dbuffer (10);
138                 ser.Deserialize ("buffer", buffer);
139                 for (size_t i = 0; i < buffer.Size(); i++)
140                         if (buffer[i] != (byte) i)
141                                 throw TestFailed (SRC_POS);
142
143                 shared_ptr <ExecutedProcessFailed> dex = Serializable::DeserializeNew <ExecutedProcessFailed> (stream);
144                 if (!dex
145                         || dex->GetCommand() != "cmd"
146                         || dex->GetExitCode() != -123
147                         || dex->GetErrorOutput() != "error output")
148                         throw TestFailed (SRC_POS);
149
150                 list < shared_ptr <ExecutedProcessFailed> > dexList;
151                 Serializable::DeserializeList (stream, dexList);
152                 i = 1;
153                 foreach_ref (const ExecutedProcessFailed &ex, dexList)
154                 {
155                         stringstream s;
156                         s << "error output" << i++;
157                         if (ex.GetErrorOutput() != s.str())
158                                 throw TestFailed (SRC_POS);
159                 }
160         }
161         
162         // shared_ptr, Mutex, ScopeLock, SyncEvent, Thread
163         static struct 
164         {
165                 shared_ptr <int> SharedIntPtr;
166                 Mutex IntMutex;
167                 SyncEvent ExitAllowedEvent;
168         } ThreadTestData;
169
170         void PlatformTest::ThreadTest ()
171         {
172                 Mutex mutex;
173                 mutex.Lock();
174                 mutex.Unlock();
175
176                 const int maxThreads = 3;
177                 ThreadTestData.SharedIntPtr.reset (new int (0));
178
179                 for (int i = 0; i < maxThreads; i++)
180                 {
181                         Thread t;
182                         t.Start (&ThreadTestProc, (void *) &ThreadTestData);
183                 }
184
185                 for (int i = 0; i < 50; i++)
186                 {
187                         {
188                                 ScopeLock sl (ThreadTestData.IntMutex);
189                                 if (*ThreadTestData.SharedIntPtr == maxThreads)
190                                         break;
191                         }
192
193                         Thread::Sleep(100);
194                 }
195
196                 if (*ThreadTestData.SharedIntPtr != maxThreads)
197                         throw TestFailed (SRC_POS);
198
199                 for (int i = 0; i < 60000; i++)
200                 {
201                         ThreadTestData.ExitAllowedEvent.Signal();
202                         Thread::Sleep(1);
203
204                         ScopeLock sl (ThreadTestData.IntMutex);
205                         if (*ThreadTestData.SharedIntPtr == 0)
206                                 break;
207                 }
208
209                 if (*ThreadTestData.SharedIntPtr != 0)
210                         throw TestFailed (SRC_POS);
211         }
212
213         TC_THREAD_PROC PlatformTest::ThreadTestProc (void *arg)
214         {
215                 
216                 if (arg != (void *) &ThreadTestData)
217                         return 0;
218
219                 {
220                         ScopeLock sl (ThreadTestData.IntMutex);
221                         ++(*ThreadTestData.SharedIntPtr);
222                 }
223
224                 ThreadTestData.ExitAllowedEvent.Wait();
225
226                 {
227                         ScopeLock sl (ThreadTestData.IntMutex);
228                         --(*ThreadTestData.SharedIntPtr);
229                 }
230
231                 return 0;
232         }
233
234         bool PlatformTest::TestAll ()
235         {
236                 // Integer types
237                 if (sizeof (byte)   != 1 || sizeof (int8)  != 1 || sizeof (__int8)  != 1) throw TestFailed (SRC_POS);
238                 if (sizeof (uint16) != 2 || sizeof (int16) != 2 || sizeof (__int16) != 2) throw TestFailed (SRC_POS);
239                 if (sizeof (uint32) != 4 || sizeof (int32) != 4 || sizeof (__int32) != 4) throw TestFailed (SRC_POS);
240                 if (sizeof (uint64) != 8 || sizeof (int64) != 8) throw TestFailed (SRC_POS);
241
242                 // Exception handling
243                 TestFlag = false;
244                 try
245                 {
246                         try
247                         {
248                                 throw TestFailed (SRC_POS);
249                         }
250                         catch (...)
251                         {
252                                 throw;
253                         }
254                         return false;
255                 }
256                 catch (Exception &)
257                 {
258                         TestFlag = true;
259                 }
260                 if (!TestFlag)
261                         return false;
262
263                 // RTTI
264                 RttiTest rtti;
265                 RttiTestBase &rttiBaseRef = rtti;
266                 RttiTestBase *rttiBasePtr = &rtti;
267
268                 if (typeid (rttiBaseRef) != typeid (rtti))
269                         throw TestFailed (SRC_POS);
270
271                 if (typeid (*rttiBasePtr) != typeid (rtti))
272                         throw TestFailed (SRC_POS);
273
274                 if (dynamic_cast <RttiTest *> (rttiBasePtr) == nullptr)
275                         throw TestFailed (SRC_POS);
276
277                 try
278                 {
279                         dynamic_cast <RttiTest &> (rttiBaseRef);
280                 }
281                 catch (...)
282                 {
283                         throw TestFailed (SRC_POS);
284                 }
285
286                 // finally
287                 TestFlag = false;
288                 {
289                         finally_do ({ TestFlag = true; });
290                         if (TestFlag)
291                                 throw TestFailed (SRC_POS);
292                 }
293                 if (!TestFlag)
294                         throw TestFailed (SRC_POS);
295
296                 TestFlag = false;
297                 {
298                         finally_do_arg (bool*, &TestFlag, { *finally_arg = true; });
299                         if (TestFlag)
300                                 throw TestFailed (SRC_POS);
301                 }
302                 if (!TestFlag)
303                         throw TestFailed (SRC_POS);
304
305                 TestFlag = false;
306                 int tesFlag2 = 0;
307                 {
308                         finally_do_arg2 (bool*, &TestFlag, int*, &tesFlag2, { *finally_arg = true; *finally_arg2 = 2; });
309                         if (TestFlag || tesFlag2 != 0)
310                                 throw TestFailed (SRC_POS);
311                 }
312                 if (!TestFlag || tesFlag2 != 2)
313                         throw TestFailed (SRC_POS);
314
315                 // uint64, vector, list, string, wstring, stringstream, wstringstream
316                 // shared_ptr, make_shared, StringConverter, foreach
317                 list <shared_ptr <uint64> > numList;
318                 
319                 numList.push_front (make_shared <uint64> (StringConverter::ToUInt64 (StringConverter::FromNumber ((uint64) 0xFFFFffffFFFFfffeULL))));
320                 numList.push_front (make_shared <uint64> (StringConverter::ToUInt32 (StringConverter::GetTrailingNumber ("str2"))));
321                 numList.push_front (make_shared <uint64> (3));
322
323                 list <wstring> testList;
324                 wstringstream wstream (L"test");
325                 foreach_reverse_ref (uint64 n, numList)
326                 {
327                         wstream.str (L"");
328                         wstream << L"str" << n;
329                         testList.push_back (wstream.str());
330                 }
331
332                 stringstream sstream;
333                 sstream << "dummy";
334                 sstream.str ("");
335                 sstream << "str18446744073709551614,str2" << " str" << StringConverter::Trim (StringConverter::ToSingle (L"\t 3 \r\n"));
336                 foreach (const string &s, StringConverter::Split (sstream.str(), ", "))
337                 {
338                         if (testList.front() != StringConverter::ToWide (s))
339                                 throw TestFailed (SRC_POS);
340                         testList.pop_front();
341                 }
342
343                 SerializerTest();
344                 ThreadTest();
345
346                 return true;
347         }
348
349         bool PlatformTest::TestFlag;
350 }
This page took 0.030877 seconds and 3 git commands to generate. Download a nemesis OSX (sierra+high sierra, tested/working) binary, with fuse-ext3 via e2fsprogs, at this link. application and installer are signed by screwjack, llc. must install fuse with macFUSE layer first.