1// Copyright (c) 2013, 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 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30// Utility class for creating a temporary file for unit tests 31// that is deleted in the destructor. 32 33#ifndef GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE 34#define GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE 35 36#include <unistd.h> 37#include <sys/types.h> 38 39#include <string> 40 41#include "breakpad_googletest_includes.h" 42#include "common/linux/eintr_wrapper.h" 43#include "common/tests/auto_tempdir.h" 44 45namespace google_breakpad { 46 47class AutoTestFile { 48 public: 49 // Create a new empty test file. 50 // test_prefix: (input) test-specific prefix, can't be NULL. 51 explicit AutoTestFile(const char* test_prefix) { 52 Init(test_prefix); 53 } 54 55 // Create a new test file, and fill it with initial data from a C string. 56 // The terminating zero is not written. 57 // test_prefix: (input) test-specific prefix, can't be NULL. 58 // text: (input) initial content. 59 AutoTestFile(const char* test_prefix, const char* text) { 60 Init(test_prefix); 61 if (fd_ >= 0) 62 WriteText(text, static_cast<size_t>(strlen(text))); 63 } 64 65 AutoTestFile(const char* test_prefix, const char* text, size_t text_len) { 66 Init(test_prefix); 67 if (fd_ >= 0) 68 WriteText(text, text_len); 69 } 70 71 // Destroy test file on scope exit. 72 ~AutoTestFile() { 73 if (fd_ >= 0) { 74 close(fd_); 75 fd_ = -1; 76 } 77 } 78 79 // Returns true iff the test file could be created properly. 80 // Useful in tests inside EXPECT_TRUE(file.IsOk()); 81 bool IsOk() { 82 return fd_ >= 0; 83 } 84 85 // Returns the Posix file descriptor for the test file, or -1 86 // If IsOk() returns false. Note: on Windows, this always returns -1. 87 int GetFd() { 88 return fd_; 89 } 90 91 private: 92 void Init(const char* test_prefix) { 93 fd_ = -1; 94 char path_templ[PATH_MAX]; 95 int ret = snprintf(path_templ, sizeof(path_templ), 96 TEMPDIR "/%s-unittest.XXXXXX", 97 test_prefix); 98 if (ret >= static_cast<int>(sizeof(path_templ))) 99 return; 100 101 fd_ = mkstemp(path_templ); 102 if (fd_ < 0) 103 return; 104 105 unlink(path_templ); 106 } 107 108 void WriteText(const char* text, size_t text_len) { 109 ssize_t r = HANDLE_EINTR(write(fd_, text, text_len)); 110 if (r != static_cast<ssize_t>(text_len)) { 111 close(fd_); 112 fd_ = -1; 113 return; 114 } 115 116 lseek(fd_, 0, SEEK_SET); 117 } 118 119 int fd_; 120}; 121 122} // namespace google_breakpad 123 124#endif // GOOGLE_BREAKPAD_COMMON_LINUX_TESTS_AUTO_TESTFILE 125