OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, 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 library record_and_replay; | |
6 | |
7 import 'dart:io'; | |
8 import 'dart:convert'; | |
9 | |
10 import 'path.dart'; | |
11 import 'test_runner.dart'; | |
12 | |
13 /* | |
14 * Json files look like this: | |
15 * | |
16 * [ | |
17 * { | |
18 * 'name' : '...', | |
19 * 'command' : { | |
20 * 'timeout_limit' : 60, | |
21 * 'executable' : '...', | |
22 * 'arguments' : ['arg1, 'arg2', '...'], | |
23 * }, | |
24 * 'command_output' : { | |
25 * 'exit_code' : 42, | |
26 * 'stdout' : '...', | |
27 * 'stderr' : '...', | |
28 * 'duration' : 1.5, | |
29 * 'did_timeout' : false, | |
30 * }, | |
31 * }, | |
32 * .... | |
33 * ] | |
34 */ | |
35 | |
36 List<String> makePathsRelativeToDart(String cwd, List<String> arguments) { | |
37 var relativeArguments = <String>[]; | |
38 for (var rawArgument in arguments) { | |
39 if (rawArgument.startsWith(cwd)) { | |
40 var relative = new Path(rawArgument).relativeTo(new Path(cwd)); | |
41 relativeArguments.add(relative.toNativePath()); | |
42 } else { | |
43 relativeArguments.add(rawArgument); | |
44 } | |
45 } | |
46 return relativeArguments; | |
47 } | |
48 | |
49 class TestCaseRecorder { | |
50 Path _outputPath; | |
51 List<Map> _recordedCommandInvocations = []; | |
52 String _cwd; | |
53 | |
54 TestCaseRecorder(this._outputPath) { | |
55 _cwd = Directory.current.path; | |
56 } | |
57 | |
58 void nextCommand(ProcessCommand command, int timeout) { | |
59 // Convert arguments from absolute to relative paths (relative to the dart | |
60 // directory) because the absolute path on the machine where we record | |
61 // may be different from the absolute path on the machine where we execute | |
62 // the commands. | |
63 var arguments = makePathsRelativeToDart(_cwd, command.arguments); | |
64 | |
65 var commandExecution = { | |
66 'name': command.displayName, | |
67 'command': { | |
68 'timeout_limit': timeout, | |
69 'executable': command.executable, | |
70 'arguments': arguments, | |
71 }, | |
72 }; | |
73 _recordedCommandInvocations.add(commandExecution); | |
74 } | |
75 | |
76 void finish() { | |
77 var file = new File(_outputPath.toNativePath()); | |
78 var jsonString = JSON.encode(_recordedCommandInvocations); | |
79 file.writeAsStringSync(jsonString); | |
80 print("TestCaseRecorder: written all TestCases to ${_outputPath}"); | |
81 } | |
82 } | |
83 | |
84 class TestCaseOutputArchive { | |
85 Map<String, Map> _commandOutputRecordings; | |
86 String _cwd; | |
87 | |
88 TestCaseOutputArchive() { | |
89 _cwd = Directory.current.path; | |
90 } | |
91 | |
92 void loadFromPath(Path recordingPath) { | |
93 var file = new File(recordingPath.toNativePath()); | |
94 var commandRecordings = JSON.decode(file.readAsStringSync()) as List; | |
95 _commandOutputRecordings = {}; | |
96 for (var commandRecording in commandRecordings) { | |
97 var key = _indexKey(commandRecording['command']['executable'] as String, | |
98 (commandRecording['command']['arguments'] as List).join(' ')); | |
99 _commandOutputRecordings[key] = commandRecording['command_output'] as Map; | |
100 } | |
101 } | |
102 | |
103 CommandOutput outputOf(ProcessCommand command) { | |
104 // Convert arguments from absolute to relative paths (relative to the dart | |
105 // directory) because the absolute path on the machine where we record | |
106 // may be different from the absolute path on the machine where we execute | |
107 // the commands. | |
108 var arguments = makePathsRelativeToDart(_cwd, command.arguments); | |
109 | |
110 var key = _indexKey(command.executable, arguments.join(' ')); | |
111 var command_output = _commandOutputRecordings[key]; | |
112 if (command_output == null) { | |
113 print("Sorry, but there is no command output for ${command.displayName}" | |
114 " ($command)"); | |
115 exit(42); | |
116 } | |
117 | |
118 double seconds = command_output['duration'] as double; | |
119 var duration = new Duration( | |
120 seconds: seconds.round(), milliseconds: (seconds / 1000).round()); | |
121 var commandOutput = createCommandOutput( | |
122 command, | |
123 command_output['exit_code'] as int, | |
124 command_output['did_timeout'] as bool, | |
125 UTF8.encode(command_output['stdout'] as String), | |
126 UTF8.encode(command_output['stderr'] as String), | |
127 duration, | |
128 false); | |
129 return commandOutput; | |
130 } | |
131 | |
132 String _indexKey(String executable, String arguments) { | |
133 return "${executable}__$arguments"; | |
134 } | |
135 } | |
OLD | NEW |