main: Pass script on CLI instead of via environment

Environment variables aren't the best option to pass parameters
to a process (wouldn't it be "fun" if SHELL_PERF_MODULE appeared
in a regular user session?).

Instead, use a (hidden) --automation-script command line flag to
specify a script file that should be used to drive an automated
session.

As a side effect, the script no longer has to be relative to the
main module itself, so it will be possible to run scripts that
aren't bundled with the shell sources.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2812>
This commit is contained in:
Florian Müllner 2023-06-13 03:53:32 +02:00
parent 5e93791708
commit bf9b9838c2
5 changed files with 45 additions and 14 deletions

View File

@ -326,9 +326,9 @@ async function _initializeUI() {
} }
let perfModule; let perfModule;
const perfModuleName = GLib.getenv('SHELL_PERF_MODULE'); const {automationScript} = global;
if (perfModuleName) { if (automationScript) {
perfModule = await import(`../perf/${perfModuleName}.js`); perfModule = await import(automationScript.get_uri());
if (perfModule.init) if (perfModule.init)
perfModule.init(); perfModule.init();
} }

View File

@ -27,7 +27,6 @@ def show_version(option, opt_str, value, parser):
def start_shell(wrap=None, perf_output=None): def start_shell(wrap=None, perf_output=None):
# Set up environment # Set up environment
env = dict(os.environ) env = dict(os.environ)
env['SHELL_PERF_MODULE'] = options.perf
filters = ['Gnome-shell-perf-helper'] + options.extra_filter filters = ['Gnome-shell-perf-helper'] + options.extra_filter
env['MUTTER_WM_CLASS_FILTER'] = ','.join(filters) env['MUTTER_WM_CLASS_FILTER'] = ','.join(filters)
@ -45,6 +44,9 @@ def start_shell(wrap=None, perf_output=None):
args += wrap.split(' ') args += wrap.split(' ')
args.append(os.path.join(self_dir, 'gnome-shell')) args.append(os.path.join(self_dir, 'gnome-shell'))
args.append('--automation-script')
args.append(options.script)
args.append('--force-animations') args.append('--force-animations')
if options.replace: if options.replace:
@ -173,7 +175,7 @@ def gnome_hwtest_log(*args):
subprocess.check_call(command) subprocess.check_call(command)
def run_performance_test(wrap=None): def run_performance_test(wrap=None):
iters = options.perf_iters iters = options.test_iters
if options.perf_warmup: if options.perf_warmup:
iters += 1 iters += 1
@ -286,10 +288,10 @@ def run_performance_test(wrap=None):
# Main program # Main program
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--perf", parser.add_argument("--script",
help="Specify the name of a performance module to run") help="Specify the path to the automation script to run")
parser.add_argument("--perf-iters", type=int, metavar="ITERS", parser.add_argument("--test-iters", type=int, metavar="ITERS",
help="Numbers of iterations of performance module to run", help="Numbers of iterations of the test to run",
default=1) default=1)
parser.add_argument("--perf-warmup", action="store_true", parser.add_argument("--perf-warmup", action="store_true",
help="Run a dry run before performance tests") help="Run a dry run before performance tests")
@ -321,16 +323,16 @@ parser.add_argument("--hotplug", action="store_true",
options = parser.parse_args() options = parser.parse_args()
if options.perf == None: if options.script == None:
if options.hwtest: if options.hwtest:
options.perf = 'hwtest' options.script = 'resource:///org/gnome/shell/perf/hwtest.js'
else: else:
options.perf = 'core' options.script = 'resource:///org/gnome/shell/perf/core.js'
if options.extra_filter is None: if options.extra_filter is None:
options.extra_filter = [] options.extra_filter = []
if options.perf == 'hwtest': if options.script == 'hwtest':
options.extra_filter.append('Gedit') options.extra_filter.append('Gedit')
normal_exit = run_performance_test(wrap=options.wrap) normal_exit = run_performance_test(wrap=options.wrap)

View File

@ -39,6 +39,7 @@ static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL; static char *session_mode = NULL;
static int caught_signal = 0; static int caught_signal = 0;
static gboolean force_animations = FALSE; static gboolean force_animations = FALSE;
static char *script_path = NULL;
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
@ -532,6 +533,12 @@ GOptionEntry gnome_shell_options[] = {
N_("Force animations to be enabled"), N_("Force animations to be enabled"),
NULL NULL
}, },
{
"automation-script", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME,
&script_path,
N_(""),
NULL
},
{ NULL } { NULL }
}; };
@ -582,6 +589,8 @@ int
main (int argc, char **argv) main (int argc, char **argv)
{ {
g_autoptr (MetaContext) context = NULL; g_autoptr (MetaContext) context = NULL;
g_autoptr (GFile) automation_script = NULL;
g_autofree char *cwd = NULL;
GError *error = NULL; GError *error = NULL;
int ecode = EXIT_SUCCESS; int ecode = EXIT_SUCCESS;
@ -606,6 +615,7 @@ main (int argc, char **argv)
meta_context_set_gnome_wm_keybindings (context, GNOME_WM_KEYBINDINGS); meta_context_set_gnome_wm_keybindings (context, GNOME_WM_KEYBINDINGS);
init_signal_handlers (context); init_signal_handlers (context);
cwd = g_get_current_dir ();
change_to_home_directory (); change_to_home_directory ();
if (session_mode == NULL) if (session_mode == NULL)
@ -628,12 +638,16 @@ main (int argc, char **argv)
dump_gjs_stack_on_signal (SIGSEGV); dump_gjs_stack_on_signal (SIGSEGV);
} }
if (script_path)
automation_script = g_file_new_for_commandline_arg_and_cwd (script_path, cwd);
/* Initialize the Shell global, including GjsContext /* Initialize the Shell global, including GjsContext
* GjsContext will iterate the default main loop to * GjsContext will iterate the default main loop to
* resolve internal modules. * resolve internal modules.
*/ */
_shell_global_init ("session-mode", session_mode, _shell_global_init ("session-mode", session_mode,
"force-animations", force_animations, "force-animations", force_animations,
"automation-script", automation_script,
NULL); NULL);
/* Setup Meta _after_ the Shell global to avoid GjsContext /* Setup Meta _after_ the Shell global to avoid GjsContext

View File

@ -73,6 +73,7 @@ struct _ShellGlobal {
char *userdatadir; char *userdatadir;
GFile *userdatadir_path; GFile *userdatadir_path;
GFile *runtime_state_path; GFile *runtime_state_path;
GFile *automation_script;
ShellWindowTracker *window_tracker; ShellWindowTracker *window_tracker;
ShellAppSystem *app_system; ShellAppSystem *app_system;
@ -120,6 +121,7 @@ enum {
PROP_FRAME_FINISH_TIMESTAMP, PROP_FRAME_FINISH_TIMESTAMP,
PROP_SWITCHEROO_CONTROL, PROP_SWITCHEROO_CONTROL,
PROP_FORCE_ANIMATIONS, PROP_FORCE_ANIMATIONS,
PROP_AUTOMATION_SCRIPT,
N_PROPS N_PROPS
}; };
@ -249,6 +251,9 @@ shell_global_set_property(GObject *object,
case PROP_FORCE_ANIMATIONS: case PROP_FORCE_ANIMATIONS:
global->force_animations = g_value_get_boolean (value); global->force_animations = g_value_get_boolean (value);
break; break;
case PROP_AUTOMATION_SCRIPT:
g_set_object (&global->automation_script, g_value_get_object (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -338,6 +343,9 @@ shell_global_get_property(GObject *object,
case PROP_FORCE_ANIMATIONS: case PROP_FORCE_ANIMATIONS:
g_value_set_boolean (value, global->force_animations); g_value_set_boolean (value, global->force_animations);
break; break;
case PROP_AUTOMATION_SCRIPT:
g_value_set_object (value, global->automation_script);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -688,6 +696,13 @@ shell_global_class_init (ShellGlobalClass *klass)
FALSE, FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT| G_PARAM_STATIC_STRINGS); G_PARAM_READWRITE | G_PARAM_CONSTRUCT| G_PARAM_STATIC_STRINGS);
props[PROP_AUTOMATION_SCRIPT] =
g_param_spec_object ("automation-script",
"automation-script",
"Automation script to run after startup",
G_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, props); g_object_class_install_properties (gobject_class, N_PROPS, props);
} }

View File

@ -71,7 +71,7 @@ foreach perf_test : perf_tests
args: [ args: [
perf_tool, perf_tool,
'--headless', '--headless',
'--perf=@0@'.format(test_name), '--script=@0@/js/perf/@1@.js'.format(meson.project_source_root(), test_name),
options, options,
], ],
is_parallel: false, is_parallel: false,