1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <memory> 21 #include <algorithm> 22 23 #include <sal/types.h> 24 #include <cppunit/TestAssert.h> 25 #include <cppunit/TestFixture.h> 26 #include <cppunit/extensions/HelperMacros.h> 27 #include <cppunit/plugin/TestPlugIn.h> 28 29 #include <rtl/random.h> 30 31 #include <string.h> 32 33 namespace rtl_random 34 { 35 36 class createPool : public CppUnit::TestFixture 37 { 38 public: 39 // insert your test code here. 40 // this is only demonstration code createPool_001()41 void createPool_001() 42 { 43 // this is demonstration code 44 45 rtlRandomPool aPool = rtl_random_createPool(); 46 47 // LLA: seems to be that another test is not possible for createPool() 48 CPPUNIT_ASSERT_MESSAGE("create failed", aPool != nullptr); 49 50 rtl_random_destroyPool(aPool); 51 } 52 53 // Change the following lines only, if you add, remove or rename 54 // member functions of the current class, 55 // because these macros are need by auto register mechanism. 56 57 CPPUNIT_TEST_SUITE(createPool); 58 CPPUNIT_TEST(createPool_001); 59 CPPUNIT_TEST_SUITE_END(); 60 }; // class createPool 61 62 class destroyPool : public CppUnit::TestFixture 63 { 64 public: 65 // insert your test code here. destroyPool_000()66 void destroyPool_000() 67 { 68 // GPF, if failed 69 rtl_random_destroyPool(nullptr); 70 } 71 destroyPool_001()72 void destroyPool_001() 73 { 74 rtlRandomPool aPool = rtl_random_createPool(); 75 76 // LLA: seems to be that another test is not possible for createPool() 77 CPPUNIT_ASSERT_MESSAGE("create failed", aPool != nullptr); 78 79 rtl_random_destroyPool(aPool); 80 } 81 // Change the following lines only, if you add, remove or rename 82 // member functions of the current class, 83 // because these macros are need by auto register mechanism. 84 85 CPPUNIT_TEST_SUITE(destroyPool); 86 CPPUNIT_TEST(destroyPool_000); 87 CPPUNIT_TEST(destroyPool_001); 88 CPPUNIT_TEST_SUITE_END(); 89 }; // class destroyPool 90 91 class addBytes : public CppUnit::TestFixture 92 { 93 public: 94 // insert your test code here. 95 // this is only demonstration code addBytes_000()96 void addBytes_000() 97 { 98 rtlRandomPool aPool = rtl_random_createPool(); 99 100 sal_uInt32 nBufLen = 4; 101 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 102 memset(pBuffer.get(), 0, nBufLen); 103 104 rtlRandomError aError = rtl_random_addBytes(nullptr, nullptr, 0); 105 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError); 106 107 /* rtlRandomError */ aError = rtl_random_addBytes(aPool, nullptr, 0); 108 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError); 109 110 /* rtlRandomError */ aError = rtl_random_addBytes(aPool, pBuffer.get(), nBufLen); 111 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError); 112 113 rtl_random_destroyPool(aPool); 114 } 115 addBytes_001()116 void addBytes_001() 117 { 118 rtlRandomPool aPool = rtl_random_createPool(); 119 120 sal_uInt32 nBufLen = 4; 121 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 122 123 memset(pBuffer.get(), 0, nBufLen); 124 125 rtl_random_addBytes(aPool, pBuffer.get(), nBufLen); 126 127 printf("%2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3]); 128 129 rtl_random_destroyPool(aPool); 130 } 131 132 // Change the following lines only, if you add, remove or rename 133 // member functions of the current class, 134 // because these macros are need by auto register mechanism. 135 136 CPPUNIT_TEST_SUITE(addBytes); 137 CPPUNIT_TEST(addBytes_000); 138 CPPUNIT_TEST(addBytes_001); 139 CPPUNIT_TEST_SUITE_END(); 140 }; // class addBytes 141 142 namespace { 143 144 class Statistics 145 { 146 int m_nDispensation[256]; 147 148 int m_nMin; 149 int m_nMax; 150 int m_nAverage; 151 int m_nMinDeviation; 152 int m_nMaxDeviation; 153 154 public: clearDispensation()155 void clearDispensation() 156 { 157 for (int i = 0;i < 256;++i) // clear array 158 { 159 m_nDispensation[i] = 0; 160 } 161 } Statistics()162 Statistics() 163 : m_nMin(0) 164 , m_nMax(0) 165 , m_nAverage(0) 166 , m_nMinDeviation(0) 167 , m_nMaxDeviation(0) 168 { 169 clearDispensation(); 170 } 171 addValue(sal_uInt8 _nIndex,sal_Int32 _nValue)172 void addValue(sal_uInt8 _nIndex, sal_Int32 _nValue) 173 { 174 m_nDispensation[_nIndex] += _nValue; 175 } 176 build(sal_Int32 _nCountMax)177 void build(sal_Int32 _nCountMax) 178 { 179 m_nMin = _nCountMax; 180 m_nMax = 0; 181 182 m_nAverage = _nCountMax / 256; 183 184 m_nMinDeviation = _nCountMax; 185 m_nMaxDeviation = 0; 186 187 for (int i = 0;i < 256;++i) // show dispensation 188 { 189 m_nMin = std::min(m_nMin, m_nDispensation[i]); 190 m_nMax = std::max(m_nMax, m_nDispensation[i]); 191 192 m_nMinDeviation = std::min(m_nMinDeviation, abs(m_nAverage - m_nDispensation[i])); 193 m_nMaxDeviation = std::max(m_nMaxDeviation, abs(m_nAverage - m_nDispensation[i])); 194 } 195 } 196 print()197 void print() 198 { 199 // LLA: these are only info values 200 printf("\nSome statistics\n"); 201 printf("Min: %d\n", m_nMin); 202 printf("Max: %d\n", m_nMax); 203 printf("Average: %d\n", m_nAverage); 204 printf("Min abs deviation: %d\n", m_nMinDeviation); 205 printf("Max abs deviation: %d\n", m_nMaxDeviation); 206 } 207 getAverage() const208 sal_Int32 getAverage() const {return m_nAverage;} getMaxDeviation() const209 sal_Int32 getMaxDeviation() const {return m_nMaxDeviation;} 210 211 }; 212 213 } 214 215 class getBytes : public CppUnit::TestFixture 216 { 217 public: 218 // insert your test code here. getBytes_000()219 void getBytes_000() 220 { 221 rtlRandomPool aPool = rtl_random_createPool(); 222 223 sal_uInt32 nBufLen = 4; 224 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 225 memset(pBuffer.get(), 0, nBufLen); 226 227 rtlRandomError aError = rtl_random_getBytes(nullptr, nullptr, 0); 228 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError); 229 230 /* rtlRandomError */ aError = rtl_random_getBytes(aPool, nullptr, 0); 231 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError); 232 233 /* rtlRandomError */ aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen); 234 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError); 235 236 rtl_random_destroyPool(aPool); 237 } 238 getBytes_001()239 void getBytes_001() 240 { 241 rtlRandomPool aPool = rtl_random_createPool(); 242 243 sal_uInt32 nBufLen = 4; 244 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 245 memset(pBuffer.get(), 0, nBufLen); 246 247 rtlRandomError aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen); 248 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError); 249 250 printf("%2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3]); 251 252 rtl_random_destroyPool(aPool); 253 } 254 getBytes_002()255 void getBytes_002() 256 { 257 rtlRandomPool aPool = rtl_random_createPool(); 258 259 sal_uInt32 nBufLen = 4; 260 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen << 1 ] ); 261 memset(pBuffer.get(), 0, nBufLen << 1); 262 263 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[4]); 264 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[5]); 265 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[6]); 266 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[7]); 267 268 rtlRandomError aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen); 269 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError); 270 271 printf("%2x %2x %2x %2x %2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4], pBuffer[5], pBuffer[6], pBuffer[7]); 272 273 CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[4]); 274 CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[5]); 275 CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[6]); 276 CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[7]); 277 278 rtl_random_destroyPool(aPool); 279 } 280 getBytes_003()281 void getBytes_003() 282 { 283 rtlRandomPool aPool = rtl_random_createPool(); 284 285 sal_uInt32 nBufLen = 1; 286 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 287 memset(pBuffer.get(), 0, nBufLen); 288 289 Statistics aStat; 290 291 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", static_cast<sal_uInt8>(0), pBuffer[0]); 292 293 int nCount = 0; 294 295 int nCountMax = 1000000; 296 for(nCount = 0;nCount < nCountMax; ++nCount) // run 100000000 through getBytes(...) 297 { 298 /* rtlRandomError aError = */ rtl_random_getBytes(aPool, pBuffer.get(), nBufLen); 299 /* CPPUNIT_ASSERT_MESSAGE("wrong parameter", aError == rtl_Random_E_None); */ 300 301 aStat.addValue(pBuffer[0], 1); 302 } 303 304 aStat.build(nCountMax); 305 aStat.print(); 306 307 CPPUNIT_ASSERT_MESSAGE("deviation should be less average", aStat.getMaxDeviation() < aStat.getAverage()); 308 309 rtl_random_destroyPool(aPool); 310 } 311 getBytes_003_1()312 void getBytes_003_1() 313 { 314 rtlRandomPool aPool = rtl_random_createPool(); 315 316 sal_uInt32 nBufLen = 256; 317 std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] ); 318 memset(pBuffer.get(), 0, nBufLen); 319 320 Statistics aStat; 321 322 CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", static_cast<sal_uInt8>(0), pBuffer[0]); 323 324 int nCount = 0; 325 326 int nCountMax = 10000; 327 for(nCount = 0;nCount < nCountMax; ++nCount) // run 100000000 through getBytes(...) 328 { 329 /* rtlRandomError aError = */ rtl_random_getBytes(aPool, pBuffer.get(), nBufLen); 330 // CPPUNIT_ASSERT_MESSAGE("wrong parameter", aError == rtl_Random_E_None); 331 332 for (sal_uInt32 i=0;i<nBufLen;++i) 333 aStat.addValue(pBuffer[i], 1); 334 } 335 336 aStat.build(nCountMax * nBufLen); 337 aStat.print(); 338 339 CPPUNIT_ASSERT_MESSAGE("deviation should be less average", aStat.getMaxDeviation() < aStat.getAverage()); 340 341 rtl_random_destroyPool(aPool); 342 } 343 344 // Change the following lines only, if you add, remove or rename 345 // member functions of the current class, 346 // because these macros are need by auto register mechanism. 347 348 CPPUNIT_TEST_SUITE(getBytes); 349 CPPUNIT_TEST(getBytes_000); 350 CPPUNIT_TEST(getBytes_001); 351 CPPUNIT_TEST(getBytes_002); 352 CPPUNIT_TEST(getBytes_003); 353 CPPUNIT_TEST(getBytes_003_1); 354 CPPUNIT_TEST_SUITE_END(); 355 }; // class getBytes 356 357 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::createPool); 358 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::destroyPool); 359 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::addBytes); 360 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::getBytes); 361 } // namespace rtl_random 362 363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 364