1 // Copyright 2017 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
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 #include "test_data.h"
29 
30 
31 class StringLineReader : public FileTest::LineReader {
32  public:
StringLineReader(const std::string & data)33   explicit StringLineReader(const std::string &data)
34       : data_(data), offset_(0) {}
35 
ReadLine(char * out,size_t len)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 
FileTestGTest(const char * path,std::function<void (FileTest *)> run_test)68 void FileTestGTest(const char *path, std::function<void(FileTest *)> run_test) {
69   FileTest t(std::make_unique<StringLineReader>(GetTestData(path)), nullptr,
70              false);
71 
72   while (true) {
73     switch (t.ReadNext()) {
74       case FileTest::kReadError:
75         ADD_FAILURE() << "Error reading test.";
76         return;
77       case FileTest::kReadEOF:
78         return;
79       case FileTest::kReadSuccess:
80         break;
81     }
82 
83     const testing::TestResult *test_result =
84         testing::UnitTest::GetInstance()->current_test_info()->result();
85     int before_part_count = test_result->total_part_count();
86 
87     SCOPED_TRACE(testing::Message() << path << ", line " << t.start_line());
88     run_test(&t);
89 
90     // Check for failures from the most recent test.
91     bool failed = false;
92     for (int i = before_part_count; i < test_result->total_part_count(); i++) {
93       if (test_result->GetTestPartResult(i).failed()) {
94         failed = true;
95         break;
96       }
97     }
98 
99     // Clean up the error queue for the next test, reporting it on failure.
100     if (failed) {
101       ERR_print_errors_fp(stdout);
102     } else {
103       ERR_clear_error();
104     }
105   }
106 }
107