1// Protocol Buffers - Google's data interchange format 2// Copyright 2014 Google Inc. All rights reserved. 3// 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file or at 6// https://developers.google.com/open-source/licenses/bsd 7 8#import "GPBTestUtilities.h" 9 10#import "objectivec/Tests/Unittest.pbobjc.h" 11#import "objectivec/Tests/UnittestObjc.pbobjc.h" 12 13static const int kNumThreads = 100; 14static const int kNumMessages = 100; 15 16// NOTE: Most of these tests don't "fail" in the sense that the XCTAsserts 17// trip. Rather, the asserts simply exercise the apis, and if there is 18// a concurancy issue, the NSAsserts in the runtime code fire and/or the 19// code just crashes outright. 20 21@interface ConcurrencyTests : GPBTestCase 22@end 23 24@implementation ConcurrencyTests 25 26- (NSArray *)createThreadsWithSelector:(SEL)selector object:(id)object { 27 NSMutableArray *array = [NSMutableArray array]; 28 for (NSUInteger i = 0; i < kNumThreads; i++) { 29 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:selector object:object]; 30 [array addObject:thread]; 31 [thread release]; 32 } 33 return array; 34} 35 36- (NSArray *)createMessagesWithType:(Class)msgType { 37 NSMutableArray *array = [NSMutableArray array]; 38 for (NSUInteger i = 0; i < kNumMessages; i++) { 39 [array addObject:[msgType message]]; 40 } 41 return array; 42} 43 44- (void)startThreads:(NSArray *)threads { 45 for (NSThread *thread in threads) { 46 [thread start]; 47 } 48} 49 50- (void)joinThreads:(NSArray *)threads { 51 for (NSThread *thread in threads) { 52 while (![thread isFinished]); 53 } 54} 55 56- (void)readForeignMessage:(NSArray *)messages { 57 for (NSUInteger i = 0; i < 10; i++) { 58 for (TestAllTypes *message in messages) { 59 XCTAssertEqual(message.optionalForeignMessage.c, 0); 60 } 61 } 62} 63 64- (void)testConcurrentReadOfUnsetMessageField { 65 NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 66 NSArray *threads = [self createThreadsWithSelector:@selector(readForeignMessage:) 67 object:messages]; 68 [self startThreads:threads]; 69 [self joinThreads:threads]; 70 for (TestAllTypes *message in messages) { 71 XCTAssertFalse(message.hasOptionalForeignMessage); 72 } 73} 74 75- (void)readRepeatedInt32:(NSArray *)messages { 76 for (int i = 0; i < 10; i++) { 77 for (TestAllTypes *message in messages) { 78 XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0); 79 } 80 } 81} 82 83- (void)testConcurrentReadOfUnsetRepeatedIntField { 84 NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 85 NSArray *threads = [self createThreadsWithSelector:@selector(readRepeatedInt32:) object:messages]; 86 [self startThreads:threads]; 87 [self joinThreads:threads]; 88 for (TestAllTypes *message in messages) { 89 XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0); 90 } 91} 92 93- (void)readRepeatedString:(NSArray *)messages { 94 for (int i = 0; i < 10; i++) { 95 for (TestAllTypes *message in messages) { 96 XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0); 97 } 98 } 99} 100 101- (void)testConcurrentReadOfUnsetRepeatedStringField { 102 NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 103 NSArray *threads = [self createThreadsWithSelector:@selector(readRepeatedString:) 104 object:messages]; 105 [self startThreads:threads]; 106 [self joinThreads:threads]; 107 for (TestAllTypes *message in messages) { 108 XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0); 109 } 110} 111 112- (void)readInt32Int32Map:(NSArray *)messages { 113 for (int i = 0; i < 10; i++) { 114 for (TestRecursiveMessageWithRepeatedField *message in messages) { 115 XCTAssertEqual([message.iToI count], (NSUInteger)0); 116 } 117 } 118} 119 120- (void)testConcurrentReadOfUnsetInt32Int32MapField { 121 NSArray *messages = [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]]; 122 NSArray *threads = [self createThreadsWithSelector:@selector(readInt32Int32Map:) object:messages]; 123 [self startThreads:threads]; 124 [self joinThreads:threads]; 125 for (TestRecursiveMessageWithRepeatedField *message in messages) { 126 XCTAssertEqual([message.iToI count], (NSUInteger)0); 127 } 128} 129 130- (void)readStringStringMap:(NSArray *)messages { 131 for (int i = 0; i < 10; i++) { 132 for (TestRecursiveMessageWithRepeatedField *message in messages) { 133 XCTAssertEqual([message.strToStr count], (NSUInteger)0); 134 } 135 } 136} 137 138- (void)testConcurrentReadOfUnsetStringStringMapField { 139 NSArray *messages = [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]]; 140 NSArray *threads = [self createThreadsWithSelector:@selector(readStringStringMap:) 141 object:messages]; 142 [self startThreads:threads]; 143 [self joinThreads:threads]; 144 for (TestRecursiveMessageWithRepeatedField *message in messages) { 145 XCTAssertEqual([message.strToStr count], (NSUInteger)0); 146 } 147} 148 149- (void)readOptionalForeignMessageExtension:(NSArray *)messages { 150 for (int i = 0; i < 10; i++) { 151 for (TestAllExtensions *message in messages) { 152 ForeignMessage *foreign = 153 [message getExtension:[UnittestRoot optionalForeignMessageExtension]]; 154 XCTAssertEqual(foreign.c, 0); 155 } 156 } 157} 158 159- (void)testConcurrentReadOfUnsetExtensionField { 160 NSArray *messages = [self createMessagesWithType:[TestAllExtensions class]]; 161 SEL sel = @selector(readOptionalForeignMessageExtension:); 162 NSArray *threads = [self createThreadsWithSelector:sel object:messages]; 163 [self startThreads:threads]; 164 [self joinThreads:threads]; 165 GPBExtensionDescriptor *extension = [UnittestRoot optionalForeignMessageExtension]; 166 for (TestAllExtensions *message in messages) { 167 XCTAssertFalse([message hasExtension:extension]); 168 } 169} 170 171@end 172