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 45 namespace google_breakpad { 46 47 class AutoTestFile { 48 public: 49 // Create a new empty test file. 50 // test_prefix: (input) test-specific prefix, can't be NULL. AutoTestFile(const char * test_prefix)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. AutoTestFile(const char * test_prefix,const char * text)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 AutoTestFile(const char * test_prefix,const char * text,size_t text_len)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. ~AutoTestFile()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()); 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. GetFd()87 int GetFd() { 88 return fd_; 89 } 90 91 private: Init(const char * test_prefix)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 WriteText(const char * text,size_t text_len)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