Преглед изворни кода

Allow FileTest to read from an abstracted line reader.

In GTest, we'll just burn the files into the binary and not worry about
this. Apparently test files is a one of computer science's great
unsolved problems and everyone has their own special-snowflake way of
doing it. Burning them into the executable is easier.

BUG=129

Change-Id: Ib39759ed4dba6eb9ba97f0282f000739ddf931fe
Reviewed-on: https://boringssl-review.googlesource.com/16506
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin пре 7 година
committed by Adam Langley
родитељ
комит
1f1eeeade2
2 измењених фајлова са 65 додато и 33 уклоњено
  1. +54
    -25
      crypto/test/file_test.cc
  2. +11
    -8
      crypto/test/file_test.h

+ 54
- 25
crypto/test/file_test.cc Прегледај датотеку

@@ -15,11 +15,13 @@
#include "file_test.h"

#include <algorithm>
#include <memory>
#include <utility>

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

@@ -28,18 +30,10 @@
#include "../internal.h"


FileTest::FileTest(const char *path) {
file_ = fopen(path, "r");
if (file_ == nullptr) {
fprintf(stderr, "Could not open file %s: %s.\n", path, strerror(errno));
}
}
FileTest::FileTest(std::unique_ptr<FileTest::LineReader> reader)
: reader_(std::move(reader)) {}

FileTest::~FileTest() {
if (file_ != nullptr) {
fclose(file_);
}
}
FileTest::~FileTest() {}

// FindDelimiter returns a pointer to the first '=' or ':' in |str| or nullptr
// if there is none.
@@ -104,23 +98,19 @@ FileTest::ReadResult FileTest::ReadNext() {

while (true) {
// Read the next line.
if (fgets(buf.get(), kBufLen, file_) == nullptr) {
if (feof(file_)) {
switch (reader_->ReadLine(buf.get(), kBufLen)) {
case kReadError:
fprintf(stderr, "Error reading from input at line %u.\n", line_ + 1);
return kReadError;
case kReadEOF:
// EOF is a valid terminator for a test.
return start_line_ > 0 ? kReadSuccess : kReadEOF;
}
fprintf(stderr, "Error reading from input.\n");
return kReadError;
case kReadSuccess:
break;
}

line_++;
size_t len = strlen(buf.get());
// Check for truncation.
if (len > 0 && buf[len - 1] != '\n' && !feof(file_)) {
fprintf(stderr, "Line %u too long.\n", line_);
return kReadError;
}

if (buf[0] == '\n' || buf[0] == '\r' || buf[0] == '\0') {
// Empty lines delimit tests.
if (start_line_ > 0) {
@@ -372,12 +362,51 @@ void FileTest::InjectInstruction(const std::string &key,
instructions_[key] = value;
}

class FileLineReader : public FileTest::LineReader {
public:
explicit FileLineReader(const char *path) : file_(fopen(path, "r")) {}
~FileLineReader() override {
if (file_ != nullptr) {
fclose(file_);
}
}

// is_open returns true if the file was successfully opened.
bool is_open() const { return file_ != nullptr; }

FileTest::ReadResult ReadLine(char *out, size_t len) override {
assert(len > 0);
if (file_ == nullptr) {
return FileTest::kReadError;
}

if (fgets(out, len, file_) == nullptr) {
return feof(file_) ? FileTest::kReadEOF : FileTest::kReadError;
}

if (strlen(out) == len - 1 && out[len - 2] != '\n' && !feof(file_)) {
fprintf(stderr, "Line too long.\n");
return FileTest::kReadError;
}

return FileTest::kReadSuccess;
}

private:
FILE *file_;

FileLineReader(const FileLineReader &) = delete;
FileLineReader &operator=(const FileLineReader &) = delete;
};

int FileTestMainSilent(FileTestFunc run_test, void *arg, const char *path) {
FileTest t(path);
if (!t.is_open()) {
std::unique_ptr<FileLineReader> reader(new FileLineReader(path));
if (!reader->is_open()) {
fprintf(stderr, "Could not open file %s: %s.\n", path, strerror(errno));
return 1;
}

FileTest t(std::move(reader));
bool failed = false;
while (true) {
FileTest::ReadResult ret = t.ReadNext();


+ 11
- 8
crypto/test/file_test.h Прегледај датотеку

@@ -18,12 +18,12 @@
#include <openssl/base.h>

#include <stdint.h>
#include <stdio.h>

OPENSSL_MSVC_PRAGMA(warning(push))
OPENSSL_MSVC_PRAGMA(warning(disable : 4702))

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -86,18 +86,21 @@ OPENSSL_MSVC_PRAGMA(warning(pop))

class FileTest {
public:
explicit FileTest(const char *path);
~FileTest();

// is_open returns true if the file was successfully opened.
bool is_open() const { return file_ != nullptr; }

enum ReadResult {
kReadSuccess,
kReadEOF,
kReadError,
};

class LineReader {
public:
virtual ~LineReader() {}
virtual ReadResult ReadLine(char *out, size_t len) = 0;
};

explicit FileTest(std::unique_ptr<LineReader> reader);
~FileTest();

// ReadNext reads the next test from the file. It returns |kReadSuccess| if
// successfully reading a test and |kReadEOF| at the end of the file. On
// error or if the previous test had unconsumed attributes, it returns
@@ -168,7 +171,7 @@ class FileTest {
void OnKeyUsed(const std::string &key);
void OnInstructionUsed(const std::string &key);

FILE *file_ = nullptr;
std::unique_ptr<LineReader> reader_;
// line_ is the number of lines read.
unsigned line_ = 0;



Loading…
Откажи
Сачувај