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