xcknife 0.6.3 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a16ad712fe21666c9ec13b16c1cc3007120bc9eb
4
- data.tar.gz: fc3109c894275ca6c8e5fed344fd35a3a11d0457
2
+ SHA256:
3
+ metadata.gz: d5e951e4ae5d93f82ed7773becf567d9ce8dc3a10295b3c9b7774617e1a10d48
4
+ data.tar.gz: 5f9cfc34b089ec42bf675280fd3fbf0da524220c79a55e0297ada05d0e3403d6
5
5
  SHA512:
6
- metadata.gz: f364876c260015cc6b0729035c5835b295e1772b27671b50448064659841ab21e2384476b4e5860387e0f397db41d80f4fe48730b6e36879776295e18d89056d
7
- data.tar.gz: 456da664e95295f2ae4a20982b245e7ade3a616047cf89dd654e0de0d5d053f2d1a11da6b9bc88b8f1099fd917111f7ed963a112b9c3c2cde6c50056a406a00d
6
+ metadata.gz: a57b87ee14efa242124ad9e14c2d7bc86937315a8dc9e9206c80480285c4744495ad4376f02ad835f7c23e52e79ebbbc7f7cbcab9ba95a3b12d894aaed0daca9
7
+ data.tar.gz: 07afb2bc56b4792c355a89001cce7d45261358375457cff69f717b73ce3dbfb0c69ac91fee0b01714d1a8761869bbf1475c0044064aa74ae8e20023ef0fc8481
data/.gitignore CHANGED
@@ -2,9 +2,10 @@
2
2
  pkg
3
3
  .idea/
4
4
  *.gem
5
- Gemfile.lock
6
5
  xcuserdata/
7
6
  testdumperbuild
8
7
  contents.xcworkspacedata
9
8
  TestDumper/TestDumper.dylib
10
9
  *.tmp
10
+ .bin/
11
+ .bundle/
@@ -1 +1 @@
1
- 2.2.3
1
+ 2.6.1
@@ -1,9 +1,14 @@
1
- language: ruby
1
+ language: objective-c
2
2
  sudo: false
3
- before_install: gem install bundler
4
- bundler_args: --without development
3
+ matrix:
4
+ include:
5
+ - os: osx
6
+ osx_image: xcode10.2
5
7
 
6
- rvm:
7
- - 2.2.3
8
- - 2.3.0
9
- - 2.3.1
8
+ before_script:
9
+ - export LANG=en_US.UTF-8
10
+ install: bundle
11
+ script:
12
+ - csrutil status
13
+ - git submodule update --init --recursive
14
+ - bundle exec rake build_test_dumper spec
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ xcknife (0.11.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (11.1.2)
11
+ rspec (3.4.0)
12
+ rspec-core (~> 3.4.0)
13
+ rspec-expectations (~> 3.4.0)
14
+ rspec-mocks (~> 3.4.0)
15
+ rspec-core (3.4.4)
16
+ rspec-support (~> 3.4.0)
17
+ rspec-expectations (3.4.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.4.0)
20
+ rspec-mocks (3.4.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.4.0)
23
+ rspec-support (3.4.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.12)
30
+ rake (~> 11.1.1)
31
+ rspec (~> 3.4.0)
32
+ xcknife!
33
+
34
+ BUNDLED WITH
35
+ 1.17.3
@@ -0,0 +1,2 @@
1
+ ---
2
+ cc: [mdx-ios]
data/README.md CHANGED
@@ -9,7 +9,7 @@ It works by leveraging [xctool's](https://github.com/facebook/xctool) [json-stre
9
9
 
10
10
  XCKnife generates a list of only arguments meant to be pass to Xctool's [*-only* test arguments](https://github.com/facebook/xctool#testing), but alternatively could used to generate multiple xcschemes with the proper test partitions.
11
11
 
12
- More information on XCKnife, go [here](https://corner.squareup.com/2016/06/xcknife-faster-distributed-tests-for-ios.html).
12
+ More information on XCKnife, go [here](https://developer.squareup.com/blog/xcknife-faster-distributed-tests-for-ios).
13
13
 
14
14
  ## Install
15
15
 
@@ -18,11 +18,12 @@ More information on XCKnife, go [here](https://corner.squareup.com/2016/06/xckni
18
18
  ## Using as command line tool
19
19
 
20
20
  ```
21
- $ xcknife -h
21
+ $ xcknife --help
22
22
  Usage: xcknife [options] worker-count historical-timings-json-stream-file [current-tests-json-stream-file]
23
- -p, --partition TARGETS Comma separated list of targets. Can be used multiple times
23
+ -p, --partition TARGETS Comma separated list of targets. Can be used multiple times.
24
24
  -o, --output FILENAME Output file. Defaults to STDOUT
25
25
  -a, --abbrev Results are abbreviated
26
+ -x, --xcodebuild-output Output is formatted for xcodebuild
26
27
  -h, --help Show this message
27
28
  ```
28
29
 
@@ -68,7 +69,7 @@ This will balance the tests onthe `iPhoneTestTarget` into 3 machines. The output
68
69
  }]}]}
69
70
  ```
70
71
 
71
- This provides a lot of data about the partitions and their imabalances (both internal to the partition sets, and amongst them).
72
+ This provides a lot of data about the partitions and their imbalances (both internal to the partition sets, and amongst them).
72
73
 
73
74
  If you only want the *-only* arguments, run with the `-a` flag:
74
75
 
@@ -193,6 +194,14 @@ XCKnife uses only a few attributes of a json-stream file. If you are storing the
193
194
 
194
195
  `$ xcknife-min example/xcknife-exemplar-historical-data.json-stream minified.json-stream`
195
196
 
197
+ ## Dependencies
198
+
199
+ XCKnife requires the use of the `gtimeout` command, which is provided in the GNU coreutils brew package. If you don't already have them, they can be installed with the command:
200
+
201
+ ```
202
+ brew install coreutils
203
+ ```
204
+
196
205
  ## Contributing
197
206
 
198
207
  Any contributors to the master *xcknife* repository must sign the
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'rspec/core/rake_task'
2
- require "bundler/gem_tasks"
3
2
  require 'fileutils'
4
3
 
5
4
  RSpec::Core::RakeTask.new(:spec)
@@ -11,7 +10,7 @@ task :build_test_dumper do
11
10
  target_dir = File.join(File.dirname(__FILE__), "TestDumper")
12
11
  Dir.chdir(target_dir) do
13
12
  system "./build.sh"
14
- FileUtils.copy_file("./testdumperbuild/Build/Products/Release-iphonesimulator/TestDumper.framework/TestDumper", "./TestDumper.dylib")
13
+ FileUtils.copy_file("./testdumperbuild/Build/Products/Debug-iphonesimulator/TestDumper.framework/TestDumper", "./TestDumper.dylib")
15
14
  puts "TestDumper.dylib was created successfully"
16
15
  end
17
16
  end
@@ -19,4 +18,5 @@ end
19
18
  desc "Release wih test_dumper"
20
19
  task :gem_release => [:build_test_dumper, :build] do
21
20
  system 'gem push pkg/xcknife-*.gem'
22
- end
21
+ end
22
+
@@ -1,6 +1,6 @@
1
1
  # TestDumper - EXPERIMENTAL
2
2
 
3
- Utility that replaces xctool for enumerating tests. It requires the `build-for-testing` feature Xcode8 introduced on xcodebuild. In particular, it leverages the xctestrun file (see `man xcodebuild.xctestrun`).
3
+ Utility that replaces xctool for enumerating tests. It requires the `build-for-testing` feature Xcode 8 introduced on xcodebuild. In particular, it leverages the xctestrun file (see `man xcodebuild.xctestrun`).
4
4
 
5
5
  ## Building.
6
6
 
@@ -8,4 +8,18 @@ Run
8
8
 
9
9
  ```
10
10
  $ ./build.sh
11
- ````
11
+ ````
12
+
13
+ ## Using as command line tool
14
+
15
+ ```
16
+ $ xcknife-test-dumper --help
17
+ Usage: xcknife-test-dumper [options] derived_data_folder output_file [device_id]
18
+ -d, --debug Debug mode enabled
19
+ -r, --retry-count COUNT Max retry count for simulator output
20
+ -x, --simctl-timeout SECONDS Max allowed time in seconds for simctl commands
21
+ -t OUTPUT_FOLDER, Sets temporary Output folder
22
+ --temporary-output
23
+ -s, --scheme XCSCHEME_FILE Reads environments variables from the xcscheme file
24
+ -h, --help Show this message
25
+ ```
@@ -181,7 +181,7 @@
181
181
  isa = PBXProject;
182
182
  attributes = {
183
183
  LastSwiftUpdateCheck = 0700;
184
- LastUpgradeCheck = 0700;
184
+ LastUpgradeCheck = 1010;
185
185
  ORGANIZATIONNAME = "Square, Inc";
186
186
  TargetAttributes = {
187
187
  F60C68B91B8D038300CC8521 = {
@@ -198,7 +198,7 @@
198
198
  };
199
199
  };
200
200
  };
201
- buildConfigurationList = F60C68B41B8D038300CC8521 /* Build configuration list for PBXProject "toolc" */;
201
+ buildConfigurationList = F60C68B41B8D038300CC8521 /* Build configuration list for PBXProject "TestDumper" */;
202
202
  compatibilityVersion = "Xcode 3.2";
203
203
  developmentRegion = English;
204
204
  hasScannedForEncodings = 0;
@@ -288,13 +288,23 @@
288
288
  CLANG_CXX_LIBRARY = "libc++";
289
289
  CLANG_ENABLE_MODULES = YES;
290
290
  CLANG_ENABLE_OBJC_ARC = YES;
291
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
291
292
  CLANG_WARN_BOOL_CONVERSION = YES;
293
+ CLANG_WARN_COMMA = YES;
292
294
  CLANG_WARN_CONSTANT_CONVERSION = YES;
295
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
293
296
  CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
294
297
  CLANG_WARN_EMPTY_BODY = YES;
295
298
  CLANG_WARN_ENUM_CONVERSION = YES;
299
+ CLANG_WARN_INFINITE_RECURSION = YES;
296
300
  CLANG_WARN_INT_CONVERSION = YES;
301
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
302
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
303
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
297
304
  CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
305
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
306
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
307
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
298
308
  CLANG_WARN_UNREACHABLE_CODE = YES;
299
309
  CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
300
310
  "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -337,13 +347,23 @@
337
347
  CLANG_CXX_LIBRARY = "libc++";
338
348
  CLANG_ENABLE_MODULES = YES;
339
349
  CLANG_ENABLE_OBJC_ARC = YES;
350
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
340
351
  CLANG_WARN_BOOL_CONVERSION = YES;
352
+ CLANG_WARN_COMMA = YES;
341
353
  CLANG_WARN_CONSTANT_CONVERSION = YES;
354
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
342
355
  CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
343
356
  CLANG_WARN_EMPTY_BODY = YES;
344
357
  CLANG_WARN_ENUM_CONVERSION = YES;
358
+ CLANG_WARN_INFINITE_RECURSION = YES;
345
359
  CLANG_WARN_INT_CONVERSION = YES;
360
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
361
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
362
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
346
363
  CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
364
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
365
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
366
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
347
367
  CLANG_WARN_UNREACHABLE_CODE = YES;
348
368
  CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
349
369
  "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -373,12 +393,13 @@
373
393
  F60C68D11B8D038300CC8521 /* Debug */ = {
374
394
  isa = XCBuildConfiguration;
375
395
  buildSettings = {
396
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
376
397
  CLANG_ENABLE_MODULES = YES;
398
+ CODE_SIGN_IDENTITY = "";
377
399
  DEFINES_MODULE = YES;
378
400
  DYLIB_COMPATIBILITY_VERSION = 1;
379
401
  DYLIB_CURRENT_VERSION = 1;
380
402
  DYLIB_INSTALL_NAME_BASE = "@rpath";
381
- EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
382
403
  FRAMEWORK_SEARCH_PATHS = (
383
404
  "$(inherited)",
384
405
  "$(SDKROOT)/../../Library/Frameworks/",
@@ -399,12 +420,13 @@
399
420
  F60C68D21B8D038300CC8521 /* Release */ = {
400
421
  isa = XCBuildConfiguration;
401
422
  buildSettings = {
423
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
402
424
  CLANG_ENABLE_MODULES = YES;
425
+ CODE_SIGN_IDENTITY = "";
403
426
  DEFINES_MODULE = YES;
404
427
  DYLIB_COMPATIBILITY_VERSION = 1;
405
428
  DYLIB_CURRENT_VERSION = 1;
406
429
  DYLIB_INSTALL_NAME_BASE = "@rpath";
407
- EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
408
430
  FRAMEWORK_SEARCH_PATHS = (
409
431
  "$(inherited)",
410
432
  "$(SDKROOT)/../../Library/Frameworks/",
@@ -483,7 +505,7 @@
483
505
  /* End XCBuildConfiguration section */
484
506
 
485
507
  /* Begin XCConfigurationList section */
486
- F60C68B41B8D038300CC8521 /* Build configuration list for PBXProject "toolc" */ = {
508
+ F60C68B41B8D038300CC8521 /* Build configuration list for PBXProject "TestDumper" */ = {
487
509
  isa = XCConfigurationList;
488
510
  buildConfigurations = (
489
511
  F60C68CE1B8D038300CC8521 /* Debug */,
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "0800"
3
+ LastUpgradeVersion = "1010"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -7,13 +7,9 @@
7
7
  //
8
8
 
9
9
  @import Dispatch;
10
+ @import Foundation;
10
11
  @import XCTest;
11
12
 
12
-
13
-
14
-
15
- @class NSSet, NSString, NSURL, NSUUID;
16
-
17
13
  @interface XCTestConfiguration : NSObject <NSSecureCoding>
18
14
  {
19
15
  NSURL *_testBundleURL;
@@ -71,6 +67,46 @@
71
67
 
72
68
  #include <dlfcn.h>
73
69
 
70
+ // Logging
71
+ FILE *logFile;
72
+
73
+ void initializeLogFile(const char *logFilePath)
74
+ {
75
+ logFile = fopen(logFilePath, "w");
76
+ }
77
+
78
+ void logDebug(NSString *, ...) NS_FORMAT_FUNCTION(1, 2);
79
+ void logDebug(NSString *msg, ...)
80
+ {
81
+ assert(logFile);
82
+ va_list varargs;
83
+ va_start(varargs, msg);
84
+ msg = [[NSString alloc] initWithFormat:msg arguments:varargs];
85
+ va_end(varargs);
86
+ fprintf(logFile, "%s\n", msg.UTF8String);
87
+
88
+ NSLog(@"%@", msg);
89
+ }
90
+
91
+ void logInit()
92
+ {
93
+ logDebug(@"Starting TestDumper...");
94
+ logDebug(@"Environment Variables:");
95
+ logDebug(@"%@", NSProcessInfo.processInfo.environment.description);
96
+ logDebug(@"Command Line Arguments:");
97
+ logDebug(@"%@", NSProcessInfo.processInfo.arguments.description);
98
+
99
+ logDebug(@"--------------------------------");
100
+ }
101
+
102
+ OS_NORETURN
103
+ void logEnd(Boolean success)
104
+ {
105
+ int exitCode = success ? EXIT_SUCCESS : EXIT_FAILURE;
106
+ logDebug(@"EndingTestDumper...\nExiting with status %d", exitCode);
107
+ fclose(logFile);
108
+ exit(exitCode);
109
+ }
74
110
 
75
111
  // Used for a structured log, just like Xctool's.
76
112
  // Example: https://github.com/square/xcknife/blob/master/example/xcknife-exemplar.json-stream
@@ -81,10 +117,10 @@ static void PrintJSON(FILE *outFile, id JSONObject)
81
117
 
82
118
  if (error) {
83
119
  fprintf(outFile, "{ \"message\" : \"Error while serializing to JSON. Check out simulator logs for details\" }");
84
- NSLog(@"ERROR: Error generating JSON for object: %s: %s\n",
120
+ logDebug(@"ERROR: Error generating JSON for object: %s: %s\n",
85
121
  [[JSONObject description] UTF8String],
86
122
  [[error localizedFailureReason] UTF8String]);
87
- exit(1);
123
+ logEnd(false);
88
124
  }
89
125
 
90
126
  fwrite([data bytes], 1, [data length], outFile);
@@ -114,51 +150,60 @@ static void PrintTestClass(FILE *outFile, NSString *testClass) {
114
150
  @"totalDuration" : @"0"});
115
151
  }
116
152
 
117
- void enumerateTests();
153
+ void enumerateTests(NSString *);
118
154
 
119
155
  const int TEST_TARGET_LEVEL = 0;
120
156
  const int TEST_CLASS_LEVEL = 1;
121
157
  const int TEST_METHOD_LEVEL = 2;
122
-
158
+ FILE *noteFile;
123
159
 
124
160
  __attribute__((constructor))
125
161
  void initialize() {
126
- NSString *testType = [NSString stringWithUTF8String: getenv("XCTEST_TYPE")];
162
+ NSLog(@"Starting TestDumper");
163
+ const char *logFilePath = [[[NSProcessInfo processInfo] arguments][3] UTF8String];
164
+ initializeLogFile(logFilePath);
165
+ logInit();
166
+ NSString *testBundlePath = [[NSProcessInfo processInfo] arguments][4];
167
+ NSString *testDumperOutputPath = NSProcessInfo.processInfo.environment[@"TestDumperOutputPath"];
168
+ NSFileManager *fileManager = [NSFileManager defaultManager];
127
169
 
170
+ if ([fileManager fileExistsAtPath:testDumperOutputPath]) {
171
+ logDebug(@"File already exists %@. Stopping", testDumperOutputPath);
172
+ logEnd(true);
173
+ }
174
+
175
+ NSString *testType = [NSString stringWithUTF8String: getenv("XCTEST_TYPE")];
128
176
  if ([testType isEqualToString: @"APPTEST"]) {
129
177
  [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
130
- enumerateTests();
178
+ enumerateTests(testBundlePath);
131
179
  }];
132
180
  } else {
133
- enumerateTests();
181
+ enumerateTests(testBundlePath);
134
182
  }
135
183
  }
136
184
 
137
-
138
- void enumerateTests() {
139
- XCTestConfiguration *config = [[XCTestConfiguration alloc] init];
140
- NSString *testType = [NSString stringWithUTF8String: getenv("XCTEST_TYPE")];
141
- NSString *testTarget = [NSString stringWithUTF8String: getenv("XCTEST_TARGET")];
142
-
143
- if ([testType isEqualToString: @"APPTEST"]) {
144
- config.testBundleURL = [NSURL fileURLWithPath:NSProcessInfo.processInfo.environment[@"XCInjectBundle"]];
145
- config.targetApplicationPath = NSProcessInfo.processInfo.environment[@"XCInjectBundleInto"];
146
-
147
- NSString *configPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%ul.xctestconfiguration", arc4random()]];
148
-
149
- NSLog(@"Writing config to %@", configPath);
150
-
151
- NSData *data = [NSKeyedArchiver archivedDataWithRootObject:config];
152
-
153
- [data writeToFile:configPath atomically:true];
154
-
155
- setenv("XCTestConfigurationFilePath", configPath.UTF8String, YES);
156
-
157
- dlopen(getenv("IDE_INJECTION_PATH"), RTLD_GLOBAL);
185
+ void enumerateTests(NSString *testBundlePath) {
186
+ logDebug(@"Listing all test bundles");
187
+ for (NSBundle *bundle in NSBundle.allBundles) {
188
+ logDebug(@"Found a test bundle named: %@", bundle.bundlePath);
158
189
  }
159
- NSString *testBundle = [[[NSProcessInfo processInfo] arguments] lastObject];
160
- [[NSBundle bundleWithPath:testBundle] load];
161
-
190
+ logDebug(@"Finished listing all test bundles");
191
+
192
+ NSBundle* testBundleObj = [NSBundle bundleWithPath:testBundlePath];
193
+ [testBundleObj load];
194
+ logDebug(@"test bundle loaded");
195
+
196
+ logDebug(@"Listing all test bundles");
197
+ for (NSBundle *bundle in NSBundle.allBundles) {
198
+ logDebug(@"Found a test bundle named: %@", bundle.bundlePath);
199
+ }
200
+ logDebug(@"Finished listing all test bundles");
201
+
202
+ NSString *testType = [NSString stringWithUTF8String: getenv("XCTEST_TYPE")];
203
+ NSString *testTarget = [[[testBundlePath componentsSeparatedByString:@"/"] lastObject] componentsSeparatedByString:@"."][0];
204
+
205
+ logDebug(@"The test target is: %@ of type %@", testTarget, testType);
206
+
162
207
  FILE *outFile;
163
208
  NSString *testDumperOutputPath = NSProcessInfo.processInfo.environment[@"TestDumperOutputPath"];
164
209
 
@@ -168,13 +213,18 @@ void enumerateTests() {
168
213
  outFile = fopen(testDumperOutputPath.UTF8String, "w+");
169
214
  }
170
215
 
171
- NSLog(@"Opened %@ with fd %p", testDumperOutputPath, outFile);
172
-
216
+ logDebug(@"Opened %@ with fd %p", testDumperOutputPath, outFile);
217
+ if (outFile == NULL) {
218
+ logDebug(@"File already exists at %@. Stopping", testDumperOutputPath);
219
+ logEnd(true);
220
+ }
221
+
173
222
  PrintDumpStart(outFile, testType);
174
- [[XCTestSuite defaultTestSuite] printTestsWithLevel:0 withTarget: testTarget withParent: nil outputFile:outFile];
223
+ XCTestSuite* testSuite = [XCTestSuite defaultTestSuite];
224
+ [testSuite printTestsWithLevel:0 withTarget: testTarget withParent: nil outputFile:outFile];
175
225
  PrintDumpEnd(outFile, testType);
176
226
  fclose(outFile);
177
- exit(0);
227
+ logEnd(true);
178
228
  }
179
229
 
180
230
 
@@ -193,8 +243,11 @@ void enumerateTests() {
193
243
  case TEST_METHOD_LEVEL:
194
244
  PrintTestClass(outputFile, parent);
195
245
  break;
246
+ case TEST_CLASS_LEVEL:
247
+ // nothing to do here
248
+ break;
196
249
  default:
197
- NSLog(@"Uknown level %ld", level);
250
+ logDebug(@"Unknown test level %ld for test %@", level, t.debugDescription);
198
251
 
199
252
  }
200
253
  if (level == TEST_METHOD_LEVEL) {