• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.ci/H04-Mar-2021-288223

.github/workflows/H04-Mar-2021-1716

doc/H03-May-2022-1813

example/H04-Mar-2021-383216

include/H04-Mar-2021-48,31831,563

m4/H03-May-2022-1,2611,138

script/H04-Mar-2021-1,4431,233

src/H04-Mar-2021-25,03818,184

test/H04-Mar-2021-13,97311,725

.clang-formatH A D04-Mar-2021117 87

.codedocsH A D04-Mar-202120 21

.gitignoreH A D04-Mar-2021905 7877

AUTHORSH A D04-Mar-2021233 1612

CONTRIBUTING.mdH A D04-Mar-20213 KiB9364

ChangeLog.mdH A D04-Mar-202139.7 KiB999822

DoxyfileH A D04-Mar-2021269 109

LICENSEH A D04-Mar-20211.4 KiB2722

Makefile.amH A D04-Mar-2021811 3221

OREADME.mdH A D04-Mar-20214.6 KiB10274

README.mdH A D04-Mar-202111.6 KiB304238

autogen.shH A D04-Mar-20213 KiB11096

configure.acH A D04-Mar-20211.6 KiB6648

README.md

1# Measurement Kit
2
3> (deprecated) Network measurement engine
4
5As of 2020-03-15, Measurement Kit is deprecated. This date has been chosen
6arbitrarily such that we could write:
7
8    Friends, OONItarians, developers, lend me your ears;
9    I come to bury Measurement Kit, not to praise it.
10    The bugs that software have live after them;
11    The good is oft interred with their remote branches;
12
13And, of course, some good, old [piece of art](
14https://it.wikipedia.org/wiki/Cesaricidio#/media/File:Vincenzo_Camuccini_-_La_morte_di_Cesare.jpg
15) is also in order:
16
17![cesaricidio](doc/cesaricidio.jpg
18  "E se Cesare vuol fare anche il padre si abitui ai pugnali e a dormir male")
19
20The rewrite of Measurement Kit in Go has been going on for quite some time now
21as [ooni/probe-engine](https://github.com/ooni/probe-engine). As part of this
22rewrite, we considered all the use cases addressed by Measurement Kit, as documented
23by [issue #1913](https://github.com/measurement-kit/measurement-kit/issues/1913).
24
25We will most likely never release v0.11.0 of Measurement Kit. We will keep
26maintaining the 0.10.x version until 2021-03-14 (which is [another
27interesting date](https://en.wikipedia.org/wiki/Pi_Day)). In the following, we'll discuss
28what options you have for replacing Measurement Kit in your use case. The
29current README reflects the situation "here and now". We are still working to
30provide a smooth upgrade path. Please, let us know if the upgrade path we have
31designed is troubling you by voting/contributing to the issues indicated below.
32
33(The content of the old README.md is still available as [OREADME.md](OREADME.md).)
34
35## Changes in the settings JSON
36
37The ooni/probe-engine implementation exposes similar APIs to Measurement Kit
38and specifically honours the [data format of Measurement Kit v0.10.11](
39https://github.com/measurement-kit/measurement-kit/tree/v0.10.11/include/measurement_kit).
40There should be no differences in the emitted events. There are however some
41differences in the settings as discussed below.
42
43You should now add the following three keys to the settings JSON:
44
45```JSON
46{
47  "assets_dir": "",
48  "state_dir": "",
49  "temp_dir": ""
50}
51```
52
53where `assets_dir` is the directory where to store assets, e.g.
54GeoIP databases; `state_dir` is the directory where to store the
55authentication information used with OONI orchestra; `temp_dir`
56is the directory where to store temporary files. If these three
57keys are not present, the test will fail during the startup
58phase (i.e. it will run for a very short time and you will see
59a bunch of `failure.startup` events emitted).
60
61Also, the Go code does recognize all the settings recognized by
62Measurement Kit, but we have only implemented the settings required
63by OONI. All the other settings, when used, cause a failure during
64the experiment startup phase. If a not implemented setting is causing
65you issues, let us know by [voting in the corresponding bug tracking
66issue](https://github.com/ooni/probe-engine/issues/494).
67
68## Android
69
70In your `app/build.gradle` file, replace
71
72```Groovy
73  implementation "org.openobservatory.measurement_kit:android-libs:$version"
74```
75
76with
77
78```Groovy
79  implementation "org.ooni:oonimkall:$version"
80```
81
82(The new package is called oonimkall because it's a OONI probe-engine based
83implementation of the `mkall` API for iOS. In turn, `mkall` means that we
84are bundling together all the MK APIs (i.e. the API for running experiments
85and all the ancillary APIs). For historical reasons `android-libs` was
86named before we defined the concept of `mkall` and was never renamed.)
87
88The following differences apply between `android-libs` and `oonimkall`:
89
901. the import path is `oonimkall` and you can use it directly as a scope
91for the classes, rather than doing `import oonimkall.Foo`;
92
932. the `MKAsyncTask` class is replaced by `oonimkall.Task` and the
94`MKAsyncTask.start` factory is replaced by `oonimkall.Oonimkall.startTask`;
95
963. the `MKGeoIPLookupResults` and `MKGeoIPLookupTask` classes are
97replaced by `oonimkall.GeoLookupResults` and `oonimkall.GeoLookupTask`;
98
994. the `MKOrchestraResults` and `MKOrchestraTask` classes cannot be
100replaced, because [it seems we are moving away from the orchestra model
101and, in going forward, we will only use orchestra internally inside of
102probe-engine to authenticate probes when they fetch input](
103https://github.com/ooni/probe-engine/issues/14#issuecomment-599547695);
104
1055. the `MKReporterResults` and `MKReporterTask` classes are replaced
106by `oonimkall.CollectorResults` and `oonimkall.CollectorTask`;
107
1086. the `MKResourcesManager` class cannot be replaced, because the new
109code manages resources differently, by downloading them when needed
110into the `assets_dir` directory mentioned above;
111
1127. the `MKVersion` class cannot be replaced because version pinning in
113Go makes it much simpler to know which version of what software we compile;
114
1158. `oonimkall` throws `Exception` in much more cases than the code in
116`android-libs` that instead was using `RuntimeException` (using the latter
117was actually an _anti-pattern_ and we are fixing it with the new code).
118
119The following diff shows how to update code that runs an experiment, which
120is probably the most common use case of `android-libs`:
121
122```diff
123--- MK.java	2020-04-10 11:54:53.973521643 +0200
124+++ PE.java	2020-04-10 11:55:50.915205613 +0200
125@@ -1,10 +1,8 @@
126 package com.example.something;
127
128-import io.ooni.mk.MKAsyncTask;
129-
130 public class Example {
131-    public static void run(settings String) {
132-        MKAsyncTask task = MKAsyncTask.start(settings);
133+    public static void run(settings String) throws Exception {
134+        oonimkall.Task task = oonimkall.Oonimkall.startTask(settings);
135         for (!task.isDone()) {
136             String event = task.waitForNextEvent();
137             System.out.println(event);
138```
139
140The most striking difference is that the function to start a task
141will explicitly throw `Exception` on failure. The old code
142would instead throw `RuntimeException`, as mentioned above. The
143required settings have slightly changed, as discussed above.
144
145## iOS
146
147In your `Podfile` replace
148
149```ruby
150    pod 'mkall', :git => 'https://github.com/measurement-kit/mkall-ios.git',
151                 :tag => '$version'
152```
153
154with
155
156```ruby
157    pod 'oonimkall', :podspec => 'https://dl.bintray.com/ooni/ios/oonimkall-$version.podspec'
158
159```
160
161The changes are similar to the ones described above for Android except
162that the `oonimkall.` prefix is `Oonimkall` for iOS. The following diff
163shows how you should be upgrading your `MKAsyncTask` code:
164
165```diff
166--- MK.m	2020-04-10 12:06:14.252573662 +0200
167+++ PE.m	2020-04-10 12:08:18.520924676 +0200
168@@ -1,11 +1,15 @@
169 #import <Foundation/Foundation.h>
170
171-#import <mkall/MKAsyncTask.h>
172+#import <oonimkall/Oonimkall.h>
173
174-void run(NSDictionary *settings) {
175-    MKAsyncTask *task = [MKAsyncTask start:settings];
176-    while (![task done]) {
177-        NSDictionary *ev = [task waitForNextEvent];
178+NSError *run(NSString *settings) {
179+    NSError *error = nil;
180+    OonimkallTask *task = OonimkallStartTask(settings, &error);
181+    if (error != nil) {
182+        return error;
183+    }
184+    while (![task isDone]) {
185+        NSString *ev = [task waitForNextEvent];
186         if (ev == nil) {
187             continue;
188         }
189```
190
191The most striking differences are the following. First, the function
192that starts a task now fails explicitly (e.g., if the settings
193are not valid JSON). Second, the new code takes in input and emits in
194output serialized JSONs rather than `NSDictionary *`. You are welcome to
195adapt [code from MKAsyncTask](
196https://github.com/measurement-kit/mkall-ios/blob/v0.8.0/mkall/MKAsyncTask.mm)
197to reimplement the previous behaviour. Also, remember that
198some extra mandatory settings are required, as described above.
199
200## Command Line
201
202The [miniooni](https://github.com/ooni/probe-engine#building-miniooni) binary
203mostly has the same CLI of the `measurement_kit` binary you could build from
204this repository. The following list describes the main differences between
205the two command line interfaces:
206
207- `miniooni` by default _appends_ measurements to `report.jsonl` while
208`measurement_kit` uses a file name including the experiment name and the
209datetime when the experiment was started;
210
211- `miniooni` uses the `-i, --input <input>` flag to uniformly provide input for
212every experiment, while in `measurement_kit` different experiments use
213different command line flags _after_ the experiment name (e.g., the `-u <URL>`
214flag is used by MK's Web Connectivity);
215
216- `miniooni` allows you to specify a proxy (e.g. Tor, Psiphon) with
217`-P, --proxy <URL>` that will be used for interacting with OONI services,
218but no such option exists in `measurement_kit`;
219
220- `miniooni` does not yet implement `-s, --list` that lists all the
221available experiments;
222
223- `miniooni` does not implement `-l, --logfile <path>` but you can use
224output redirection and `tee` to save logs anyway;
225
226- `miniooni` does not implement `--ca-bundle-path <path>`, `--version`,
227`--geoip-country-path <path>`, `--geoip-asn-path <path>`, because
228these resources are now downloaded and managed automatically;
229
230- `miniooni` does not implement `--no-resolver-lookup`;
231
232- `miniooni` writes state at `$HOME/.miniooni`.
233
234We automatically build `miniooni` for windows/amd64, linux/amd64,
235and darwin/amd64 at every commit. The Linux build is static and does not depend
236on any external shared library. You can find the builds by looking into the
237[GitHub actions of probe-engine](https://github.com/ooni/probe-engine/actions)
238and selecting for `cli-windows`, `cli-linux`, or `cli-darwin`. If you want us
239to attach such binaries to every release, please [upvote
240the related issue](https://github.com/ooni/probe-engine/issues/495).
241
242## Shared Library
243
244The [libooniffi](https://github.com/ooni/probe-engine/tree/master/libooniffi)
245package of ooni/probe-engine is a drop-in replacement for the [Measurement
246Kit FFI API](include/measurement_kit). The new API is defined by the
247`ooniffi.h` header. It is ABI compatible with MK's API. The
248only required change is to replace the `mk_` prefix with `ooniffi_`. This
249diff shows the changes you typically need:
250
251```diff
252--- MK.c	2020-04-10 12:32:13.582783743 +0200
253+++ PE.c	2020-04-10 12:32:36.633038633 +0200
254@@ -1,19 +1,19 @@
255 #include <stdio.h>
256
257-#include <measurement_kit/ffi.h>
258+#include <ooniffi.h>
259
260 void run(const char *settings) {
261-    mk_task_t *task = mk_task_start(settings);
262+    ooniffi_task_t *task = ooniffi_task_start(settings);
263     if (task == NULL) {
264         return;
265     }
266-    while (!mk_task_is_done(task)) {
267-        mk_event_t *event = mk_task_wait_for_next_event(task);
268+    while (!ooniffi_task_is_done(task)) {
269+        ooniffi_event_t *event = ooniffi_task_wait_for_next_event(task);
270         if (event == NULL) {
271             continue;
272         }
273-        printf("%s\n", mk_event_serialization(event));
274-        mk_event_destroy(event);
275+        printf("%s\n", ooniffi_event_serialization(event));
276+        ooniffi_event_destroy(event);
277     }
278-    mk_task_destroy(task);
279+    ooniffi_task_destroy(task);
280 }
281```
282
283Of course, you also need to take into account the changes to
284the settings documented above.
285
286You can generate your own builds with:
287
288```bash
289# macOS from macOS or Linux from Linux
290go build -v -tags nomk -ldflags='-s -w' -buildmode c-shared -o libooniffi.so ./libooniffi
291rm libooniffi.h  # not needed
292cp libooniffi/ooniffi.h .  # use this header
293
294# Windows from Linux or macOS with mingw-w64 installed
295export CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc
296go build -v -tags nomk -ldflags='-s -w' -buildmode c-shared -o libooniffi.dll ./libooniffi
297rm libooniffi.h  # not needed
298cp libooniffi/ooniffi.h .  # use this header
299```
300
301Let us know if you want us to automatically publish `libooniffi` dynamic
302libraries [by upvoting the related issue](
303https://github.com/ooni/probe-engine/issues/496).
304