Commit d2b67389 authored by Josh Haberman's avatar Josh Haberman

Conformance tests can now be excluded based on their names.

This allows us to enable conformance tests even when we know
that some tests are failing and need to be fixed.

Change-Id: I372f43663008747db6f2b2cf06e6ffa4c6d85b2d
parent 96f1d4ad
......@@ -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
......@@ -57,11 +57,13 @@ option java_package = "com.google.protobuf.conformance";
// 2. parse the protobuf or JSON payload in "payload" (which may fail)
// 3. if the parse succeeded, serialize the message in the requested format.
message ConformanceRequest {
string test_name = 1;
// The payload (whether protobuf of JSON) is always for a TestAllTypes proto
// (see below).
oneof payload {
bytes protobuf_payload = 1;
string json_payload = 2;
bytes protobuf_payload = 2;
string json_payload = 3;
}
enum RequestedOutput {
......@@ -71,7 +73,7 @@ message ConformanceRequest {
}
// Which format should the testee serialize its message to?
RequestedOutput requested_output = 3;
RequestedOutput requested_output = 4;
}
// Represents a single test case's output.
......
This diff is collapsed.
......@@ -83,24 +83,49 @@ 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 ReportSuccess(const std::string& test_name);
void ReportFailure(const std::string& test_name, const char* fmt, ...);
void RunTest(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