OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 @TestOn("vm") |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:convert'; |
| 9 import 'dart:io'; |
| 10 |
| 11 import 'package:path/path.dart' as p; |
| 12 import 'package:test/test.dart'; |
| 13 import 'package:test/src/util/io.dart'; |
| 14 |
| 15 import '../io.dart'; |
| 16 |
| 17 String _sandbox; |
| 18 |
| 19 String get _tempDir => p.join(_sandbox, "tmp"); |
| 20 |
| 21 final _lines = UTF8.decoder.fuse(const LineSplitter()); |
| 22 |
| 23 // This test is inherently prone to race conditions. If it fails, it will likely |
| 24 // do so flakily, but if it succeeds, it will succeed consistently. The tests |
| 25 // represent a best effort to kill the test runner at certain times during its |
| 26 // execution. |
| 27 void main() { |
| 28 setUp(() { |
| 29 _sandbox = createTempDir(); |
| 30 }); |
| 31 |
| 32 tearDown(() { |
| 33 new Directory(_sandbox).deleteSync(recursive: true); |
| 34 }); |
| 35 |
| 36 group("during loading,", () { |
| 37 test("cleans up if killed while loading a VM test", () { |
| 38 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 39 void main() { |
| 40 print("in test.dart"); |
| 41 // Spin for a long time so the test is probably killed while still loading. |
| 42 for (var i = 0; i < 100000000; i++) {} |
| 43 } |
| 44 """); |
| 45 |
| 46 return _startUnittest(["test.dart"]).then((process) { |
| 47 return _lines.bind(process.stdout).first.then((line) { |
| 48 expect(line, equals("in test.dart")); |
| 49 process.kill(); |
| 50 return process.exitCode; |
| 51 }).then((_) { |
| 52 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 53 }); |
| 54 }); |
| 55 }); |
| 56 |
| 57 test("cleans up if killed while loading a browser test", () { |
| 58 new File(p.join(_sandbox, "test.dart")) |
| 59 .writeAsStringSync("void main() {}"); |
| 60 |
| 61 return _startUnittest(["-p", "chrome", "test.dart"]).then((process) { |
| 62 return _lines.bind(process.stdout).first.then((line) { |
| 63 expect(line, equals("Compiling test.dart...")); |
| 64 process.kill(); |
| 65 return process.exitCode; |
| 66 }).then((_) { |
| 67 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 68 }); |
| 69 }); |
| 70 }); |
| 71 |
| 72 test("exits immediately if ^C is sent twice", () { |
| 73 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 74 void main() { |
| 75 print("in test.dart"); |
| 76 while (true) {} |
| 77 } |
| 78 """); |
| 79 |
| 80 return _startUnittest(["test.dart"]).then((process) { |
| 81 return _lines.bind(process.stdout).first.then((line) { |
| 82 expect(line, equals("in test.dart")); |
| 83 process.kill(); |
| 84 |
| 85 // TODO(nweiz): Sending two signals in close succession can cause the |
| 86 // second one to be ignored, so we wait a bit before the second |
| 87 // one. Remove this hack when issue 23047 is fixed. |
| 88 return new Future.delayed(new Duration(seconds: 1)); |
| 89 }).then((_) { |
| 90 process.kill(); |
| 91 return process.exitCode; |
| 92 }).then((_) { |
| 93 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 94 }); |
| 95 }); |
| 96 }); |
| 97 }); |
| 98 |
| 99 group("during test running", () { |
| 100 test("waits for a VM test to finish running", () { |
| 101 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 102 import 'dart:async'; |
| 103 import 'dart:io'; |
| 104 |
| 105 import 'package:test/test.dart'; |
| 106 |
| 107 void main() { |
| 108 tearDown(() => new File("output").writeAsStringSync("ran teardown")); |
| 109 |
| 110 test("test", () { |
| 111 print("running test"); |
| 112 return new Future.delayed(new Duration(seconds: 1)); |
| 113 }); |
| 114 } |
| 115 """); |
| 116 |
| 117 return _startUnittest(["test.dart"]).then((process) { |
| 118 return _lines.bind(process.stdout).skip(2).first.then((line) { |
| 119 expect(line, equals("running test")); |
| 120 process.kill(); |
| 121 return process.exitCode; |
| 122 }).then((_) { |
| 123 expect(new File(p.join(_sandbox, "output")).readAsStringSync(), |
| 124 equals("ran teardown")); |
| 125 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 126 }); |
| 127 }); |
| 128 }); |
| 129 |
| 130 test("kills a browser test immediately", () { |
| 131 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 132 import 'dart:async'; |
| 133 |
| 134 import 'package:test/test.dart'; |
| 135 |
| 136 void main() { |
| 137 test("test", () { |
| 138 print("running test"); |
| 139 |
| 140 // Allow an event loop to pass so the preceding print can be handled. |
| 141 return new Future(() { |
| 142 // Loop forever so that if the test isn't stopped while running, it never |
| 143 // stops. |
| 144 while (true) {} |
| 145 }); |
| 146 }); |
| 147 } |
| 148 """); |
| 149 |
| 150 return _startUnittest(["-p", "chrome", "test.dart"]).then((process) { |
| 151 return _lines.bind(process.stdout).skip(3).first.then((line) { |
| 152 expect(line, equals("running test")); |
| 153 process.kill(); |
| 154 return process.exitCode; |
| 155 }).then((_) { |
| 156 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 157 }); |
| 158 }); |
| 159 }); |
| 160 |
| 161 test("kills a VM test immediately if ^C is sent twice", () { |
| 162 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 163 import 'package:test/test.dart'; |
| 164 |
| 165 void main() { |
| 166 test("test", () { |
| 167 print("running test"); |
| 168 while (true) {} |
| 169 }); |
| 170 } |
| 171 """); |
| 172 |
| 173 return _startUnittest(["test.dart"]).then((process) { |
| 174 return _lines.bind(process.stdout).skip(2).first.then((line) { |
| 175 expect(line, equals("running test")); |
| 176 process.kill(); |
| 177 |
| 178 // TODO(nweiz): Sending two signals in close succession can cause the |
| 179 // second one to be ignored, so we wait a bit before the second |
| 180 // one. Remove this hack when issue 23047 is fixed. |
| 181 return new Future.delayed(new Duration(seconds: 1)); |
| 182 }).then((_) { |
| 183 process.kill(); |
| 184 return process.exitCode; |
| 185 }); |
| 186 }); |
| 187 }); |
| 188 |
| 189 test("causes expect() to always throw an error immediately", () { |
| 190 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 191 import 'dart:async'; |
| 192 import 'dart:io'; |
| 193 |
| 194 import 'package:test/test.dart'; |
| 195 |
| 196 void main() { |
| 197 var expectThrewError = false; |
| 198 |
| 199 tearDown(() { |
| 200 new File("output").writeAsStringSync(expectThrewError.toString()); |
| 201 }); |
| 202 |
| 203 test("test", () { |
| 204 print("running test"); |
| 205 |
| 206 return new Future.delayed(new Duration(seconds: 1)).then((_) { |
| 207 try { |
| 208 expect(true, isTrue); |
| 209 } catch (_) { |
| 210 expectThrewError = true; |
| 211 } |
| 212 }); |
| 213 }); |
| 214 } |
| 215 """); |
| 216 |
| 217 return _startUnittest(["test.dart"]).then((process) { |
| 218 return _lines.bind(process.stdout).skip(2).first.then((line) { |
| 219 expect(line, equals("running test")); |
| 220 process.kill(); |
| 221 return process.exitCode; |
| 222 }).then((_) { |
| 223 expect(new File(p.join(_sandbox, "output")).readAsStringSync(), |
| 224 equals("true")); |
| 225 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 226 }); |
| 227 }); |
| 228 }); |
| 229 |
| 230 test("causes expectAsync() to always throw an error immediately", () { |
| 231 new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" |
| 232 import 'dart:async'; |
| 233 import 'dart:io'; |
| 234 |
| 235 import 'package:test/test.dart'; |
| 236 |
| 237 void main() { |
| 238 var expectAsyncThrewError = false; |
| 239 |
| 240 tearDown(() { |
| 241 new File("output").writeAsStringSync(expectAsyncThrewError.toString()); |
| 242 }); |
| 243 |
| 244 test("test", () { |
| 245 print("running test"); |
| 246 |
| 247 return new Future.delayed(new Duration(seconds: 1)).then((_) { |
| 248 try { |
| 249 expectAsync(() {}); |
| 250 } catch (_) { |
| 251 expectAsyncThrewError = true; |
| 252 } |
| 253 }); |
| 254 }); |
| 255 } |
| 256 """); |
| 257 |
| 258 return _startUnittest(["test.dart"]).then((process) { |
| 259 return _lines.bind(process.stdout).skip(2).first.then((line) { |
| 260 expect(line, equals("running test")); |
| 261 process.kill(); |
| 262 return process.exitCode; |
| 263 }).then((_) { |
| 264 expect(new File(p.join(_sandbox, "output")).readAsStringSync(), |
| 265 equals("true")); |
| 266 expect(new Directory(_tempDir).listSync(), isEmpty); |
| 267 }); |
| 268 }); |
| 269 }); |
| 270 }); |
| 271 } |
| 272 |
| 273 Future<Process> _startUnittest(List<String> args) { |
| 274 new Directory(_tempDir).create(); |
| 275 return startUnittest(args, workingDirectory: _sandbox, |
| 276 environment: {"_UNITTEST_TEMP_DIR": _tempDir}); |
| 277 } |
OLD | NEW |