Commit a3ca1fa4 authored by Joshua Haberman's avatar Joshua Haberman

Merge pull request #588 from haberman/conformance-json

Added support for JSON and valid input to conformance tests.
parents fe500440 b0500b37
......@@ -54,7 +54,7 @@ class ConformanceJava {
break;
}
case JSON_PAYLOAD: {
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
}
case PAYLOAD_NOT_SET: {
throw new RuntimeException("Request didn't have payload.");
......@@ -65,7 +65,7 @@ class ConformanceJava {
}
}
switch (request.getRequestedOutput()) {
switch (request.getRequestedOutputFormat()) {
case UNSPECIFIED:
throw new RuntimeException("Unspecified output format.");
......@@ -73,7 +73,7 @@ class ConformanceJava {
return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
case JSON:
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
default: {
throw new RuntimeException("Unexpected request output.");
......
......@@ -51,6 +51,12 @@ option java_package = "com.google.protobuf.conformance";
// - running as a sub-process may be more tricky in unusual environments like
// iOS apps, where fork/stdin/stdout are not available.
enum WireFormat {
UNSPECIFIED = 0;
PROTOBUF = 1;
JSON = 2;
}
// Represents a single test case's input. The testee should:
//
// 1. parse this proto (which should always succeed)
......@@ -64,14 +70,8 @@ message ConformanceRequest {
string json_payload = 2;
}
enum RequestedOutput {
UNSPECIFIED = 0;
PROTOBUF = 1;
JSON = 2;
}
// Which format should the testee serialize its message to?
RequestedOutput requested_output = 3;
WireFormat requested_output_format = 3;
}
// Represents a single test case's output.
......@@ -96,6 +96,10 @@ message ConformanceResponse {
// If the input was successfully parsed and the requested output was JSON,
// serialize to JSON and set it in this field.
string json_payload = 4;
// For when the testee skipped the test, likely because a certain feature
// wasn't supported, like JSON input/output.
string skipped = 5;
}
}
......
......@@ -33,14 +33,33 @@
#include <unistd.h>
#include "conformance.pb.h"
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/type_resolver_util.h>
using std::string;
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using conformance::TestAllTypes;
using google::protobuf::Descriptor;
using google::protobuf::DescriptorPool;
using google::protobuf::internal::scoped_ptr;
using google::protobuf::util::BinaryToJsonString;
using google::protobuf::util::JsonToBinaryString;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
using google::protobuf::util::Status;
using google::protobuf::util::TypeResolver;
using std::string;
static const char kTypeUrlPrefix[] = "type.googleapis.com";
static string GetTypeUrl(const Descriptor* message) {
return string(kTypeUrlPrefix) + "/" + message->full_name();
}
int test_count = 0;
bool verbose = false;
TypeResolver* type_resolver;
string* type_url;
bool CheckedRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
......@@ -79,27 +98,43 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
}
break;
case ConformanceRequest::kJsonPayload:
response->set_runtime_error("JSON input is not yet supported.");
case ConformanceRequest::kJsonPayload: {
string proto_binary;
Status status = JsonToBinaryString(type_resolver, *type_url,
request.json_payload(), &proto_binary);
if (!status.ok()) {
response->set_parse_error(string("Parse error: ") +
status.error_message().as_string());
return;
}
GOOGLE_CHECK(test_message.ParseFromString(proto_binary));
break;
}
case ConformanceRequest::PAYLOAD_NOT_SET:
GOOGLE_LOG(FATAL) << "Request didn't have payload.";
break;
}
switch (request.requested_output()) {
case ConformanceRequest::UNSPECIFIED:
switch (request.requested_output_format()) {
case conformance::UNSPECIFIED:
GOOGLE_LOG(FATAL) << "Unspecified output format";
break;
case ConformanceRequest::PROTOBUF:
test_message.SerializeToString(response->mutable_protobuf_payload());
case conformance::PROTOBUF:
GOOGLE_CHECK(
test_message.SerializeToString(response->mutable_protobuf_payload()));
break;
case ConformanceRequest::JSON:
response->set_runtime_error("JSON output is not yet supported.");
case conformance::JSON: {
string proto_binary;
GOOGLE_CHECK(test_message.SerializeToString(&proto_binary));
Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary,
response->mutable_json_payload());
GOOGLE_CHECK(status.ok());
break;
}
}
}
......@@ -146,6 +181,9 @@ bool DoTestIo() {
}
int main() {
type_resolver = NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool());
type_url = new string(GetTypeUrl(TestAllTypes::descriptor()));
while (1) {
if (!DoTestIo()) {
fprintf(stderr, "conformance-cpp: received EOF from test runner "
......
This diff is collapsed.
......@@ -39,6 +39,8 @@
#define CONFORMANCE_CONFORMANCE_TEST_H
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/wire_format_lite.h>
namespace conformance {
......@@ -98,10 +100,22 @@ class ConformanceTestSuite {
private:
void ReportSuccess(const std::string& test_name);
void ReportFailure(const std::string& test_name, const char* fmt, ...);
void ReportFailure(const string& test_name,
const conformance::ConformanceRequest& request,
const conformance::ConformanceResponse& response,
const char* fmt, ...);
void ReportSkip(const string& test_name,
const conformance::ConformanceRequest& request,
const conformance::ConformanceResponse& response);
void RunTest(const std::string& test_name,
const conformance::ConformanceRequest& request,
conformance::ConformanceResponse* response);
void RunValidInputTest(const string& test_name, const string& input,
conformance::WireFormat input_format,
const string& equivalent_text_format,
conformance::WireFormat requested_output);
void RunValidJsonTest(const string& test_name, const string& input_json,
const string& equivalent_text_format);
void ExpectParseFailureForProto(const std::string& proto,
const std::string& test_name);
void ExpectHardParseFailureForProto(const std::string& proto,
......@@ -110,7 +124,7 @@ class ConformanceTestSuite {
bool CheckSetEmpty(const set<string>& set_to_check, const char* msg);
ConformanceTestRunner* runner_;
int successes_;
int failures_;
int expected_failures_;
bool verbose_;
std::string output_;
......@@ -127,6 +141,13 @@ class ConformanceTestSuite {
// The set of tests that succeeded, but weren't expected to.
std::set<std::string> unexpected_succeeding_tests_;
// The set of tests that the testee opted out of;
std::set<std::string> skipped_;
google::protobuf::internal::scoped_ptr<google::protobuf::util::TypeResolver>
type_resolver_;
std::string type_url_;
};
} // namespace protobuf
......
......@@ -7,15 +7,15 @@
# 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
ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInPackedField.BOOL
ProtobufInput.PrematureEofInPackedField.ENUM
ProtobufInput.PrematureEofInPackedField.INT32
ProtobufInput.PrematureEofInPackedField.INT64
ProtobufInput.PrematureEofInPackedField.SINT32
ProtobufInput.PrematureEofInPackedField.SINT64
ProtobufInput.PrematureEofInPackedField.UINT32
ProtobufInput.PrematureEofInPackedField.UINT64
ProtobufInput.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