aboutsummaryrefslogtreecommitdiffhomepage
path: root/objectivec/Tests
diff options
context:
space:
mode:
Diffstat (limited to 'objectivec/Tests')
-rw-r--r--objectivec/Tests/GPBExtensionRegistryTest.m138
-rw-r--r--objectivec/Tests/GPBMessageTests+Serialization.m69
-rw-r--r--objectivec/Tests/GPBPerfTests.m106
3 files changed, 284 insertions, 29 deletions
diff --git a/objectivec/Tests/GPBExtensionRegistryTest.m b/objectivec/Tests/GPBExtensionRegistryTest.m
new file mode 100644
index 00000000..b1168826
--- /dev/null
+++ b/objectivec/Tests/GPBExtensionRegistryTest.m
@@ -0,0 +1,138 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2017 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 "GPBTestUtilities.h"
+
+#import "GPBExtensionRegistry.h"
+#import "google/protobuf/Unittest.pbobjc.h"
+
+@interface GPBExtensionRegistryTest : GPBTestCase
+@end
+
+@implementation GPBExtensionRegistryTest
+
+- (void)testBasics {
+ GPBExtensionRegistry *reg = [[[GPBExtensionRegistry alloc] init] autorelease];
+ XCTAssertNotNil(reg);
+
+ XCTAssertNil([reg extensionForDescriptor:[TestAllExtensions descriptor]
+ fieldNumber:1]);
+ XCTAssertNil([reg extensionForDescriptor:[TestAllTypes descriptor]
+ fieldNumber:1]);
+
+ [reg addExtension:[UnittestRoot optionalInt32Extension]];
+ [reg addExtension:[UnittestRoot packedInt64Extension]];
+
+ XCTAssertTrue([reg extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+ [UnittestRoot optionalInt32Extension]); // ptr equality
+ XCTAssertNil([reg extensionForDescriptor:[TestAllTypes descriptor]
+ fieldNumber:1]);
+ XCTAssertTrue([reg extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+ [UnittestRoot packedInt64Extension]); // ptr equality
+}
+
+- (void)testCopy {
+ GPBExtensionRegistry *reg1 = [[[GPBExtensionRegistry alloc] init] autorelease];
+ [reg1 addExtension:[UnittestRoot optionalInt32Extension]];
+
+ GPBExtensionRegistry *reg2 = [[reg1 copy] autorelease];
+ XCTAssertNotNil(reg2);
+
+ XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+ [UnittestRoot optionalInt32Extension]); // ptr equality
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+ [UnittestRoot optionalInt32Extension]); // ptr equality
+
+ // Message class that had registered extension(s) at the -copy time.
+
+ [reg1 addExtension:[UnittestRoot optionalBoolExtension]];
+ [reg2 addExtension:[UnittestRoot optionalStringExtension]];
+
+ XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13] ==
+ [UnittestRoot optionalBoolExtension]); // ptr equality
+ XCTAssertNil([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14]);
+ XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13]);
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14] ==
+ [UnittestRoot optionalStringExtension]); // ptr equality
+
+ // Message class that did not have any registered extensions at the -copy time.
+
+ [reg1 addExtension:[UnittestRoot packedInt64Extension]];
+ [reg2 addExtension:[UnittestRoot packedSint32Extension]];
+
+ XCTAssertTrue([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+ [UnittestRoot packedInt64Extension]); // ptr equality
+ XCTAssertNil([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94]);
+ XCTAssertNil([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91]);
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94] ==
+ [UnittestRoot packedSint32Extension]); // ptr equality
+
+}
+
+- (void)testAddExtensions {
+ GPBExtensionRegistry *reg1 = [[[GPBExtensionRegistry alloc] init] autorelease];
+ [reg1 addExtension:[UnittestRoot optionalInt32Extension]];
+
+ GPBExtensionRegistry *reg2 = [[[GPBExtensionRegistry alloc] init] autorelease];
+
+ XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor]
+ fieldNumber:1]);
+
+ [reg2 addExtensions:reg1];
+
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+ [UnittestRoot optionalInt32Extension]); // ptr equality
+
+ // Confirm adding to the first doesn't add to the second.
+
+ [reg1 addExtension:[UnittestRoot optionalBoolExtension]];
+ [reg1 addExtension:[UnittestRoot packedInt64Extension]];
+
+ XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13] ==
+ [UnittestRoot optionalBoolExtension]); // ptr equality
+ XCTAssertTrue([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+ [UnittestRoot packedInt64Extension]); // ptr equality
+ XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13]);
+ XCTAssertNil([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91]);
+
+ // Confirm adding to the second doesn't add to the first.
+
+ [reg2 addExtension:[UnittestRoot optionalStringExtension]];
+ [reg2 addExtension:[UnittestRoot packedSint32Extension]];
+
+ XCTAssertNil([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14]);
+ XCTAssertNil([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94]);
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14] ==
+ [UnittestRoot optionalStringExtension]); // ptr equality
+ XCTAssertTrue([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94] ==
+ [UnittestRoot packedSint32Extension]); // ptr equality
+}
+
+@end
diff --git a/objectivec/Tests/GPBMessageTests+Serialization.m b/objectivec/Tests/GPBMessageTests+Serialization.m
index 3c861fef..4a4c5447 100644
--- a/objectivec/Tests/GPBMessageTests+Serialization.m
+++ b/objectivec/Tests/GPBMessageTests+Serialization.m
@@ -113,35 +113,6 @@ static NSData *DataFromCStr(const char *str) {
[msg release];
}
-- (void)testProto3DroppingUnknownFields {
- DropUnknownsFooWithExtraFields *fooWithExtras =
- [[DropUnknownsFooWithExtraFields alloc] init];
-
- fooWithExtras.int32Value = 1;
- fooWithExtras.enumValue = DropUnknownsFooWithExtraFields_NestedEnum_Baz;
- fooWithExtras.extraInt32Value = 2;
-
- NSData *data = [fooWithExtras data];
- XCTAssertNotNil(data);
- DropUnknownsFoo *foo = [DropUnknownsFoo parseFromData:data error:NULL];
-
- XCTAssertEqual(foo.int32Value, 1);
- XCTAssertEqual(foo.enumValue, DropUnknownsFoo_NestedEnum_Baz);
- // Nothing should end up in the unknowns.
- XCTAssertEqual([foo.unknownFields countOfFields], 0U);
-
- [fooWithExtras release];
- data = [foo data];
- fooWithExtras =
- [DropUnknownsFooWithExtraFields parseFromData:data error:NULL];
- XCTAssertEqual(fooWithExtras.int32Value, 1);
- XCTAssertEqual(fooWithExtras.enumValue,
- DropUnknownsFooWithExtraFields_NestedEnum_Baz);
- // And the extra value is gone (back to the default).
- XCTAssertEqual(fooWithExtras.extraInt32Value, 0);
- XCTAssertEqual([foo.unknownFields countOfFields], 0U);
-}
-
- (void)testProto2UnknownEnumToUnknownField {
Message3 *orig = [[Message3 alloc] init];
@@ -946,6 +917,41 @@ static NSData *DataFromCStr(const char *str) {
XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag);
}
+- (void)testZeroFieldNum {
+ // These are ConformanceTestSuite::TestIllegalTags.
+
+ const char *tests[] = {
+ "\1DEADBEEF",
+ "\2\1\1",
+ "\3\4",
+ "\5DEAD"
+ };
+
+ for (size_t i = 0; i < GPBARRAYSIZE(tests); ++i) {
+ NSData *data = DataFromCStr(tests[i]);
+
+ {
+ // Message from proto2 syntax file
+ NSError *error = nil;
+ Message2 *msg = [Message2 parseFromData:data error:&error];
+ XCTAssertNil(msg, @"i = %zd", i);
+ XCTAssertNotNil(error, @"i = %zd", i);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+ }
+
+ {
+ // Message from proto3 syntax file
+ NSError *error = nil;
+ Message3 *msg = [Message3 parseFromData:data error:&error];
+ XCTAssertNil(msg, @"i = %zd", i);
+ XCTAssertNotNil(error, @"i = %zd", i);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+ }
+ }
+}
+
- (void)testErrorRecursionDepthReached {
NSData *data = DataFromCStr(
"\x0A\xF2\x01\x0A\xEF\x01\x0A\xEC\x01\x0A\xE9\x01\x0A\xE6\x01"
@@ -1149,22 +1155,27 @@ static NSData *DataFromCStr(const char *str) {
[msg.mapInt32Int32 setInt32:101 forKey:2001];
[msg.mapInt64Int64 setInt64:1002 forKey:202];
[msg.mapInt64Int64 setInt64:103 forKey:2003];
+ [msg.mapInt64Int64 setInt64:4294967296 forKey:4294967297];
[msg.mapUint32Uint32 setUInt32:1004 forKey:204];
[msg.mapUint32Uint32 setUInt32:105 forKey:2005];
[msg.mapUint64Uint64 setUInt64:1006 forKey:206];
[msg.mapUint64Uint64 setUInt64:107 forKey:2007];
+ [msg.mapUint64Uint64 setUInt64:4294967298 forKey:4294967299];
[msg.mapSint32Sint32 setInt32:1008 forKey:208];
[msg.mapSint32Sint32 setInt32:109 forKey:2009];
[msg.mapSint64Sint64 setInt64:1010 forKey:210];
[msg.mapSint64Sint64 setInt64:111 forKey:2011];
+ [msg.mapSint64Sint64 setInt64:4294967300 forKey:4294967301];
[msg.mapFixed32Fixed32 setUInt32:1012 forKey:212];
[msg.mapFixed32Fixed32 setUInt32:113 forKey:2013];
[msg.mapFixed64Fixed64 setUInt64:1014 forKey:214];
[msg.mapFixed64Fixed64 setUInt64:115 forKey:2015];
+ [msg.mapFixed64Fixed64 setUInt64:4294967302 forKey:4294967303];
[msg.mapSfixed32Sfixed32 setInt32:1016 forKey:216];
[msg.mapSfixed32Sfixed32 setInt32:117 forKey:2017];
[msg.mapSfixed64Sfixed64 setInt64:1018 forKey:218];
[msg.mapSfixed64Sfixed64 setInt64:119 forKey:2019];
+ [msg.mapSfixed64Sfixed64 setInt64:4294967304 forKey:4294967305];
[msg.mapInt32Float setFloat:1020.f forKey:220];
[msg.mapInt32Float setFloat:121.f forKey:2021];
[msg.mapInt32Double setDouble:1022. forKey:222];
diff --git a/objectivec/Tests/GPBPerfTests.m b/objectivec/Tests/GPBPerfTests.m
index 1259d146..8dd0ffc5 100644
--- a/objectivec/Tests/GPBPerfTests.m
+++ b/objectivec/Tests/GPBPerfTests.m
@@ -64,6 +64,112 @@ static const uint32_t kRepeatedCount = 100;
}];
}
+- (void)testMessageSerialParsingPerformance {
+ // This and the next test are meant to monitor that the parsing functionality of protos does not
+ // lock across threads when parsing different instances. The Serial version of the test should run
+ // around ~2 times slower than the Parallel version since it's parsing the protos in the same
+ // thread.
+ TestAllTypes *allTypesMessage = [TestAllTypes message];
+ [self setAllFields:allTypesMessage repeatedCount:2];
+ NSData *allTypesData = allTypesMessage.data;
+
+ [self measureBlock:^{
+ for (int i = 0; i < 500; ++i) {
+ [TestAllTypes parseFromData:allTypesData error:NULL];
+ [TestAllTypes parseFromData:allTypesData error:NULL];
+ }
+ }];
+}
+
+- (void)testMessageParallelParsingPerformance {
+ // This and the previous test are meant to monitor that the parsing functionality of protos does
+ // not lock across threads when parsing different instances. The Serial version of the test should
+ // run around ~2 times slower than the Parallel version since it's parsing the protos in the same
+ // thread.
+ TestAllTypes *allTypesMessage = [TestAllTypes message];
+ [self setAllFields:allTypesMessage repeatedCount:2];
+ NSData *allTypesData = allTypesMessage.data;
+
+ dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
+
+ [self measureBlock:^{
+ for (int i = 0; i < 500; ++i) {
+ dispatch_group_t group = dispatch_group_create();
+
+ dispatch_group_async(group, concurrentQueue, ^{
+ [TestAllTypes parseFromData:allTypesData error:NULL];
+ });
+
+ dispatch_group_async(group, concurrentQueue, ^{
+ [TestAllTypes parseFromData:allTypesData error:NULL];
+ });
+
+ dispatch_group_notify(group, concurrentQueue, ^{});
+
+ dispatch_release(group);
+ }
+ }];
+
+ dispatch_release(concurrentQueue);
+}
+
+- (void)testMessageSerialExtensionsParsingPerformance {
+ // This and the next test are meant to monitor that the parsing functionality of protos does not
+ // lock across threads when parsing different instances when using extensions. The Serial version
+ // of the test should run around ~2 times slower than the Parallel version since it's parsing the
+ // protos in the same thread.
+ TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
+ [self setAllExtensions:allExtensionsMessage repeatedCount:2];
+ NSData *allExtensionsData = allExtensionsMessage.data;
+
+ [self measureBlock:^{
+ for (int i = 0; i < 500; ++i) {
+ [TestAllExtensions parseFromData:allExtensionsData
+ extensionRegistry:[self extensionRegistry]
+ error:NULL];
+ [TestAllExtensions parseFromData:allExtensionsData
+ extensionRegistry:[self extensionRegistry]
+ error:NULL];
+ }
+ }];
+}
+
+- (void)testMessageParallelExtensionsParsingPerformance {
+ // This and the previous test are meant to monitor that the parsing functionality of protos does
+ // not lock across threads when parsing different instances when using extensions. The Serial
+ // version of the test should run around ~2 times slower than the Parallel version since it's
+ // parsing the protos in the same thread.
+ TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
+ [self setAllExtensions:allExtensionsMessage repeatedCount:2];
+ NSData *allExtensionsData = allExtensionsMessage.data;
+
+ dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
+
+ [self measureBlock:^{
+ for (int i = 0; i < 500; ++i) {
+ dispatch_group_t group = dispatch_group_create();
+
+ dispatch_group_async(group, concurrentQueue, ^{
+ [TestAllExtensions parseFromData:allExtensionsData
+ extensionRegistry:[UnittestRoot extensionRegistry]
+ error:NULL];
+ });
+
+ dispatch_group_async(group, concurrentQueue, ^{
+ [TestAllExtensions parseFromData:allExtensionsData
+ extensionRegistry:[UnittestRoot extensionRegistry]
+ error:NULL];
+ });
+
+ dispatch_group_notify(group, concurrentQueue, ^{});
+
+ dispatch_release(group);
+ }
+ }];
+
+ dispatch_release(concurrentQueue);
+}
+
- (void)testExtensionsPerformance {
[self measureBlock:^{
for (int i = 0; i < 200; ++i) {