Add support for computing iOS code coverage

Also disable failing PosixSignalDeliveryTest* tests for iOS

Bug: chromium:844647
Change-Id: I64bb233bef2f06f6778f2d475b6d3ad685fb9143
Reviewed-on: https://webrtc-review.googlesource.com/c/105641
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Peter Hanspers <peterhanspers@webrtc.org>
Reviewed-by: Artem Titarenko <artit@webrtc.org>
Commit-Queue: Artem Titarenko <artit@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25524}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index cd931b4..d136e96 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -648,12 +648,13 @@
       rtc_ios_xctest_test("apprtcmobile_tests") {
         info_plist = "objc/AppRTCMobile/ios/Info.plist"
         sources = [
-          "objc/AppRTCMobile/ios/main.m",
+          "objc/AppRTCMobile/tests/main.mm",
         ]
         deps = [
           ":AppRTCMobile_lib",
           ":apprtcmobile_test_sources",
           "../sdk:framework_objc",
+          "//test:test_support",
         ]
         ldflags = [ "-all_load" ]
       }
diff --git a/sdk/objc/unittests/main.m b/examples/objc/AppRTCMobile/tests/main.mm
similarity index 75%
copy from sdk/objc/unittests/main.m
copy to examples/objc/AppRTCMobile/tests/main.mm
index 217fb4f..3625ffd 100644
--- a/sdk/objc/unittests/main.m
+++ b/examples/objc/AppRTCMobile/tests/main.mm
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -8,10 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
 
+#include "test/ios/coverage_util_ios.h"
+
 int main(int argc, char* argv[]) {
+  rtc::test::ConfigureCoverageReportPath();
+
   @autoreleasepool {
     return UIApplicationMain(argc, argv, nil, nil);
   }
diff --git a/rtc_base/physicalsocketserver_unittest.cc b/rtc_base/physicalsocketserver_unittest.cc
index 1e046c0..4b36cd5 100644
--- a/rtc_base/physicalsocketserver_unittest.cc
+++ b/rtc_base/physicalsocketserver_unittest.cc
@@ -547,7 +547,13 @@
 
 // Test receiving a synchronous signal while not in Wait() and then entering
 // Wait() afterwards.
-TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_RaiseThenWait DISABLED_RaiseThenWait
+#else
+#define MAYBE_RaiseThenWait RaiseThenWait
+#endif
+TEST_F(PosixSignalDeliveryTest, MAYBE_RaiseThenWait) {
   ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
   raise(SIGTERM);
   EXPECT_TRUE(ss_->Wait(0, true));
@@ -557,7 +563,13 @@
 
 // Test that we can handle getting tons of repeated signals and that we see all
 // the different ones.
-TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_InsanelyManySignals DISABLED_InsanelyManySignals
+#else
+#define MAYBE_InsanelyManySignals InsanelyManySignals
+#endif
+TEST_F(PosixSignalDeliveryTest, MAYBE_InsanelyManySignals) {
   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
   ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
   for (int i = 0; i < 10000; ++i) {
@@ -597,7 +609,13 @@
 
 // Test that it works no matter what thread the kernel chooses to give the
 // signal to (since it's not guaranteed to be the one that Wait() runs on).
-TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_SignalOnDifferentThread DISABLED_SignalOnDifferentThread
+#else
+#define MAYBE_SignalOnDifferentThread SignalOnDifferentThread
+#endif
+TEST_F(PosixSignalDeliveryTest, DISABLED_SignalOnDifferentThread) {
   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
   // Mask out SIGTERM so that it can't be delivered to this thread.
   sigset_t mask;
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index f703918..98de1a3 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -1106,7 +1106,7 @@
         rtc_ios_xctest_test("sdk_unittests") {
           info_plist = "//test/ios/Info.plist"
           sources = [
-            "objc/unittests/main.m",
+            "objc/unittests/main.mm",
           ]
 
           _bundle_id_suffix = ios_generic_test_bundle_id_suffix
@@ -1115,6 +1115,7 @@
             ":peerconnectionfactory_base_objc",
             ":sdk_unittests_bundle_data",
             ":sdk_unittests_sources",
+            "//test:test_support",
           ]
           ldflags = [ "-all_load" ]
         }
@@ -1124,7 +1125,7 @@
           info_plist = "//test/ios/Info.plist"
           sources = [
             "objc/unittests/RTCDoNotPutCPlusPlusInFrameworkHeaders_xctest.m",
-            "objc/unittests/main.m",
+            "objc/unittests/main.mm",
           ]
 
           _bundle_id_suffix = ios_generic_test_bundle_id_suffix
@@ -1132,6 +1133,7 @@
           deps = [
             ":framework_objc+link",
             ":ios_framework_bundle",
+            "//test:test_support",
           ]
         }
       }
diff --git a/sdk/objc/unittests/main.m b/sdk/objc/unittests/main.mm
similarity index 86%
rename from sdk/objc/unittests/main.m
rename to sdk/objc/unittests/main.mm
index 217fb4f..77a88a6 100644
--- a/sdk/objc/unittests/main.m
+++ b/sdk/objc/unittests/main.mm
@@ -10,8 +10,11 @@
 
 #import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
+#include "test/ios/coverage_util_ios.h"
 
 int main(int argc, char* argv[]) {
+  rtc::test::ConfigureCoverageReportPath();
+
   @autoreleasepool {
     return UIApplicationMain(argc, argv, nil, nil);
   }
diff --git a/test/BUILD.gn b/test/BUILD.gn
index c7218b6..8e7f1b0 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -137,6 +137,8 @@
     testonly = true
     visibility = [ ":test_support" ]
     sources = [
+      "ios/coverage_util_ios.h",
+      "ios/coverage_util_ios.mm",
       "ios/test_support.h",
       "ios/test_support.mm",
     ]
@@ -144,6 +146,15 @@
       ":perf_test",
       "../sdk:helpers_objc",
     ]
+    configs += [ ":test_support_objc_config" ]
+  }
+
+  config("test_support_objc_config") {
+    defines = []
+
+    if (use_clang_coverage) {
+      defines += [ "WEBRTC_IOS_ENABLE_COVERAGE" ]
+    }
   }
 }
 
diff --git a/test/ios/coverage_util_ios.h b/test/ios/coverage_util_ios.h
new file mode 100644
index 0000000..a17b69d
--- /dev/null
+++ b/test/ios/coverage_util_ios.h
@@ -0,0 +1,24 @@
+/*
+ *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_IOS_COVERAGE_UTIL_IOS_H_
+#define TEST_IOS_COVERAGE_UTIL_IOS_H_
+
+namespace rtc {
+namespace test {
+
+// In debug builds, if IOS_ENABLE_COVERAGE is defined, sets the filename of the
+// coverage file. Otherwise, it does nothing.
+void ConfigureCoverageReportPath();
+
+}  // namespace test
+}  // namespace rtc
+
+#endif  // TEST_IOS_COVERAGE_UTIL_IOS_H_
diff --git a/test/ios/coverage_util_ios.mm b/test/ios/coverage_util_ios.mm
new file mode 100644
index 0000000..c21a16d
--- /dev/null
+++ b/test/ios/coverage_util_ios.mm
@@ -0,0 +1,42 @@
+/*
+ *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import <Foundation/Foundation.h>
+
+#ifdef WEBRTC_IOS_ENABLE_COVERAGE
+extern "C" void __llvm_profile_set_filename(const char* name);
+#endif
+
+namespace rtc {
+namespace test {
+
+void ConfigureCoverageReportPath() {
+#ifdef WEBRTC_IOS_ENABLE_COVERAGE
+  static dispatch_once_t once_token;
+  dispatch_once(&once_token, ^{
+    // Writes the profraw file to the Documents directory, where the app has
+    // write rights.
+    NSArray* paths =
+        NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+    NSString* documents_directory = [paths firstObject];
+    NSString* file_name = [documents_directory stringByAppendingPathComponent:@"coverage.profraw"];
+
+    // For documentation, see:
+    // http://clang.llvm.org/docs/SourceBasedCodeCoverage.html
+    __llvm_profile_set_filename([file_name cStringUsingEncoding:NSUTF8StringEncoding]);
+
+    // Print the path for easier retrieval.
+    NSLog(@"Coverage data at %@.", file_name);
+  });
+#endif  // ifdef WEBRTC_IOS_ENABLE_COVERAGE
+}
+
+}  // namespace test
+}  // namespace rtc
diff --git a/test/ios/test_support.mm b/test/ios/test_support.mm
index fec5978..8600597 100644
--- a/test/ios/test_support.mm
+++ b/test/ios/test_support.mm
@@ -10,6 +10,7 @@
 
 #import <UIKit/UIKit.h>
 
+#include "test/ios/coverage_util_ios.h"
 #include "test/ios/test_support.h"
 #include "test/testsupport/perf_test.h"
 
@@ -70,6 +71,8 @@
 }
 
 - (void)runTests {
+  rtc::test::ConfigureCoverageReportPath();
+
   int exitStatus = g_test_suite();
 
   if (g_save_chartjson_result) {