Home | History | Annotate | Download | only in unittest
      1 #ifdef OS_darwin_10
      2 #include <dispatch/dispatch.h>
      3 #endif
      4 
      5 #include <gtest/gtest.h>
      6 #include <sys/types.h>
      7 #include <sys/mman.h>
      8 #import <Foundation/Foundation.h>
      9 
     10 #include "test_utils.h"
     11 #include "gtest_fixture_injection.h"
     12 
     13 #ifndef OS_darwin
     14 #error "This file should be built on Darwin only."
     15 #endif
     16 
     17 class Task {
     18  public:
     19   Task()  {};
     20   void Run() { printf("Inside Task::Run()\n"); }
     21 };
     22 
     23 @interface TaskOperation : NSOperation {
     24  @private
     25   Task *task_;
     26 }
     27 
     28 + (id)taskOperationWithTask:(Task*)task;
     29 
     30 - (id)initWithTask:(Task*)task;
     31 
     32 @end  // @interface TaskOperation
     33 
     34 @implementation TaskOperation
     35 
     36 + (id)taskOperationWithTask:(Task*)task {
     37   return [[TaskOperation alloc] initWithTask:task];
     38 }
     39 
     40 - (id)init {
     41   return [self initWithTask:NULL];
     42 }
     43 
     44 - (id)initWithTask:(Task*)task {
     45   if ((self = [super init])) {
     46     task_ = task;
     47   }
     48   return self;
     49 }
     50 
     51 - (void)main {
     52   if (!task_) {
     53     return;
     54   }
     55 
     56   task_->Run();
     57   delete task_;
     58   task_ = NULL;
     59 }
     60 
     61 - (void)dealloc {
     62   if (task_) delete task_;
     63   [super dealloc];
     64 }
     65 
     66 @end  // @implementation TaskOperation
     67 
     68 namespace MacTests {
     69 // Regression test for https://bugs.kde.org/show_bug.cgi?id=216837.
     70 TEST(MacTests, WqthreadRegressionTest) {
     71   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     72   Task *task = new Task();
     73   NSOperationQueue *queue = [[NSOperationQueue alloc] init];
     74   [queue addOperation:[TaskOperation taskOperationWithTask:task]];
     75 
     76   sleep(1);  // wait for the worker thread to start.
     77   // If the bug is still there, ThreadSanitizer should crash after starting
     78   // the worker thread.
     79   [pool release];
     80 }
     81 
     82 // Regression test for a bug with passing a 32-bit value instead of a 64-bit
     83 // as the last parameter to mmap().
     84 TEST(MacTests, ShmMmapRegressionTest) {
     85 #ifdef OS_darwin_9
     86   int md;
     87   void *virt_addr;
     88   shm_unlink("apple.shm.notification_center");
     89   md = shm_open("apple.shm.notification_center", 0, 0);
     90   if (md != -1) {
     91     virt_addr = mmap(0, 4096, 1, 1, md, 0);
     92     if (virt_addr == (void*)-1) {
     93       shm_unlink("apple.shm.notification_center");
     94       FAIL() << "mmap returned -1";
     95     } else {
     96       munmap(virt_addr, 4096);
     97       shm_unlink("apple.shm.notification_center");
     98     } 
     99   } else {
    100     printf("shm_open() returned -1\n");
    101   }
    102 #endif
    103 }
    104 
    105 }  // namespace MacTests
    106 
    107 #ifdef OS_darwin_10
    108 namespace SnowLeopardTests {
    109 
    110 int GLOB = 0;
    111 StealthNotification sn1, sn2;
    112 
    113 void worker_do_add(int *var, int val,
    114                    StealthNotification *notify,
    115                    StealthNotification *waitfor) {
    116   (*var) += val;
    117   fprintf(stderr, "var=%d\n", *var);
    118   notify->signal();
    119   // Make sure that the callbacks are ran on different threads.
    120   if (waitfor) {
    121     waitfor->wait();
    122   }
    123 }
    124 
    125 TEST(SnowLeopardTests, GCD_GlobalQueueRace) {
    126   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "SnowLeopardTests.GCD_GlobalQueueRace TP.");
    127   dispatch_queue_t queue = dispatch_get_global_queue(0,0);
    128   dispatch_block_t block_plus = ^{ worker_do_add(&GLOB, 1, &sn1, &sn2); };
    129   dispatch_block_t block_minus = ^{ worker_do_add(&GLOB, -1, &sn2, NULL); };
    130   dispatch_async(queue, block_plus);
    131   dispatch_async(queue, block_minus);
    132   sn1.wait();
    133   sn2.wait();
    134 }
    135 
    136 }  // namespace SnowLeopardTests
    137 #endif
    138