diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2012-02-07 14:31:27 -0500 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2012-02-07 14:31:27 -0500 | 
| commit | 2681d5403ca0cdf686077d7b14ffa9111f9e9f5d (patch) | |
| tree | 1de7a70c9cf77417b893cdf8a163de315520a213 /indra/test | |
| parent | 33a42b32ca72031a79edca821966f6ebbdcddc93 (diff) | |
| parent | 32e11494ffde368b2ac166e16dc294d66a18492f (diff) | |
Automated merge with file:C%3A%5CUsers%5CNat%5Clinden%5Cviewer-tut-fix
Diffstat (limited to 'indra/test')
| -rw-r--r-- | indra/test/manageapr.h | 46 | ||||
| -rw-r--r-- | indra/test/namedtempfile.h | 114 | 
2 files changed, 160 insertions, 0 deletions
| diff --git a/indra/test/manageapr.h b/indra/test/manageapr.h new file mode 100644 index 0000000000..2452fb6ae4 --- /dev/null +++ b/indra/test/manageapr.h @@ -0,0 +1,46 @@ +/** + * @file   manageapr.h + * @author Nat Goodspeed + * @date   2012-01-13 + * @brief  ManageAPR class for simple test programs + *  + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Copyright (c) 2012, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_MANAGEAPR_H) +#define LL_MANAGEAPR_H + +#include "llapr.h" +#include <boost/noncopyable.hpp> + +/** + * Declare a static instance of this class for dead-simple ll_init_apr() at + * program startup, ll_cleanup_apr() at termination. This is recommended for + * use only with simple test programs. Once you start introducing static + * instances of other classes that depend on APR already being initialized, + * the indeterminate static-constructor-order problem rears its ugly head. + */ +class ManageAPR: public boost::noncopyable +{ +public: +    ManageAPR() +    { +        ll_init_apr(); +    } + +    ~ManageAPR() +    { +        ll_cleanup_apr(); +    } + +    static std::string strerror(apr_status_t rv) +    { +        char errbuf[256]; +        apr_strerror(rv, errbuf, sizeof(errbuf)); +        return errbuf; +    } +}; + +#endif /* ! defined(LL_MANAGEAPR_H) */ diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h new file mode 100644 index 0000000000..aa7058b111 --- /dev/null +++ b/indra/test/namedtempfile.h @@ -0,0 +1,114 @@ +/** + * @file   namedtempfile.h + * @author Nat Goodspeed + * @date   2012-01-13 + * @brief  NamedTempFile class for tests that need disk files as fixtures. + *  + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Copyright (c) 2012, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_NAMEDTEMPFILE_H) +#define LL_NAMEDTEMPFILE_H + +#include "llapr.h" +#include "apr_file_io.h" +#include <string> +#include <boost/function.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/lambda/bind.hpp> +#include <boost/noncopyable.hpp> +#include <iostream> +#include <sstream> + +/** + * Create a text file with specified content "somewhere in the + * filesystem," cleaning up when it goes out of scope. + */ +class NamedTempFile: public boost::noncopyable +{ +public: +    NamedTempFile(const std::string& pfx, const std::string& content, apr_pool_t* pool=gAPRPoolp): +        mPool(pool) +    { +        createFile(pfx, boost::lambda::_1 << content); +    } + +    // Disambiguate when passing string literal +    NamedTempFile(const std::string& pfx, const char* content, apr_pool_t* pool=gAPRPoolp): +        mPool(pool) +    { +        createFile(pfx, boost::lambda::_1 << content); +    } + +    // Function that accepts an ostream ref and (presumably) writes stuff to +    // it, e.g.: +    // (boost::lambda::_1 << "the value is " << 17 << '\n') +    typedef boost::function<void(std::ostream&)> Streamer; + +    NamedTempFile(const std::string& pfx, const Streamer& func, apr_pool_t* pool=gAPRPoolp): +        mPool(pool) +    { +        createFile(pfx, func); +    } + +    ~NamedTempFile() +    { +        ll_apr_assert_status(apr_file_remove(mPath.c_str(), mPool)); +    } + +    std::string getName() const { return mPath; } + +    void peep() +    { +        std::cout << "File '" << mPath << "' contains:\n"; +        std::ifstream reader(mPath.c_str()); +        std::string line; +        while (std::getline(reader, line)) +            std::cout << line << '\n'; +        std::cout << "---\n"; +    } + +private: +    void createFile(const std::string& pfx, const Streamer& func) +    { +        // Create file in a temporary place. +        const char* tempdir = NULL; +        ll_apr_assert_status(apr_temp_dir_get(&tempdir, mPool)); + +        // Construct a temp filename template in that directory. +        char *tempname = NULL; +        ll_apr_assert_status(apr_filepath_merge(&tempname, +                                                tempdir, +                                                (pfx + "XXXXXX").c_str(), +                                                0, +                                                mPool)); + +        // Create a temp file from that template. +        apr_file_t* fp = NULL; +        ll_apr_assert_status(apr_file_mktemp(&fp, +                                             tempname, +                                             APR_CREATE | APR_WRITE | APR_EXCL, +                                             mPool)); +        // apr_file_mktemp() alters tempname with the actual name. Not until +        // now is it valid to capture as our mPath. +        mPath = tempname; + +        // Write desired content. +        std::ostringstream out; +        // Stream stuff to it. +        func(out); + +        std::string data(out.str()); +        apr_size_t writelen(data.length()); +        ll_apr_assert_status(apr_file_write(fp, data.c_str(), &writelen)); +        ll_apr_assert_status(apr_file_close(fp)); +        llassert_always(writelen == data.length()); +    } + +    std::string mPath; +    apr_pool_t* mPool; +}; + +#endif /* ! defined(LL_NAMEDTEMPFILE_H) */ | 
