auto_array_test.cpp revision 275988
1// Copyright (c) 2007 The NetBSD Foundation, 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
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8//    notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10//    notice, this list of conditions and the following disclaimer in the
11//    documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26#include "atf-c++/detail/auto_array.hpp"
27
28extern "C" {
29#include <sys/types.h>
30}
31
32#include <iostream>
33
34#include <atf-c++.hpp>
35
36extern "C" {
37#include "atf-c/defs.h"
38}
39
40// ------------------------------------------------------------------------
41// Tests for the "auto_array" class.
42// ------------------------------------------------------------------------
43
44class test_array {
45public:
46    int m_value;
47
48    static ssize_t m_nblocks;
49
50    static
51    atf::auto_array< test_array >
52    do_copy(atf::auto_array< test_array >& ta)
53    {
54        return atf::auto_array< test_array >(ta);
55    }
56
57    void* operator new(size_t size ATF_DEFS_ATTRIBUTE_UNUSED)
58    {
59        ATF_FAIL("New called but should have been new[]");
60        return new int(5);
61    }
62
63    void* operator new[](size_t size)
64    {
65        m_nblocks++;
66        void* mem = ::operator new(size);
67        std::cout << "Allocated 'test_array' object " << mem << "\n";
68        return mem;
69    }
70
71    void operator delete(void* mem ATF_DEFS_ATTRIBUTE_UNUSED)
72    {
73        ATF_FAIL("Delete called but should have been delete[]");
74    }
75
76    void operator delete[](void* mem)
77    {
78        std::cout << "Releasing 'test_array' object " << mem << "\n";
79        if (m_nblocks == 0)
80            ATF_FAIL("Unbalanced delete[]");
81        m_nblocks--;
82        ::operator delete(mem);
83    }
84};
85
86ssize_t test_array::m_nblocks = 0;
87
88ATF_TEST_CASE(auto_array_scope);
89ATF_TEST_CASE_HEAD(auto_array_scope)
90{
91    set_md_var("descr", "Tests the automatic scope handling in the "
92               "auto_array smart pointer class");
93}
94ATF_TEST_CASE_BODY(auto_array_scope)
95{
96    using atf::auto_array;
97
98    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
99    {
100        auto_array< test_array > t(new test_array[10]);
101        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
102    }
103    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
104}
105
106ATF_TEST_CASE(auto_array_copy);
107ATF_TEST_CASE_HEAD(auto_array_copy)
108{
109    set_md_var("descr", "Tests the auto_array smart pointer class' copy "
110               "constructor");
111}
112ATF_TEST_CASE_BODY(auto_array_copy)
113{
114    using atf::auto_array;
115
116    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
117    {
118        auto_array< test_array > t1(new test_array[10]);
119        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
120
121        {
122            auto_array< test_array > t2(t1);
123            ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
124        }
125        ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
126    }
127    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
128}
129
130ATF_TEST_CASE(auto_array_copy_ref);
131ATF_TEST_CASE_HEAD(auto_array_copy_ref)
132{
133    set_md_var("descr", "Tests the auto_array smart pointer class' copy "
134               "constructor through the auxiliary auto_array_ref object");
135}
136ATF_TEST_CASE_BODY(auto_array_copy_ref)
137{
138    using atf::auto_array;
139
140    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
141    {
142        auto_array< test_array > t1(new test_array[10]);
143        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
144
145        {
146            auto_array< test_array > t2 = test_array::do_copy(t1);
147            ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
148        }
149        ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
150    }
151    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
152}
153
154ATF_TEST_CASE(auto_array_get);
155ATF_TEST_CASE_HEAD(auto_array_get)
156{
157    set_md_var("descr", "Tests the auto_array smart pointer class' get "
158               "method");
159}
160ATF_TEST_CASE_BODY(auto_array_get)
161{
162    using atf::auto_array;
163
164    test_array* ta = new test_array[10];
165    auto_array< test_array > t(ta);
166    ATF_REQUIRE_EQ(t.get(), ta);
167}
168
169ATF_TEST_CASE(auto_array_release);
170ATF_TEST_CASE_HEAD(auto_array_release)
171{
172    set_md_var("descr", "Tests the auto_array smart pointer class' release "
173               "method");
174}
175ATF_TEST_CASE_BODY(auto_array_release)
176{
177    using atf::auto_array;
178
179    test_array* ta1 = new test_array[10];
180    {
181        auto_array< test_array > t(ta1);
182        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
183        test_array* ta2 = t.release();
184        ATF_REQUIRE_EQ(ta2, ta1);
185        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
186    }
187    ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
188    delete [] ta1;
189}
190
191ATF_TEST_CASE(auto_array_reset);
192ATF_TEST_CASE_HEAD(auto_array_reset)
193{
194    set_md_var("descr", "Tests the auto_array smart pointer class' reset "
195               "method");
196}
197ATF_TEST_CASE_BODY(auto_array_reset)
198{
199    using atf::auto_array;
200
201    test_array* ta1 = new test_array[10];
202    test_array* ta2 = new test_array[10];
203    ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
204
205    {
206        auto_array< test_array > t(ta1);
207        ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
208        t.reset(ta2);
209        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
210        t.reset();
211        ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
212    }
213    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
214}
215
216ATF_TEST_CASE(auto_array_assign);
217ATF_TEST_CASE_HEAD(auto_array_assign)
218{
219    set_md_var("descr", "Tests the auto_array smart pointer class' "
220               "assignment operator");
221}
222ATF_TEST_CASE_BODY(auto_array_assign)
223{
224    using atf::auto_array;
225
226    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
227    {
228        auto_array< test_array > t1(new test_array[10]);
229        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
230
231        {
232            auto_array< test_array > t2;
233            t2 = t1;
234            ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
235        }
236        ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
237    }
238    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
239}
240
241ATF_TEST_CASE(auto_array_assign_ref);
242ATF_TEST_CASE_HEAD(auto_array_assign_ref)
243{
244    set_md_var("descr", "Tests the auto_array smart pointer class' "
245               "assignment operator through the auxiliary auto_array_ref "
246               "object");
247}
248ATF_TEST_CASE_BODY(auto_array_assign_ref)
249{
250    using atf::auto_array;
251
252    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
253    {
254        auto_array< test_array > t1(new test_array[10]);
255        ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
256
257        {
258            auto_array< test_array > t2;
259            t2 = test_array::do_copy(t1);
260            ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
261        }
262        ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
263    }
264    ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
265}
266
267ATF_TEST_CASE(auto_array_access);
268ATF_TEST_CASE_HEAD(auto_array_access)
269{
270    set_md_var("descr", "Tests the auto_array smart pointer class' access "
271               "operator");
272}
273ATF_TEST_CASE_BODY(auto_array_access)
274{
275    using atf::auto_array;
276
277    auto_array< test_array > t(new test_array[10]);
278
279    for (int i = 0; i < 10; i++)
280        t[i].m_value = i * 2;
281
282    for (int i = 0; i < 10; i++)
283        ATF_REQUIRE_EQ(t[i].m_value, i * 2);
284}
285
286// ------------------------------------------------------------------------
287// Main.
288// ------------------------------------------------------------------------
289
290ATF_INIT_TEST_CASES(tcs)
291{
292    // Add the test for the "auto_array" class.
293    ATF_ADD_TEST_CASE(tcs, auto_array_scope);
294    ATF_ADD_TEST_CASE(tcs, auto_array_copy);
295    ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
296    ATF_ADD_TEST_CASE(tcs, auto_array_get);
297    ATF_ADD_TEST_CASE(tcs, auto_array_release);
298    ATF_ADD_TEST_CASE(tcs, auto_array_reset);
299    ATF_ADD_TEST_CASE(tcs, auto_array_assign);
300    ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
301    ATF_ADD_TEST_CASE(tcs, auto_array_access);
302}
303