auto_array_test.cpp revision 1.1.1.1
1// Copyright 2010 Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution. 13// * Neither the name of Google Inc. nor the names of its contributors 14// may be used to endorse or promote products derived from this software 15// without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29#include "utils/auto_array.ipp" 30 31extern "C" { 32#include <sys/types.h> 33} 34 35#include <iostream> 36 37#include <atf-c++.hpp> 38 39#include "utils/defs.hpp" 40 41using utils::auto_array; 42 43 44namespace { 45 46 47/// Mock class to capture calls to the new and delete operators. 48class test_array { 49public: 50 /// User-settable cookie to disambiguate instances of this class. 51 int m_value; 52 53 /// The current balance of existing test_array instances. 54 static ssize_t m_nblocks; 55 56 /// Captures invalid calls to new on an array. 57 /// 58 /// \param unused_size The amount of memory to allocate, in bytes. 59 /// 60 /// \return Nothing; this always fails the test case. 61 void* 62 operator new(const size_t UTILS_UNUSED_PARAM(size)) 63 { 64 ATF_FAIL("New called but should have been new[]"); 65 return new int(5); 66 } 67 68 /// Obtains memory for a new instance and increments m_nblocks. 69 /// 70 /// \param size The amount of memory to allocate, in bytes. 71 /// 72 /// \return A pointer to the allocated memory. 73 /// 74 /// \throw std::bad_alloc If the memory cannot be allocated. 75 void* 76 operator new[](const size_t size) 77 { 78 void* mem = ::operator new(size); 79 m_nblocks++; 80 std::cout << "Allocated 'test_array' object " << mem << "\n"; 81 return mem; 82 } 83 84 /// Captures invalid calls to delete on an array. 85 /// 86 /// \param unused_mem The pointer to the memory to be deleted. 87 /// 88 /// \return Nothing; this always fails the test case. 89 void 90 operator delete(void* UTILS_UNUSED_PARAM(mem)) 91 { 92 ATF_FAIL("Delete called but should have been delete[]"); 93 } 94 95 /// Deletes a previously allocated array and decrements m_nblocks. 96 /// 97 /// \param mem The pointer to the memory to be deleted. 98 void 99 operator delete[](void* mem) 100 { 101 std::cout << "Releasing 'test_array' object " << mem << "\n"; 102 if (m_nblocks == 0) 103 ATF_FAIL("Unbalanced delete[]"); 104 m_nblocks--; 105 ::operator delete(mem); 106 } 107}; 108 109 110ssize_t test_array::m_nblocks = 0; 111 112 113} // anonymous namespace 114 115 116ATF_TEST_CASE(scope); 117ATF_TEST_CASE_HEAD(scope) 118{ 119 set_md_var("descr", "Tests the automatic scope handling in the " 120 "auto_array smart pointer class"); 121} 122ATF_TEST_CASE_BODY(scope) 123{ 124 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 125 { 126 auto_array< test_array > t(new test_array[10]); 127 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 128 } 129 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 130} 131 132 133ATF_TEST_CASE(copy); 134ATF_TEST_CASE_HEAD(copy) 135{ 136 set_md_var("descr", "Tests the auto_array smart pointer class' copy " 137 "constructor"); 138} 139ATF_TEST_CASE_BODY(copy) 140{ 141 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 142 { 143 auto_array< test_array > t1(new test_array[10]); 144 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 145 146 { 147 auto_array< test_array > t2(t1); 148 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 149 } 150 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 151 } 152 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 153} 154 155 156ATF_TEST_CASE(copy_ref); 157ATF_TEST_CASE_HEAD(copy_ref) 158{ 159 set_md_var("descr", "Tests the auto_array smart pointer class' copy " 160 "constructor through the auxiliary ref object"); 161} 162ATF_TEST_CASE_BODY(copy_ref) 163{ 164 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 165 { 166 auto_array< test_array > t1(new test_array[10]); 167 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 168 169 { 170 auto_array< test_array > t2 = t1; 171 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 172 } 173 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 174 } 175 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 176} 177 178 179ATF_TEST_CASE(get); 180ATF_TEST_CASE_HEAD(get) 181{ 182 set_md_var("descr", "Tests the auto_array smart pointer class' get " 183 "method"); 184} 185ATF_TEST_CASE_BODY(get) 186{ 187 test_array* ta = new test_array[10]; 188 auto_array< test_array > t(ta); 189 ATF_REQUIRE_EQ(t.get(), ta); 190} 191 192 193ATF_TEST_CASE(release); 194ATF_TEST_CASE_HEAD(release) 195{ 196 set_md_var("descr", "Tests the auto_array smart pointer class' release " 197 "method"); 198} 199ATF_TEST_CASE_BODY(release) 200{ 201 test_array* ta1 = new test_array[10]; 202 { 203 auto_array< test_array > t(ta1); 204 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 205 test_array* ta2 = t.release(); 206 ATF_REQUIRE_EQ(ta2, ta1); 207 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 208 } 209 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 210 delete [] ta1; 211} 212 213 214ATF_TEST_CASE(reset); 215ATF_TEST_CASE_HEAD(reset) 216{ 217 set_md_var("descr", "Tests the auto_array smart pointer class' reset " 218 "method"); 219} 220ATF_TEST_CASE_BODY(reset) 221{ 222 test_array* ta1 = new test_array[10]; 223 test_array* ta2 = new test_array[10]; 224 ATF_REQUIRE_EQ(test_array::m_nblocks, 2); 225 226 { 227 auto_array< test_array > t(ta1); 228 ATF_REQUIRE_EQ(test_array::m_nblocks, 2); 229 t.reset(ta2); 230 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 231 t.reset(); 232 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 233 } 234 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 235} 236 237 238ATF_TEST_CASE(assign); 239ATF_TEST_CASE_HEAD(assign) 240{ 241 set_md_var("descr", "Tests the auto_array smart pointer class' " 242 "assignment operator"); 243} 244ATF_TEST_CASE_BODY(assign) 245{ 246 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 247 { 248 auto_array< test_array > t1(new test_array[10]); 249 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 250 251 { 252 auto_array< test_array > t2; 253 t2 = t1; 254 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 255 } 256 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 257 } 258 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 259} 260 261 262ATF_TEST_CASE(assign_ref); 263ATF_TEST_CASE_HEAD(assign_ref) 264{ 265 set_md_var("descr", "Tests the auto_array smart pointer class' " 266 "assignment operator through the auxiliary ref " 267 "object"); 268} 269ATF_TEST_CASE_BODY(assign_ref) 270{ 271 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 272 { 273 auto_array< test_array > t1(new test_array[10]); 274 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 275 276 { 277 auto_array< test_array > t2; 278 t2 = t1; 279 ATF_REQUIRE_EQ(test_array::m_nblocks, 1); 280 } 281 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 282 } 283 ATF_REQUIRE_EQ(test_array::m_nblocks, 0); 284} 285 286 287ATF_TEST_CASE(access); 288ATF_TEST_CASE_HEAD(access) 289{ 290 set_md_var("descr", "Tests the auto_array smart pointer class' access " 291 "operator"); 292} 293ATF_TEST_CASE_BODY(access) 294{ 295 auto_array< test_array > t(new test_array[10]); 296 297 for (int i = 0; i < 10; i++) 298 t[i].m_value = i * 2; 299 300 for (int i = 0; i < 10; i++) 301 ATF_REQUIRE_EQ(t[i].m_value, i * 2); 302} 303 304 305ATF_INIT_TEST_CASES(tcs) 306{ 307 ATF_ADD_TEST_CASE(tcs, scope); 308 ATF_ADD_TEST_CASE(tcs, copy); 309 ATF_ADD_TEST_CASE(tcs, copy_ref); 310 ATF_ADD_TEST_CASE(tcs, get); 311 ATF_ADD_TEST_CASE(tcs, release); 312 ATF_ADD_TEST_CASE(tcs, reset); 313 ATF_ADD_TEST_CASE(tcs, assign); 314 ATF_ADD_TEST_CASE(tcs, assign_ref); 315 ATF_ADD_TEST_CASE(tcs, access); 316} 317