]> git.saurik.com Git - apple/xnu.git/blame - libkdd/tests/Tests.swift
xnu-3789.1.32.tar.gz
[apple/xnu.git] / libkdd / tests / Tests.swift
CommitLineData
39037602
A
1//
2// Tests.swift
3//
4// Some of these tests here verify that kdd is able to parse old
5// kcdata files and generate the correct output. To do so, we include
6// compressed versions of the raw kcdata and as well as the expected
7// plist output.
8//
9// NOTE: If you're adding sample data/plist files, you'll need to first
10// add them to the project and then make sure each is part of the
11// tests target.
12//
13// Other tests verify the expected behavior of libkdd for certain
14// situations.
15//
16//
17
18import XCTest
19import Foundation
20
21// Swift's bridging to uuid_t is awkward.
22
23func nsuuid2uuid_t(nsuuid : NSUUID) -> uuid_t {
24 let dat = nsuuid2array(nsuuid)
25 return nsarray2uuid(dat)
26}
27
28func nsarray2uuid(x : AnyObject) -> uuid_t {
29 let a = x as! NSArray
30 return uuid_t(UInt8(a[0] as! Int),
31 UInt8(a[1] as! Int),
32 UInt8(a[2] as! Int),
33 UInt8(a[3] as! Int),
34 UInt8(a[4] as! Int),
35 UInt8(a[5] as! Int),
36 UInt8(a[6] as! Int),
37 UInt8(a[7] as! Int),
38 UInt8(a[8] as! Int),
39 UInt8(a[9] as! Int),
40 UInt8(a[10] as! Int),
41 UInt8(a[11] as! Int),
42 UInt8(a[12] as! Int),
43 UInt8(a[13] as! Int),
44 UInt8(a[14] as! Int),
45 UInt8(a[15] as! Int))
46}
47
48func nsuuid2array(uuid : NSUUID) -> [Int] {
49 var ret = [Int]()
50 let ptr = UnsafeMutablePointer<UInt8>.alloc(16)
51
52 defer { ptr.dealloc(16) }
53
54 uuid.getUUIDBytes(ptr)
55 for i in 0..<16 {
56 ret.append(Int(ptr[i]))
57 }
58 return ret
59}
60
61func decompress(data:NSData) throws -> NSData {
62 var stream = z_stream(next_in: nil, avail_in: 0, total_in: 0, next_out: nil, avail_out: 0, total_out: 0, msg: nil, state: nil, zalloc: nil, zfree: nil, opaque: nil, data_type: 0, adler: 0, reserved: 0)
63
64 let bufsize : Int = 1000
65 let buffer = UnsafeMutablePointer<UInt8>.alloc(bufsize)
66 defer { buffer.dealloc(bufsize) }
67 let output = NSMutableData()
68 stream.next_out = buffer
69 stream.avail_out = UInt32(bufsize)
70 stream.next_in = UnsafeMutablePointer(data.bytes)
71 stream.avail_in = UInt32(data.length)
72 inflateInit2_(&stream, 16+MAX_WBITS, ZLIB_VERSION, Int32(sizeof(z_stream)))
73
74 while (true) {
75 let z = inflate(&stream, Z_NO_FLUSH);
76 if (z == Z_OK || z == Z_STREAM_END) {
77 output.appendBytes(buffer, length: bufsize - Int(stream.avail_out))
78 stream.avail_out = UInt32(bufsize)
79 stream.next_out = buffer
80 if (z == Z_STREAM_END) {
81 return output;
82 }
83 } else {
84 throw NSError(domain: "zlib", code: Int(z), userInfo: nil)
85 }
86 }
87}
88
89
90
91class Tests: XCTestCase {
92
93 override func setUp() {
94 super.setUp()
95 continueAfterFailure = false
96 }
97
98 override func tearDown() {
99 // Put teardown code here. This method is called after the invocation of each test method in the class.
100 super.tearDown()
101 }
102
103 func parseBuffer(buffer:NSData) throws -> NSDictionary {
104 var error : NSError?
105 guard let dict = parseKCDataBuffer(UnsafeMutablePointer(buffer.bytes), UInt32(buffer.length), &error)
106 else {
107 XCTAssert(error != nil)
108 throw error!
109 }
110 return dict
111 }
112
113 func testPaddingFlags(pad : Int) {
114 let buffer = NSMutableData(capacity:1000)!
115
116 var item = kcdata_item()
117
118 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
119 item.flags = 0
120 item.size = 0
121 buffer.appendBytes(&item, length: sizeof(kcdata_item))
122
123 item.type = UInt32(KCDATA_TYPE_LIBRARY_LOADINFO)
124 item.flags = UInt64(pad)
125 item.size = UInt32(sizeof(dyld_uuid_info_32))
126 buffer.appendBytes(&item, length: sizeof(kcdata_item))
127
128 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
129
130 var payload = dyld_uuid_info_32(imageLoadAddress: 42, imageUUID: nsuuid2uuid_t(uuid))
131 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32))
132
133 item.type = KCDATA_TYPE_BUFFER_END
134 item.flags = 0
135 item.size = 0
136 buffer.appendBytes(&item, length: sizeof(kcdata_item))
137
138 guard let dict = try? self.parseBuffer(buffer)
139 else { XCTFail(); return; }
140
141 var uuidarray = nsuuid2array(uuid)
142 for _ in 0..<pad {
143 uuidarray.removeLast()
144 }
145
146 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageLoadAddress"] == 42)
147 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageUUID"] == uuidarray)
148 }
149
150 func testPaddingFlags() {
151 for i in 0..<15 {
152 testPaddingFlags(i)
153 }
154 }
155
156 func testBootArgs() {
157 let s = "hello, I am some boot args"
158
159 let buffer = NSMutableData(capacity:1000)!
160
161 var item = kcdata_item()
162
163 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
164 item.flags = 0
165 item.size = 0
166 buffer.appendBytes(&item, length: sizeof(kcdata_item))
167
168 item.type = UInt32(STACKSHOT_KCTYPE_BOOTARGS)
169 item.flags = 0
170 item.size = UInt32(s.utf8.count + 1)
171 buffer.appendBytes(&item, length: sizeof(kcdata_item))
172 s.nulTerminatedUTF8.withUnsafeBufferPointer({
173 buffer.appendBytes($0.baseAddress, length:s.utf8.count + 1)
174 })
175
176 item.type = KCDATA_TYPE_BUFFER_END
177 item.flags = 0
178 item.size = 0
179 buffer.appendBytes(&item, length: sizeof(kcdata_item))
180
181 guard let dict = try? self.parseBuffer(buffer) else { XCTFail(); return; }
182 XCTAssert(dict["kcdata_crashinfo"]?["boot_args"] == s)
183 }
184
185 func testBootArgsMissingNul() {
186 let s = "hello, I am some boot args"
187
188 let buffer = NSMutableData(capacity:1000)!
189
190 var item = kcdata_item()
191
192 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
193 item.flags = 0
194 item.size = 0
195 buffer.appendBytes(&item, length: sizeof(kcdata_item))
196
197 item.type = UInt32(STACKSHOT_KCTYPE_BOOTARGS)
198 item.flags = 0
199 item.size = UInt32(s.utf8.count)
200 buffer.appendBytes(&item, length: sizeof(kcdata_item))
201 s.nulTerminatedUTF8.withUnsafeBufferPointer({
202 buffer.appendBytes($0.baseAddress, length:s.utf8.count)
203 })
204
205 item.type = KCDATA_TYPE_BUFFER_END
206 item.flags = 0
207 item.size = 0
208 buffer.appendBytes(&item, length: sizeof(kcdata_item))
209
210 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
211 }
212
213 func testLoadInfo() {
214 let buffer = NSMutableData(capacity:1000)!
215
216 var item = kcdata_item()
217
218 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
219 item.flags = 0
220 item.size = 0
221 buffer.appendBytes(&item, length: sizeof(kcdata_item))
222
223 item.type = UInt32(KCDATA_TYPE_LIBRARY_LOADINFO)
224 item.flags = 0
225 item.size = UInt32(sizeof(dyld_uuid_info_32))
226 buffer.appendBytes(&item, length: sizeof(kcdata_item))
227
228 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
229
230 var payload = dyld_uuid_info_32(imageLoadAddress: 42, imageUUID: nsuuid2uuid_t(uuid))
231 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32))
232
233 item.type = KCDATA_TYPE_BUFFER_END
234 item.flags = 0
235 item.size = 0
236 buffer.appendBytes(&item, length: sizeof(kcdata_item))
237
238 guard let dict = try? self.parseBuffer(buffer)
239 else { XCTFail(); return; }
240
241 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageLoadAddress"] == 42)
242 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageUUID"] == nsuuid2array(uuid))
243 }
244
245 func testLoadInfoWrongSize() {
246 // test what happens when a struct size is short
247
248 let buffer = NSMutableData(capacity:1000)!
249
250 var item = kcdata_item()
251
252 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
253 item.flags = 0
254 item.size = 0
255 buffer.appendBytes(&item, length: sizeof(kcdata_item))
256
257 item.type = UInt32(KCDATA_TYPE_LIBRARY_LOADINFO)
258 item.flags = 0
259 item.size = UInt32(sizeof(dyld_uuid_info_32)) - 1
260 buffer.appendBytes(&item, length: sizeof(kcdata_item))
261
262 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
263
264 var payload = dyld_uuid_info_32(imageLoadAddress: 42, imageUUID: nsuuid2uuid_t(uuid))
265 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32) - 1)
266
267 item.type = KCDATA_TYPE_BUFFER_END
268 item.flags = 0
269 item.size = 0
270 buffer.appendBytes(&item, length: sizeof(kcdata_item))
271
272 guard let dict = try? self.parseBuffer(buffer)
273 else { XCTFail(); return; }
274 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageLoadAddress"] == 42)
275 var uuidarray = nsuuid2array(uuid)
276 uuidarray.removeLast()
277 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageUUID"] == uuidarray)
278 }
279
280 func testLoadInfoWayWrongSize() {
281 // test what happens when a struct size is short
282
283 let buffer = NSMutableData(capacity:1000)!
284
285 var item = kcdata_item()
286
287 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
288 item.flags = 0
289 item.size = 0
290 buffer.appendBytes(&item, length: sizeof(kcdata_item))
291
292 item.type = UInt32(KCDATA_TYPE_LIBRARY_LOADINFO)
293 item.flags = 0
294 item.size = UInt32(sizeof(dyld_uuid_info_32)) - 16
295 buffer.appendBytes(&item, length: sizeof(kcdata_item))
296
297 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
298
299 var payload = dyld_uuid_info_32(imageLoadAddress: 42, imageUUID: nsuuid2uuid_t(uuid))
300 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32) - 16)
301
302 item.type = KCDATA_TYPE_BUFFER_END
303 item.flags = 0
304 item.size = 0
305 buffer.appendBytes(&item, length: sizeof(kcdata_item))
306
307 guard let dict = try? self.parseBuffer(buffer)
308 else { XCTFail(); return; }
309 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageLoadAddress"] == 42)
310 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageUUID"] == nil)
311 }
312
313 func testLoadInfoPreposterousWrongSize() {
314 // test what happens when a struct size is short
315
316 let buffer = NSMutableData(capacity:1000)!
317
318 var item = kcdata_item()
319
320 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
321 item.flags = 0
322 item.size = 0
323 buffer.appendBytes(&item, length: sizeof(kcdata_item))
324
325 item.type = UInt32(KCDATA_TYPE_LIBRARY_LOADINFO)
326 item.flags = 0
327 item.size = UInt32(1)
328 buffer.appendBytes(&item, length: sizeof(kcdata_item))
329
330 var payload = UInt8(42)
331 buffer.appendBytes(&payload, length:1)
332
333 item.type = KCDATA_TYPE_BUFFER_END
334 item.flags = 0
335 item.size = 0
336 buffer.appendBytes(&item, length: sizeof(kcdata_item))
337
338 guard let dict = try? self.parseBuffer(buffer)
339 else { XCTFail(); return; }
340 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageLoadAddress"] == nil)
341 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??["imageUUID"] == nil)
342 }
343
344
345 func testNewArray(n : Int, pad : Int) {
346 let buffer = NSMutableData(capacity:1000)!
347 var item = kcdata_item()
348
349 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
350 item.flags = 0
351 item.size = 0
352 buffer.appendBytes(&item, length: sizeof(kcdata_item))
353
354 item.type = UInt32(KCDATA_TYPE_ARRAY_PAD0) + UInt32(pad)
355 item.flags = UInt64(STACKSHOT_KCTYPE_DONATING_PIDS) << 32 | UInt64(n)
356 item.size = UInt32(n * sizeof(UInt32) + pad)
357 buffer.appendBytes(&item, length: sizeof(kcdata_item))
358
359 for i in 0..<n {
360 var payload = UInt32(42 * i)
361 buffer.appendBytes(&payload, length:sizeof(UInt32))
362 }
363
364 for i in 0..<pad {
365 var payload = UInt8(42-i)
366 buffer.appendBytes(&payload, length:sizeof(UInt8))
367 }
368
369 item.type = KCDATA_TYPE_BUFFER_END
370 item.flags = 0
371 item.size = 0
372 buffer.appendBytes(&item, length: sizeof(kcdata_item))
373
374 guard let dict = try? self.parseBuffer(buffer)
375 else { XCTFail(); return; }
376 XCTAssert(dict["kcdata_crashinfo"]?["donating_pids"]??.count == n)
377 for i in 0..<n {
378 let x = dict["kcdata_crashinfo"] as? NSDictionary
379 let y = x?["donating_pids"] as? NSArray
380 XCTAssert((y?[i]) as? NSObject == 42 * i)
381 }
382 }
383
384 func testNewArrays() {
385 self.testNewArray(0,pad:0)
386 for i in 1..<20 {
387 for pad in 0..<16 {
388 self.testNewArray(i, pad:pad)
389 }
390 }
391 }
392
393
394 func testArrayLoadInfo(n : Int) {
395 let buffer = NSMutableData(capacity:1000)!
396 var item = kcdata_item()
397
398 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
399 item.flags = 0
400 item.size = 0
401 buffer.appendBytes(&item, length: sizeof(kcdata_item))
402
403 item.type = UInt32(KCDATA_TYPE_ARRAY_PAD0)
404 item.flags = UInt64(KCDATA_TYPE_LIBRARY_LOADINFO) << 32 | UInt64(n)
405 item.size = UInt32(n * sizeof(dyld_uuid_info_32))
406 buffer.appendBytes(&item, length: sizeof(kcdata_item))
407
408 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
409
410
411 for i in 0..<n {
412 var payload = dyld_uuid_info_32(imageLoadAddress:UInt32(i+42), imageUUID: nsuuid2uuid_t(uuid))
413
414 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32))
415 }
416
417 item.type = KCDATA_TYPE_BUFFER_END
418 item.flags = 0
419 item.size = 0
420 buffer.appendBytes(&item, length: sizeof(kcdata_item))
421
422 guard let dict = try? self.parseBuffer(buffer)
423 else { XCTFail(); return; }
424 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??.count == n)
425 for i in 0..<n {
426 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageLoadAddress"] == 42+i)
427 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageUUID"] == nsuuid2array(uuid))
428 }
429 }
430
431 func testArrayLoadInfo() {
432 for n in 0..<20 {
433 testArrayLoadInfo(n)
434 }
435 }
436
437 func testArrayLoadInfoWrongSize() {
438 // test what happens when array element sizes are too short
439
440 let n = 7
441 let wrong = 1
442 let buffer = NSMutableData(capacity:1000)!
443 var item = kcdata_item()
444
445 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
446 item.flags = 0
447 item.size = 0
448 buffer.appendBytes(&item, length: sizeof(kcdata_item))
449
450 item.type = UInt32(KCDATA_TYPE_ARRAY_PAD0)
451 item.flags = UInt64(KCDATA_TYPE_LIBRARY_LOADINFO) << 32 | UInt64(n)
452 item.size = UInt32(n * (sizeof(dyld_uuid_info_32) - wrong))
453 buffer.appendBytes(&item, length: sizeof(kcdata_item))
454
455 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
456
457 for i in 0..<n {
458 var payload = dyld_uuid_info_32(imageLoadAddress:UInt32(i+42), imageUUID: nsuuid2uuid_t(uuid))
459 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32)-wrong)
460 }
461
462 item.type = KCDATA_TYPE_BUFFER_END
463 item.flags = 0
464 item.size = 0
465 buffer.appendBytes(&item, length: sizeof(kcdata_item))
466
467 var uuidarray = nsuuid2array(uuid)
468 uuidarray.removeLast()
469
470 guard let dict = try? self.parseBuffer(buffer)
471 else { XCTFail(); return; }
472 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??.count == n)
473 for i in 0..<n {
474 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageLoadAddress"] == 42+i)
475 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageUUID"] == uuidarray)
476 }
477 }
478
479
480 func testArrayLoadInfoWayWrongSize() {
481 // test what happens when array element sizes are too short
482
483 let n = 7
484 let wrong = 16
485 let buffer = NSMutableData(capacity:1000)!
486 var item = kcdata_item()
487
488 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
489 item.flags = 0
490 item.size = 0
491 buffer.appendBytes(&item, length: sizeof(kcdata_item))
492
493 item.type = UInt32(KCDATA_TYPE_ARRAY_PAD0)
494 item.flags = UInt64(KCDATA_TYPE_LIBRARY_LOADINFO) << 32 | UInt64(n)
495 item.size = UInt32(n * (sizeof(dyld_uuid_info_32) - wrong))
496 buffer.appendBytes(&item, length: sizeof(kcdata_item))
497
498 let uuid = NSUUID(UUIDString: "de305d54-75b4-431b-adb2-eb6b9e546014")!
499
500 for i in 0..<n {
501 var payload = dyld_uuid_info_32(imageLoadAddress:UInt32(i+42), imageUUID: nsuuid2uuid_t(uuid))
502 buffer.appendBytes(&payload, length:sizeof(dyld_uuid_info_32)-wrong)
503 }
504
505 item.type = KCDATA_TYPE_BUFFER_END
506 item.flags = 0
507 item.size = 0
508 buffer.appendBytes(&item, length: sizeof(kcdata_item))
509
510 guard let dict = try? self.parseBuffer(buffer)
511 else { XCTFail(); return; }
512 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??.count == n)
513 for i in 0..<n {
514 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageLoadAddress"] == 42+i)
515 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageUUID"] == nil)
516 }
517 }
518
519 func testArrayLoadInfoPreposterouslyWrongSize() {
520 // test what happens when array element sizes are too short
521
522 let n = 7
523 let wrong = 19
524 let buffer = NSMutableData(capacity:1000)!
525 var item = kcdata_item()
526
527 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
528 item.flags = 0
529 item.size = 0
530 buffer.appendBytes(&item, length: sizeof(kcdata_item))
531
532 item.type = UInt32(KCDATA_TYPE_ARRAY_PAD0)
533 item.flags = UInt64(KCDATA_TYPE_LIBRARY_LOADINFO) << 32 | UInt64(n)
534 item.size = UInt32(n * (sizeof(dyld_uuid_info_32) - wrong))
535 buffer.appendBytes(&item, length: sizeof(kcdata_item))
536
537 for i in 0..<n {
538 var payload = UInt8(42*i)
539 buffer.appendBytes(&payload, length:1)
540 }
541
542 item.type = KCDATA_TYPE_BUFFER_END
543 item.flags = 0
544 item.size = 0
545 buffer.appendBytes(&item, length: sizeof(kcdata_item))
546
547 guard let dict = try? self.parseBuffer(buffer)
548 else { XCTFail(); return; }
549 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??.count == n)
550 for i in 0..<n {
551 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageLoadAddress"] == nil)
552 XCTAssert(dict["kcdata_crashinfo"]?["dyld_load_info"]??[i]?["imageUUID"] == nil)
553 }
554 }
555
556
557 func testNested() {
558 let buffer = NSMutableData(capacity:1000)!
559
560 var item = kcdata_item()
561
562 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
563 item.flags = 0
564 item.size = 0
565 buffer.appendBytes(&item, length: sizeof(kcdata_item))
566
567 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
568 item.flags = 0
569 item.size = UInt32(sizeof(UInt64))
570 buffer.appendBytes(&item, length: sizeof(kcdata_item))
571
572 var payload : UInt64 = 42
573 buffer.appendBytes(&payload, length:sizeof(UInt64))
574
575 item.type = KCDATA_TYPE_BUFFER_END
576 item.flags = 0
577 item.size = 0
578 buffer.appendBytes(&item, length: sizeof(kcdata_item))
579
580 let buffer2 = NSMutableData(capacity:1000)!
581
582 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
583 item.flags = 0
584 item.size = 0
585 buffer2.appendBytes(&item, length: sizeof(kcdata_item))
586
587 item.type = UInt32(KCDATA_TYPE_NESTED_KCDATA)
588 item.flags = 0
589 item.size = UInt32(buffer.length)
590 buffer2.appendBytes(&item, length: sizeof(kcdata_item))
591 buffer2.appendData(buffer)
592
593 item.type = KCDATA_TYPE_BUFFER_END
594 item.flags = 0
595 item.size = 0
596 buffer2.appendBytes(&item, length: sizeof(kcdata_item))
597
598 guard let dict2 = try? self.parseBuffer(buffer2)
599 else { XCTFail(); return; }
600
601 XCTAssert(dict2["kcdata_crashinfo"]?["kcdata_crashinfo"]??["crashed_threadid"] == 42)
602 }
603
604
605 func testReadThreadid() {
606 let buffer = NSMutableData(capacity:1000)!
607
608 var item = kcdata_item()
609
610 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
611 item.flags = 0
612 item.size = 0
613 buffer.appendBytes(&item, length: sizeof(kcdata_item))
614
615 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
616 item.flags = 0
617 item.size = UInt32(sizeof(UInt64))
618 buffer.appendBytes(&item, length: sizeof(kcdata_item))
619
620 var payload : UInt64 = 42
621 buffer.appendBytes(&payload, length:sizeof(UInt64))
622
623 item.type = KCDATA_TYPE_BUFFER_END
624 item.flags = 0
625 item.size = 0
626 buffer.appendBytes(&item, length: sizeof(kcdata_item))
627
628 guard let dict = try? self.parseBuffer(buffer)
629 else { XCTFail(); return; }
630
631 XCTAssert(dict["kcdata_crashinfo"]!["crashed_threadid"] == 42)
632 }
633
634
635 func testRepeatedKey() {
636 // test a repeated item of the same key causes error
637
638 let buffer = NSMutableData(capacity:1000)!
639
640 var item = kcdata_item()
641
642 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
643 item.flags = 0
644 item.size = 0
645 buffer.appendBytes(&item, length: sizeof(kcdata_item))
646
647 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
648 item.flags = 0
649 item.size = UInt32(sizeof(UInt64))
650 buffer.appendBytes(&item, length: sizeof(kcdata_item))
651
652 var payload : UInt64 = 42
653 buffer.appendBytes(&payload, length:sizeof(UInt64))
654
655 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
656 item.flags = 0
657 item.size = UInt32(sizeof(UInt64))
658 buffer.appendBytes(&item, length: sizeof(kcdata_item))
659
660 payload = 42
661 buffer.appendBytes(&payload, length:sizeof(UInt64))
662
663 item.type = KCDATA_TYPE_BUFFER_END
664 item.flags = 0
665 item.size = 0
666 buffer.appendBytes(&item, length: sizeof(kcdata_item))
667
668 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
669 }
670
671
672 func testContainer() {
673 let buffer = NSMutableData(capacity:1000)!
674
675 var item = kcdata_item()
676 var payload64 : UInt64
677 var payload32 : UInt32
678
679 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
680 item.flags = 0
681 item.size = 0
682 buffer.appendBytes(&item, length: sizeof(kcdata_item))
683
684 item.type = UInt32(KCDATA_TYPE_CONTAINER_BEGIN)
685 item.flags = 0
686 item.size = UInt32(sizeof(UInt32))
687 buffer.appendBytes(&item, length: sizeof(kcdata_item))
688 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
689 buffer.appendBytes(&payload32, length:sizeof(UInt32))
690
691 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
692 item.flags = 0
693 item.size = UInt32(sizeof(UInt64))
694 buffer.appendBytes(&item, length: sizeof(kcdata_item))
695 payload64 = 42
696 buffer.appendBytes(&payload64, length:sizeof(UInt64))
697
698 item.type = UInt32(KCDATA_TYPE_CONTAINER_END)
699 item.flags = 0
700 item.size = UInt32(sizeof(UInt32))
701 buffer.appendBytes(&item, length: sizeof(kcdata_item))
702 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
703 buffer.appendBytes(&payload32, length:sizeof(UInt32))
704
705
706 item.type = KCDATA_TYPE_BUFFER_END
707 item.flags = 0
708 item.size = 0
709 buffer.appendBytes(&item, length: sizeof(kcdata_item))
710
711 guard let dict = try? self.parseBuffer(buffer)
712 else { XCTFail(); return; }
713
714 XCTAssert(dict["kcdata_crashinfo"]?["task_snapshots"]??["0"]??["crashed_threadid"] == 42)
715
716 }
717
718 func testRepeatedContainer() {
719 //repeated container of same name and key shoudl fail
720
721 let buffer = NSMutableData(capacity:1000)!
722
723 var item = kcdata_item()
724 var payload64 : UInt64
725 var payload32 : UInt32
726
727 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
728 item.flags = 0
729 item.size = 0
730 buffer.appendBytes(&item, length: sizeof(kcdata_item))
731
732 item.type = UInt32(KCDATA_TYPE_CONTAINER_BEGIN)
733 item.flags = 0
734 item.size = UInt32(sizeof(UInt32))
735 buffer.appendBytes(&item, length: sizeof(kcdata_item))
736 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
737 buffer.appendBytes(&payload32, length:sizeof(UInt32))
738
739 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
740 item.flags = 0
741 item.size = UInt32(sizeof(UInt64))
742 buffer.appendBytes(&item, length: sizeof(kcdata_item))
743 payload64 = 42
744 buffer.appendBytes(&payload64, length:sizeof(UInt64))
745
746 item.type = UInt32(KCDATA_TYPE_CONTAINER_END)
747 item.flags = 0
748 item.size = UInt32(sizeof(UInt32))
749 buffer.appendBytes(&item, length: sizeof(kcdata_item))
750 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
751 buffer.appendBytes(&payload32, length:sizeof(UInt32))
752
753
754 item.type = UInt32(KCDATA_TYPE_CONTAINER_BEGIN)
755 item.flags = 0
756 item.size = UInt32(sizeof(UInt32))
757 buffer.appendBytes(&item, length: sizeof(kcdata_item))
758 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
759 buffer.appendBytes(&payload32, length:sizeof(UInt32))
760
761 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
762 item.flags = 0
763 item.size = UInt32(sizeof(UInt64))
764 buffer.appendBytes(&item, length: sizeof(kcdata_item))
765 payload64 = 42
766 buffer.appendBytes(&payload64, length:sizeof(UInt64))
767
768 item.type = UInt32(KCDATA_TYPE_CONTAINER_END)
769 item.flags = 0
770 item.size = UInt32(sizeof(UInt32))
771 buffer.appendBytes(&item, length: sizeof(kcdata_item))
772 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
773 buffer.appendBytes(&payload32, length:sizeof(UInt32))
774
775 item.type = KCDATA_TYPE_BUFFER_END
776 item.flags = 0
777 item.size = 0
778 buffer.appendBytes(&item, length: sizeof(kcdata_item))
779
780 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
781 }
782
783
784 func testContainerNoEnd() {
785 let buffer = NSMutableData(capacity:1000)!
786
787 var item = kcdata_item()
788 var payload64 : UInt64
789 var payload32 : UInt32
790
791 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
792 item.flags = 0
793 item.size = 0
794 buffer.appendBytes(&item, length: sizeof(kcdata_item))
795
796 item.type = UInt32(KCDATA_TYPE_CONTAINER_BEGIN)
797 item.flags = 0
798 item.size = UInt32(sizeof(UInt32))
799 buffer.appendBytes(&item, length: sizeof(kcdata_item))
800 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
801 buffer.appendBytes(&payload32, length:sizeof(UInt32))
802
803 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
804 item.flags = 0
805 item.size = UInt32(sizeof(UInt64))
806 buffer.appendBytes(&item, length: sizeof(kcdata_item))
807 payload64 = 42
808 buffer.appendBytes(&payload64, length:sizeof(UInt64))
809
810 item.type = KCDATA_TYPE_BUFFER_END
811 item.flags = 0
812 item.size = 0
813 buffer.appendBytes(&item, length: sizeof(kcdata_item))
814
815 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
816 }
817
818 func testContainerNoEndNoEnd() {
819 let buffer = NSMutableData(capacity:1000)!
820
821 var item = kcdata_item()
822 var payload64 : UInt64
823 var payload32 : UInt32
824
825 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
826 item.flags = 0
827 item.size = 0
828 buffer.appendBytes(&item, length: sizeof(kcdata_item))
829
830 item.type = UInt32(KCDATA_TYPE_CONTAINER_BEGIN)
831 item.flags = 0
832 item.size = UInt32(sizeof(UInt32))
833 buffer.appendBytes(&item, length: sizeof(kcdata_item))
834 payload32 = UInt32(STACKSHOT_KCCONTAINER_TASK)
835 buffer.appendBytes(&payload32, length:sizeof(UInt32))
836
837 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
838 item.flags = 0
839 item.size = UInt32(sizeof(UInt64))
840 buffer.appendBytes(&item, length: sizeof(kcdata_item))
841 payload64 = 42
842 buffer.appendBytes(&payload64, length:sizeof(UInt64))
843
844 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
845 }
846
847
848
849 func testNoEnd() {
850 let buffer = NSMutableData(capacity:1000)!
851
852 var item = kcdata_item()
853
854 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
855 item.flags = 0
856 item.size = 0
857 buffer.appendBytes(&item, length: sizeof(kcdata_item))
858
859 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
860 item.flags = 0
861 item.size = UInt32(sizeof(UInt64))
862 buffer.appendBytes(&item, length: sizeof(kcdata_item))
863
864 var payload : UInt64 = 42
865 buffer.appendBytes(&payload, length:sizeof(UInt64))
866
867 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
868 }
869
870
871 func testCrazySize() {
872 let buffer = NSMutableData(capacity:1000)!
873
874 var item = kcdata_item()
875
876 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
877 item.flags = 0
878 item.size = 0
879 buffer.appendBytes(&item, length: sizeof(kcdata_item))
880
881 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
882 item.flags = 0
883 item.size = 99999
884 buffer.appendBytes(&item, length: sizeof(kcdata_item))
885
886 var payload : UInt64 = 42
887 buffer.appendBytes(&payload, length:sizeof(UInt64))
888
889 item.type = KCDATA_TYPE_BUFFER_END
890 item.flags = 0
891 item.size = 0
892 buffer.appendBytes(&item, length: sizeof(kcdata_item))
893
894 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
895 }
896
897 func testReadRepeatedArray() {
898 // repeated arrays should be concatenated
899 let n = 10
900
901 let buffer = NSMutableData(capacity:1000)!
902
903 var item = kcdata_item()
904
905 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
906 item.flags = 0
907 item.size = 0
908 buffer.appendBytes(&item, length: sizeof(kcdata_item))
909
910 item.type = UInt32(KCDATA_TYPE_ARRAY)
911 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
912 item.size = UInt32(n * sizeof(UInt64))
913 buffer.appendBytes(&item, length: sizeof(kcdata_item))
914
915 for i in 0..<n {
916 var payload : UInt64 = UInt64(i)
917 buffer.appendBytes(&payload, length:sizeof(UInt64))
918 }
919
920 item.type = UInt32(KCDATA_TYPE_ARRAY)
921 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
922 item.size = UInt32(n * sizeof(UInt64))
923 buffer.appendBytes(&item, length: sizeof(kcdata_item))
924
925 for i in 0..<n {
926 var payload : UInt64 = UInt64(i)
927 buffer.appendBytes(&payload, length:sizeof(UInt64))
928 }
929
930 item.type = KCDATA_TYPE_BUFFER_END
931 item.flags = 0
932 item.size = 0
933 buffer.appendBytes(&item, length: sizeof(kcdata_item))
934
935 guard let dict = try? self.parseBuffer(buffer)
936 else { XCTFail(); return }
937
938 XCTAssert( 2*n == dict["kcdata_crashinfo"]!["crashed_threadid"]!!.count)
939 for i in 0..<2*n {
940 let x = dict["kcdata_crashinfo"] as? NSDictionary
941 let y = x?["crashed_threadid"] as? NSArray
942 XCTAssert((y?[i]) as? NSObject == i % n)
943 }
944 }
945
946 func testReadThreadidArray(n : Int, pad : Int) {
947 let buffer = NSMutableData(capacity:1000)!
948
949 var item = kcdata_item()
950
951 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
952 item.flags = 0
953 item.size = 0
954 buffer.appendBytes(&item, length: sizeof(kcdata_item))
955
956 item.type = UInt32(KCDATA_TYPE_ARRAY)
957 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
958 item.size = UInt32(n * sizeof(UInt64) + pad)
959 buffer.appendBytes(&item, length: sizeof(kcdata_item))
960
961 for i in 0..<n {
962 var payload : UInt64 = UInt64(i)
963 buffer.appendBytes(&payload, length:sizeof(UInt64))
964 }
965
966 for _ in 0..<pad {
967 var payload : UInt8 = 0
968 buffer.appendBytes(&payload, length:1)
969 }
970
971 item.type = KCDATA_TYPE_BUFFER_END
972 item.flags = 0
973 item.size = 0
974 buffer.appendBytes(&item, length: sizeof(kcdata_item))
975
976 guard let dict = try? self.parseBuffer(buffer)
977 else { XCTFail(); return; }
978
979 XCTAssert( n == dict["kcdata_crashinfo"]?["crashed_threadid"]??.count)
980 for i in 0..<n {
981 let x = dict["kcdata_crashinfo"] as? NSDictionary
982 let y = x?["crashed_threadid"] as? NSArray
983 XCTAssert((y?[i]) as? NSObject == i)
984 }
985
986 }
987
988 func testReadThreadidArray() {
989 // test that we can correctly read old arrays with a variety of sizes and paddings
990 self.testReadThreadidArray(0, pad:0)
991 for n in 1..<100 {
992 for pad in 0..<16 {
993 self.testReadThreadidArray(n, pad:pad)
994 }
995 }
996 }
997
998 func testReadThreadidArrayWrongSize1() {
999 /// for old style arrays, if the element size is determined by the type. If the array of that size element at the given count doesn't fit, then parsing should fail
1000
1001 let n = 1
1002
1003 let buffer = NSMutableData(capacity:1000)!
1004
1005 var item = kcdata_item()
1006
1007 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
1008 item.flags = 0
1009 item.size = 0
1010 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1011
1012 item.type = UInt32(KCDATA_TYPE_ARRAY)
1013 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
1014 item.size = UInt32(4)
1015 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1016
1017 var payload : UInt32 = UInt32(42)
1018 buffer.appendBytes(&payload, length:sizeof(UInt32))
1019
1020 item.type = KCDATA_TYPE_BUFFER_END
1021 item.flags = 0
1022 item.size = 0
1023 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1024
1025 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
1026 }
1027
1028 func testReadThreadidArrayWrongSize5() {
1029 /// if the count is bigger than the buffer, parsing will just fail
1030
1031 let n = 5
1032
1033 let buffer = NSMutableData(capacity:1000)!
1034
1035 var item = kcdata_item()
1036
1037 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
1038 item.flags = 0
1039 item.size = 0
1040 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1041
1042 item.type = UInt32(KCDATA_TYPE_ARRAY)
1043 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
1044 item.size = UInt32(4)
1045 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1046
1047 var payload : UInt32 = UInt32(42)
1048 buffer.appendBytes(&payload, length:sizeof(UInt32))
1049
1050 item.type = KCDATA_TYPE_BUFFER_END
1051 item.flags = 0
1052 item.size = 0
1053 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1054
1055 XCTAssert( (try? self.parseBuffer(buffer)) == nil )
1056 }
1057
1058
1059 func testReadThreadidArrayPaddedSize() {
1060 // test that we can tolerate a little padding at the end of an array
1061 let n = 5
1062
1063 let buffer = NSMutableData(capacity:1000)!
1064
1065 var item = kcdata_item()
1066
1067 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
1068 item.flags = 0
1069 item.size = 0
1070 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1071
1072 item.type = UInt32(KCDATA_TYPE_ARRAY)
1073 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
1074 item.size = UInt32(n * sizeof(UInt64)) + 1
1075 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1076
1077 for i in 0..<n {
1078 var payload : UInt64 = UInt64(i)
1079 buffer.appendBytes(&payload, length:sizeof(UInt64))
1080 }
1081 var payload : UInt8 = 0
1082 buffer.appendBytes(&payload, length:1)
1083
1084 item.type = KCDATA_TYPE_BUFFER_END
1085 item.flags = 0
1086 item.size = 0
1087 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1088
1089 guard let dict = try? self.parseBuffer(buffer)
1090 else { XCTFail(); return; }
1091
1092 XCTAssert( n == dict["kcdata_crashinfo"]?["crashed_threadid"]??.count)
1093 for i in 0..<n {
1094 let x = dict["kcdata_crashinfo"] as? NSDictionary
1095 let y = x?["crashed_threadid"] as? NSArray
1096 XCTAssert((y?[i]) as? NSObject == i)
1097 }
1098 }
1099
1100 func testReadThreadidArrayPaddedSize15() {
1101 // test that we can tolerate a little padding at the end of an array
1102 let n = 5
1103
1104 let buffer = NSMutableData(capacity:1000)!
1105
1106 var item = kcdata_item()
1107
1108 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
1109 item.flags = 0
1110 item.size = 0
1111 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1112
1113 item.type = UInt32(KCDATA_TYPE_ARRAY)
1114 item.flags = UInt64(TASK_CRASHINFO_CRASHED_THREADID) << 32 | UInt64(n)
1115 item.size = UInt32(n * sizeof(UInt64)) + 15
1116 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1117
1118 for i in 0..<n {
1119 var payload : UInt64 = UInt64(i)
1120 buffer.appendBytes(&payload, length:sizeof(UInt64))
1121 }
1122 for i in 0..<15 {
1123 i;
1124 var payload : UInt8 = 0
1125 buffer.appendBytes(&payload, length:1)
1126 }
1127
1128 item.type = KCDATA_TYPE_BUFFER_END
1129 item.flags = 0
1130 item.size = 0
1131 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1132
1133 guard let dict = try? self.parseBuffer(buffer)
1134 else { XCTFail(); return; }
1135
1136 XCTAssert( n == dict["kcdata_crashinfo"]?["crashed_threadid"]??.count)
1137 for i in 0..<n {
1138 let x = dict["kcdata_crashinfo"] as? NSDictionary
1139 let y = x?["crashed_threadid"] as? NSArray
1140 XCTAssert((y?[i]) as? NSObject == i)
1141 }
1142 }
1143
1144
1145 func testReadThreadidWrongSize(size : UInt32) {
1146 let buffer = NSMutableData(capacity:1000)!
1147
1148 var item = kcdata_item()
1149
1150 item.type = KCDATA_BUFFER_BEGIN_CRASHINFO
1151 item.flags = 0
1152 item.size = 0
1153 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1154
1155 item.type = UInt32(TASK_CRASHINFO_CRASHED_THREADID)
1156 item.flags = 0
1157 item.size = size
1158 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1159
1160 var payload : UInt64 = 42
1161 buffer.appendBytes(&payload, length:Int(size))
1162
1163 item.type = KCDATA_TYPE_BUFFER_END
1164 item.flags = 0
1165 item.size = 0
1166 buffer.appendBytes(&item, length: sizeof(kcdata_item))
1167
1168 guard let dict = try? self.parseBuffer(buffer)
1169 else { XCTFail(); return; }
1170
1171 XCTAssert(dict["kcdata_crashinfo"]?["crashed_threadid"] == nil)
1172 }
1173
1174 func testReadThreadidWrongSize0() {
1175 self.testReadThreadidWrongSize(0)
1176 }
1177
1178 func testReadThreadidWrongSize7() {
1179 self.testReadThreadidWrongSize(7)
1180 }
1181
1182 func dataWithResource(name:String) -> NSData? {
1183 guard let filename = NSBundle(forClass: self.classForCoder).pathForResource(name, ofType: nil)
1184 else { return nil }
1185 return NSData(contentsOfFile:filename)!
1186 }
1187
1188 func testSampleStackshot(name : String) {
1189 // check that we agree with sample file
1190
1191 guard let sampledata = self.dataWithResource(name)
1192 else { XCTFail(); return }
1193 var dict : NSDictionary?
1194
1195 dict = try? self.parseBuffer(sampledata)
1196
1197 if (dict == nil) {
1198 if let decoded = NSData(base64EncodedData: sampledata, options:.IgnoreUnknownCharacters) {
1199 dict = try? self.parseBuffer(decoded)
1200 }
1201 }
1202
1203 if (dict == nil) {
1204 if let decompressed = try? decompress(sampledata) {
1205 dict = try? self.parseBuffer(decompressed)
1206 }
1207 }
1208
1209 if (dict == nil) {
1210 XCTFail(); return;
1211 }
1212
1213 guard let plistdata = self.dataWithResource(name + ".plist.gz") ??
1214 self.dataWithResource(name + ".plist")
1215 else {XCTFail(); return}
1216
1217 var dict2 = try? NSPropertyListSerialization.propertyListWithData(plistdata, options: NSPropertyListReadOptions.Immutable, format: nil)
1218 if dict2 == nil {
1219 dict2 = try? NSPropertyListSerialization.propertyListWithData(decompress(plistdata), options: .Immutable, format: nil)
1220 }
1221
1222 XCTAssert(dict2 != nil)
1223
1224 XCTAssert(dict == dict2 as? NSDictionary)
1225
1226 // check that we agree with python
1227
1228 #if os(OSX)
1229
1230 let kcdatapy = NSBundle(forClass: self.classForCoder).pathForResource("kcdata.py", ofType: nil)
1231
1232 let task = NSTask()
1233 task.launchPath = kcdatapy
1234 task.arguments = ["-p",
1235 NSBundle(forClass:self.classForCoder).pathForResource(name, ofType: nil)!]
1236 let pipe = NSPipe()
1237 task.standardOutput = pipe
1238 task.launch()
1239
1240 let data = pipe.fileHandleForReading.readDataToEndOfFile()
1241
1242 guard let dict3 = try? NSPropertyListSerialization.propertyListWithData(data, options: .Immutable, format: nil) as? NSDictionary
1243 else { XCTFail(); return }
1244
1245 XCTAssert(dict == dict3)
1246
1247 #endif
1248 }
1249
1250 func testSampleStackshot() {
1251 self.testSampleStackshot("stackshot-sample")
1252 }
1253
1254 func testSampleStackshotOldArrays() {
1255 self.testSampleStackshot("stackshot-sample-old-arrays")
1256 }
1257
1258 func testSampleStackshotNewArrays() {
1259 self.testSampleStackshot("stackshot-sample-new-arrays")
1260 }
1261
1262 func testSampleDeltaStackshotOldArrays() {
1263 self.testSampleStackshot("delta-stackshot-sample-old-arrays")
1264 }
1265
1266 func testSampleDeltaStackshotNewArrays() {
1267 self.testSampleStackshot("delta-stackshot-sample-new-arrays")
1268 }
1269
1270 func testSampleCorpse() {
1271 self.testSampleStackshot("corpse-sample")
1272 }
1273
1274 func testSampleStackshotTailspin() {
1275 self.testSampleStackshot("stackshot-sample-tailspin")
1276 }
1277
1278 func testSampleStackshotTailspin2() {
1279 self.testSampleStackshot("stackshot-sample-tailspin-2")
1280 }
1281
1282 func testSampleExitReason() {
1283 self.testSampleStackshot("exitreason-sample")
1284 }
1285
1286 func testSampleThreadT() {
1287 self.testSampleStackshot("stackshot-sample-ths-thread-t")
1288 }
1289
1290 func testSampleCpuTimes() {
1291 self.testSampleStackshot("stackshot-sample-cputime")
1292 }
1293
1294 func testSampleDuration() {
1295 self.testSampleStackshot("stackshot-sample-duration")
1296 }
1297
1298 func testSampleNested() {
1299 self.testSampleStackshot("nested-sample")
1300 }
1301
1302 func testSampleTermWithReason() {
1303 self.testSampleStackshot("test-twr-sample")
1304 }
1305
1306 func testSampleCorpseTermWithReason() {
1307 self.testSampleStackshot("corpse-twr-sample")
1308 }
1309
1310 func testSampleCorpseTermWithReasonV2() {
1311 self.testSampleStackshot("corpse-twr-sample-v2")
1312 }
1313
1314 func testSampleCodesigningExitReason() {
1315 self.testSampleStackshot("exitreason-codesigning")
1316 }
1317
1318 func testStackshotSharedcacheV2() {
1319 self.testSampleStackshot("stackshot-sample-sharedcachev2")
1320 }
1321
1322 func testStackshotFaultStats() {
1323 self.testSampleStackshot("stackshot-fault-stats")
1324 }
1325
1326 func testStackshotwithKCID() {
1327 self.testSampleStackshot("stackshot-with-kcid")
1328 }
1329
1330 func testXNUPostTestConfig() {
1331 self.testSampleStackshot("xnupost_testconfig-sample")
1332 }
1333
1334 func testTrivial() {
1335 }
1336}