aboutsummaryrefslogtreecommitdiffhomepage
path: root/conformance
diff options
context:
space:
mode:
authorGravatar Thomas Van Lenten <thomasvl@google.com>2015-11-17 10:18:49 -0500
committerGravatar Thomas Van Lenten <thomasvl@google.com>2015-11-18 11:58:19 -0500
commit1745f7eae9bc206ffeb47d63dcdfa039ef3774e8 (patch)
tree94c3b61e4b025c453c949c45255c5681914c799b /conformance
parent8162451b727e5abd46ea934a81d44c6ff7e0963e (diff)
Add support for the conformance test for objc when run on OS X
Diffstat (limited to 'conformance')
-rw-r--r--conformance/Makefile.am38
-rw-r--r--conformance/conformance_objc.m179
-rw-r--r--conformance/failure_list_objc.txt2
3 files changed, 215 insertions, 4 deletions
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index b6fda2a8..d7bb9397 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -9,7 +9,9 @@ protoc_outputs = \
other_language_protoc_outputs = \
conformance.rb \
- com/google/protobuf/conformance/Conformance.java
+ com/google/protobuf/conformance/Conformance.java \
+ Conformance.pbobjc.h \
+ Conformance.pbobjc.m
bin_PROGRAMS = conformance-test-runner conformance-cpp
@@ -17,16 +19,37 @@ conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_test_runner_SOURCES = conformance_test.cc conformance_test_runner.cc
nodist_conformance_test_runner_SOURCES = conformance.pb.cc
conformance_test_runner_CPPFLAGS = -I$(top_srcdir)/src
+# Explicit deps beacuse BUILT_SOURCES are only done before a "make all/check"
+# so a direct "make test_cpp" could fail if parallel enough.
+conformance_test_runner-conformance_test.$(OBJEXT): conformance.pb.h
+conformance_test_runner-conformance_test_runner.$(OBJEXT): conformance.pb.h
conformance_cpp_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_cpp_SOURCES = conformance_cpp.cc
nodist_conformance_cpp_SOURCES = conformance.pb.cc
conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
+# Explicit dep beacuse BUILT_SOURCES are only done before a "make all/check"
+# so a direct "make test_cpp" could fail if parallel enough.
+conformance_cpp-conformance_cpp.$(OBJEXT): conformance.pb.h
+
+if OBJC_CONFORMANCE_TEST
+
+bin_PROGRAMS += conformance-objc
+
+conformance_objc_SOURCES = conformance_objc.m ../objectivec/GPBProtocolBuffers.m
+nodist_conformance_objc_SOURCES = Conformance.pbobjc.m
+conformance_objc_CPPFLAGS = -I$(top_srcdir)/objectivec
+conformance_objc_LDFLAGS = -framework Foundation
+# Explicit dep beacuse BUILT_SOURCES are only done before a "make all/check"
+# so a direct "make test_objc" could fail if parallel enough.
+conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h
+
+endif
if USE_EXTERNAL_PROTOC
protoc_middleman: $(protoc_inputs)
- $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. --ruby_out=. $^
+ $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. $^
touch protoc_middleman
else
@@ -35,7 +58,7 @@ else
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
- oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd $(protoc_inputs) )
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd $(protoc_inputs) )
touch protoc_middleman
endif
@@ -44,7 +67,7 @@ $(protoc_outputs): protoc_middleman
$(other_language_protoc_outputs): protoc_middleman
-BUILT_SOURCES = $(protoc_outputs)
+BUILT_SOURCES = $(protoc_outputs) $(other_language_protoc_outputs)
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp $(other_language_protoc_outputs)
@@ -82,3 +105,10 @@ test_csharp: protoc_middleman conformance-test-runner conformance-csharp
test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb
+
+if OBJC_CONFORMANCE_TEST
+
+test_objc: protoc_middleman conformance-test-runner conformance-objc
+ ./conformance-test-runner --failure_list failure_list_objc.txt ./conformance-objc
+
+endif
diff --git a/conformance/conformance_objc.m b/conformance/conformance_objc.m
new file mode 100644
index 00000000..06c97a82
--- /dev/null
+++ b/conformance/conformance_objc.m
@@ -0,0 +1,179 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#import <Foundation/Foundation.h>
+
+#import "Conformance.pbobjc.h"
+
+static void Die(NSString *format, ...) __dead2;
+
+static BOOL verbose = NO;
+static int32_t testCount = 0;
+
+static void Die(NSString *format, ...) {
+ va_list args;
+ va_start(args, format);
+ NSString *msg = [[NSString alloc] initWithFormat:format arguments:args];
+ NSLog(@"%@", msg);
+ va_end(args);
+ [msg release];
+ exit(66);
+}
+
+static NSData *CheckedReadDataOfLength(NSFileHandle *handle, NSUInteger numBytes) {
+ NSData *data = [handle readDataOfLength:numBytes];
+ NSUInteger dataLen = data.length;
+ if (dataLen == 0) {
+ return nil; // EOF.
+ }
+ if (dataLen != numBytes) {
+ Die(@"Failed to read the request length (%d), only got: %@",
+ numBytes, data);
+ }
+ return data;
+}
+
+static ConformanceResponse *DoTest(ConformanceRequest *request) {
+ ConformanceResponse *response = [ConformanceResponse message];
+ TestAllTypes *testMessage = nil;
+
+ switch (request.payloadOneOfCase) {
+ case ConformanceRequest_Payload_OneOfCase_GPBUnsetOneOfCase:
+ Die(@"Request didn't have a payload: %@", request);
+ break;
+
+ case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: {
+ NSError *error = nil;
+ testMessage = [TestAllTypes parseFromData:request.protobufPayload
+ error:&error];
+ if (!testMessage) {
+ response.parseError =
+ [NSString stringWithFormat:@"Parse error: %@", error];
+ }
+ break;
+ }
+
+ case ConformanceRequest_Payload_OneOfCase_JsonPayload:
+ response.skipped = @"ObjC doesn't support parsing JSON";
+ break;
+ }
+
+ if (testMessage) {
+ switch (request.requestedOutputFormat) {
+ case WireFormat_GPBUnrecognizedEnumeratorValue:
+ case WireFormat_Unspecified:
+ Die(@"Unrecognized/unspecified output format: %@", request);
+ break;
+
+ case WireFormat_Protobuf:
+ response.protobufPayload = testMessage.data;
+ if (!response.protobufPayload) {
+ response.runtimeError =
+ [NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
+ }
+ break;
+
+ case WireFormat_Json:
+ response.skipped = @"ObjC doesn't support generating JSON";
+ break;
+ }
+ }
+
+ return response;
+}
+
+static uint32_t UInt32FromLittleEndianData(NSData *data) {
+ if (data.length != sizeof(uint32_t)) {
+ Die(@"Data not the right size for uint32_t: %@", data);
+ }
+ uint32_t value;
+ memcpy(&value, data.bytes, sizeof(uint32_t));
+ return CFSwapInt32LittleToHost(value);
+}
+
+static NSData *UInt32ToLittleEndianData(uint32_t num) {
+ uint32_t value = CFSwapInt32HostToLittle(num);
+ return [NSData dataWithBytes:&value length:sizeof(uint32_t)];
+}
+
+static BOOL DoTestIo(NSFileHandle *input, NSFileHandle *output) {
+ // See conformance_test_runner.cc for the wire format.
+ NSData *data = CheckedReadDataOfLength(input, sizeof(uint32_t));
+ if (!data) {
+ // EOF.
+ return NO;
+ }
+ uint32_t numBytes = UInt32FromLittleEndianData(data);
+ data = CheckedReadDataOfLength(input, numBytes);
+ if (!data) {
+ Die(@"Failed to read request");
+ }
+
+ NSError *error = nil;
+ ConformanceRequest *request = [ConformanceRequest parseFromData:data
+ error:&error];
+ if (!request) {
+ Die(@"Failed to parse the message data: %@", error);
+ }
+
+ ConformanceResponse *response = DoTest(request);
+ if (!response) {
+ Die(@"Failed to make a reply from %@", request);
+ }
+
+ data = response.data;
+ [output writeData:UInt32ToLittleEndianData((int32_t)data.length)];
+ [output writeData:data];
+
+ if (verbose) {
+ NSLog(@"Request: %@", request);
+ NSLog(@"Response: %@", response);
+ }
+
+ ++testCount;
+ return YES;
+}
+
+int main(int argc, const char *argv[]) {
+ @autoreleasepool {
+ NSFileHandle *input = [[NSFileHandle fileHandleWithStandardInput] retain];
+ NSFileHandle *output = [[NSFileHandle fileHandleWithStandardOutput] retain];
+
+ BOOL notDone = YES;
+ while (notDone) {
+ @autoreleasepool {
+ notDone = DoTestIo(input, output);
+ }
+ }
+
+ NSLog(@"Received EOF from test runner after %d tests, exiting.", testCount);
+ }
+ return 0;
+}
diff --git a/conformance/failure_list_objc.txt b/conformance/failure_list_objc.txt
new file mode 100644
index 00000000..a34b3f5b
--- /dev/null
+++ b/conformance/failure_list_objc.txt
@@ -0,0 +1,2 @@
+ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
+ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE