-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbootstrap_smoke_test.drush.inc
321 lines (268 loc) · 9.71 KB
/
bootstrap_smoke_test.drush.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<?php
/**
* Implements hook_drush_command().
*/
function bootstrap_smoke_test_drush_command() {
$items = array();
$items['bootstrap-smoke-test'] = array(
'description' => 'Measure time and memory consumption within a full Drupal bootstrap.',
'callback' => 'drush_bootstrap_smoke_test',
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, // No bootstrap.
'options' => array(
'no-table' => 'Output rows of pipe-separated results (e.g. for easy sorting).',
),
'examples' => array(
'drush bst --no-table' => 'Measure time and memory consumption within a full Drupal bootstrap, output rows of pipe-separated results.',
),
'aliases' => array('bst'),
);
return $items;
}
function drush_bootstrap_smoke_test() {
global $bst_output;
$bst_output[] = array('operation', 'time', 'time-delta', 'memory', 'memory-delta');
if (!drush_bootstrap_to_phase(DRUSH_BOOTSTRAP_DRUPAL_DATABASE) || !defined('DRUPAL_ROOT')) {
return drush_set_error('DRUPAL_SITE_NOT_FOUND', dt('You need to specify an alias or run this command within a drupal site.'));
}
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
require_once DRUPAL_ROOT . '/includes/common.inc';
if ((defined('DRUPAL_CORE_COMPATIBILITY') && DRUPAL_CORE_COMPATIBILITY == '6.x') || function_exists('drupal_init_language')) {
drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);
bst_bootstrap_full_d6();
}
else {
// assume D7 for now
drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE);
bst_bootstrap_full_d7();
}
// todo: add options to sort by memory or time-delta within drush
if (drush_get_option('no-table')) {
foreach ($bst_output as $output_line) {
$line = implode('|', $output_line);
drush_print($line);
}
}
else {
drush_print_table($bst_output, TRUE);
}
}
/**
* based on https://api.drupal.org/api/drupal/includes%21common.inc/function/_drupal_bootstrap_full/6
*/
function bst_bootstrap_full_d6() {
timer_start('bst');
bst_debug('starting bootstrap_full');
static $called;
if ($called) {
return;
}
$called = 1;
require_once './includes/theme.inc';
require_once './includes/pager.inc';
require_once './includes/menu.inc';
require_once './includes/tablesort.inc';
require_once './includes/file.inc';
require_once './includes/unicode.inc';
require_once './includes/image.inc';
require_once './includes/form.inc';
require_once './includes/mail.inc';
require_once './includes/actions.inc';
bst_debug('finished includes');
// Set the Drupal custom error handler.
set_error_handler('drupal_error_handler');
// Emit the correct charset HTTP header.
drupal_set_header('Content-Type: text/html; charset=utf-8');
// Detect string handling method
unicode_check();
// Undo magic quotes
fix_gpc_magic();
bst_debug('loading enabled modules');
// Load all enabled modules
bst_module_load_all_d6();
bst_debug('modules loaded');
// out-of-date copies of D6 might not have this function
// it's probably not necessary for what we're trying to do anyway
if (function_exists('drupal_random_bytes')) {
// Ensure mt_rand is reseeded, to prevent random values from one page load
// being exploited to predict random values in subsequent page loads.
$seed = unpack("L", drupal_random_bytes(4));
mt_srand($seed[1]);
}
// Let all modules take action before menu system handles the request
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
bst_debug('starting to invoke hook_init');
bst_module_invoke_all_d6('init');
bst_debug('finished hook_init');
}
bst_debug('end of bootstrap_full');
}
/**
* based on https://api.drupal.org/api/drupal/includes%21common.inc/function/_drupal_bootstrap_full/7
*/
function bst_bootstrap_full_d7() {
timer_start('bst');
bst_debug('starting bootstrap_full');
static $called = FALSE;
if ($called) {
return;
}
$called = TRUE;
require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'includes/path.inc');
require_once DRUPAL_ROOT . '/includes/theme.inc';
require_once DRUPAL_ROOT . '/includes/pager.inc';
require_once DRUPAL_ROOT . '/' . variable_get('menu_inc', 'includes/menu.inc');
require_once DRUPAL_ROOT . '/includes/tablesort.inc';
require_once DRUPAL_ROOT . '/includes/file.inc';
require_once DRUPAL_ROOT . '/includes/unicode.inc';
require_once DRUPAL_ROOT . '/includes/image.inc';
require_once DRUPAL_ROOT . '/includes/form.inc';
require_once DRUPAL_ROOT . '/includes/mail.inc';
require_once DRUPAL_ROOT . '/includes/actions.inc';
require_once DRUPAL_ROOT . '/includes/ajax.inc';
require_once DRUPAL_ROOT . '/includes/token.inc';
require_once DRUPAL_ROOT . '/includes/errors.inc';
bst_debug('finished includes');
// Detect string handling method
unicode_check();
// Undo magic quotes
fix_gpc_magic();
bst_debug('loading enabled modules');
// Load all enabled modules
bst_module_load_all_d7();
bst_debug('modules loaded');
bst_debug('getting stream_wrappers');
// Make sure all stream wrappers are registered.
file_get_stream_wrappers();
bst_debug('got stream_wrappers');
$test_info = &$GLOBALS['drupal_test_info'];
if (!empty($test_info['in_child_site'])) {
// Running inside the simpletest child site, log fatal errors to test
// specific file directory.
ini_set('log_errors', 1);
ini_set('error_log', 'public://error.log');
}
bst_debug('initialising path');
// Initialize $_GET['q'] prior to invoking hook_init().
drupal_path_initialize();
bst_debug('initialised path');
// Let all modules take action before the menu system handles the request.
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
// Prior to invoking hook_init(), initialize the theme (potentially a custom
// one for this page), so that:
// - Modules with hook_init() implementations that call theme() or
// theme_get_registry() don't initialize the incorrect theme.
// - The theme can have hook_*_alter() implementations affect page building
// (e.g., hook_form_alter(), hook_node_view_alter(), hook_page_alter()),
// ahead of when rendering starts.
bst_debug('setting custom theme');
menu_set_custom_theme();
bst_debug('set custom theme');
bst_debug('initialising theme');
drupal_theme_initialize();
bst_debug('initialised theme');
bst_debug('starting to invoke hook_init');
bst_module_invoke_all_d7('init');
bst_debug('finished hook_init');
}
bst_debug('end of bootstrap_full');
}
/**
* based on https://api.drupal.org/api/drupal/includes!module.inc/function/module_load_all/7
*/
function bst_module_load_all_d7($bootstrap = FALSE) {
static $has_run = FALSE;
if (isset($bootstrap)) {
foreach (module_list(TRUE, $bootstrap) as $module) {
bst_debug("loading module $module");
drupal_load('module', $module);
bst_debug("loaded module $module");
}
// $has_run will be TRUE if $bootstrap is FALSE.
$has_run = !$bootstrap;
}
/**
* This will slow things down a little, but without it any calls to theme() within hook_init
* implementations will throw an exception (in D7), as it will appear that modules have not
* been loaded. The static within drupal_load should mean this returns fairly fast without
* really doing very much work. We'll track this step for transparency though.
*/
bst_debug("calling the real module_load_all");
module_load_all();
bst_debug("called the real module_load_all");
return $has_run;
}
/**
* based on https://api.drupal.org/api/drupal/includes!module.inc/function/module_load_all/6
*/
function bst_module_load_all_d6() {
foreach (module_list(TRUE, FALSE) as $module) {
bst_debug("loading module $module");
drupal_load('module', $module);
bst_debug("loaded module $module");
}
}
/**
* based on https://api.drupal.org/api/drupal/includes%21module.inc/function/module_invoke_all/7
*/
function bst_module_invoke_all_d7($hook) {
$args = func_get_args();
// Remove $hook from the arguments.
unset($args[0]);
$return = array();
foreach (module_implements($hook) as $module) {
bst_debug("start hook_$hook in $module");
$function = $module . '_' . $hook;
if (function_exists($function)) {
$result = call_user_func_array($function, $args);
if (isset($result) && is_array($result)) {
$return = array_merge_recursive($return, $result);
}
elseif (isset($result)) {
$return[] = $result;
}
}
bst_debug("end hook_$hook in $module");
}
return $return;
}
/**
* based on https://api.drupal.org/api/drupal/includes%21module.inc/function/module_invoke_all/6
*/
function bst_module_invoke_all_d6() {
$args = func_get_args();
$hook = $args[0];
unset($args[0]);
$return = array();
foreach (module_implements($hook) as $module) {
bst_debug("start hook_$hook in $module");
$function = $module . '_' . $hook;
$result = call_user_func_array($function, $args);
if (isset($result) && is_array($result)) {
$return = array_merge_recursive($return, $result);
}
else if (isset($result)) {
$return[] = $result;
}
bst_debug("end hook_$hook in $module");
}
return $return;
}
function bst_debug($mark) {
global $bst_output;
static $old_time, $old_memory;
$time = round(timer_read('bst')); // sometimes returns floats without this round
$time_delta = $time - $old_time;
$old_time = $time;
$memory = round(memory_get_peak_usage(TRUE) / 1024 / 1024, 2) . 'MB';
$memory_delta = $memory - $old_memory;
$old_memory = $memory;
$bst_output[] = array(
'mark' => $mark,
't' => $time,
't^' => $time_delta,
'm' => $memory,
'm^' => $memory_delta,
);
}