1*1b3f573fSAndroid Build Coastguard Worker// Protocol Buffers - Google's data interchange format 2*1b3f573fSAndroid Build Coastguard Worker// Copyright 2014 Google Inc. All rights reserved. 3*1b3f573fSAndroid Build Coastguard Worker// https://developers.google.com/protocol-buffers/ 4*1b3f573fSAndroid Build Coastguard Worker// 5*1b3f573fSAndroid Build Coastguard Worker// Redistribution and use in source and binary forms, with or without 6*1b3f573fSAndroid Build Coastguard Worker// modification, are permitted provided that the following conditions are 7*1b3f573fSAndroid Build Coastguard Worker// met: 8*1b3f573fSAndroid Build Coastguard Worker// 9*1b3f573fSAndroid Build Coastguard Worker// * Redistributions of source code must retain the above copyright 10*1b3f573fSAndroid Build Coastguard Worker// notice, this list of conditions and the following disclaimer. 11*1b3f573fSAndroid Build Coastguard Worker// * Redistributions in binary form must reproduce the above 12*1b3f573fSAndroid Build Coastguard Worker// copyright notice, this list of conditions and the following disclaimer 13*1b3f573fSAndroid Build Coastguard Worker// in the documentation and/or other materials provided with the 14*1b3f573fSAndroid Build Coastguard Worker// distribution. 15*1b3f573fSAndroid Build Coastguard Worker// * Neither the name of Google Inc. nor the names of its 16*1b3f573fSAndroid Build Coastguard Worker// contributors may be used to endorse or promote products derived from 17*1b3f573fSAndroid Build Coastguard Worker// this software without specific prior written permission. 18*1b3f573fSAndroid Build Coastguard Worker// 19*1b3f573fSAndroid Build Coastguard Worker// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*1b3f573fSAndroid Build Coastguard Worker// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*1b3f573fSAndroid Build Coastguard Worker// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*1b3f573fSAndroid Build Coastguard Worker// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*1b3f573fSAndroid Build Coastguard Worker// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*1b3f573fSAndroid Build Coastguard Worker// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*1b3f573fSAndroid Build Coastguard Worker// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*1b3f573fSAndroid Build Coastguard Worker// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*1b3f573fSAndroid Build Coastguard Worker// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*1b3f573fSAndroid Build Coastguard Worker// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*1b3f573fSAndroid Build Coastguard Worker// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*1b3f573fSAndroid Build Coastguard Worker 31*1b3f573fSAndroid Build Coastguard Worker#import "GPBTestUtilities.h" 32*1b3f573fSAndroid Build Coastguard Worker 33*1b3f573fSAndroid Build Coastguard Worker#import "google/protobuf/Unittest.pbobjc.h" 34*1b3f573fSAndroid Build Coastguard Worker#import "google/protobuf/UnittestObjc.pbobjc.h" 35*1b3f573fSAndroid Build Coastguard Worker 36*1b3f573fSAndroid Build Coastguard Workerstatic const int kNumThreads = 100; 37*1b3f573fSAndroid Build Coastguard Workerstatic const int kNumMessages = 100; 38*1b3f573fSAndroid Build Coastguard Worker 39*1b3f573fSAndroid Build Coastguard Worker// NOTE: Most of these tests don't "fail" in the sense that the XCTAsserts 40*1b3f573fSAndroid Build Coastguard Worker// trip. Rather, the asserts simply exercise the apis, and if there is 41*1b3f573fSAndroid Build Coastguard Worker// a concurancy issue, the NSAsserts in the runtime code fire and/or the 42*1b3f573fSAndroid Build Coastguard Worker// code just crashes outright. 43*1b3f573fSAndroid Build Coastguard Worker 44*1b3f573fSAndroid Build Coastguard Worker@interface ConcurrencyTests : GPBTestCase 45*1b3f573fSAndroid Build Coastguard Worker@end 46*1b3f573fSAndroid Build Coastguard Worker 47*1b3f573fSAndroid Build Coastguard Worker@implementation ConcurrencyTests 48*1b3f573fSAndroid Build Coastguard Worker 49*1b3f573fSAndroid Build Coastguard Worker- (NSArray *)createThreadsWithSelector:(SEL)selector object:(id)object { 50*1b3f573fSAndroid Build Coastguard Worker NSMutableArray *array = [NSMutableArray array]; 51*1b3f573fSAndroid Build Coastguard Worker for (NSUInteger i = 0; i < kNumThreads; i++) { 52*1b3f573fSAndroid Build Coastguard Worker NSThread *thread = 53*1b3f573fSAndroid Build Coastguard Worker [[NSThread alloc] initWithTarget:self selector:selector object:object]; 54*1b3f573fSAndroid Build Coastguard Worker [array addObject:thread]; 55*1b3f573fSAndroid Build Coastguard Worker [thread release]; 56*1b3f573fSAndroid Build Coastguard Worker } 57*1b3f573fSAndroid Build Coastguard Worker return array; 58*1b3f573fSAndroid Build Coastguard Worker} 59*1b3f573fSAndroid Build Coastguard Worker 60*1b3f573fSAndroid Build Coastguard Worker- (NSArray *)createMessagesWithType:(Class)msgType { 61*1b3f573fSAndroid Build Coastguard Worker NSMutableArray *array = [NSMutableArray array]; 62*1b3f573fSAndroid Build Coastguard Worker for (NSUInteger i = 0; i < kNumMessages; i++) { 63*1b3f573fSAndroid Build Coastguard Worker [array addObject:[msgType message]]; 64*1b3f573fSAndroid Build Coastguard Worker } 65*1b3f573fSAndroid Build Coastguard Worker return array; 66*1b3f573fSAndroid Build Coastguard Worker} 67*1b3f573fSAndroid Build Coastguard Worker 68*1b3f573fSAndroid Build Coastguard Worker- (void)startThreads:(NSArray *)threads { 69*1b3f573fSAndroid Build Coastguard Worker for (NSThread *thread in threads) { 70*1b3f573fSAndroid Build Coastguard Worker [thread start]; 71*1b3f573fSAndroid Build Coastguard Worker } 72*1b3f573fSAndroid Build Coastguard Worker} 73*1b3f573fSAndroid Build Coastguard Worker 74*1b3f573fSAndroid Build Coastguard Worker- (void)joinThreads:(NSArray *)threads { 75*1b3f573fSAndroid Build Coastguard Worker for (NSThread *thread in threads) { 76*1b3f573fSAndroid Build Coastguard Worker while (![thread isFinished]) 77*1b3f573fSAndroid Build Coastguard Worker ; 78*1b3f573fSAndroid Build Coastguard Worker } 79*1b3f573fSAndroid Build Coastguard Worker} 80*1b3f573fSAndroid Build Coastguard Worker 81*1b3f573fSAndroid Build Coastguard Worker- (void)readForeignMessage:(NSArray *)messages { 82*1b3f573fSAndroid Build Coastguard Worker for (NSUInteger i = 0; i < 10; i++) { 83*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 84*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual(message.optionalForeignMessage.c, 0); 85*1b3f573fSAndroid Build Coastguard Worker } 86*1b3f573fSAndroid Build Coastguard Worker } 87*1b3f573fSAndroid Build Coastguard Worker} 88*1b3f573fSAndroid Build Coastguard Worker 89*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetMessageField { 90*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 91*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = 92*1b3f573fSAndroid Build Coastguard Worker [self createThreadsWithSelector:@selector(readForeignMessage:) 93*1b3f573fSAndroid Build Coastguard Worker object:messages]; 94*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 95*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 96*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 97*1b3f573fSAndroid Build Coastguard Worker XCTAssertFalse(message.hasOptionalForeignMessage); 98*1b3f573fSAndroid Build Coastguard Worker } 99*1b3f573fSAndroid Build Coastguard Worker} 100*1b3f573fSAndroid Build Coastguard Worker 101*1b3f573fSAndroid Build Coastguard Worker- (void)readRepeatedInt32:(NSArray *)messages { 102*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 103*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 104*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0); 105*1b3f573fSAndroid Build Coastguard Worker } 106*1b3f573fSAndroid Build Coastguard Worker } 107*1b3f573fSAndroid Build Coastguard Worker} 108*1b3f573fSAndroid Build Coastguard Worker 109*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetRepeatedIntField { 110*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 111*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = 112*1b3f573fSAndroid Build Coastguard Worker [self createThreadsWithSelector:@selector(readRepeatedInt32:) 113*1b3f573fSAndroid Build Coastguard Worker object:messages]; 114*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 115*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 116*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 117*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0); 118*1b3f573fSAndroid Build Coastguard Worker } 119*1b3f573fSAndroid Build Coastguard Worker} 120*1b3f573fSAndroid Build Coastguard Worker 121*1b3f573fSAndroid Build Coastguard Worker- (void)readRepeatedString:(NSArray *)messages { 122*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 123*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 124*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0); 125*1b3f573fSAndroid Build Coastguard Worker } 126*1b3f573fSAndroid Build Coastguard Worker } 127*1b3f573fSAndroid Build Coastguard Worker} 128*1b3f573fSAndroid Build Coastguard Worker 129*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetRepeatedStringField { 130*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = [self createMessagesWithType:[TestAllTypes class]]; 131*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = 132*1b3f573fSAndroid Build Coastguard Worker [self createThreadsWithSelector:@selector(readRepeatedString:) 133*1b3f573fSAndroid Build Coastguard Worker object:messages]; 134*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 135*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 136*1b3f573fSAndroid Build Coastguard Worker for (TestAllTypes *message in messages) { 137*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0); 138*1b3f573fSAndroid Build Coastguard Worker } 139*1b3f573fSAndroid Build Coastguard Worker} 140*1b3f573fSAndroid Build Coastguard Worker 141*1b3f573fSAndroid Build Coastguard Worker- (void)readInt32Int32Map:(NSArray *)messages { 142*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 143*1b3f573fSAndroid Build Coastguard Worker for (TestRecursiveMessageWithRepeatedField *message in messages) { 144*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.iToI count], (NSUInteger)0); 145*1b3f573fSAndroid Build Coastguard Worker } 146*1b3f573fSAndroid Build Coastguard Worker } 147*1b3f573fSAndroid Build Coastguard Worker} 148*1b3f573fSAndroid Build Coastguard Worker 149*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetInt32Int32MapField { 150*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = 151*1b3f573fSAndroid Build Coastguard Worker [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]]; 152*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = 153*1b3f573fSAndroid Build Coastguard Worker [self createThreadsWithSelector:@selector(readInt32Int32Map:) 154*1b3f573fSAndroid Build Coastguard Worker object:messages]; 155*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 156*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 157*1b3f573fSAndroid Build Coastguard Worker for (TestRecursiveMessageWithRepeatedField *message in messages) { 158*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.iToI count], (NSUInteger)0); 159*1b3f573fSAndroid Build Coastguard Worker } 160*1b3f573fSAndroid Build Coastguard Worker} 161*1b3f573fSAndroid Build Coastguard Worker 162*1b3f573fSAndroid Build Coastguard Worker- (void)readStringStringMap:(NSArray *)messages { 163*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 164*1b3f573fSAndroid Build Coastguard Worker for (TestRecursiveMessageWithRepeatedField *message in messages) { 165*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.strToStr count], (NSUInteger)0); 166*1b3f573fSAndroid Build Coastguard Worker } 167*1b3f573fSAndroid Build Coastguard Worker } 168*1b3f573fSAndroid Build Coastguard Worker} 169*1b3f573fSAndroid Build Coastguard Worker 170*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetStringStringMapField { 171*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = 172*1b3f573fSAndroid Build Coastguard Worker [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]]; 173*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = 174*1b3f573fSAndroid Build Coastguard Worker [self createThreadsWithSelector:@selector(readStringStringMap:) 175*1b3f573fSAndroid Build Coastguard Worker object:messages]; 176*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 177*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 178*1b3f573fSAndroid Build Coastguard Worker for (TestRecursiveMessageWithRepeatedField *message in messages) { 179*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual([message.strToStr count], (NSUInteger)0); 180*1b3f573fSAndroid Build Coastguard Worker } 181*1b3f573fSAndroid Build Coastguard Worker} 182*1b3f573fSAndroid Build Coastguard Worker 183*1b3f573fSAndroid Build Coastguard Worker- (void)readOptionalForeignMessageExtension:(NSArray *)messages { 184*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 185*1b3f573fSAndroid Build Coastguard Worker for (TestAllExtensions *message in messages) { 186*1b3f573fSAndroid Build Coastguard Worker ForeignMessage *foreign = 187*1b3f573fSAndroid Build Coastguard Worker [message getExtension:[UnittestRoot optionalForeignMessageExtension]]; 188*1b3f573fSAndroid Build Coastguard Worker XCTAssertEqual(foreign.c, 0); 189*1b3f573fSAndroid Build Coastguard Worker } 190*1b3f573fSAndroid Build Coastguard Worker } 191*1b3f573fSAndroid Build Coastguard Worker} 192*1b3f573fSAndroid Build Coastguard Worker 193*1b3f573fSAndroid Build Coastguard Worker- (void)testConcurrentReadOfUnsetExtensionField { 194*1b3f573fSAndroid Build Coastguard Worker NSArray *messages = [self createMessagesWithType:[TestAllExtensions class]]; 195*1b3f573fSAndroid Build Coastguard Worker SEL sel = @selector(readOptionalForeignMessageExtension:); 196*1b3f573fSAndroid Build Coastguard Worker NSArray *threads = [self createThreadsWithSelector:sel object:messages]; 197*1b3f573fSAndroid Build Coastguard Worker [self startThreads:threads]; 198*1b3f573fSAndroid Build Coastguard Worker [self joinThreads:threads]; 199*1b3f573fSAndroid Build Coastguard Worker GPBExtensionDescriptor *extension = 200*1b3f573fSAndroid Build Coastguard Worker [UnittestRoot optionalForeignMessageExtension]; 201*1b3f573fSAndroid Build Coastguard Worker for (TestAllExtensions *message in messages) { 202*1b3f573fSAndroid Build Coastguard Worker XCTAssertFalse([message hasExtension:extension]); 203*1b3f573fSAndroid Build Coastguard Worker } 204*1b3f573fSAndroid Build Coastguard Worker} 205*1b3f573fSAndroid Build Coastguard Worker 206*1b3f573fSAndroid Build Coastguard Worker@end 207