xref: /src/contrib/kyua/utils/auto_array_test.cpp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
108334c51SBrooks Davis // Copyright 2010 The Kyua Authors.
208334c51SBrooks Davis // All rights reserved.
308334c51SBrooks Davis //
408334c51SBrooks Davis // Redistribution and use in source and binary forms, with or without
508334c51SBrooks Davis // modification, are permitted provided that the following conditions are
608334c51SBrooks Davis // met:
708334c51SBrooks Davis //
808334c51SBrooks Davis // * Redistributions of source code must retain the above copyright
908334c51SBrooks Davis //   notice, this list of conditions and the following disclaimer.
1008334c51SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
1108334c51SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
1208334c51SBrooks Davis //   documentation and/or other materials provided with the distribution.
1308334c51SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
1408334c51SBrooks Davis //   may be used to endorse or promote products derived from this software
1508334c51SBrooks Davis //   without specific prior written permission.
1608334c51SBrooks Davis //
1708334c51SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1808334c51SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1908334c51SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2008334c51SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2108334c51SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2208334c51SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2308334c51SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2408334c51SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2508334c51SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2608334c51SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2708334c51SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2808334c51SBrooks Davis 
2908334c51SBrooks Davis #include "utils/auto_array.ipp"
3008334c51SBrooks Davis 
3108334c51SBrooks Davis extern "C" {
3208334c51SBrooks Davis #include <sys/types.h>
3308334c51SBrooks Davis }
3408334c51SBrooks Davis 
3508334c51SBrooks Davis #include <iostream>
3608334c51SBrooks Davis 
3708334c51SBrooks Davis #include <atf-c++.hpp>
3808334c51SBrooks Davis 
3908334c51SBrooks Davis #include "utils/defs.hpp"
4008334c51SBrooks Davis 
4108334c51SBrooks Davis using utils::auto_array;
4208334c51SBrooks Davis 
4308334c51SBrooks Davis 
4408334c51SBrooks Davis namespace {
4508334c51SBrooks Davis 
4608334c51SBrooks Davis 
4708334c51SBrooks Davis /// Mock class to capture calls to the new and delete operators.
4808334c51SBrooks Davis class test_array {
4908334c51SBrooks Davis public:
5008334c51SBrooks Davis     /// User-settable cookie to disambiguate instances of this class.
5108334c51SBrooks Davis     int m_value;
5208334c51SBrooks Davis 
5308334c51SBrooks Davis     /// The current balance of existing test_array instances.
5408334c51SBrooks Davis     static ssize_t m_nblocks;
5508334c51SBrooks Davis 
5608334c51SBrooks Davis     /// Captures invalid calls to new on an array.
5708334c51SBrooks Davis     ///
5808334c51SBrooks Davis     /// \return Nothing; this always fails the test case.
5908334c51SBrooks Davis     void*
operator new(const size_t)6008334c51SBrooks Davis     operator new(const size_t /* size */)
6108334c51SBrooks Davis     {
6208334c51SBrooks Davis         ATF_FAIL("New called but should have been new[]");
6308334c51SBrooks Davis         return new int(5);
6408334c51SBrooks Davis     }
6508334c51SBrooks Davis 
6608334c51SBrooks Davis     /// Obtains memory for a new instance and increments m_nblocks.
6708334c51SBrooks Davis     ///
6808334c51SBrooks Davis     /// \param size The amount of memory to allocate, in bytes.
6908334c51SBrooks Davis     ///
7008334c51SBrooks Davis     /// \return A pointer to the allocated memory.
7108334c51SBrooks Davis     ///
7208334c51SBrooks Davis     /// \throw std::bad_alloc If the memory cannot be allocated.
7308334c51SBrooks Davis     void*
operator new[](const size_t size)7408334c51SBrooks Davis     operator new[](const size_t size)
7508334c51SBrooks Davis     {
7608334c51SBrooks Davis         void* mem = ::operator new(size);
7708334c51SBrooks Davis         m_nblocks++;
7808334c51SBrooks Davis         std::cout << "Allocated 'test_array' object " << mem << "\n";
7908334c51SBrooks Davis         return mem;
8008334c51SBrooks Davis     }
8108334c51SBrooks Davis 
8208334c51SBrooks Davis     /// Captures invalid calls to delete on an array.
8308334c51SBrooks Davis     ///
8408334c51SBrooks Davis     /// \return Nothing; this always fails the test case.
8508334c51SBrooks Davis     void
operator delete(void *)8608334c51SBrooks Davis     operator delete(void* /* mem */)
8708334c51SBrooks Davis     {
8808334c51SBrooks Davis         ATF_FAIL("Delete called but should have been delete[]");
8908334c51SBrooks Davis     }
9008334c51SBrooks Davis 
9108334c51SBrooks Davis     /// Deletes a previously allocated array and decrements m_nblocks.
9208334c51SBrooks Davis     ///
9308334c51SBrooks Davis     /// \param mem The pointer to the memory to be deleted.
9408334c51SBrooks Davis     void
operator delete[](void * mem)9508334c51SBrooks Davis     operator delete[](void* mem)
9608334c51SBrooks Davis     {
9708334c51SBrooks Davis         std::cout << "Releasing 'test_array' object " << mem << "\n";
9808334c51SBrooks Davis         if (m_nblocks == 0)
9908334c51SBrooks Davis             ATF_FAIL("Unbalanced delete[]");
10008334c51SBrooks Davis         m_nblocks--;
10108334c51SBrooks Davis         ::operator delete(mem);
10208334c51SBrooks Davis     }
10308334c51SBrooks Davis };
10408334c51SBrooks Davis 
10508334c51SBrooks Davis 
10608334c51SBrooks Davis ssize_t test_array::m_nblocks = 0;
10708334c51SBrooks Davis 
10808334c51SBrooks Davis 
10908334c51SBrooks Davis }  // anonymous namespace
11008334c51SBrooks Davis 
11108334c51SBrooks Davis 
11208334c51SBrooks Davis ATF_TEST_CASE(scope);
ATF_TEST_CASE_HEAD(scope)11308334c51SBrooks Davis ATF_TEST_CASE_HEAD(scope)
11408334c51SBrooks Davis {
11508334c51SBrooks Davis     set_md_var("descr", "Tests the automatic scope handling in the "
11608334c51SBrooks Davis                "auto_array smart pointer class");
11708334c51SBrooks Davis }
ATF_TEST_CASE_BODY(scope)11808334c51SBrooks Davis ATF_TEST_CASE_BODY(scope)
11908334c51SBrooks Davis {
12008334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
12108334c51SBrooks Davis     {
12208334c51SBrooks Davis         auto_array< test_array > t(new test_array[10]);
12308334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
12408334c51SBrooks Davis     }
12508334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
12608334c51SBrooks Davis }
12708334c51SBrooks Davis 
12808334c51SBrooks Davis 
12908334c51SBrooks Davis ATF_TEST_CASE(copy);
ATF_TEST_CASE_HEAD(copy)13008334c51SBrooks Davis ATF_TEST_CASE_HEAD(copy)
13108334c51SBrooks Davis {
13208334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' copy "
13308334c51SBrooks Davis                "constructor");
13408334c51SBrooks Davis }
ATF_TEST_CASE_BODY(copy)13508334c51SBrooks Davis ATF_TEST_CASE_BODY(copy)
13608334c51SBrooks Davis {
13708334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
13808334c51SBrooks Davis     {
13908334c51SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
14008334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
14108334c51SBrooks Davis 
14208334c51SBrooks Davis         {
14308334c51SBrooks Davis             auto_array< test_array > t2(t1);
14408334c51SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
14508334c51SBrooks Davis         }
14608334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
14708334c51SBrooks Davis     }
14808334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
14908334c51SBrooks Davis }
15008334c51SBrooks Davis 
15108334c51SBrooks Davis 
15208334c51SBrooks Davis ATF_TEST_CASE(copy_ref);
ATF_TEST_CASE_HEAD(copy_ref)15308334c51SBrooks Davis ATF_TEST_CASE_HEAD(copy_ref)
15408334c51SBrooks Davis {
15508334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' copy "
15608334c51SBrooks Davis                "constructor through the auxiliary ref object");
15708334c51SBrooks Davis }
ATF_TEST_CASE_BODY(copy_ref)15808334c51SBrooks Davis ATF_TEST_CASE_BODY(copy_ref)
15908334c51SBrooks Davis {
16008334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
16108334c51SBrooks Davis     {
16208334c51SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
16308334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
16408334c51SBrooks Davis 
16508334c51SBrooks Davis         {
16608334c51SBrooks Davis             auto_array< test_array > t2 = t1;
16708334c51SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
16808334c51SBrooks Davis         }
16908334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
17008334c51SBrooks Davis     }
17108334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
17208334c51SBrooks Davis }
17308334c51SBrooks Davis 
17408334c51SBrooks Davis 
17508334c51SBrooks Davis ATF_TEST_CASE(get);
ATF_TEST_CASE_HEAD(get)17608334c51SBrooks Davis ATF_TEST_CASE_HEAD(get)
17708334c51SBrooks Davis {
17808334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' get "
17908334c51SBrooks Davis                "method");
18008334c51SBrooks Davis }
ATF_TEST_CASE_BODY(get)18108334c51SBrooks Davis ATF_TEST_CASE_BODY(get)
18208334c51SBrooks Davis {
18308334c51SBrooks Davis     test_array* ta = new test_array[10];
18408334c51SBrooks Davis     auto_array< test_array > t(ta);
18508334c51SBrooks Davis     ATF_REQUIRE_EQ(t.get(), ta);
18608334c51SBrooks Davis }
18708334c51SBrooks Davis 
18808334c51SBrooks Davis 
18908334c51SBrooks Davis ATF_TEST_CASE(release);
ATF_TEST_CASE_HEAD(release)19008334c51SBrooks Davis ATF_TEST_CASE_HEAD(release)
19108334c51SBrooks Davis {
19208334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' release "
19308334c51SBrooks Davis                "method");
19408334c51SBrooks Davis }
ATF_TEST_CASE_BODY(release)19508334c51SBrooks Davis ATF_TEST_CASE_BODY(release)
19608334c51SBrooks Davis {
19708334c51SBrooks Davis     test_array* ta1 = new test_array[10];
19808334c51SBrooks Davis     {
19908334c51SBrooks Davis         auto_array< test_array > t(ta1);
20008334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
20108334c51SBrooks Davis         test_array* ta2 = t.release();
20208334c51SBrooks Davis         ATF_REQUIRE_EQ(ta2, ta1);
20308334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
20408334c51SBrooks Davis     }
20508334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
20608334c51SBrooks Davis     delete [] ta1;
20708334c51SBrooks Davis }
20808334c51SBrooks Davis 
20908334c51SBrooks Davis 
21008334c51SBrooks Davis ATF_TEST_CASE(reset);
ATF_TEST_CASE_HEAD(reset)21108334c51SBrooks Davis ATF_TEST_CASE_HEAD(reset)
21208334c51SBrooks Davis {
21308334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' reset "
21408334c51SBrooks Davis                "method");
21508334c51SBrooks Davis }
ATF_TEST_CASE_BODY(reset)21608334c51SBrooks Davis ATF_TEST_CASE_BODY(reset)
21708334c51SBrooks Davis {
21808334c51SBrooks Davis     test_array* ta1 = new test_array[10];
21908334c51SBrooks Davis     test_array* ta2 = new test_array[10];
22008334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
22108334c51SBrooks Davis 
22208334c51SBrooks Davis     {
22308334c51SBrooks Davis         auto_array< test_array > t(ta1);
22408334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
22508334c51SBrooks Davis         t.reset(ta2);
22608334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
22708334c51SBrooks Davis         t.reset();
22808334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
22908334c51SBrooks Davis     }
23008334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
23108334c51SBrooks Davis }
23208334c51SBrooks Davis 
23308334c51SBrooks Davis 
23408334c51SBrooks Davis ATF_TEST_CASE(assign);
ATF_TEST_CASE_HEAD(assign)23508334c51SBrooks Davis ATF_TEST_CASE_HEAD(assign)
23608334c51SBrooks Davis {
23708334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' "
23808334c51SBrooks Davis                "assignment operator");
23908334c51SBrooks Davis }
ATF_TEST_CASE_BODY(assign)24008334c51SBrooks Davis ATF_TEST_CASE_BODY(assign)
24108334c51SBrooks Davis {
24208334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
24308334c51SBrooks Davis     {
24408334c51SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
24508334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
24608334c51SBrooks Davis 
24708334c51SBrooks Davis         {
24808334c51SBrooks Davis             auto_array< test_array > t2;
24908334c51SBrooks Davis             t2 = t1;
25008334c51SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
25108334c51SBrooks Davis         }
25208334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
25308334c51SBrooks Davis     }
25408334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
25508334c51SBrooks Davis }
25608334c51SBrooks Davis 
25708334c51SBrooks Davis 
25808334c51SBrooks Davis ATF_TEST_CASE(assign_ref);
ATF_TEST_CASE_HEAD(assign_ref)25908334c51SBrooks Davis ATF_TEST_CASE_HEAD(assign_ref)
26008334c51SBrooks Davis {
26108334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' "
26208334c51SBrooks Davis                "assignment operator through the auxiliary ref "
26308334c51SBrooks Davis                "object");
26408334c51SBrooks Davis }
ATF_TEST_CASE_BODY(assign_ref)26508334c51SBrooks Davis ATF_TEST_CASE_BODY(assign_ref)
26608334c51SBrooks Davis {
26708334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
26808334c51SBrooks Davis     {
26908334c51SBrooks Davis         auto_array< test_array > t1(new test_array[10]);
27008334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
27108334c51SBrooks Davis 
27208334c51SBrooks Davis         {
27308334c51SBrooks Davis             auto_array< test_array > t2;
27408334c51SBrooks Davis             t2 = t1;
27508334c51SBrooks Davis             ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
27608334c51SBrooks Davis         }
27708334c51SBrooks Davis         ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
27808334c51SBrooks Davis     }
27908334c51SBrooks Davis     ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
28008334c51SBrooks Davis }
28108334c51SBrooks Davis 
28208334c51SBrooks Davis 
28308334c51SBrooks Davis ATF_TEST_CASE(access);
ATF_TEST_CASE_HEAD(access)28408334c51SBrooks Davis ATF_TEST_CASE_HEAD(access)
28508334c51SBrooks Davis {
28608334c51SBrooks Davis     set_md_var("descr", "Tests the auto_array smart pointer class' access "
28708334c51SBrooks Davis                "operator");
28808334c51SBrooks Davis }
ATF_TEST_CASE_BODY(access)28908334c51SBrooks Davis ATF_TEST_CASE_BODY(access)
29008334c51SBrooks Davis {
29108334c51SBrooks Davis     auto_array< test_array > t(new test_array[10]);
29208334c51SBrooks Davis 
29308334c51SBrooks Davis     for (int i = 0; i < 10; i++)
29408334c51SBrooks Davis         t[i].m_value = i * 2;
29508334c51SBrooks Davis 
29608334c51SBrooks Davis     for (int i = 0; i < 10; i++)
29708334c51SBrooks Davis         ATF_REQUIRE_EQ(t[i].m_value, i * 2);
29808334c51SBrooks Davis }
29908334c51SBrooks Davis 
30008334c51SBrooks Davis 
ATF_INIT_TEST_CASES(tcs)30108334c51SBrooks Davis ATF_INIT_TEST_CASES(tcs)
30208334c51SBrooks Davis {
30308334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, scope);
30408334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, copy);
30508334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, copy_ref);
30608334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, get);
30708334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, release);
30808334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, reset);
30908334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, assign);
31008334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, assign_ref);
31108334c51SBrooks Davis     ATF_ADD_TEST_CASE(tcs, access);
31208334c51SBrooks Davis }
313