Merge lp:~thomir-deactivatedaccount/autopilot/fix-ap-launch-bugs into lp:autopilot

Proposed by Thomi Richards
Status: Merged
Approved by: Christopher Lee
Approved revision: 144
Merged at revision: 142
Proposed branch: lp:~thomir-deactivatedaccount/autopilot/fix-ap-launch-bugs
Merge into: lp:autopilot
Diff against target: 133 lines (+32/-11)
3 files modified
autopilot/introspection/__init__.py (+14/-4)
autopilot/tests/test_autopilot_functional.py (+1/-1)
bin/autopilot (+17/-6)
To merge this branch: bzr merge lp:~thomir-deactivatedaccount/autopilot/fix-ap-launch-bugs
Reviewer Review Type Date Requested Status
Christopher Lee (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+149741@code.launchpad.net

Commit message

Fix bugs in the launch command. Don't swallow launched process stdout & stderr, and allow launching non-binary applications.

Description of the change

This branch fixes two bugs with the autopilot launch command:

1) It's not possible to use autopilot launch to launch a non-dynamically linked binary.
2) The launch command swallows stdout and stderr of the application launched.

This branch fixes both bugs.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Lee (veebers) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'autopilot/introspection/__init__.py'
2--- autopilot/introspection/__init__.py 2013-02-12 22:02:05 +0000
3+++ autopilot/introspection/__init__.py 2013-02-21 02:47:24 +0000
4@@ -56,6 +56,9 @@
5 * *launch_dir*. If set to a directory that exists the process will be
6 launched from that directory.
7
8+ * *capture_output*. If set to True (the default), the process output
9+ will be captured and attached to the test as test detail.
10+
11 :raises: **ValueError** if unknown keyword arguments are passed.
12 :return: A proxy object that represents the application. Introspection
13 data is retrievable via this object.
14@@ -64,6 +67,7 @@
15 if not isinstance(application, basestring):
16 raise TypeError("'application' parameter must be a string.")
17 cwd = kwargs.pop('launch_dir', None)
18+ capture_output = kwargs.pop('capture_output', True)
19 if kwargs:
20 raise ValueError("Unknown keyword arguments: %s." %
21 (', '.join( repr(k) for k in kwargs.keys())))
22@@ -74,7 +78,10 @@
23
24 path, args = self.prepare_environment(application, list(arguments))
25
26- process = launch_autopilot_enabled_process(path, args, cwd=cwd)
27+ process = launch_autopilot_enabled_process(path,
28+ args,
29+ capture_output,
30+ cwd=cwd)
31 self.addCleanup(self._kill_process_and_attach_logs, process)
32 return get_autopilot_proxy_object_for_process(process)
33
34@@ -96,15 +103,18 @@
35 self.addDetail('process-stderr', text_content(stderr))
36
37
38-def launch_autopilot_enabled_process(application, args, **kwargs):
39+def launch_autopilot_enabled_process(application, args, capture_output, **kwargs):
40 """Launch an autopilot-enabled process and return the proxy object."""
41 commandline = [application]
42 commandline.extend(args)
43 logger.info("Launching process: %r", commandline)
44+ cap_mode = None
45+ if capture_output:
46+ cap_mode = subprocess.PIPE
47 process = subprocess.Popen(commandline,
48 stdin=subprocess.PIPE,
49- stdout=subprocess.PIPE,
50- stderr=subprocess.PIPE,
51+ stdout=cap_mode,
52+ stderr=cap_mode,
53 close_fds=True,
54 **kwargs)
55 return process
56
57=== modified file 'autopilot/tests/test_autopilot_functional.py'
58--- autopilot/tests/test_autopilot_functional.py 2013-02-12 23:33:28 +0000
59+++ autopilot/tests/test_autopilot_functional.py 2013-02-21 02:47:24 +0000
60@@ -594,7 +594,7 @@
61
62 self.assertThat(rc, Equals(1))
63 self.assertThat(stdout,
64- Contains("Error: Only dynamically linked binaries are supported at the moment."))
65+ Contains("Error: Cannot auto-detect introspection plugin to load.\nUse the '-i' argument to specify an interface."))
66
67
68 class AutopilotVerboseFunctionalTests(AutopilotFunctionalTestsBase):
69
70=== modified file 'bin/autopilot'
71--- bin/autopilot 2013-02-12 23:33:28 +0000
72+++ bin/autopilot 2013-02-21 02:47:24 +0000
73@@ -27,7 +27,8 @@
74 from argparse import ArgumentParser
75 from unittest.loader import TestLoader
76 from unittest import TestSuite
77-
78+from autopilot.introspection.gtk import GtkIntrospectionTestMixin
79+from autopilot.introspection.qt import QtIntrospectionTestMixin
80
81 # list autopilot depends here, with the form:
82 # ('python module name', 'ubuntu package name'),
83@@ -126,6 +127,11 @@
84
85 parser_launch = subparsers.add_parser('launch',
86 help="Launch an application with introspection enabled")
87+ parser_launch.add_argument('-i', '--interface',
88+ choices=('Gtk', 'Qt', 'Auto'), default='Auto',
89+ help="Specify which introspection interface to load. \
90+ The default ('Auto') uses ldd to try and detect which \
91+ interface to load.")
92 parser_launch.add_argument('-v', '--verbose', required=False, default=False,
93 action='count', help="Show autopilot log messages. \
94 Set twice to also log data useful for debugging \
95@@ -339,7 +345,13 @@
96 exit(1)
97
98 # We now have a full path to the application.
99- IntrospectionBase = get_application_introspection_base(app_name)
100+ IntrospectionBase = None
101+ if args.interface == 'Auto':
102+ IntrospectionBase = get_application_introspection_base(app_name)
103+ elif args.interface == 'Gtk':
104+ IntrospectionBase = GtkIntrospectionTestMixin
105+ elif args.interface == 'Qt':
106+ IntrospectionBase = QtIntrospectionTestMixin
107 if IntrospectionBase is None:
108 print "Error: Could not determine introspection type to use for application '%s'." % app_name
109 exit(1)
110@@ -353,7 +365,7 @@
111
112 b = IntrospectionBase()
113 try:
114- b.launch_test_application(app_name)
115+ b.launch_test_application(app_name, capture_output=False)
116 except RuntimeError as e:
117 print "Error: " + e.message
118 exit(1)
119@@ -371,13 +383,12 @@
120 try:
121 ldd_output = subprocess.check_output(["ldd", app_path]).strip().lower()
122 except subprocess.CalledProcessError:
123- print "Error: Only dynamically linked binaries are supported at the moment."
124+ print "Error: Cannot auto-detect introspection plugin to load."
125+ print "Use the '-i' argument to specify an interface."
126 exit(1)
127 if 'libqtcore' in ldd_output:
128- from autopilot.introspection.qt import QtIntrospectionTestMixin
129 return QtIntrospectionTestMixin
130 elif 'libgtk' in ldd_output:
131- from autopilot.introspection.gtk import GtkIntrospectionTestMixin
132 return GtkIntrospectionTestMixin
133 return None
134

Subscribers

People subscribed via source and target branches