1 /* Copyright (c) 2017, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #include "file_test.h" 16 17 #include <assert.h> 18 #include <string.h> 19 20 #include <memory> 21 #include <string> 22 #include <utility> 23 24 #include <gtest/gtest.h> 25 26 #include <openssl/err.h> 27 28 29 std::string GetTestData(const char *path); 30 31 class StringLineReader : public FileTest::LineReader { 32 public: 33 explicit StringLineReader(const std::string &data) 34 : data_(data), offset_(0) {} 35 36 FileTest::ReadResult ReadLine(char *out, size_t len) override { 37 assert(len > 0); 38 if (offset_ == data_.size()) { 39 return FileTest::kReadEOF; 40 } 41 42 size_t idx = data_.find('\n', offset_); 43 if (idx == std::string::npos) { 44 idx = data_.size(); 45 } else { 46 idx++; // Include the newline. 47 } 48 49 if (idx - offset_ > len - 1) { 50 ADD_FAILURE() << "Line too long."; 51 return FileTest::kReadError; 52 } 53 54 memcpy(out, data_.data() + offset_, idx - offset_); 55 out[idx - offset_] = '\0'; 56 offset_ = idx; 57 return FileTest::kReadSuccess; 58 } 59 60 private: 61 std::string data_; 62 size_t offset_; 63 64 StringLineReader(const StringLineReader &) = delete; 65 StringLineReader &operator=(const StringLineReader &) = delete; 66 }; 67 68 void FileTestGTest(const char *path, std::function<void(FileTest *)> run_test) { 69 std::unique_ptr<StringLineReader> reader( 70 new StringLineReader(GetTestData(path))); 71 FileTest t(std::move(reader), nullptr, false); 72 73 while (true) { 74 switch (t.ReadNext()) { 75 case FileTest::kReadError: 76 ADD_FAILURE() << "Error reading test."; 77 return; 78 case FileTest::kReadEOF: 79 return; 80 case FileTest::kReadSuccess: 81 break; 82 } 83 84 const testing::TestResult *test_result = 85 testing::UnitTest::GetInstance()->current_test_info()->result(); 86 int before_part_count = test_result->total_part_count(); 87 88 SCOPED_TRACE(testing::Message() << path << ", line " << t.start_line()); 89 run_test(&t); 90 91 // Check for failures from the most recent test. 92 bool failed = false; 93 for (int i = before_part_count; i < test_result->total_part_count(); i++) { 94 if (test_result->GetTestPartResult(i).failed()) { 95 failed = true; 96 break; 97 } 98 } 99 100 // Clean up the error queue for the next test, reporting it on failure. 101 if (failed) { 102 ERR_print_errors_fp(stdout); 103 } else { 104 ERR_clear_error(); 105 } 106 } 107 } 108