Added conformance test support for Java.

Change-Id: I4c81808e6ace77d2b5737a43417045321b0b10f0
changes/96/230396/2
Josh Haberman 10 years ago
parent 4e63b52088
commit 420f938bac
  1. 120
      conformance/ConformanceJava.java
  2. 31
      conformance/Makefile.am
  3. 1
      conformance/conformance.proto
  4. 4
      conformance/conformance_test_runner.cc

@ -0,0 +1,120 @@
import com.google.protobuf.conformance.Conformance;
import com.google.protobuf.InvalidProtocolBufferException;
class ConformanceJava {
private int testCount = 0;
private boolean readFromStdin(byte[] buf, int len) throws Exception {
int ofs = 0;
while (len > 0) {
int read = System.in.read(buf, ofs, len);
if (read == -1) {
return false; // EOF
}
ofs += read;
len -= read;
}
return true;
}
private void writeToStdout(byte[] buf) throws Exception {
System.out.write(buf);
}
// Returns -1 on EOF (the actual values will always be positive).
private int readLittleEndianIntFromStdin() throws Exception {
byte[] buf = new byte[4];
if (!readFromStdin(buf, 4)) {
return -1;
}
return buf[0] | (buf[1] << 1) | (buf[2] << 2) | (buf[3] << 3);
}
private void writeLittleEndianIntToStdout(int val) throws Exception {
byte[] buf = new byte[4];
buf[0] = (byte)val;
buf[1] = (byte)(val >> 8);
buf[2] = (byte)(val >> 16);
buf[3] = (byte)(val >> 24);
writeToStdout(buf);
}
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
Conformance.TestAllTypes testMessage;
switch (request.getPayloadCase()) {
case PROTOBUF_PAYLOAD: {
try {
testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
} catch (InvalidProtocolBufferException e) {
return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
}
break;
}
case JSON_PAYLOAD: {
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
}
case PAYLOAD_NOT_SET: {
throw new RuntimeException("Request didn't have payload.");
}
default: {
throw new RuntimeException("Unexpected payload case.");
}
}
switch (request.getRequestedOutput()) {
case UNSPECIFIED:
throw new RuntimeException("Unspecified output format.");
case PROTOBUF:
return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
case JSON:
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
default: {
throw new RuntimeException("Unexpected request output.");
}
}
}
private boolean doTestIo() throws Exception {
int bytes = readLittleEndianIntFromStdin();
if (bytes == -1) {
return false; // EOF
}
byte[] serializedInput = new byte[bytes];
if (!readFromStdin(serializedInput, bytes)) {
throw new RuntimeException("Unexpected EOF from test program.");
}
Conformance.ConformanceRequest request =
Conformance.ConformanceRequest.parseFrom(serializedInput);
Conformance.ConformanceResponse response = doTest(request);
byte[] serializedOutput = response.toByteArray();
writeLittleEndianIntToStdout(serializedOutput.length);
writeToStdout(serializedOutput);
return true;
}
public void run() throws Exception {
while (doTestIo()) {
// Empty.
}
System.err.println("ConformanceJava: received EOF from test runner after " +
this.testCount + " tests");
}
public static void main(String[] args) throws Exception {
new ConformanceJava().run();
}
}

@ -21,30 +21,43 @@ conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
if USE_EXTERNAL_PROTOC
unittest_proto_middleman: $(protoc_inputs)
$(PROTOC) -I$(srcdir) --cpp_out=. $^
touch unittest_proto_middleman
protoc_middleman: $(protoc_inputs)
$(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. $^
touch protoc_middleman
else
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
unittest_proto_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) )
touch unittest_proto_middleman
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd $(protoc_inputs) )
touch protoc_middleman
endif
$(protoc_outputs): unittest_proto_middleman
$(protoc_outputs): protoc_middleman
BUILT_SOURCES = $(protoc_outputs)
CLEANFILES = $(protoc_outputs) unittest_proto_middleman
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java
MAINTAINERCLEANFILES = \
Makefile.in
javac_middleman: ConformanceJava.java protoc_middleman
javac ConformanceJava.java com/google/protobuf/conformance/Conformance.java
@touch javac_middleman
conformance-java: javac_middleman
@echo "Writing shortcut script conformance-java..."
@echo '#! /bin/sh' > conformance-java
@echo 'java -classpath .:$$CLASSPATH ConformanceJava "$$@"' >> conformance-java
@chmod +x conformance-java
# Targets for actually running tests.
test_cpp: unittest_proto_middleman conformance-test-runner conformance-cpp
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner ./conformance-java

@ -30,6 +30,7 @@
syntax = "proto3";
package conformance;
option java_package = "com.google.protobuf.conformance";
// This defines the conformance testing protocol. This protocol exists between
// the conformance test suite itself and the code being tested. For each test,

@ -48,9 +48,9 @@
// Every test consists of a ConformanceRequest/ConformanceResponse
// request/reply pair. The protocol on the pipe is simply:
//
// 1. tester sends 4-byte length N
// 1. tester sends 4-byte length N (little endian)
// 2. tester sends N bytes representing a ConformanceRequest proto
// 3. testee sends 4-byte length M
// 3. testee sends 4-byte length M (little endian)
// 4. testee sends M bytes representing a ConformanceResponse proto
#include <errno.h>

Loading…
Cancel
Save