forked from ooni/probe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HACKING
286 lines (193 loc) · 7.65 KB
/
HACKING
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
Hacking on OONI
***************
This documents gives guidelines on where to start looking
for helping out in developing OONI and what guidelines you
should follow when writing code.
We try to follow the general python best practices and styling
guides as specified in PEP.
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
- Tim Peters, The Zen of Python
Code Structure
---------
- HACKING
The document you are currently reading.
- inputs/
Contains input files for tests.
- ooni/
Contains the main ooni probe comand line client
- ooni/inputunit.py
In here we have functions related to the creation of input
units. Input units are how the inputs to be fed to tests are
split up into.
- ooni/nettest.py
In here is the NetTest API definition. This is how people
interested in writing ooniprobe tests will be specifying
them.
- ooni/nodes.py
Mostly broken code for the remote dispatching of tests.
- ooni/oonicli.py
In here we take care of running ooniprobe from the command
line interface
- ooni/reporter.py
In here goes the logic for the creation of ooniprobe
reports.
- ooni/runner.py
Handles running ooni.nettests as well as
ooni.plugoo.tests.OONITests.
- ooni/settings.py
Parts of the code related to parsing OONI
configuration files and making them accessible
to other components of the software.
- ooni/otime.py
Generation of timestamps, time conversions and all the rest
- ooni/kit/
In here go utilities that can be used by tests.
- ooni/utils/
In here go internal utilities that are useful to ooniprobe
- ooni/geoip.py
In here go functions related to the understanding of
geographical information of the probe
- ooni/utils/hacks.py
When some software has issues and we need to fix it in a
hackish way, we put it in here. This one day will be empty.
- ooni/utils/log.py
log realted functions.
- ooni/utils/net.py
utilities for networking related operations
- ooni/utils/onion.py
Utilities for working with Tor.
XXX this code should be removed and merged into txtorcon.
- ooni/utils/txscapy.py
Tools for making scapy work well with twisted.
- ooniprobe.conf
The main OONI-probe configuration file. This can be used
to configure your OONI CLI, tell it where it should report
to, where the asset files are located, what should be used
for control, etc.
Test related conventions
------------------------
These are the conventions for tests that are written in ooniprobe. That is what
goes inside of nettests/.
Naming
......
All methods that are relevant to the test should be all lower case separated by
underscore.
All variables that are specific to your test should be all lower case separated
by underscore.
Simplicity
..........
Tests written in ooniprobe should be as short as possible and should contain as
little code not related to the measurement as possible. It should be possible
from reading the test to understand what it does without clutter.
Everything that is not related directly to the test should go inside of the
test template of which the test you are writing is a subclass of.
Style guide
-----------
This is an extract of the most important parts of PEP-8. When in doubt on
what code style should be followed first consult this doc, then PEP-8 and
if all fails use your best judgement or ask for help.
The most important part to read is the following as it contains the guidelines
of naming of variables, functions and classes, as it does not follow pure
PEP-8.
Naming convention
.................
Class names should follow the CapWords convention.
Note: When using abbreviations in CapWords, capitalize all the letters
of the abbreviation. Thus HTTPServerError is better than
HttpServerError.
Exception names should follow the class names convention as exceptions
should be classes.
Method names should follow camelCase with the first letter non-capital.
Class attributes should also follow camelCase with the first letter non-capital.
Functions should follow camelCase with the first letter non-capital.
Functions and variables that are inside the local scope of a class or method
should be all lowercase separated by an underscore.
Indentation
...........
Use 4 spaces per indentation level.
This can be setup in vi with:
set tabstop=4
set shiftwidth=4
set expandtab
Continuation lines should be wrapper like this:
foo = long_function_name(var_one, var_two,
var_three, var_four)
or this:
def long_function_name(var_one,
var_two, var_three,
var_four):
print(var_one)
They should NOT be wrapper like this:
foo = long_function_name(var_one, var_two,
var_three, var_four)
and NOT like this:
# See how it creates confusion with what is inside the function?
def long_function_name(var_one,
var_two, var_three,
var_four):
print(var_one)
Tabs or Spaces?
...............
Every time you insert a \t into any piece of code a kitten dies.
Only spaces. Please.
(code should be run with python -tt)
Maximum Line Length
...................
Maximum of 79 characters. 72 characters for long blocks of text is recommended.
Blank Lines
...........
Separate top-level function and class definitions with two blank lines.
Method definitions inside of class are separated by a single blank line.
Encoding
........
Always use UTF-8 encoding. This can be specified by adding the encoding cookie
to the beginning of your python files:
# -*- coding: UTF-8
All identifiers should be ASCII-only. All doc strings and comments should also
only be in ASCII. Non ASCII characters are allowed when they are related to
testing non-ASCII features or for the names of authors.
Imports
.......
Import should be one per line as so:
import os
import sys
from subprocess import Popen, PIPE
Imports are always at the top of the file just after any module comments
and docstrings, berfore module globals and constants.
Imports should be grouped in the following order:
1. standard library imports
2. related third party imports
3. local application/library specific imports
You should put a blank line between each group of imports.
Comments
........
Comments should always be up to date with the code. Don't have
comments that contraddict with the code.
Comments should always be written in English.
Blocks comments are indented to the same level of the code that
they refer to. They start with # and are followed by a single space.
Use inline comments sparingly. # Gotcha?
Documentation strings
.....................
Write docstrings for all public modules, functions, classes and
methods. Even better if you write them also for non-public methods.
Place docstrings under the def.
For a better overview on how to write docstrings consult: PEP-257