Merge pull request #980 from thomasvl/obj_conformance
Add support for the conformance test for objc when run on OS Xpull/1001/head
commit
4e3388168d
7 changed files with 245 additions and 7 deletions
@ -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; |
||||
} |
@ -0,0 +1,2 @@ |
||||
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE |
||||
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE |
Loading…
Reference in new issue