Commit 68975a4e authored by Joshua Haberman's avatar Joshua Haberman

Merge pull request #460 from haberman/conformance-names

Conformance tests can now be excluded based on their names.
parents 8fe039a6 23bf3b56
......@@ -57,7 +57,7 @@ conformance-java: javac_middleman
# Targets for actually running tests.
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner ./conformance-cpp
./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner ./conformance-java
This diff is collapsed.
......@@ -83,24 +83,50 @@ class ConformanceTestSuite {
public:
ConformanceTestSuite() : verbose_(false) {}
// Sets the list of tests that are expected to fail when RunSuite() is called.
// RunSuite() will fail unless the set of failing tests is exactly the same
// as this list.
void SetFailureList(const std::vector<std::string>& failure_list);
// Run all the conformance tests against the given test runner.
// Test output will be stored in "output".
void RunSuite(ConformanceTestRunner* runner, std::string* output);
//
// Returns true if the set of failing tests was exactly the same as the
// failure list. If SetFailureList() was not called, returns true if all
// tests passed.
bool RunSuite(ConformanceTestRunner* runner, std::string* output);
private:
void ReportSuccess();
void ReportFailure(const char* fmt, ...);
void RunTest(const conformance::ConformanceRequest& request,
void ReportSuccess(const std::string& test_name);
void ReportFailure(const std::string& test_name, const char* fmt, ...);
void RunTest(const std::string& test_name,
const conformance::ConformanceRequest& request,
conformance::ConformanceResponse* response);
void DoExpectParseFailureForProto(const std::string& proto, int line);
void TestPrematureEOFForType(
google::protobuf::internal::WireFormatLite::FieldType type);
void ExpectParseFailureForProto(const std::string& proto,
const std::string& test_name);
void ExpectHardParseFailureForProto(const std::string& proto,
const std::string& test_name);
void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
bool CheckSetEmpty(const set<string>& set_to_check, const char* msg);
ConformanceTestRunner* runner_;
int successes_;
int failures_;
bool verbose_;
std::string output_;
// The set of test names that are expected to fail in this run, but haven't
// failed yet.
std::set<std::string> expected_to_fail_;
// The set of test names that have been run. Used to ensure that there are no
// duplicate names in the suite.
std::set<std::string> test_names_;
// The set of tests that failed, but weren't expected to.
std::set<std::string> unexpected_failing_tests_;
// The set of tests that succeeded, but weren't expected to.
std::set<std::string> unexpected_succeeding_tests_;
};
} // namespace protobuf
......
......@@ -55,6 +55,8 @@
#include <errno.h>
#include <unistd.h>
#include <fstream>
#include <vector>
#include "conformance.pb.h"
#include "conformance_test.h"
......@@ -62,6 +64,8 @@
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using google::protobuf::internal::scoped_array;
using std::string;
using std::vector;
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
......@@ -180,18 +184,67 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
std::string executable_;
};
void UsageError() {
fprintf(stderr,
"Usage: conformance-test-runner [options] <test-program>\n");
fprintf(stderr, "\n");
fprintf(stderr, "Options:\n");
fprintf(stderr,
" --failure_list <filename> Use to specify list of tests\n");
fprintf(stderr,
" that are expected to fail. File\n");
fprintf(stderr,
" should contain one test name per\n");
fprintf(stderr,
" line. Use '#' for comments.\n");
exit(1);
}
void ParseFailureList(const char *filename, vector<string>* failure_list) {
std::ifstream infile(filename);
for (string line; getline(infile, line);) {
// Remove whitespace.
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
line.end());
// Remove comments.
line = line.substr(0, line.find("#"));
if (!line.empty()) {
failure_list->push_back(line);
}
}
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: conformance-test-runner <test-program>\n");
exit(1);
int arg = 1;
char *program;
vector<string> failure_list;
for (int arg = 1; arg < argc; ++arg) {
if (strcmp(argv[arg], "--failure_list") == 0) {
if (++arg == argc) UsageError();
ParseFailureList(argv[arg], &failure_list);
} else if (argv[arg][0] == '-') {
fprintf(stderr, "Unknown option: %s\n", argv[arg]);
UsageError();
} else {
if (arg != argc - 1) {
fprintf(stderr, "Too many arguments.\n");
UsageError();
}
program = argv[arg];
}
}
ForkPipeRunner runner(argv[1]);
ForkPipeRunner runner(program);
google::protobuf::ConformanceTestSuite suite;
suite.SetFailureList(failure_list);
std::string output;
suite.RunSuite(&runner, &output);
bool ok = suite.RunSuite(&runner, &output);
fwrite(output.c_str(), 1, output.size(), stderr);
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
# This is the list of conformance tests that are known to fail for the C++
# implementation right now. These should be fixed.
#
# By listing them here we can keep tabs on which ones are failing and be sure
# that we don't introduce regressions in other tests.
#
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
PrematureEofBeforeKnownRepeatedValue.MESSAGE
PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
PrematureEofInPackedField.BOOL
PrematureEofInPackedField.ENUM
PrematureEofInPackedField.INT32
PrematureEofInPackedField.INT64
PrematureEofInPackedField.SINT32
PrematureEofInPackedField.SINT64
PrematureEofInPackedField.UINT32
PrematureEofInPackedField.UINT64
PrematureEofInsideKnownRepeatedValue.MESSAGE
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment