This repository has been archived by the owner on Aug 20, 2018. It is now read-only.
/
event_handlers.txt
134 lines (98 loc) · 5.98 KB
/
event_handlers.txt
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
[Mozmill](https://developer.mozilla.org/en/Mozmill)
is an event dispatcher system, using jsbridge to communicate
events triggered in JavaScript to the python harness.
# Events
Events send the signature `(eventType, obj)`. `eventType` is
the string name of the event (e.g. `mozmill.endTest`) and `obj` is
an object sent with the event. A python callable signature for a given event
takes `obj` as an argument, e.g:
self.add_listener(self.persist_listener, eventType="mozmill.persist")
def persist_listener(self, obj):
self.persisted = obj
Several event listeners are added in the
[Mozmill constructor](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/__init__.py)
vital for test harness functionality. In addition, handlers may be
passed to the constructor from which event listeners may be added.
# Pluggable Event Listeners
Mozmill allows python classes to plug into the event listener system.
This is done by denoting them as a
[setuptools entry point](http://peak.telecommunity.com/DevCenter/setuptools#dynamic-discovery-of-services-and-plugins)
with the key `mozmill.event_handlers` in the `entry_points` section (see mozmill's
[setup.py](https://github.com/mozilla/mozmill/blob/master/mozmill/setup.py)).
Three event handlers are included with Mozmill by default via
the setuptools entry point `mozmill.event_handlers`:
- [Logging](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/logger.py) :
log results to stdout or a file in a [format appropriate to Mozilla tests](https://developer.mozilla.org/en/Test_log_format)
- [Report](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/report.py) :
generate a JSON report of the run
- [PythonCallbacks](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/python_callbacks.py) :
call a python module and method from JavaScript
When running from the command line, these are on by default. However,
you may use the `--disable` command line argument to turn them off:
mozmill -t foo.js --disable Logging --report stdout
This command line will dump the JSON of the report to stdout.
You can also add free-standing python modules as pluggable event
listeners from the command line using the switch
`--handler=PATH:CLASS`, where `PATH` is the path to the python file
and `CLASS` is the name of the event handler class in the file
As an example, if you want to override the default reporting handler
and replace with your own reporting handler, `NewReport`, in
`myreport.py`, you would invoke mozmill as such:
mozmill --disable Report --handler myreport.py:NewReport [...]
`NewReport` could conceivably subclass from `mozmill.report:Report` as
desired.
# API Usage
One of the primary motiviations for the restructuring of the command
line handling as well as adding pluggable events is to make writing
APIs around Mozmill easier. Prior to Mozmill 2.0, it was difficult (a
significant chunk of code needed to be replicated, which of course
relies on innards not changing to be maintainable) to invoke MozMill
programmatically at all and impossible to extend it in many ways.
The `mozmill.CLI` command line controller inserts the (global) handlers as
designated by the `mozmill.event_handlers` entry point (unless
disabled with the `--disable` flag) as well as any classes designated
via `--handler PATH:CLASS` when constructing a `MozMill` object.
When instantiating `MozMill` as an API, you must instantiate
and pass in the handlers that you want to use.
You can also call `MozMill.add_listener(...)` or
`MozMill.add_global_listener(...)` following object construction.
# Structure of an Event Handler
The basic methods for an event handler is given and documented in
[mozmill.handlers.EventHandler](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/handlers.py).
While this class is never inherited from, it shows the basic methods that event handlers can
have and documentation on what they are used for.
The `add_options` method is used to add options to the command line
parser.
In order to be utilized from the command line, the handler should have
a constructor. A blank one is fine. The attribute names for the
constructor signature should match those in `add_options` if you
wished them to be controllable from the command line.
If an event handler is callable, then all events and their event types
will be passed to the `__call__` method. It is a global event handler.
The event handler should have an `events` method. This should
return a dict of names of events to listen for mapped to the methods
that listen to these events.
Currently the event type is a convention-based string. There
is no catalog of events to be listened for. A list of applicable
events should be maintained as well as when each is called by the
tests. It would be even better if this was programmatic.
If the event handler has a `stop()` method, this is called at the
end of the test run internally to python (no JS communication is done
here). Whether the stop is fatal or not (something bad has happened,
e.g. an exception) is passed in. This gives event handlers the
opportunity to output final statistics and otherwise do cleanup.
## Command Line Arguments
Event handlers may add arguments via an `add_options` class method to
which the parser is passed (see: `mozmill.CLI.add_options`).
When driving via the command line, the handlers are instantiated with
the passed-in options. `mozmill.handlers.instantiate_handler`
introspects the passed in handler to determine which command line
options are needed and constructs the object based on this
information (it is a handler-factory). If the handler raises a
`mozmill.handlers.HandlerMatchException` the handler is not
instantiated or passed to the MozMill constructor.
As an example, see the constructor of
[mozmill.report.Report](https://github.com/mozilla/mozmill/blob/master/mozmill/mozmill/report.py).
If `report` is `None`, as it would be if not specified via the command
line (see the class's `add_options` method for `--report`), then
the class is not instantiated or utilized.