PageRenderTime 60ms CodeModel.GetById 11ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/tests/llinstancetracker_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 232 lines | 172 code | 15 blank | 45 comment | 5 complexity | 5f6b89e18f572e3913902a9981ee5d46 MD5 | raw file
  1/**
  2 * @file   llinstancetracker_test.cpp
  3 * @author Nat Goodspeed
  4 * @date   2009-11-10
  5 * @brief  Test for llinstancetracker.
  6 * 
  7 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  8 * Second Life Viewer Source Code
  9 * Copyright (C) 2010, Linden Research, Inc.
 10 * 
 11 * This library is free software; you can redistribute it and/or
 12 * modify it under the terms of the GNU Lesser General Public
 13 * License as published by the Free Software Foundation;
 14 * version 2.1 of the License only.
 15 * 
 16 * This library is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * Lesser General Public License for more details.
 20 * 
 21 * You should have received a copy of the GNU Lesser General Public
 22 * License along with this library; if not, write to the Free Software
 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 24 * 
 25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 26 * $/LicenseInfo$
 27 */
 28
 29// Precompiled header
 30#include "linden_common.h"
 31// associated header
 32#include "llinstancetracker.h"
 33// STL headers
 34#include <string>
 35#include <vector>
 36#include <set>
 37#include <algorithm>                // std::sort()
 38// std headers
 39// external library headers
 40#include <boost/scoped_ptr.hpp>
 41// other Linden headers
 42#include "../test/lltut.h"
 43#include "wrapllerrs.h"
 44
 45struct Keyed: public LLInstanceTracker<Keyed, std::string>
 46{
 47    Keyed(const std::string& name):
 48        LLInstanceTracker<Keyed, std::string>(name),
 49        mName(name)
 50    {}
 51    std::string mName;
 52};
 53
 54struct Unkeyed: public LLInstanceTracker<Unkeyed>
 55{
 56};
 57
 58/*****************************************************************************
 59*   TUT
 60*****************************************************************************/
 61namespace tut
 62{
 63    struct llinstancetracker_data
 64    {
 65    };
 66    typedef test_group<llinstancetracker_data> llinstancetracker_group;
 67    typedef llinstancetracker_group::object object;
 68    llinstancetracker_group llinstancetrackergrp("llinstancetracker");
 69
 70    template<> template<>
 71    void object::test<1>()
 72    {
 73        ensure_equals(Keyed::instanceCount(), 0);
 74        {
 75            Keyed one("one");
 76            ensure_equals(Keyed::instanceCount(), 1);
 77            Keyed* found = Keyed::getInstance("one");
 78            ensure("couldn't find stack Keyed", found);
 79            ensure_equals("found wrong Keyed instance", found, &one);
 80            {
 81                boost::scoped_ptr<Keyed> two(new Keyed("two"));
 82                ensure_equals(Keyed::instanceCount(), 2);
 83                Keyed* found = Keyed::getInstance("two");
 84                ensure("couldn't find heap Keyed", found);
 85                ensure_equals("found wrong Keyed instance", found, two.get());
 86            }
 87            ensure_equals(Keyed::instanceCount(), 1);
 88        }
 89        Keyed* found = Keyed::getInstance("one");
 90        ensure("Keyed key lives too long", ! found);
 91        ensure_equals(Keyed::instanceCount(), 0);
 92    }
 93
 94    template<> template<>
 95    void object::test<2>()
 96    {
 97        ensure_equals(Unkeyed::instanceCount(), 0);
 98        {
 99            Unkeyed one;
100            ensure_equals(Unkeyed::instanceCount(), 1);
101            Unkeyed* found = Unkeyed::getInstance(&one);
102            ensure_equals(found, &one);
103            {
104                boost::scoped_ptr<Unkeyed> two(new Unkeyed);
105                ensure_equals(Unkeyed::instanceCount(), 2);
106                Unkeyed* found = Unkeyed::getInstance(two.get());
107                ensure_equals(found, two.get());
108            }
109            ensure_equals(Unkeyed::instanceCount(), 1);
110        }
111        ensure_equals(Unkeyed::instanceCount(), 0);
112    }
113
114    template<> template<>
115    void object::test<3>()
116    {
117        Keyed one("one"), two("two"), three("three");
118        // We don't want to rely on the underlying container delivering keys
119        // in any particular order. That allows us the flexibility to
120        // reimplement LLInstanceTracker using, say, a hash map instead of a
121        // std::map. We DO insist that every key appear exactly once.
122        typedef std::vector<std::string> StringVector;
123        StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
124        std::sort(keys.begin(), keys.end());
125        StringVector::const_iterator ki(keys.begin());
126        ensure_equals(*ki++, "one");
127        ensure_equals(*ki++, "three");
128        ensure_equals(*ki++, "two");
129        // Use ensure() here because ensure_equals would want to display
130        // mismatched values, and frankly that wouldn't help much.
131        ensure("didn't reach end", ki == keys.end());
132
133        // Use a somewhat different approach to order independence with
134        // beginInstances(): explicitly capture the instances we know in a
135        // set, and delete them as we iterate through.
136        typedef std::set<Keyed*> InstanceSet;
137        InstanceSet instances;
138        instances.insert(&one);
139        instances.insert(&two);
140        instances.insert(&three);
141        for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
142             ii != iend; ++ii)
143        {
144            Keyed& ref = *ii;
145            ensure_equals("spurious instance", instances.erase(&ref), 1);
146        }
147        ensure_equals("unreported instance", instances.size(), 0);
148    }
149
150    template<> template<>
151    void object::test<4>()
152    {
153        Unkeyed one, two, three;
154        typedef std::set<Unkeyed*> KeySet;
155    
156        KeySet instances;
157        instances.insert(&one);
158        instances.insert(&two);
159        instances.insert(&three);
160
161		for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances()); ii != iend; ++ii)
162		{
163			Unkeyed& ref = *ii;
164			ensure_equals("spurious instance", instances.erase(&ref), 1);
165		}
166
167        ensure_equals("unreported instance", instances.size(), 0);
168    }
169
170    template<> template<>
171    void object::test<5>()
172    {
173        set_test_name("delete Keyed with outstanding instance_iter");
174        std::string what;
175        Keyed* keyed = new Keyed("one");
176        {
177            WrapLL_ERRS wrapper;
178            Keyed::instance_iter i(Keyed::beginInstances());
179            try
180            {
181                delete keyed;
182            }
183            catch (const WrapLL_ERRS::FatalException& e)
184            {
185                what = e.what();
186            }
187        }
188        ensure(! what.empty());
189    }
190
191    template<> template<>
192    void object::test<6>()
193    {
194        set_test_name("delete Keyed with outstanding key_iter");
195        std::string what;
196        Keyed* keyed = new Keyed("one");
197        {
198            WrapLL_ERRS wrapper;
199            Keyed::key_iter i(Keyed::beginKeys());
200            try
201            {
202                delete keyed;
203            }
204            catch (const WrapLL_ERRS::FatalException& e)
205            {
206                what = e.what();
207            }
208        }
209        ensure(! what.empty());
210    }
211
212    template<> template<>
213    void object::test<7>()
214    {
215        set_test_name("delete Unkeyed with outstanding instance_iter");
216        std::string what;
217        Unkeyed* unkeyed = new Unkeyed;
218        {
219            WrapLL_ERRS wrapper;
220            Unkeyed::instance_iter i(Unkeyed::beginInstances());
221            try
222            {
223                delete unkeyed;
224            }
225            catch (const WrapLL_ERRS::FatalException& e)
226            {
227                what = e.what();
228            }
229        }
230        ensure(! what.empty());
231    }
232} // namespace tut