From 9dbcda1a6bcd432037c0ab7411517f8f3b62a5e7 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Mon, 20 Jul 2020 13:45:04 +0200 Subject: [PATCH 1/2] Refactored the README by moving plugin specific parts to their respective folders and added some introductory text on Android Runner --- .../Plugins/android/README_Android.md | 15 ++++ .../batterystats/README_Batterystats.md | 22 ++++++ .../Plugins/frametimes/README_Frametimes.md | 20 +++++ .../README_Garbagecollection.md | 15 ++++ AndroidRunner/Plugins/trepn/README_Trepn.md | 13 ++++ README.md | 69 ++++++------------ documentation/overview.jpg | Bin 0 -> 84290 bytes 7 files changed, 106 insertions(+), 48 deletions(-) create mode 100644 AndroidRunner/Plugins/android/README_Android.md create mode 100644 AndroidRunner/Plugins/batterystats/README_Batterystats.md create mode 100644 AndroidRunner/Plugins/frametimes/README_Frametimes.md create mode 100644 AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md create mode 100644 AndroidRunner/Plugins/trepn/README_Trepn.md create mode 100644 documentation/overview.jpg diff --git a/AndroidRunner/Plugins/android/README_Android.md b/AndroidRunner/Plugins/android/README_Android.md new file mode 100644 index 0000000000..2665e8969a --- /dev/null +++ b/AndroidRunner/Plugins/android/README_Android.md @@ -0,0 +1,15 @@ +# Android Plugin +This plugin collects memory and CPU usage via the `cpuinfo` and `meminfo` Android utilities. + +## Configuration +Below, an example configuration can be found. +```json + "profilers": { + "android": { + "sample_interval": 100, + "data_points": ["cpu", "mem"], + "subject_aggregation": "user_subject_aggregation.py", + "experiment_aggregation": "user_experiment_aggregation.py" + } + } +``` diff --git a/AndroidRunner/Plugins/batterystats/README_Batterystats.md b/AndroidRunner/Plugins/batterystats/README_Batterystats.md new file mode 100644 index 0000000000..a23ad1015e --- /dev/null +++ b/AndroidRunner/Plugins/batterystats/README_Batterystats.md @@ -0,0 +1,22 @@ +# Batterystats Plugin +This plugin uses the `batterystats` utility and estimates energy consumption via the algorithm proposed in [this article](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7884613&casa_token=oEEnY7XOip8AAAAA:AyRZxwboUh55-n9vmW5NGT62mL_hv85T4wPGWlDQGJ36VpF3bcAV1ufvYBhsYxlB0lIMOYJ_Hc-O&tag=1). + +## Configuration +Below, an example configuration can be found. +```json + "profilers": { + "batterystats": { + "cleanup": true, + "subject_aggregation": "default", + "experiment_aggregation": "default", + "enable_systrace_parsing": true, + "python2_path": "python2" + } + } +``` + +**enable_systrace_parsing** *boolean* +The Batterystats profiler uses the profiling tool Systrace internally to measure CPU specific activity and energy consumption on the mobile device. For some devices the parsing of the output of Systrace fails, causing the experiment run to fail. You can safely disable the Systrace parsing when you encounter Systrace parsing errors given that your experiment does not need rely on CPU specific information, but rather on the overall energy consumption of the mobile device. The overall energy consumption is not affected by the Systrace logs since it is tracked using another tool. The default is *true*. + +**python2_path** *string* +The path to python 2 that is used to launch Systrace. The default is *python2*. \ No newline at end of file diff --git a/AndroidRunner/Plugins/frametimes/README_Frametimes.md b/AndroidRunner/Plugins/frametimes/README_Frametimes.md new file mode 100644 index 0000000000..3539600e26 --- /dev/null +++ b/AndroidRunner/Plugins/frametimes/README_Frametimes.md @@ -0,0 +1,20 @@ +# Frametimes Plugin +The frame times plugin gathers unique frame rendering durations (in nanoseconds) by utilizing `dumpsys gfxinfo framestats` and counts the amount of delayed frames that occurred following the 16ms threshold [defined by Google](https://developer.android.com/training/testing/performance). + +## Configuration +Below an example of the configuration options is found: +```json + "profilers": { + "Frametimes": { + "subject_aggregation" : "default", + "sample_interval": 1000 + } + } +``` + +**sample_interval** *boolean* +The sample interval is configurable but advised to keep under 120 seconds as the framestats command returns only data from frames rendered in the past 120 seconds as described [here](https://developer.android.com/training/testing/performance). +Shorter sample intervals will not cause duplication in the frames gathered as only unique frames are kept. + +**subject_aggregation** *string* +The default subject aggregation consists of combining both the frametimes as the delayed frames count in single files for easy further processing. \ No newline at end of file diff --git a/AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md b/AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md new file mode 100644 index 0000000000..08ba4518d3 --- /dev/null +++ b/AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md @@ -0,0 +1,15 @@ +# Garbage Collection Plugin +The garbage collection (GC) plugin gathers and counts GC log statements by searching in adb's logcat for logs that meet the format of a GC call as described [here](https://dzone.com/articles/understanding-android-gc-logs). + +## Configuration +Below an example configuration is found: +```json + "profilers": { + "Garbagecollection": { + "subject_aggregation" : "default" + } + } +``` + +**subject_aggregation** *string* +The default configuration for this plugin is the subject aggregation which lists the counted GC calls in a single file for easy further processing. \ No newline at end of file diff --git a/AndroidRunner/Plugins/trepn/README_Trepn.md b/AndroidRunner/Plugins/trepn/README_Trepn.md new file mode 100644 index 0000000000..a964756a5b --- /dev/null +++ b/AndroidRunner/Plugins/trepn/README_Trepn.md @@ -0,0 +1,13 @@ +# Trepn Plugin +This plugin collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. + +## Configuration +Below an example configuration is found: +```json + "profilers": { + "trepn": { + "sample_interval": 100, + "data_points": ["battery_power", "mem_usage"] + } + } +``` \ No newline at end of file diff --git a/README.md b/README.md index 7003545ce2..09135574f1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,15 @@ [![Build Status](https://travis-ci.org/S2-group/android-runner.svg?branch=master)](https://travis-ci.org/S2-group/android-runner) [![Coverage Status](https://coveralls.io/repos/github/S2-group/android-runner/badge.svg?branch=master)](https://coveralls.io/github/S2-group/android-runner?branch=master&service=github) # Android Runner -Automated experiment execution on Android devices +Android Runner (AR) is a tool for automatically executing measurement-based experiments on native and web apps running on Android devices. +As visualized below, it consists of the following components: +- **Experiment orchestrator**: Is in charge of executing the whole experiment according to the experiment configuration provided by the user. +- **Devices manager**: Is responsible for providing a layer of abstraction on the low-level operations involving the Android devices. +- **Progress manager**: Keeps track of the execution of each run of the experiment. +- **Plugin handler**: Provides a set of facilities for managing the profilers and an extension point that third-party developers can use for integrating their own measurement tools into AR. + +![Overview of Android Runner](./documentation/overview.jpg) + ## Install This tool is only tested on Ubuntu, but it should work in other linux distributions. @@ -143,18 +151,13 @@ The package names of the apps to test when the apps are already installed on the The names of browser(s) to use. Currently supported values are `chrome`. **profilers** *JSON* -A JSON object to describe the profilers to be used and their arguments. Below are several examples: -```js +A JSON object to describe the profiler plugins to be used and their arguments. Below, an example is found: +```json "profilers": { "trepn": { "sample_interval": 100, "data_points": ["battery_power", "mem_usage"] - } - } -``` - -```js - "profilers": { + }, "android": { "sample_interval": 100, "data_points": ["cpu", "mem"], @@ -163,40 +166,16 @@ A JSON object to describe the profilers to be used and their arguments. Below ar } } ``` +Out of the box, AR contains the plugins listed below which can immediately be used as a profiler for an experiment. -```js - "profilers": { - "batterystats": { - "cleanup": true, - "subject_aggregation": "default", - "experiment_aggregation": "default", - "enable_systrace_parsing": true, - "python2_path": "python2" - } - } -``` - -```json - "profilers": { - "Garbagecollection": { - "subject_aggregation" : "default" - } - } -``` -The garbage collection (GC) plugin gathers and counts GC log statements by searching in adb's logcat for logs that meet the format of a GC call as described [here](https://dzone.com/articles/understanding-android-gc-logs). -The default subject aggregation lists the counted GC calls in a single file for easy further processing. -```json - "profilers": { - "Frametimes": { - "subject_aggregation" : "default", - "sample_interval": 1000 - } - } -``` -The frame times plugin gathers unique frame rendering durations (in nanoseconds) by utilizing `dumpsys gfxinfo framestats` and counts the amount of delayed frames that occurred following the 16ms threshold [defined by Google](https://developer.android.com/training/testing/performance). -The sample interval is configurable but advised to keep under 120 seconds as the framestats command returns only data from frames rendered in the past 120 seconds as described [here](https://developer.android.com/training/testing/performance). -Shorter sample intervals will not cause duplication in the frames gathered as only unique frames are kept. -The default subject aggregation consists of combining both the frametimes as the delayed frames count in single files for easy further processing. +| Name (quality) | Description | +|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [batterystats](./AndroidRunner/Plugins/batterystats/README_Batterystats.md) (Energy) | Uses the `batterystats` utility and estimates energy consumption via the algorithm proposed in [this article](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7884613&casa_token=oEEnY7XOip8AAAAA:AyRZxwboUh55-n9vmW5NGT62mL_hv85T4wPGWlDQGJ36VpF3bcAV1ufvYBhsYxlB0lIMOYJ_Hc-O&tag=1). | +| [monsoon](./AndroidRunner/Plugins/monsoon/README_Monsoon.md) (Energy) | Collects energy consumption via the Monsoon hard-ware profiler and the [Physalia tool](https://github.com/TQRG/physalia). | +| [trepn](./AndroidRunner/Plugins/trepn/README_Trepn.md) (mixed) | Collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. | +| [mem-CPU](./AndroidRunner/Plugins/android/README_Android.md) (Performance) | Collects memory and CPU usage via the `cpuinfo` and `meminfo` Android utilities. | +| [frametimes](./AndroidRunner/Plugins/frametimes/README_Frametimes.md) (Performance) | Collects frame rendering durations and the number of delayed frames with the technique used in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | +| [gc](./AndroidRunner/Plugins/trepn/README_Trepn.md) (Performance) | Collects the number of garbage collections as in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | **subject_aggregation** *string* Specify which subject aggregation to use. The default is the subject aggregation provided by the profiler. If a user specified aggregation script is used then the script should contain a ```bash main(dummy, data_dir)``` method, as this method is used as the entry point to the script. @@ -207,12 +186,6 @@ Specify which experiment aggregation to use. The default is the experiment aggre **cleanup** *boolean* Delete log files required by Batterystats after completion of the experiment. The default is *true*. -**enable_systrace_parsing** *boolean* -The Batterystats profiler uses the profiling tool Systrace internally to measure CPU specific activity and energy consumption on the mobile device. For some devices the parsing of the output of Systrace fails, causing the experiment run to fail. You can safely disable the Systrace parsing when you encounter Systrace parsing errors given that your experiment does not need rely on CPU specific information, but rather on the overall energy consumption of the mobile device. The overall energy consumption is not affected by the Systrace logs since it is tracked using another tool. The default is *true*. - -**python2_path** *string* -The path to python 2 that is used to launch Systrace. The default is *python2*. - **scripts** *JSON* A JSON list of types and paths of scripts to run. Below is an example: ```js diff --git a/documentation/overview.jpg b/documentation/overview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..47f4f824c8fd7b0889208ce7dff7623b61d012ce GIT binary patch literal 84290 zcmd432|Sc--#32RL)rIj6jIr;moQ0%B#Hv^B&df)f|c|Y%2C&zJ|$9bH`?^u4n?{7IUJ~QS3zH?{I z&H_wK0FVj(0~k0U@Jy)pbpWui0FD3vum@mek^tDi6j%i?WRm=k^jW4u0Lvfc%m5JQ z4Y2;R&IR!IuM2GLk9Yp@o4J7bUp1I<1uXxOzWu8zg8&?}@(KtHxZ@RYQ&v;;C~)kQ znFZ^w7QyR}w89@rzESDqFDRgfb?F}G<5lu01Ov}}(#+TxW_8K(tl9Z9e-Ofa)adl7 zGt7Jd;O8HB`;y5i*(>%AvK)gTE!==0pb4CCal3QV$ja*cuQvSy{5}3?`%gc%#{cL$ zFrxCStv@~b?=xI(H*W`m)u`aD;qGzA4IGH0VA?k%@FrN!^b|}Bx%&Q*e)%hX+vbun zSl$Vyc|8A-9{rVe{YQG?SNb+c1XySDSAEYv(#(5)rCtA#mimN8vnM6MRyX@Z|atpd0{LdT{vnBxiclm#}@l*@|EK31^ zmHO{8trP$#PzC_rjDMFMR0jY)H2`RN%4h}n_b}gP#<4IR0GRoiSooP3od5(JYBr`n zu77oliJ66!jh$l;Cl@zZp^gt=W@2GsW@TYx`?XM+BEaVWD?gjSesv>u!HX^&2W|;z zL_RFsBX{amoA9L}qP(W-?I=zz5m7O535A1-hYlan($>*Ec3jW+^qI3Jre^1?Z7$o| zfn9WS_qguq-%c=QK*pxVm<0B+FoBDSg&%+d zG-^@eA>e=Qc26_e>!b$_W{F)KUTeVJ7tLH=5r&ba&HQ|b<+z#%`CDp=%|X(&ITP18I-T&ELr z10CRx2N#a-BQ=2@`4<)a2bez;q@9%KQQ9eO%$XM@IL%`wCGivY=zLh}xk0*YLNlaj zg&)@8A(O(Mqf)z-CT}e#Ucw#VsZ{ZJXIj^zR{|?!sFa_~0Ep)3SZA5>>qr8M9d0_J z4|yJow@DrDW&o=xb#KLL)8u=X7iXgZ-o=d$BtKmywC`fe5OqI3Mf56WM6C2@bb&oB0Rig_> ze#XQ+H66(GY`E8O-F>f-YbQPU$|U_m7V;%BSvz0yYL_B`eOBRmvQz)jaR`)V z*%tEIgM@OqImsF`Mn`ky;Mz#))Ka%rwhi3_-y9lhVx_TkO8*4-NdRRq1<0 zE&J|x-`kMZXu;76)zeXmee8=FUrZq&Q(xgu$sT)xqa&Q>^|E@xINu6GYn zPVa%%t}=i+&kihK=(qWfa@?~)>ct3L+l{Q)&GX80b@>CcE^*!gwSHe}=lw&Z=0YvI zEvMq}+xHoOw}so5KiPEAovcpW~O*T9wK%?Pwldi zZK5p$3}9~?9$OQz4#m0nAncx`P@t~^-!;AJzBM7e(nFV{>X8#jP&!xHyd@7@og5cJ z9I!*R)`wWW_;Tf0q1;rDaN@hSiDoWLPPtd=S5xk}c@WBl6pM1|R|7PsYqW zp$mnMv`*ex(Mx$&jL6bSDl`5nUKSpkI^()N9y+}sq+U;4U_sURBNX8}HN>x3$pQNI zg>3~sm*SOw+6O7Qzk2&5DN@Rg-AE|)d_at?;@1FUR9k+mj4;VA25|&2iR3brTUME0 zi(ewXw&f?cAhp$03GyRuQ+^Az)$yr{b?wQI)Yb3M`39W#fCR4wKF8ut%mj&>h)f=N=;xW9nH1@tOJG$afRjt!Go2b4^ zIaUp+pT61a3YmI(v)b4k=qG9Iud9<5&9QF14z_nNzbr!fnM^Eu=Iw&)zoK z%i&O9s6sswAetXnIS=K92vy$D6B|=O)^-FA@WDzP*r#67MJ! z)wKb!$h#|Iu^>+C?#3Hc(p8Tv zv_A5y^r_pNI`v$BQ)-Z7y4Eh4%0*t9Lrt=@4w6UO(#*L*ByoLAtFmr=ZL@L#==BW} zwRw2w0b-?`C%T;dUG_hTMdxFDC7a$sx17muBV4pHCv@n0NPA!Qb3a~4J^k`&rQBgQ zd(-!_3lhLCdm)1x;Alh}zh=qo<8bXGt+NH{{d_o9hv1_gN%0D*0 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 Date: Wed, 22 Jul 2020 08:45:31 +0200 Subject: [PATCH 2/2] Expanded on the configuration options of each plugin and improved consistency --- .../android/{README_Android.md => README.md} | 14 ++++++++++ .../{README_Batterystats.md => README.md} | 8 +++++- .../{README_Frametimes.md => README.md} | 7 +++-- ...{README_Garbagecollection.md => README.md} | 5 +++- .../monsoon/{README_Monsoon.md => README.md} | 0 AndroidRunner/Plugins/trepn/README.md | 26 ++++++++++++++++++ AndroidRunner/Plugins/trepn/README_Trepn.md | 13 --------- .../Plugins/trepn}/com.quicinc.trepn.apk | Bin README.md | 16 +++++------ 9 files changed, 64 insertions(+), 25 deletions(-) rename AndroidRunner/Plugins/android/{README_Android.md => README.md} (52%) rename AndroidRunner/Plugins/batterystats/{README_Batterystats.md => README.md} (89%) rename AndroidRunner/Plugins/frametimes/{README_Frametimes.md => README.md} (88%) rename AndroidRunner/Plugins/garbagecollection/{README_Garbagecollection.md => README.md} (83%) rename AndroidRunner/Plugins/monsoon/{README_Monsoon.md => README.md} (100%) create mode 100644 AndroidRunner/Plugins/trepn/README.md delete mode 100644 AndroidRunner/Plugins/trepn/README_Trepn.md rename {examples => AndroidRunner/Plugins/trepn}/com.quicinc.trepn.apk (100%) diff --git a/AndroidRunner/Plugins/android/README_Android.md b/AndroidRunner/Plugins/android/README.md similarity index 52% rename from AndroidRunner/Plugins/android/README_Android.md rename to AndroidRunner/Plugins/android/README.md index 2665e8969a..1d66028863 100644 --- a/AndroidRunner/Plugins/android/README_Android.md +++ b/AndroidRunner/Plugins/android/README.md @@ -13,3 +13,17 @@ Below, an example configuration can be found. } } ``` + +**sample_interval** *int* +The sample interval in which the ADB commands are executed and the data points are gathered. + +**data_points** *Array* +The types of data that should be measured defined in an array of string enums. Possible options are: +- `cpu` - collects the CPU usage as a percentage of the device's total CPU capacity at a given point in time. +- `mem` - collects the memory usage in KB at a given point in time. + +**subject_aggregation** *string* +TODO: default subject aggregation + +**experiment_aggregation** *string* +TODO: default experiment aggregation \ No newline at end of file diff --git a/AndroidRunner/Plugins/batterystats/README_Batterystats.md b/AndroidRunner/Plugins/batterystats/README.md similarity index 89% rename from AndroidRunner/Plugins/batterystats/README_Batterystats.md rename to AndroidRunner/Plugins/batterystats/README.md index a23ad1015e..d0bc207520 100644 --- a/AndroidRunner/Plugins/batterystats/README_Batterystats.md +++ b/AndroidRunner/Plugins/batterystats/README.md @@ -19,4 +19,10 @@ Below, an example configuration can be found. The Batterystats profiler uses the profiling tool Systrace internally to measure CPU specific activity and energy consumption on the mobile device. For some devices the parsing of the output of Systrace fails, causing the experiment run to fail. You can safely disable the Systrace parsing when you encounter Systrace parsing errors given that your experiment does not need rely on CPU specific information, but rather on the overall energy consumption of the mobile device. The overall energy consumption is not affected by the Systrace logs since it is tracked using another tool. The default is *true*. **python2_path** *string* -The path to python 2 that is used to launch Systrace. The default is *python2*. \ No newline at end of file +The path to python 2 that is used to launch Systrace. The default is *python2*. + +**subject_aggregation** *string* +TODO: default subject aggregation + +**experiment_aggregation** *string* +TODO: default experiment aggregation \ No newline at end of file diff --git a/AndroidRunner/Plugins/frametimes/README_Frametimes.md b/AndroidRunner/Plugins/frametimes/README.md similarity index 88% rename from AndroidRunner/Plugins/frametimes/README_Frametimes.md rename to AndroidRunner/Plugins/frametimes/README.md index 3539600e26..1b9a59ef92 100644 --- a/AndroidRunner/Plugins/frametimes/README_Frametimes.md +++ b/AndroidRunner/Plugins/frametimes/README.md @@ -12,9 +12,12 @@ Below an example of the configuration options is found: } ``` -**sample_interval** *boolean* +**sample_interval** *int* The sample interval is configurable but advised to keep under 120 seconds as the framestats command returns only data from frames rendered in the past 120 seconds as described [here](https://developer.android.com/training/testing/performance). Shorter sample intervals will not cause duplication in the frames gathered as only unique frames are kept. **subject_aggregation** *string* -The default subject aggregation consists of combining both the frametimes as the delayed frames count in single files for easy further processing. \ No newline at end of file +The default subject aggregation consists of combining both the frametimes as the delayed frames count in single files for easy further processing. + +**experiment_aggregation** *string* +This plugin contains no default experiment aggregation. \ No newline at end of file diff --git a/AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md b/AndroidRunner/Plugins/garbagecollection/README.md similarity index 83% rename from AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md rename to AndroidRunner/Plugins/garbagecollection/README.md index 08ba4518d3..dae5531b70 100644 --- a/AndroidRunner/Plugins/garbagecollection/README_Garbagecollection.md +++ b/AndroidRunner/Plugins/garbagecollection/README.md @@ -12,4 +12,7 @@ Below an example configuration is found: ``` **subject_aggregation** *string* -The default configuration for this plugin is the subject aggregation which lists the counted GC calls in a single file for easy further processing. \ No newline at end of file +The default configuration for this plugin is the subject aggregation which lists the counted GC calls in a single file for easy further processing. + +**experiment_aggregation** *string* +This plugin contains no default experiment aggregation. \ No newline at end of file diff --git a/AndroidRunner/Plugins/monsoon/README_Monsoon.md b/AndroidRunner/Plugins/monsoon/README.md similarity index 100% rename from AndroidRunner/Plugins/monsoon/README_Monsoon.md rename to AndroidRunner/Plugins/monsoon/README.md diff --git a/AndroidRunner/Plugins/trepn/README.md b/AndroidRunner/Plugins/trepn/README.md new file mode 100644 index 0000000000..81dfc583bb --- /dev/null +++ b/AndroidRunner/Plugins/trepn/README.md @@ -0,0 +1,26 @@ +# Trepn Plugin +This plugin collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. +The plugin depends on the [Trepn Android app](./com.quicinc.trepn.apk) being installed on the device. + +## Configuration +Below an example configuration is found: +```json + "profilers": { + "trepn": { + "sample_interval": 100, + "data_points": ["battery_power", "mem_usage"] + } + } +``` + +**sample_interval** *int* +The sample interval in which the data points are gathered. + +**data_points** *Array* +The types of data that should be measured defined in an array of string enums. Possible options are listed in [data_points.json](./data_points.json). + +**subject_aggregation** *string* +TODO: default subject aggregation + +**experiment_aggregation** *string* +TODO: default experiment aggregation \ No newline at end of file diff --git a/AndroidRunner/Plugins/trepn/README_Trepn.md b/AndroidRunner/Plugins/trepn/README_Trepn.md deleted file mode 100644 index a964756a5b..0000000000 --- a/AndroidRunner/Plugins/trepn/README_Trepn.md +++ /dev/null @@ -1,13 +0,0 @@ -# Trepn Plugin -This plugin collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. - -## Configuration -Below an example configuration is found: -```json - "profilers": { - "trepn": { - "sample_interval": 100, - "data_points": ["battery_power", "mem_usage"] - } - } -``` \ No newline at end of file diff --git a/examples/com.quicinc.trepn.apk b/AndroidRunner/Plugins/trepn/com.quicinc.trepn.apk similarity index 100% rename from examples/com.quicinc.trepn.apk rename to AndroidRunner/Plugins/trepn/com.quicinc.trepn.apk diff --git a/README.md b/README.md index 09135574f1..5aef5bc693 100644 --- a/README.md +++ b/README.md @@ -168,14 +168,14 @@ A JSON object to describe the profiler plugins to be used and their arguments. B ``` Out of the box, AR contains the plugins listed below which can immediately be used as a profiler for an experiment. -| Name (quality) | Description | -|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [batterystats](./AndroidRunner/Plugins/batterystats/README_Batterystats.md) (Energy) | Uses the `batterystats` utility and estimates energy consumption via the algorithm proposed in [this article](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7884613&casa_token=oEEnY7XOip8AAAAA:AyRZxwboUh55-n9vmW5NGT62mL_hv85T4wPGWlDQGJ36VpF3bcAV1ufvYBhsYxlB0lIMOYJ_Hc-O&tag=1). | -| [monsoon](./AndroidRunner/Plugins/monsoon/README_Monsoon.md) (Energy) | Collects energy consumption via the Monsoon hard-ware profiler and the [Physalia tool](https://github.com/TQRG/physalia). | -| [trepn](./AndroidRunner/Plugins/trepn/README_Trepn.md) (mixed) | Collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. | -| [mem-CPU](./AndroidRunner/Plugins/android/README_Android.md) (Performance) | Collects memory and CPU usage via the `cpuinfo` and `meminfo` Android utilities. | -| [frametimes](./AndroidRunner/Plugins/frametimes/README_Frametimes.md) (Performance) | Collects frame rendering durations and the number of delayed frames with the technique used in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | -| [gc](./AndroidRunner/Plugins/trepn/README_Trepn.md) (Performance) | Collects the number of garbage collections as in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | +| Name (quality attribute) | Description | +|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [batterystats](./AndroidRunner/Plugins/batterystats/README.md) (Energy) | Uses the `batterystats` utility and estimates energy consumption via the algorithm proposed in [this article](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7884613&casa_token=oEEnY7XOip8AAAAA:AyRZxwboUh55-n9vmW5NGT62mL_hv85T4wPGWlDQGJ36VpF3bcAV1ufvYBhsYxlB0lIMOYJ_Hc-O&tag=1). | +| [monsoon](./AndroidRunner/Plugins/monsoon/README.md) (Energy) | Collects energy consumption via the Monsoon hard-ware profiler and the [Physalia tool](https://github.com/TQRG/physalia). | +| [trepn](./AndroidRunner/Plugins/trepn/README.md) (mixed) | Collects data via the Trepn profiler, e.g., power consumption, battery temperature, CPUs frequency. | +| [mem-CPU](./AndroidRunner/Plugins/android/README.md) (Performance) | Collects memory and CPU usage via the `cpuinfo` and `meminfo` Android utilities found in ADB's [dumpsys](https://developer.android.com/studio/command-line/dumpsys). | +| [frametimes](./AndroidRunner/Plugins/frametimes/README.md) (Performance) | Collects frame rendering durations and the number of delayed frames with the technique used in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | +| [gc](./AndroidRunner/Plugins/trepn/README.md) (Performance) | Collects the number of garbage collections as in [this article](https://dl.acm.org/doi/pdf/10.1145/2897073.2897100?casa_token=jD3bYLV001kAAAAA:OZiAzZFwtvSO-uK3hgWlz6iNVcTt6uYoT1UWroDEGhDHrEBvLbsIl4E13RhAtRK4IaEPd6putLTzzZw). | **subject_aggregation** *string* Specify which subject aggregation to use. The default is the subject aggregation provided by the profiler. If a user specified aggregation script is used then the script should contain a ```bash main(dummy, data_dir)``` method, as this method is used as the entry point to the script.