1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20//
21//  TestCase.h
22//  Copyright (c) 2009 Apple Inc. All rights reserved.
23//
24
25#import <Foundation/Foundation.h>
26#import <dispatch/dispatch.h>
27#import "auto_zone.h"
28
29@class TestCase;
30
31/* TestFinalizer sends didFinalize:self to the currently running TestCase from its -finalize */
32@interface TestFinalizer : NSObject
33{
34    TestCase *_allocatingTest;
35}
36@end
37
38typedef enum {
39    PENDING,
40    SKIPPED,
41    IN_PROGRESS,
42    PASSED,
43    FAILED
44} TestResult;
45
46@interface TestCase : NSObject {
47    // test thread support
48    pthread_t _testThread;
49    pthread_mutex_t _mutex;
50    pthread_cond_t _cond;
51    SEL _selector;
52    vm_address_t _disguisedStackBuffer;
53    BOOL _outputCompleteCalled;
54    NSMutableString *_testOutput;
55
56    dispatch_queue_t _testQueue;
57    dispatch_queue_t _completionCallbackQueue;
58    void (^_completionCallback)(void);
59    TestResult _result;
60    NSString *_resultMessage;
61
62    // for monitoring stderr during the test
63    int _orig_fd;
64    int _fds[2];
65}
66
67/* Subclass overrides */
68
69// TestCase returns true for subclasses which implement a -performTest method.
70// Abstract subclasses can override to be skipped from the test class scan.
71+ (BOOL)isConcreteTestCase;
72
73// override to implement the test
74- (void)performTest;
75
76// subclasses can determine at runtime that the test should not be attempted
77// to skip the test the subclass should return a string explaining why the test could not be run
78// to run the test subclasses should return [super shouldSkip]
79- (NSString *)shouldSkip;
80
81// tests can monitor test object finalization by overriding
82- (void)didFinalize:(TestFinalizer *)finalizer;
83
84// Tests which monitor console output can override to scan the output. Output is delivered one line at a time.
85// The current implementation uses a small-ish buffer for output.
86- (void)processOutputLine:(NSString *)line;
87
88// Invoked after all output has been sent to processOutputLine:. Tests that expect to see output can override to fail as needed.
89// Subclasses must call super.
90- (void)outputComplete;
91
92
93/* for use by test implementors */
94
95// Access auto environment variable controlled settings
96- (BOOL)resurrectionIsFatal;
97
98// Returns a string like "PASSED" or "FAILED: message"
99- (NSString *)resultString;
100
101// subclasses invoke to indicate test result
102- (void)setTestResult:(TestResult)result message:(NSString *)msg;
103
104// invokes setTestResult:PASSED, but only if the result is not already failed
105// thus it is safe to call -passed at the end of the test without overriding an earlier failure
106- (void)passed;
107
108// subclasses invoke to indicate a test failure
109// invokes setTestResult:FAILED
110// (for whitebox tests pass a constant object if calling from a collector callout where allocation is unsafe)
111- (void)fail:(NSString *)msg;
112
113// subclasses invoke on the test queue to signal the test is complete
114- (void)testFinished;
115
116// subclasses which need to scan output can invoke -flushStderr to flush any pending output.
117// can only be invoked once, as the flush destroys the output stream
118- (void)flushStderr;
119
120// invokes auto_zone_collect with the requested options
121- (void)collectWithOptions:(auto_zone_options_t)options;
122- (void)collectWithOptions:(auto_zone_options_t)options completionCallback:(void (^)(void))callback;
123
124- (void)runThreadLocalCollection;
125- (void)requestAdvisoryCollectionWithCompletionCallback:(void (^)(void))callback;      // AUTO_ZONE_COLLECT_NO_OPTIONS
126- (void)requestGenerationalCollectionWithCompletionCallback:(void (^)(void))callback;  // AUTO_ZONE_COLLECT_GENERATIONAL_COLLECTION
127- (void)requestFullCollectionWithCompletionCallback:(void (^)(void))callback;          // AUTO_ZONE_COLLECT_FULL_COLLECTION
128- (void)requestExhaustiveCollectionWithCompletionCallback:(void (^)(void))callback;    // AUTO_ZONE_COLLECT_EXHAUSTIVE_COLLECTION
129
130- (void)clearStack;
131
132- (BOOL)block:(void *)block isInList:(void **)blockList count:(uint32_t)count;
133
134- (auto_zone_t *)auto_zone;
135
136/* Utility methods to disguise/undisguise a pointer. A disguised pointer will be invisible to the collector. */
137- (vm_address_t)disguise:(void *)pointer;
138- (void *)undisguise:(vm_address_t)disguisedPointer;
139
140- (void)startTestThread;
141- (void)stopTestThread;
142- (void)performSelectorOnTestThread:(SEL)cmd;
143- (id *)testThreadStackBuffer;
144- (uintptr_t)testThreadStackBufferSize;
145
146/* For use by the test machienery */
147// returns an array containing all the concrete test classes
148+ (NSArray *)testClasses;
149
150// returns the currently running test case
151+ (id)currentTestCase;
152
153- (void)setCompletionCallback:(void (^)(void))completionCallback;
154
155- (void)startTest;
156- (void)testFinished;
157
158- (TestResult)result;
159
160- (NSString *)testOutput;
161
162// subclasses invoke to indicate test result and complete the test
163- (void)setTestResult:(TestResult)result message:(NSString *)msg;
164
165// invokes setTestResult:PASSED
166- (void)passed;
167
168// subclasses invoke to indicate a test failure
169// invokes setTestResult:FAILED
170// (for whitebox tests pass a constant object if calling from a collector callout where allocation is unsafe)
171- (void)fail:(NSString *)msg;
172
173- (BOOL)failed; // returns YES if the test has previously set a failure condition
174
175// invokes auto_zone_collect with the requested options
176- (void)collectWithOptions:(auto_zone_options_t)options;
177- (void)collectWithOptions:(auto_zone_options_t)options completionCallback:(void (^)(void))callback;
178
179
180- (void)runThreadLocalCollection;
181- (void)requestAdvisoryCollectionWithCompletionCallback:(void (^)(void))callback;      // AUTO_ZONE_COLLECT_NO_OPTIONS
182- (void)requestGenerationalCollectionWithCompletionCallback:(void (^)(void))callback;  // AUTO_ZONE_COLLECT_GENERATIONAL_COLLECTION
183- (void)requestFullCollectionWithCompletionCallback:(void (^)(void))callback;          // AUTO_ZONE_COLLECT_FULL_COLLECTION
184- (void)requestExhaustiveCollectionWithCompletionCallback:(void (^)(void))callback;    // AUTO_ZONE_COLLECT_EXHAUSTIVE_COLLECTION
185
186- (void)requestCompactionWithCompletionCallback:(void (^)(void))callback;
187- (void)requestCompactionAnalysisWithCompletionCallback:(void (^)(void))callback;
188
189@end
190