Home | History | Annotate | Download | only in test
      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