Showing preview only (2,599K chars total). Download the full file or copy to clipboard to get everything.
Repository: ARM-software/workload-automation
Branch: master
Commit: 251c263c564b
Files: 534
Total size: 2.4 MB
Directory structure:
gitextract_n5js309u/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ ├── question---support-.md
│ │ └── question.md
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .readthedocs.yml
├── LICENSE
├── MANIFEST.in
├── README.rst
├── dev_scripts/
│ ├── README
│ ├── clean_install
│ ├── clear_env
│ ├── get_apk_versions
│ ├── pep8
│ ├── pylint
│ ├── pylint_plugins.py
│ ├── rebuild_all_uiauto
│ └── update_copyrights
├── doc/
│ ├── Makefile
│ ├── build_instrument_method_map.py
│ ├── build_plugin_docs.py
│ ├── make.bat
│ ├── requirements.txt
│ └── source/
│ ├── api/
│ │ ├── output.rst
│ │ └── workload.rst
│ ├── api.rst
│ ├── changes.rst
│ ├── conf.py
│ ├── developer_information/
│ │ ├── developer_guide/
│ │ │ └── writing_plugins.rst
│ │ ├── developer_guide.rst
│ │ ├── developer_reference/
│ │ │ ├── contributing.rst
│ │ │ ├── framework_overview.rst
│ │ │ ├── plugins.rst
│ │ │ ├── revent.rst
│ │ │ └── serialization.rst
│ │ ├── developer_reference.rst
│ │ ├── how_to.rst
│ │ └── how_tos/
│ │ ├── adding_plugins.rst
│ │ └── processing_output.rst
│ ├── developer_information.rst
│ ├── faq.rst
│ ├── glossary.rst
│ ├── index.rst
│ ├── instrument_method_map.template
│ ├── migration_guide.rst
│ ├── plugins.rst
│ ├── user_information/
│ │ ├── how_to.rst
│ │ ├── how_tos/
│ │ │ ├── agenda.rst
│ │ │ ├── device_setup.rst
│ │ │ └── revent.rst
│ │ ├── installation.rst
│ │ ├── user_guide.rst
│ │ ├── user_reference/
│ │ │ ├── agenda.rst
│ │ │ ├── configuration.rst
│ │ │ ├── invocation.rst
│ │ │ ├── output_directory.rst
│ │ │ └── runtime_parameters.rst
│ │ └── user_reference.rst
│ └── user_information.rst
├── extras/
│ ├── Dockerfile
│ ├── README
│ ├── pylintrc
│ └── walog.vim
├── pytest.ini
├── requirements.txt
├── scripts/
│ ├── cpustates
│ └── wa
├── setup.py
├── tests/
│ ├── __init__.py
│ ├── ci/
│ │ └── idle_agenda.yaml
│ ├── data/
│ │ ├── bad-syntax-agenda.yaml
│ │ ├── extensions/
│ │ │ └── devices/
│ │ │ └── test_device.py
│ │ ├── includes/
│ │ │ ├── agenda.yaml
│ │ │ ├── configs/
│ │ │ │ └── test.yaml
│ │ │ ├── section-include.yaml
│ │ │ ├── sections/
│ │ │ │ ├── section1.yaml
│ │ │ │ └── section2.yaml
│ │ │ ├── user/
│ │ │ │ └── config.yaml
│ │ │ └── workloads.yaml
│ │ ├── interrupts/
│ │ │ ├── after
│ │ │ ├── before
│ │ │ └── result
│ │ ├── logcat.2.log
│ │ ├── logcat.log
│ │ ├── test-agenda.yaml
│ │ └── test-config.py
│ ├── test_agenda_parser.py
│ ├── test_config.py
│ ├── test_diff.py
│ ├── test_exec_control.py
│ ├── test_execution.py
│ ├── test_plugin.py
│ ├── test_runtime_param_utils.py
│ ├── test_signal.py
│ └── test_utils.py
└── wa/
├── __init__.py
├── assets/
│ └── bin/
│ ├── arm64/
│ │ └── revent
│ └── armeabi/
│ └── revent
├── commands/
│ ├── __init__.py
│ ├── create.py
│ ├── list.py
│ ├── postgres_schemas/
│ │ ├── postgres_schema.sql
│ │ ├── postgres_schema_update_v1.2.sql
│ │ ├── postgres_schema_update_v1.3.sql
│ │ ├── postgres_schema_update_v1.4.sql
│ │ ├── postgres_schema_update_v1.5.sql
│ │ └── postgres_schema_update_v1.6.sql
│ ├── process.py
│ ├── report.py
│ ├── revent.py
│ ├── run.py
│ ├── schema_changelog.rst
│ ├── show.py
│ └── templates/
│ ├── apk_workload
│ ├── apkrevent_workload
│ ├── apkuiauto_workload
│ ├── basic_workload
│ ├── revent_workload
│ ├── setup.template
│ ├── uiauto/
│ │ ├── UiAutomation.java
│ │ ├── uiauto_AndroidManifest.xml
│ │ ├── uiauto_build.gradle
│ │ ├── uiauto_build_script
│ │ └── uiauto_workload_template/
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ └── uiauto_workload
├── framework/
│ ├── __init__.py
│ ├── command.py
│ ├── configuration/
│ │ ├── __init__.py
│ │ ├── core.py
│ │ ├── default.py
│ │ ├── execution.py
│ │ ├── parsers.py
│ │ ├── plugin_cache.py
│ │ └── tree.py
│ ├── entrypoint.py
│ ├── exception.py
│ ├── execution.py
│ ├── getters.py
│ ├── host.py
│ ├── instrument.py
│ ├── job.py
│ ├── output.py
│ ├── output_processor.py
│ ├── plugin.py
│ ├── pluginloader.py
│ ├── resource.py
│ ├── run.py
│ ├── signal.py
│ ├── target/
│ │ ├── __init__.py
│ │ ├── assistant.py
│ │ ├── config.py
│ │ ├── descriptor.py
│ │ ├── info.py
│ │ ├── manager.py
│ │ ├── runtime_config.py
│ │ └── runtime_parameter_manager.py
│ ├── uiauto/
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── arm/
│ │ │ └── wa/
│ │ │ └── uiauto/
│ │ │ ├── ActionLogger.java
│ │ │ ├── ApplaunchInterface.java
│ │ │ ├── BaseUiAutomation.java
│ │ │ ├── UiAutoUtils.java
│ │ │ └── UxPerfUiAutomation.java
│ │ ├── build.gradle
│ │ ├── build.sh
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ ├── settings.gradle
│ │ └── uiauto.aar
│ ├── version.py
│ └── workload.py
├── instruments/
│ ├── __init__.py
│ ├── delay.py
│ ├── dmesg.py
│ ├── energy_measurement.py
│ ├── fps.py
│ ├── hwmon.py
│ ├── misc.py
│ ├── perf.py
│ ├── perfetto.py
│ ├── poller/
│ │ ├── Makefile
│ │ ├── __init__.py
│ │ ├── bin/
│ │ │ ├── arm64/
│ │ │ │ └── poller
│ │ │ └── armeabi/
│ │ │ └── poller
│ │ └── poller.c
│ ├── proc_stat/
│ │ ├── __init__.py
│ │ └── gather-load.sh
│ ├── screencap.py
│ ├── serialmon.py
│ └── trace_cmd.py
├── output_processors/
│ ├── __init__.py
│ ├── cpustates.py
│ ├── csvproc.py
│ ├── postgresql.py
│ ├── sqlite.py
│ ├── status.py
│ ├── targz.py
│ └── uxperf.py
├── tools/
│ └── revent/
│ ├── Makefile
│ └── revent.c
├── utils/
│ ├── __init__.py
│ ├── android.py
│ ├── cpustates.py
│ ├── diff.py
│ ├── doc.py
│ ├── exec_control.py
│ ├── formatter.py
│ ├── log.py
│ ├── misc.py
│ ├── postgres.py
│ ├── revent.py
│ ├── serializer.py
│ ├── terminalsize.py
│ ├── trace_cmd.py
│ └── types.py
└── workloads/
├── __init__.py
├── adobereader/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.adobereader.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── adobereader/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── aitutu/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.aitutu.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── aitutu/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── androbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.androbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── androbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── angrybirds_rio/
│ └── __init__.py
├── antutu/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.antutu.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── antutu/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── apache.py
├── applaunch/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.applaunch.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── applaunch/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── benchmarkpi/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.benchmarkpi.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── benchmarkpi/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── chrome/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.chrome.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── deepbench/
│ └── __init__.py
├── dhrystone/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── dhrystone
│ │ └── armeabi/
│ │ └── dhrystone
│ └── src/
│ ├── Makefile
│ └── dhrystone.c
├── drarm/
│ └── __init__.py
├── exoplayer/
│ └── __init__.py
├── geekbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.geekbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── geekbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gfxbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.gfxbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── gfxbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── glbenchmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.glbenchmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── glbenchmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gmail/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.gmail.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── gmail/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googlemaps/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googlemaps.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googlephotos/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googlephotos.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googlephotos/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googleplaybooks/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googleplaybooks.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googleplaybooks/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googleslides/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googleslides.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googleslides/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── hackbench/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── hackbench
│ │ └── armeabi/
│ │ └── hackbench
│ └── src/
│ └── LICENSE
├── homescreen/
│ └── __init__.py
├── honorofkings/
│ └── __init__.py
├── hwuitest/
│ └── __init__.py
├── idle.py
├── jankbench/
│ └── __init__.py
├── lmbench/
│ ├── __init__.py
│ └── bin/
│ ├── COPYING
│ ├── COPYING-2
│ ├── README
│ ├── arm64/
│ │ ├── bw_mem
│ │ └── lat_mem_rd
│ └── armeabi/
│ ├── bw_mem
│ └── lat_mem_rd
├── manual/
│ └── __init__.py
├── meabo/
│ └── __init__.py
├── memcpy/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── memcpy
│ │ └── armeabi/
│ │ └── memcpy
│ └── src/
│ ├── build.sh
│ └── memcopy.c
├── mongoperf/
│ └── __init__.py
├── motionmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.motionmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── motionmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── openssl/
│ └── __init__.py
├── pcmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.pcmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── pcmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── recentfling/
│ └── __init__.py
├── rt_app/
│ ├── LICENSE
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── armeabi/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── ppc64le/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── x86/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ └── x86_64/
│ │ ├── README.rt-app
│ │ └── rt-app
│ ├── use_cases/
│ │ ├── browser-long.json
│ │ ├── browser-short.json
│ │ ├── camera-long.json
│ │ ├── camera-short.json
│ │ ├── mp3-long.json
│ │ ├── mp3-short.json
│ │ ├── spreading-tasks.json
│ │ ├── taskset.json
│ │ ├── video-long.json
│ │ └── video-short.json
│ └── workgen
├── schbench/
│ ├── __init__.py
│ ├── bin/
│ │ └── arm64/
│ │ └── schbench
│ └── src/
│ └── LICENSE
├── shellscript/
│ └── __init__.py
├── speedometer/
│ ├── LICENSE
│ ├── __init__.py
│ ├── speedometer_archive-2.0.tar.lzma
│ ├── speedometer_archive-2.1.tar.lzma
│ └── speedometer_archive-3.0.tar.lzma
├── stress_ng/
│ ├── LICENSE
│ ├── __init__.py
│ └── bin/
│ ├── arm64/
│ │ └── stress-ng
│ └── armeabi/
│ └── stress-ng
├── sysbench/
│ ├── LICENSE
│ ├── __init__.py
│ └── bin/
│ ├── arm64/
│ │ └── sysbench
│ └── armeabi/
│ └── sysbench
├── templerun2/
│ └── __init__.py
├── the_chase/
│ └── __init__.py
├── uibench/
│ └── __init__.py
├── uibenchjanktests/
│ └── __init__.py
├── vellamo/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.vellamo.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── vellamo/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── youtube/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.youtube.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── youtube/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
└── youtube_playback/
└── __init__.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help resolve an issue.
title: ''
labels: bug
assignees: ''
---
**Describe the issue**
A clear and concise description of what the bug is.
**Run Log**
Please attach your `run.log` detailing the issue.
**Other comments (optional)**
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context about the feature request here.
================================================
FILE: .github/ISSUE_TEMPLATE/question---support-.md
================================================
---
name: 'Question / Support '
about: Ask a question or reqeust support
title: ''
labels: question
assignees: ''
---
**
================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question
title: ''
labels: question
assignees: ''
---
**Describe you query**
What would you like to know / what are you trying to achieve?
================================================
FILE: .github/workflows/main.yml
================================================
name: WA Test Suite
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
types: [opened, synchronize, reopened, ready_for_review]
schedule:
- cron: 0 2 * * *
# Allows runing this workflow manually from the Actions tab
workflow_dispatch:
jobs:
Run-Linters-and-Tests:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8.18
uses: actions/setup-python@v2
with:
python-version: 3.8.18
- name: git-bash
uses: pkg-src/github-action-git-bash@v1.1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd /tmp && git clone https://github.com/ARM-software/devlib.git && cd devlib && pip install .
cd $GITHUB_WORKSPACE && pip install .[test]
python -m pip install pylint==2.6.2 pep8 flake8 mock nose
- name: Run pylint
run: |
cd $GITHUB_WORKSPACE && ./dev_scripts/pylint wa/
- name: Run PEP8
run: |
cd $GITHUB_WORKSPACE && ./dev_scripts/pep8 wa
- name: Run nose tests
run: |
nosetests
Execute-Test-Workload-and-Process:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: [3.7.17, 3.8.18, 3.9.21, 3.10.16, 3.13.2]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: git-bash
uses: pkg-src/github-action-git-bash@v1.1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd /tmp && git clone https://github.com/ARM-software/devlib.git && cd devlib && pip install .
cd $GITHUB_WORKSPACE && pip install .
- name: Run test workload
run: |
cd /tmp && wa run $GITHUB_WORKSPACE/tests/ci/idle_agenda.yaml -v -d idle_workload
- name: Test Process Command
run: |
cd /tmp && wa process -f -p csv idle_workload
Test-WA-Commands:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: [3.7.17, 3.8.18, 3.9.21, 3.10.16, 3.13.2]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: git-bash
uses: pkg-src/github-action-git-bash@v1.1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd /tmp && git clone https://github.com/ARM-software/devlib.git && cd devlib && pip install .
cd $GITHUB_WORKSPACE && pip install .
- name: Test Show Command
run: |
wa show dhrystone && wa show generic_android && wa show trace-cmd && wa show csv
- name: Test List Command
run: |
wa list all
- name: Test Create Command
run: |
wa create agenda dhrystone generic_android csv trace_cmd && wa create package test && wa create workload test
================================================
FILE: .gitignore
================================================
*.egg-info
*.pyc
*.bak
*.o
*.cmd
*.iml
Module.symvers
modules.order
*~
tags
build/
dist/
.ropeproject/
wa_output/
doc/source/plugins/
MANIFEST
*.orig
local.properties
pmu_logger.mod.c
.tmp_versions
obj/
libs/armeabi
**/uiauto/**/build/
**/uiauto/**/.gradle
**/uiauto/**/.idea
**/uiauto/**/proguard-rules.pro
**/uiauto/app/libs/
**/uiauto/*.properties
**/uiauto/**/.project
**/uiauto/**/.settings
**/uiauto/**/.classpath
doc/source/developer_information/developer_guide/instrument_method_map.rst
doc/source/run_config/
.eggs
================================================
FILE: .readthedocs.yml
================================================
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
builder: html
configuration: doc/source/conf.py
# Build the docs in additional formats such as PDF and ePub
formats: all
# Configure the build environment
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Ensure doc dependencies are installed before building
python:
install:
- requirements: doc/requirements.txt
- method: pip
path: .
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MANIFEST.in
================================================
recursive-include scripts *
recursive-include doc *
recursive-include wa *
================================================
FILE: README.rst
================================================
[DEPRECATED] Workload Automation
++++++++++++++++++++++++++++++++++++++++++++
⚠️ **Development of this project has moved to a new repository.**
Please visit the new location for the latest code, issues, and contributions:
https://gitlab.arm.com/tooling/workload-automation/workload-automation
This repository is no longer actively maintained.
-------------
Workload Automation (WA) is a framework for executing workloads and collecting
measurements on Android and Linux devices. WA includes automation for nearly 40
workloads and supports some common instrumentation (ftrace, hwmon) along with a
number of output formats.
WA is designed primarily as a developer tool/framework to facilitate data driven
development by providing a method of collecting measurements from a device in a
repeatable way.
WA is highly extensible. Most of the concrete functionality is implemented via
plug-ins, and it is easy to write new plug-ins to support new device types,
workloads, instruments or output processing.
Requirements
============
- Python 3.5+
- Linux (should work on other Unixes, but untested)
- Latest Android SDK (ANDROID_HOME must be set) for Android devices, or
- SSH for Linux devices
Installation
============
To install::
git clone git@github.com:ARM-software/workload-automation.git workload-automation
sudo -H python setup [install|develop]
Note: A `requirements.txt` is included however this is designed to be used as a
reference for known working versions rather than as part of a standard
installation.
Please refer to the `installation section <http://workload-automation.readthedocs.io/en/latest/user_information.html#install>`_
in the documentation for more details.
Basic Usage
===========
Please see the `Quickstart <http://workload-automation.readthedocs.io/en/latest/user_information.html#user-guide>`_
section of the documentation.
Documentation
=============
You can view pre-built HTML documentation `here <http://workload-automation.readthedocs.io/en/latest/>`_.
Documentation in reStructuredText format may be found under ``doc/source``. To
compile it into cross-linked HTML, make sure you have `Sphinx
<http://sphinx-doc.org/install.html>`_ installed, and then ::
cd doc
make html
License
=======
Workload Automation is distributed under `Apache v2.0 License
<http://www.apache.org/licenses/LICENSE-2.0>`_. Workload automation includes
binaries distributed under different licenses (see LICENSE files in specific
directories).
Feedback, Contributions and Support
===================================
- Please use the GitHub Issue Tracker associated with this repository for
feedback.
- ARM licensees may contact ARM directly via their partner managers.
- We welcome code contributions via GitHub Pull requests. Please see
"Contributing Code" section of the documentation for details.
================================================
FILE: dev_scripts/README
================================================
This directory contains scripts that aid the development of Workload Automation.
They were written to work as part of WA development environment and are not
guarnteed to work if moved outside their current location. They should not be
distributed as part of WA releases.
Scripts
-------
:clean_install: Performs a clean install of WA from source. This will remove any
existing WA install (regardless of whether it was made from
source or through a tarball with pip).
:clear_env: Clears ~/.workload_automation.
:get_apk_versions: Prints out a table of APKs and their versons found under the
path specified as the argument.
:pep8: Runs flake8 (formerly called "pep8") code checker (must be
installed) over wa/ with the correct settings for WA.
:pylint: Runs pylint (must be installed) over wlauto with the correct settings
for WA.
:rebuild_all_uiauto: Rebuild UIAutomator APKs for workloads that have them. This
is useful to make sure they're all using the latest
uiauto.arr after the latter has been updated.
:update_copyrights: Checks and updates the year of the copyright in source files,
adding a copyright header if it's not already there.
================================================
FILE: dev_scripts/clean_install
================================================
#!/usr/bin/env python
import os
import sys
import shutil
import logging
logging.basicConfig(level=logging.INFO)
def get_installed_path():
paths = [p for p in sys.path if len(p) > 2]
for path in paths:
candidate = os.path.join(path, 'wlauto')
if os.path.isdir(candidate):
return candidate
if __name__ == '__main__':
installed_path = get_installed_path()
if installed_path:
logging.info('Removing installed package from {}.'.format(installed_path))
shutil.rmtree(installed_path)
if os.path.isdir('build'):
logging.info('Removing local build directory.')
shutil.rmtree('build')
logging.info('Removing *.pyc files.')
for root, dirs, files in os.walk('wlauto'):
for file in files:
if file.lower().endswith('.pyc'):
os.remove(os.path.join(root, file))
os.system('python setup.py install')
================================================
FILE: dev_scripts/clear_env
================================================
#!/bin/bash
# Clear workload automation user environment.
rm -rf ~/.workload_automation/
================================================
FILE: dev_scripts/get_apk_versions
================================================
#!/usr/bin/env python
import os
import sys
import re
import logging
import subprocess
import argparse
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from wlauto.exceptions import WAError, ToolError
from wlauto.utils.doc import format_simple_table
def get_aapt_path():
"""Return the full path to aapt tool."""
sdk_path = os.getenv('ANDROID_HOME')
if not sdk_path:
raise ToolError('Please make sure you have Android SDK installed and have ANDROID_HOME set.')
build_tools_directory = os.path.join(sdk_path, 'build-tools')
versions = os.listdir(build_tools_directory)
for version in reversed(sorted(versions)):
aapt_path = os.path.join(build_tools_directory, version, 'aapt')
if os.path.isfile(aapt_path):
logging.debug('Found aapt for version {}'.format(version))
return aapt_path
else:
raise ToolError('aapt not found. Please make sure at least one Android platform is installed.')
def get_apks(path):
"""Return a list of paths to all APK files found under the specified directory."""
apks = []
for root, dirs, files in os.walk(path):
for file in files:
_, ext = os.path.splitext(file)
if ext.lower() == '.apk':
apks.append(os.path.join(root, file))
return apks
class ApkVersionInfo(object):
def __init__(self, workload=None, package=None, label=None, version_name=None, version_code=None):
self.workload = workload
self.package = package
self.label = label
self.version_name = version_name
self.version_code = version_code
def to_tuple(self):
return (self.workload, self.package, self.label, self.version_name, self.version_code)
version_regex = re.compile(r"name='(?P<name>[^']+)' versionCode='(?P<vcode>[^']+)' versionName='(?P<vname>[^']+)'")
def extract_version_info(apk_path, aapt):
command = [aapt, 'dump', 'badging', apk_path]
output = subprocess.check_output(command)
version_info = ApkVersionInfo(workload=apk_path.split(os.sep)[-2])
for line in output.split('\n'):
if line.startswith('application-label:'):
version_info.label = line.split(':')[1].strip().replace('\'', '')
elif line.startswith('package:'):
match = version_regex.search(line)
if match:
version_info.package = match.group('name')
version_info.version_code = match.group('vcode')
version_info.version_name = match.group('vname')
else:
pass # not interested
return version_info
def get_apk_versions(path, aapt):
apks = get_apks(path)
versions = [extract_version_info(apk, aapt) for apk in apks]
return versions
if __name__ == '__main__':
try:
aapt = get_aapt_path()
parser = argparse.ArgumentParser()
parser.add_argument('path', metavar='PATH', help='Location to look for APKs.')
args = parser.parse_args()
versions = get_apk_versions(args.path, aapt)
table = format_simple_table([v.to_tuple() for v in versions],
align='<<<>>',
headers=['workload', 'package', 'name', 'version code', 'version name'])
print table
except WAError, e:
logging.error(e)
sys.exit(1)
================================================
FILE: dev_scripts/pep8
================================================
#!/bin/bash
DEFAULT_DIRS=(
wa
)
EXCLUDE=wa/tests,wa/framework/target/descriptor.py
EXCLUDE_COMMA=
IGNORE=E501,E265,E266,W391,E401,E402,E731,W503,W605,F401
if ! hash flake8 2>/dev/null; then
echo "flake8 not found in PATH"
echo "you can install it with \"sudo pip install flake8\""
exit 1
fi
if [[ "$1" == "" ]]; then
THIS_DIR="`dirname \"$0\"`"
pushd $THIS_DIR/.. > /dev/null
for dir in "${DEFAULT_DIRS[@]}"; do
flake8 --exclude=$EXCLUDE,$EXCLUDE_COMMA --ignore=$IGNORE $dir
done
flake8 --exclude=$EXCLUDE --ignore=$IGNORE,E241 $(echo "$EXCLUDE_COMMA" | sed 's/,/ /g')
popd > /dev/null
else
flake8 --exclude=$EXCLUDE,$EXCLUDE_COMMA --ignore=$IGNORE $1
fi
================================================
FILE: dev_scripts/pylint
================================================
#!/bin/bash
DEFAULT_DIRS=(
wa
)
target=$1
compare_versions() {
if [[ $1 == $2 ]]; then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++)); do
if [[ -z ${ver2[i]} ]]; then
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]})); then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then
return 2
fi
done
return 0
}
pylint_version=$(python -c 'from pylint.__pkginfo__ import version; print(version)' 2>/dev/null)
if [ "x$pylint_version" == "x" ]; then
pylint_version=$(python3 -c 'from pylint.__pkginfo__ import version; print(version)' 2>/dev/null)
fi
if [ "x$pylint_version" == "x" ]; then
pylint_version=$(python3 -c 'from pylint import version; print(version)' 2>/dev/null)
fi
if [ "x$pylint_version" == "x" ]; then
echo "ERROR: no pylint verison found; is it installed?"
exit 1
fi
compare_versions $pylint_version "1.9.2"
result=$?
if [ "$result" == "2" ]; then
echo "ERROR: pylint version must be at least 1.9.2; found $pylint_version"
exit 1
fi
set -e
THIS_DIR="`dirname \"$0\"`"
CWD=$PWD
pushd $THIS_DIR > /dev/null
if [[ "$target" == "" ]]; then
for dir in "${DEFAULT_DIRS[@]}"; do
PYTHONPATH=. pylint --rcfile ../extras/pylintrc --load-plugins pylint_plugins ../$dir
done
else
PYTHONPATH=. pylint --rcfile ../extras/pylintrc --load-plugins pylint_plugins $CWD/$target
fi
popd > /dev/null
================================================
FILE: dev_scripts/pylint_plugins.py
================================================
import sys
from astroid import MANAGER
from astroid import scoped_nodes
IGNORE_ERRORS = {
('attribute-defined-outside-init', ): [
'wa.workloads',
'wa.instruments',
'wa.output_procesors',
]
}
def register(linter):
pass
def transform(mod):
for errors, paths in IGNORE_ERRORS.items():
for path in paths:
if path in mod.name:
text = mod.stream().read()
if not text.strip():
return
text = text.split(b'\n')
# NOTE: doing it this way because the "correct" approach below does not
# work. We can get away with this, because in well-formated WA files,
# the initial line is the copyright header's blank line.
if b'pylint:' in text[0]:
msg = 'pylint directive found on the first line of {}; please move to below copyright header'
raise RuntimeError(msg.format(mod.name))
char = chr(text[0][0])
if text[0].strip() and char != '#':
msg = 'first line of {} is not a comment; is the copyright header missing?'
raise RuntimeError(msg.format(mod.name))
text[0] = '# pylint: disable={}'.format(','.join(errors)).encode('utf-8')
mod.file_bytes = b'\n'.join(text)
# This is what *should* happen, but doesn't work.
# text.insert(0, '# pylint: disable=attribute-defined-outside-init')
# mod.file_bytes = '\n'.join(text)
# mod.tolineno += 1
MANAGER.register_transform(scoped_nodes.Module, transform)
================================================
FILE: dev_scripts/rebuild_all_uiauto
================================================
#!/bin/bash
#
# This script rebuilds all uiauto APKs as well as the base uiauto.arr. This is
# useful when changes have been made to the base uiautomation classes and so
# all automation needs to be rebuilt to link against the updated uiauto.arr.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$SCRIPT_DIR/../wa/framework/uiauto"
WORKLOADS_DIR="$SCRIPT_DIR/../wa/workloads"
pushd $BASE_DIR > /dev/null
echo "building $(pwd)"
./build.sh
popd > /dev/null
for uiauto_dir in $(find $WORKLOADS_DIR -type d -name uiauto); do
pushd $uiauto_dir > /dev/null
if [ -f build.sh ]; then
echo "building $(pwd)"
./build.sh
fi
popd > /dev/null
done
================================================
FILE: dev_scripts/update_copyrights
================================================
#!/usr/bin/env python
#
# Script to put copyright headers into source files.
#
import argparse
import logging
import os
import re
import string
import subprocess
from datetime import datetime
SOURCE_EXTENSIONS = {
'.py': ('#', '#', '#'),
'.sh': ('#', '#', '#'),
'.java': ('/*', '*/', ' *'),
'.c': ('/*', '*/', ' *'),
'.h': ('/*', '*/', ' *'),
'.cpp': ('/*', '*/', ' *'),
}
OLD_HEADER_TEMPLATE = string.Template(
"""${begin_symbol} $$Copyright:
${symbol} ----------------------------------------------------------------
${symbol} This confidential and proprietary software may be used only as
${symbol} authorised by a licensing agreement from ARM Limited
${symbol} (C) COPYRIGHT ${year} ARM Limited
${symbol} ALL RIGHTS RESERVED
${symbol} The entire notice above must be reproduced on all authorised
${symbol} copies and copies may only be made to the extent permitted
${symbol} by a licensing agreement from ARM Limited.
${symbol} ----------------------------------------------------------------
${symbol} File: ${file}
${symbol} ----------------------------------------------------------------
${symbol} $$
${end_symbol}
"""
)
HEADER_TEMPLATE = string.Template(
"""${begin_symbol} Copyright ${year} ARM Limited
${symbol}
${symbol} Licensed under the Apache License, Version 2.0 (the "License");
${symbol} you may not use this file except in compliance with the License.
${symbol} You may obtain a copy of the License at
${symbol}
${symbol} http://www.apache.org/licenses/LICENSE-2.0
${symbol}
${symbol} Unless required by applicable law or agreed to in writing, software
${symbol} distributed under the License is distributed on an "AS IS" BASIS,
${symbol} WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
${symbol} See the License for the specific language governing permissions and
${symbol} limitations under the License.
${end_symbol}
"""
)
# Minimum length, in characters, of a copy right header.
MIN_HEADER_LENGTH = 500
OLD_COPYRIGHT_REGEX = re.compile(r'\(C\) COPYRIGHT\s+(?:(\d+)-)?(\d+)')
COPYRIGHT_REGEX = re.compile(r'Copyright\s+(?:(\d+)\s*[-,]\s*)?(\d+) ARM Limited')
DEFAULT_EXCLUDE_PATHS = [
os.path.join('wa', 'commands', 'templates'),
]
logging.basicConfig(level=logging.INFO, format='%(levelname)-8s %(message)s')
def remove_old_copyright(filepath):
begin_symbol, end_symbol, symbol = SOURCE_EXTENSIONS[ext.lower()]
header = HEADER_TEMPLATE.substitute(begin_symbol=begin_symbol,
end_symbol=end_symbol,
symbol=symbol,
year='0',
file=os.path.basename(filepath))
header_line_count = len(header.splitlines())
with open(filepath) as fh:
lines = fh.readlines()
for i, line in enumerate(lines):
if OLD_COPYRIGHT_REGEX.search(line):
start_line = i -4
break
lines = lines[0:start_line] + lines[start_line + header_line_count:]
return ''.join(lines)
def add_copyright_header(filepath, year):
_, ext = os.path.splitext(filepath)
begin_symbol, end_symbol, symbol = SOURCE_EXTENSIONS[ext.lower()]
with open(filepath) as fh:
text = fh.read()
match = OLD_COPYRIGHT_REGEX.search(text)
if match:
_, year = update_year(text, year, copyright_regex=OLD_COPYRIGHT_REGEX)
text = remove_old_copyright(filepath)
header = HEADER_TEMPLATE.substitute(begin_symbol=begin_symbol,
end_symbol=end_symbol,
symbol=symbol,
year=year)
if text.strip().startswith('#!') or text.strip().startswith('# -*-'):
first_line, rest = text.split('\n', 1)
updated_text = '\n'.join([first_line, header, rest])
else:
updated_text = '\n'.join([header, text])
with open(filepath, 'w') as wfh:
wfh.write(updated_text)
def update_year(text, year, copyright_regex=COPYRIGHT_REGEX, match=None):
if match is None:
match = copyright_regex.search(text)
old_year = match.group(1) or match.group(2)
updated_year_text = 'Copyright {}-{} ARM Limited'.format(old_year, year)
if old_year == year:
ret_year = '{}'.format(year)
else:
ret_year = '{}-{}'.format(old_year, year)
return (text.replace(match.group(0), updated_year_text), ret_year)
def get_git_year(path):
info = subprocess.check_output('git log -n 1 {}'.format(os.path.basename(path)),
shell=True, cwd=os.path.dirname(path))
if not info.strip():
return None
i = 1
while 'copyright' in info.lower():
info = subprocess.check_output('git log -n 1 --skip {} {}'.format(i, os.path.basename(path)),
shell=True, cwd=os.path.dirname(path))
if not info.strip():
return None
info_split_lines = info.split('\n')
info_split_words = info_split_lines[2].split()
return int(info_split_words[5])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('path', help='Location to add copyrights to source files in.')
parser.add_argument('-n', '--update-no-ext', action='store_true',
help='Will update files with on textension using # as the comment symbol.')
parser.add_argument('-x', '--exclude', action='append',
help='Exclude this directory form the scan. May be used multiple times.')
args = parser.parse_args()
if args.update_no_ext:
SOURCE_EXTENSIONS[''] = ('#', '#', '#')
exclude_paths = DEFAULT_EXCLUDE_PATHS + (args.exclude or [])
current_year = datetime.now().year
for root, dirs, files in os.walk(args.path):
should_skip = False
for exclude_path in exclude_paths:
if exclude_path in os.path.realpath(root):
should_skip = True
break
if should_skip:
logging.info('Skipping {}'.format(root))
continue
logging.info('Checking {}'.format(root))
for entry in files:
_, ext = os.path.splitext(entry)
if ext.lower() in SOURCE_EXTENSIONS:
filepath = os.path.join(root, entry)
should_skip = False
for exclude_path in exclude_paths:
if exclude_path in os.path.realpath(filepath):
should_skip = True
break
if should_skip:
logging.info('\tSkipping {}'.format(entry))
continue
with open(filepath) as fh:
text = fh.read()
if not text.strip():
logging.info('\tSkipping empty {}'.format(entry))
continue
year_modified = get_git_year(filepath) or current_year
if len(text) < MIN_HEADER_LENGTH:
logging.info('\tAdding header to {}'.format(entry))
add_copyright_header(filepath, year_modified)
else:
first_chunk = text[:MIN_HEADER_LENGTH]
match = COPYRIGHT_REGEX.search(first_chunk)
if not match:
if OLD_COPYRIGHT_REGEX.search(first_chunk):
logging.warn('\tOld copyright message detected and replaced in {}'.format(entry))
add_copyright_header(filepath, year_modified)
elif '(c)' in first_chunk or '(C)' in first_chunk:
logging.warn('\tAnother copyright header appears to be in {}'.format(entry))
else:
logging.info('\tAdding header to {}'.format(entry))
add_copyright_header(filepath, current_year)
else:
# Found an existing copyright header. Update the
# year if needed, otherwise, leave it alone.
last_year = int(match.group(2))
if year_modified > last_year:
logging.info('\tUpdating year in {}'.format(entry))
text, _ = update_year(text, year_modified, COPYRIGHT_REGEX, match)
with open(filepath, 'w') as wfh:
wfh.write(text)
else:
logging.info('\t{}: OK'.format(entry))
================================================
FILE: doc/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
SPHINXAPI = sphinx-apidoc
SPHINXAPIOPTS =
WAEXT = ./build_plugin_docs.py
WAEXTOPTS = source/plugins ../wa ../wa/tests ../wa/framework
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run documentation coverage checks"
clean:
rm -rf $(BUILDDIR)/*
rm -rf source/plugins/*
rm -rf source/developer_guide/instrument_method_map.rst
rm -rf source/run_config/*
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo
@echo "Build finished. The coverage reports are in $(BUILDDIR)/coverage."
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/WorkloadAutomation2.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/WorkloadAutomation2.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/WorkloadAutomation2"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/WorkloadAutomation2"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
================================================
FILE: doc/build_instrument_method_map.py
================================================
#!/usr/bin/env python
# Copyright 2015-2019 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import sys
import string
from copy import copy
from wa.framework.instrument import SIGNAL_MAP
from wa.framework.signal import CallbackPriority
from wa.utils.doc import format_simple_table
OUTPUT_TEMPLATE_FILE = os.path.join(os.path.dirname(__file__), 'source', 'instrument_method_map.template')
def generate_instrument_method_map(outfile):
signal_table = format_simple_table([(k, v) for k, v in SIGNAL_MAP.items()],
headers=['method name', 'signal'], align='<<')
decorator_names = map(lambda x: x.replace('high', 'fast').replace('low', 'slow'), CallbackPriority.names)
priority_table = format_simple_table(zip(decorator_names, CallbackPriority.names, CallbackPriority.values),
headers=['decorator', 'CallbackPriority name', 'CallbackPriority value'], align='<>')
with open(OUTPUT_TEMPLATE_FILE) as fh:
template = string.Template(fh.read())
with open(outfile, 'w') as wfh:
wfh.write(template.substitute(signal_names=signal_table, priority_prefixes=priority_table))
if __name__ == '__main__':
generate_instrument_method_map(sys.argv[1])
================================================
FILE: doc/build_plugin_docs.py
================================================
#!/usr/bin/env python
# Copyright 2014-2019 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import sys
from wa import pluginloader
from wa.framework.configuration.core import RunConfiguration, MetaConfiguration
from wa.framework.target.descriptor import list_target_descriptions
from wa.utils.doc import (strip_inlined_text, get_rst_from_plugin,
get_params_rst, underline, line_break)
from wa.utils.misc import capitalize
GENERATE_FOR_PACKAGES = [
'wa.workloads',
'wa.instruments',
'wa.output_processors',
]
def insert_contents_table(title='', depth=1):
"""
Insert a sphinx directive to insert a contents page with
a configurable title and depth.
"""
text = '''\n
.. contents:: {}
:depth: {}
:local:\n
'''.format(title, depth)
return text
def generate_plugin_documentation(source_dir, outdir, ignore_paths):
# pylint: disable=unused-argument
pluginloader.clear()
pluginloader.update(packages=GENERATE_FOR_PACKAGES)
if not os.path.exists(outdir):
os.mkdir(outdir)
for ext_type in pluginloader.kinds:
outfile = os.path.join(outdir, '{}s.rst'.format(ext_type))
with open(outfile, 'w') as wfh:
wfh.write('.. _{}s:\n\n'.format(ext_type.replace('_', '-')))
title = ' '.join([capitalize(w) for w in ext_type.split('_')])
wfh.write(underline('{}s'.format(title)))
wfh.write(insert_contents_table())
wfh.write(line_break())
exts = pluginloader.list_plugins(ext_type)
sorted_exts = iter(sorted(exts, key=lambda x: x.name))
try:
wfh.write(get_rst_from_plugin(next(sorted_exts)))
except StopIteration:
return
for ext in sorted_exts:
wfh.write(line_break())
wfh.write(get_rst_from_plugin(ext))
def generate_target_documentation(outdir):
targets_to_generate = ['generic_android',
'generic_linux',
'generic_chromeos',
'generic_local',
'juno_linux',
'juno_android']
intro = (
'\nThis is a list of commonly used targets and their device '
'parameters, to see a complete for a complete reference please use the'
' WA :ref:`list command <list-command>`.\n\n\n'
)
pluginloader.clear()
pluginloader.update(packages=['wa.framework.target.descriptor'])
target_descriptors = list_target_descriptions(pluginloader)
outfile = os.path.join(outdir, 'targets.rst')
with open(outfile, 'w') as wfh:
wfh.write(underline('Common Targets'))
wfh.write(intro)
for td in sorted(target_descriptors, key=lambda t: t.name):
if td.name not in targets_to_generate:
continue
text = underline(td.name, '~')
if hasattr(td, 'description'):
desc = strip_inlined_text(td.description or '')
text += desc
text += underline('Device Parameters:', '-')
text += get_params_rst(td.conn_params)
text += get_params_rst(td.platform_params)
text += get_params_rst(td.target_params)
text += get_params_rst(td.assistant_params)
wfh.write(text)
def generate_run_config_documentation(outdir):
generate_config_documentation(RunConfiguration, outdir)
def generate_meta_config_documentation(outdir):
generate_config_documentation(MetaConfiguration, outdir)
def generate_config_documentation(config, outdir):
if not os.path.exists(outdir):
os.mkdir(outdir)
config_name = '_'.join(config.name.split())
outfile = os.path.join(outdir, '{}.rst'.format(config_name))
with open(outfile, 'w') as wfh:
wfh.write(get_params_rst(config.config_points))
if __name__ == '__main__':
generate_plugin_documentation(sys.argv[2], sys.argv[1], sys.argv[3:])
================================================
FILE: doc/make.bat
================================================
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 2> nul
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\devlib.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\devlib.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end
================================================
FILE: doc/requirements.txt
================================================
nose
numpy
pandas
sphinx_rtd_theme==1.0.0
sphinx==4.2
docutils<0.18
devlib @ git+https://github.com/ARM-software/devlib@master
================================================
FILE: doc/source/api/output.rst
================================================
.. _output_processing_api:
Output
======
A WA output directory can be accessed via a :class:`RunOutput` object. There are
two ways of getting one -- either instantiate it with a path to a WA output
directory, or use :func:`discover_wa_outputs` to traverse a directory tree
iterating over all WA output directories found.
.. function:: discover_wa_outputs(path)
Recursively traverse ``path`` looking for WA output directories. Return
an iterator over :class:`RunOutput` objects for each discovered output.
:param path: The directory to scan for WA output
.. class:: RunOutput(path)
The main interface into a WA output directory.
:param path: must be the path to the top-level output directory (the one
containing ``__meta`` subdirectory and ``run.log``).
WA output stored in a Postgres database by the ``Postgres`` output processor
can be accessed via a :class:`RunDatabaseOutput` which can be initialized as follows:
.. class:: RunDatabaseOutput(password, host='localhost', user='postgres', port='5432', dbname='wa', run_uuid=None, list_runs=False)
The main interface into Postgres database containing WA results.
:param password: The password used to authenticate with
:param host: The database host address. Defaults to ``'localhost'``
:param user: The user name used to authenticate with. Defaults to ``'postgres'``
:param port: The database connection port number. Defaults to ``'5432'``
:param dbname: The database name. Defaults to ``'wa'``
:param run_uuid: The ``run_uuid`` to identify the selected run
:param list_runs: Will connect to the database and will print out the available runs
with their corresponding run_uuids. Defaults to ``False``
Example
-------
.. seealso:: :ref:`processing_output`
To demonstrate how we can use the output API if we have an existing WA output
called ``wa_output`` in the current working directory we can initialize a
``RunOutput`` as follows:
.. code-block:: python
In [1]: from wa import RunOutput
...:
...: output_directory = 'wa_output'
...: run_output = RunOutput(output_directory)
Alternatively if the results have been stored in a Postgres database we can
initialize a ``RunDatabaseOutput`` as follows:
.. code-block:: python
In [1]: from wa import RunDatabaseOutput
...:
...: db_settings = {
...: host: 'localhost',
...: port: '5432',
...: dbname: 'wa'
...: user: 'postgres',
...: password: 'wa'
...: }
...:
...: RunDatabaseOutput(list_runs=True, **db_settings)
Available runs are:
========= ============ ============= =================== =================== ====================================
Run Name Project Project Stage Start Time End Time run_uuid
========= ============ ============= =================== =================== ====================================
Test Run my_project None 2018-11-29 14:53:08 2018-11-29 14:53:24 aa3077eb-241a-41d3-9610-245fd4e552a9
run_1 my_project None 2018-11-29 14:53:34 2018-11-29 14:53:37 4c2885c9-2f4a-49a1-bbc5-b010f8d6b12a
========= ============ ============= =================== =================== ====================================
In [2]: run_uuid = '4c2885c9-2f4a-49a1-bbc5-b010f8d6b12a'
...: run_output = RunDatabaseOutput(run_uuid=run_uuid, **db_settings)
From here we can retrieve various information about the run. For example if we
want to see what the overall status of the run was, along with the runtime
parameters and the metrics recorded from the first job was we can do the following:
.. code-block:: python
In [2]: run_output.status
Out[2]: OK(7)
# List all of the jobs for the run
In [3]: run_output.jobs
Out[3]:
[<wa.framework.output.JobOutput at 0x7f70358a1f10>,
<wa.framework.output.JobOutput at 0x7f70358a1150>,
<wa.framework.output.JobOutput at 0x7f7035862810>,
<wa.framework.output.JobOutput at 0x7f7035875090>]
# Examine the first job that was ran
In [4]: job_1 = run_output.jobs[0]
In [5]: job_1.label
Out[5]: u'dhrystone'
# Print out all the runtime parameters and their values for this job
In [6]: for k, v in job_1.spec.runtime_parameters.items():
...: print (k, v)
(u'airplane_mode': False)
(u'brightness': 100)
(u'governor': 'userspace')
(u'big_frequency': 1700000)
(u'little_frequency': 1400000)
# Print out all the metrics available for this job
In [7]: job_1.metrics
Out[7]:
[<thread 0 score: 14423105 (+)>,
<thread 0 DMIPS: 8209 (+)>,
<thread 1 score: 14423105 (+)>,
<thread 1 DMIPS: 8209 (+)>,
<thread 2 score: 14423105 (+)>,
<thread 2 DMIPS: 8209 (+)>,
<thread 3 score: 18292638 (+)>,
<thread 3 DMIPS: 10411 (+)>,
<thread 4 score: 17045532 (+)>,
<thread 4 DMIPS: 9701 (+)>,
<thread 5 score: 14150917 (+)>,
<thread 5 DMIPS: 8054 (+)>,
<time: 0.184497 seconds (-)>,
<total DMIPS: 52793 (+)>,
<total score: 92758402 (+)>]
# Load the run results csv file into pandas
In [7]: pd.read_csv(run_output.get_artifact_path('run_result_csv'))
Out[7]:
id workload iteration metric value units
0 450000-wk1 dhrystone 1 thread 0 score 1.442310e+07 NaN
1 450000-wk1 dhrystone 1 thread 0 DMIPS 8.209700e+04 NaN
2 450000-wk1 dhrystone 1 thread 1 score 1.442310e+07 NaN
3 450000-wk1 dhrystone 1 thread 1 DMIPS 8.720900e+04 NaN
...
We can also retrieve information about the target that the run was performed on
for example:
.. code-block:: python
# Print out the target's abi:
In [9]: run_output.target_info.abi
Out[9]: u'arm64'
# The os the target was running
In [9]: run_output.target_info.os
Out[9]: u'android'
# And other information about the os version
In [10]: run_output.target_info.os_version
Out[10]:
OrderedDict([(u'all_codenames', u'REL'),
(u'incremental', u'3687331'),
(u'preview_sdk', u'0'),
(u'base_os', u''),
(u'release', u'7.1.1'),
(u'codename', u'REL'),
(u'security_patch', u'2017-03-05'),
(u'sdk', u'25')])
:class:`RunOutput`
------------------
:class:`RunOutput` provides access to the output of a WA :term:`run`, including metrics,
artifacts, metadata, and configuration. It has the following attributes:
``jobs``
A list of :class:`JobOutput` objects for each job that was executed during
the run.
``status``
Run status. This indicates whether the run has completed without problems
(``Status.OK``) or if there were issues.
``metrics``
A list of :class:`Metric`\ s for the run.
.. note:: these are *overall run* metrics only. Metrics for individual
jobs are contained within the corresponding :class:`JobOutput`\ s.
``artifacts``
A list of :class:`Artifact`\ s for the run. These are usually backed by a
file and can contain traces, raw data, logs, etc.
.. note:: these are *overall run* artifacts only. Artifacts for individual
jobs are contained within the corresponding :class:`JobOutput`\ s.
``info``
A :ref:`RunInfo <run-info-api>` object that contains information about the run
itself for example it's duration, name, uuid etc.
``target_info``
A :ref:`TargetInfo <target-info-api>` object which can be used to access
various information about the target that was used during the run for example
it's ``abi``, ``hostname``, ``os`` etc.
``run_config``
A :ref:`RunConfiguration <run-configuration>` object that can be used to
access all the configuration of the run itself, for example the
``reboot_policy``, ``execution_order``, ``device_config`` etc.
``classifiers``
:ref:`classifiers <classifiers>` defined for the entire run.
``metadata``
:ref:`metadata <metadata>` associated with the run.
``events``
A list of any events logged during the run, that are not associated with a
particular job.
``event_summary``
A condensed summary of any events that occurred during the run.
``augmentations``
A list of the :term:`augmentation`\ s that were enabled during the run (these
augmentations may or may not have been active for a particular job).
``basepath``
A (relative) path to the WA output directory backing this object.
methods
~~~~~~~
.. method:: RunOutput.get_artifact(name)
Return the :class:`Artifact` specified by ``name``. This will only look
at the run artifacts; this will not search the artifacts of the individual
jobs.
:param name: The name of the artifact who's path to retrieve.
:return: The :class:`Artifact` with that name
:raises HostError: If the artifact with the specified name does not exist.
.. method:: RunOutput.get_artifact_path(name)
Return the path to the file backing the artifact specified by ``name``. This
will only look at the run artifacts; this will not search the artifacts of
the individual jobs.
:param name: The name of the artifact who's path to retrieve.
:return: The path to the artifact
:raises HostError: If the artifact with the specified name does not exist.
.. method:: RunOutput.get_metric(name)
Return the :class:`Metric` associated with the run (not the individual jobs)
with the specified `name`.
:return: The :class:`Metric` object for the metric with the specified name.
.. method:: RunOutput.get_job_spec(spec_id)
Return the :class:`JobSpec` with the specified `spec_id`. A :term:`spec`
describes the job to be executed. Each :class:`Job` has an associated
:class:`JobSpec`, though a single :term:`spec` can be associated with
multiple :term:`job`\ s (If the :term:`spec` specifies multiple iterations).
.. method:: RunOutput.list_workloads()
List unique workload labels that featured in this run. The labels will be
in the order in which they first ran.
:return: A list of `str` labels of workloads that were part of this run.
.. method:: RunOutput.add_classifier(name, value, overwrite=False)
Add a classifier to the run as a whole. If a classifier with the specified
``name`` already exists, a``ValueError`` will be raised, unless
`overwrite=True` is specified.
:class:`RunDatabaseOutput`
---------------------------
:class:`RunDatabaseOutput` provides access to the output of a WA :term:`run`,
including metrics,artifacts, metadata, and configuration stored in a postgres database.
The majority of attributes and methods are the same :class:`RunOutput` however the
noticeable differences are:
``jobs``
A list of :class:`JobDatabaseOutput` objects for each job that was executed
during the run.
``basepath``
A representation of the current database and host information backing this object.
methods
~~~~~~~
.. method:: RunDatabaseOutput.get_artifact(name)
Return the :class:`Artifact` specified by ``name``. This will only look
at the run artifacts; this will not search the artifacts of the individual
jobs. The `path` attribute of the :class:`Artifact` will be set to the Database OID of the object.
:param name: The name of the artifact who's path to retrieve.
:return: The :class:`Artifact` with that name
:raises HostError: If the artifact with the specified name does not exist.
.. method:: RunDatabaseOutput.get_artifact_path(name)
If the artifcat is a file this method returns a `StringIO` object containing
the contents of the artifact specified by ``name``. If the aritifcat is a
directory, the method returns a path to a locally extracted version of the
directory which is left to the user to remove after use. This will only look
at the run artifacts; this will not search the artifacts of the individual
jobs.
:param name: The name of the artifact who's path to retrieve.
:return: A `StringIO` object with the contents of the artifact
:raises HostError: If the artifact with the specified name does not exist.
:class:`JobOutput`
------------------
:class:`JobOutput` provides access to the output of a single :term:`job`
executed during a WA :term:`run`, including metrics,
artifacts, metadata, and configuration. It has the following attributes:
``status``
Job status. This indicates whether the job has completed without problems
(``Status.OK``) or if there were issues.
.. note:: Under typical configuration, WA will make a number of attempts to
re-run a job in case of issue. This status (and the rest of the
output) will represent the the latest attempt. I.e. a
``Status.OK`` indicates that the latest attempt was successful,
but it does mean that there weren't prior failures. You can check
the ``retry`` attribute (see below) to whether this was the first
attempt or not.
``retry``
Retry number for this job. If a problem is detected during job execution, the
job will be re-run up to :confval:`max_retries` times. This indicates the
final retry number for the output. A value of ``0`` indicates that the job
succeeded on the first attempt, and no retries were necessary.
.. note:: Outputs for previous attempts are moved into ``__failed``
subdirectory of WA output. These are currently not exposed via the
API.
``id``
The ID of the :term:`spec` associated with with job. This ID is unique to
the spec, but not necessary to the job -- jobs representing multiple
iterations of the same spec will share the ID.
``iteration``
The iteration number of this job. Together with the ``id`` (above), this
uniquely identifies a job with a run.
``label``
The workload label associated with this job. Usually, this will be the name
or :term:`alias` of the workload, however maybe overwritten by the user in
the :term:`agenda`.
``metrics``
A list of :class:`Metric`\ s for the job.
``artifacts``
A list of :class:`Artifact`\ s for the job These are usually backed by a
file and can contain traces, raw data, logs, etc.
``classifiers``
:ref:`classifiers <classifiers>` defined for the job.
``metadata``
:ref:`metadata <metadata>` associated with the job.
``events``
A list of any events logged during the execution of the job.
``event_summary``
A condensed summary of any events that occurred during the execution of the
job.
``augmentations``
A list of the :term:`augmentation`\ s that were enabled for this job. This may
be different from overall augmentations specified for the run, as they may be
enabled/disabled on per-job basis.
``basepath``
A (relative) path to the WA output directory backing this object.
methods
~~~~~~~
.. method:: JobOutput.get_artifact(name)
Return the :class:`Artifact` specified by ``name`` associated with this job.
:param name: The name of the artifact to retrieve.
:return: The :class:`Artifact` with that name
:raises HostError: If the artifact with the specified name does not exist.
.. method:: JobOutput.get_artifact_path(name)
Return the path to the file backing the artifact specified by ``name``,
associated with this job.
:param name: The name of the artifact who's path to retrieve.
:return: The path to the artifact
:raises HostError: If the artifact with the specified name does not exist.
.. method:: JobOutput.get_metric(name)
Return the :class:`Metric` associated with this job with the specified
`name`.
:return: The :class:`Metric` object for the metric with the specified name.
.. method:: JobOutput.add_classifier(name, value, overwrite=False)
Add a classifier to the job. The classifier will be propagated to all
existing artifacts and metrics, as well as those added afterwards. If a
classifier with the specified ``name`` already exists, a ``ValueError`` will
be raised, unless `overwrite=True` is specified.
:class:`JobDatabaseOutput`
---------------------------
:class:`JobOutput` provides access to the output of a single :term:`job`
executed during a WA :term:`run`, including metrics, artifacts, metadata, and
configuration stored in a postgres database.
The majority of attributes and methods are the same :class:`JobOutput` however the
noticeable differences are:
``basepath``
A representation of the current database and host information backing this object.
methods
~~~~~~~
.. method:: JobDatabaseOutput.get_artifact(name)
Return the :class:`Artifact` specified by ``name`` associated with this job.
The `path` attribute of the :class:`Artifact` will be set to the Database
OID of the object.
:param name: The name of the artifact to retrieve.
:return: The :class:`Artifact` with that name
:raises HostError: If the artifact with the specified name does not exist.
.. method:: JobDatabaseOutput.get_artifact_path(name)
If the artifcat is a file this method returns a `StringIO` object containing
the contents of the artifact specified by ``name`` associated with this job.
If the aritifcat is a directory, the method returns a path to a locally
extracted version of the directory which is left to the user to remove after
use.
:param name: The name of the artifact who's path to retrieve.
:return: A `StringIO` object with the contents of the artifact
:raises HostError: If the artifact with the specified name does not exist.
:class:`Metric`
---------------
A metric represent a single numerical measurement/score collected as a result of
running the workload. It would be generated either by the workload or by one of
the augmentations active during the execution of the workload.
A :class:`Metric` has the following attributes:
``name``
The name of the metric.
.. note:: A name of the metric is not necessarily unique, even for the same
job. Some workloads internally run multiple sub-tests, each
generating a metric with the same name. In such cases,
:term:`classifier`\ s are used to distinguish between them.
``value``
The value of the metrics collected.
``units``
The units of the metrics. This maybe ``None`` if the metric has no units.
``lower_is_better``
The default assumption is that higher metric values are better. This may be
overridden by setting this to ``True``, e.g. if metrics such as "run time"
or "latency". WA does not use this internally (at the moment) but this may
be used by external parties to sensibly process WA results in a generic way.
``classifiers``
These can be user-defined :term:`classifier`\ s propagated from the job/run,
or they may have been added by the workload to help distinguish between
otherwise identical metrics.
``label``
This is a string constructed from the name and classifiers, to provide a
more unique identifier, e.g. for grouping values across iterations. The
format is in the form ``name/cassifier1=value1/classifier2=value2/...``.
:class:`Artifact`
-----------------
An artifact is a file that is created on the host as part of executing a
workload. This could be trace, logging, raw output, or pretty much anything
else. Pretty much every file under WA output directory that is not already
represented by some other framework object will have an :class:`Artifact`
associated with it.
An :class:`Artifact` has the following attributes:
``name``
The name of this artifact. This will be unique for the job/run (unlike
metric names). This is intended as a consistent "handle" for this artifact.
The actual file name for the artifact may vary from job to job (e.g. some
benchmarks that create files with results include timestamps in the file
names), however the name will always be the same.
``path``
Partial path to the file associated with this artifact. Often, this is just
the file name. To get the complete path that maybe used to access the file,
use :func:`get_artifact_path` of the corresponding output object.
``kind``
Describes the nature of this artifact to facilitate generic processing.
Possible kinds are:
:log: A log file. Not part of the "output" as such but contains
information about the run/workload execution that be useful for
diagnostics/meta analysis.
:meta: A file containing metadata. This is not part of the "output", but
contains information that may be necessary to reproduce the
results (contrast with ``log`` artifacts which are *not*
necessary).
:data: This file contains new data, not available otherwise and should
be considered part of the "output" generated by WA. Most traces
would fall into this category.
:export: Exported version of results or some other artifact. This
signifies that this artifact does not contain any new data
that is not available elsewhere and that it may be safely
discarded without losing information.
:raw: Signifies that this is a raw dump/log that is normally processed
to extract useful information and is then discarded. In a sense,
it is the opposite of ``export``, but in general may also be
discarded.
.. note:: Whether a file is marked as ``log``/``data`` or ``raw``
depends on how important it is to preserve this file,
e.g. when archiving, vs how much space it takes up.
Unlike ``export`` artifacts which are (almost) always
ignored by other exporters as that would never result
in data loss, ``raw`` files *may* be processed by
exporters if they decided that the risk of losing
potentially (though unlikely) useful data is greater
than the time/space cost of handling the artifact (e.g.
a database uploader may choose to ignore ``raw``
artifacts, where as a network filer archiver may choose
to archive them).
.. note:: The kind parameter is intended to represent the logical
function of a particular artifact, not it's intended means of
processing -- this is left entirely up to the output
processors.
``description``
This may be used by the artifact's creator to provide additional free-form
information about the artifact. In practice, this is often ``None``
``classifiers``
Job- and run-level :term:`classifier`\ s will be propagated to the artifact.
Additional run info
-------------------
:class:`RunOutput` object has ``target_info`` and ``run_info`` attributes that
contain structures that provide additional information about the run and device.
.. _target-info-api:
:class:`TargetInfo`
~~~~~~~~~~~~~~~~~~~
The :class:`TargetInfo` class presents various pieces of information about the
target device. An instance of this class will be instantiated and populated
automatically from the devlib `target
<http://devlib.readthedocs.io/en/latest/target.html>`_ created during a WA run
and serialized to a json file as part of the metadata exported
by WA at the end of a run.
The available attributes of the class are as follows:
``target``
The name of the target class that was uised ot interact with the device
during the run E.g. ``"AndroidTarget"``, ``"LinuxTarget"`` etc.
``modules``
A list of names of modules that have been loaded by the target. Modules
provide additional functionality, such as access to ``cpufreq`` and which
modules are installed may impact how much of the ``TargetInfo`` has been
populated.
``cpus``
A list of :class:`CpuInfo` objects describing the capabilities of each CPU.
``os``
A generic name of the OS the target was running (e.g. ``"android"``).
``os_version``
A dict that contains a mapping of OS version elements to their values. This
mapping is OS-specific.
``abi``
The ABI of the target device.
``hostname``
The hostname of the the device the run was executed on.
``is_rooted``
A boolean value specifying whether root was detected on the device.
``kernel_version``
The version of the kernel on the target device. This returns a
:class:`KernelVersion` instance that has separate version and release
fields.
``kernel_config``
A :class:`KernelConfig` instance that contains parsed kernel config from the
target device. This may be ``None`` if the kernel config could not be
extracted.
``sched_features``
A list of the available tweaks to the scheduler, if available from the
device.
``hostid``
The unique identifier of the particular device the WA run was executed on.
.. _run-info-api:
:class:`RunInfo`
~~~~~~~~~~~~~~~~
The :class:`RunInfo` provides general run information. It has the following
attributes:
``uuid``
A unique identifier for that particular run.
``run_name``
The name of the run (if provided)
``project``
The name of the project the run belongs to (if provided)
``project_stage``
The project stage the run is associated with (if provided)
``duration``
The length of time the run took to complete.
``start_time``
The time the run was stared.
``end_time``
The time at which the run finished.
================================================
FILE: doc/source/api/workload.rst
================================================
.. _workloads-api:
Workloads
~~~~~~~~~
.. _workload-api:
Workload
^^^^^^^^
The base :class:`Workload` interface is as follows, and is the base class for
all :ref:`workload types <workload-types>`. For more information about to
implement your own workload please see the
:ref:`Developer How Tos <adding-a-workload-example>`.
All instances of a workload will have the following attributes:
``name``
This identifies the workload (e.g. it is used to specify the
workload in the :ref:`agenda <agenda>`).
``phones_home``
This can be set to True to mark that this workload poses a risk of
exposing information to the outside world about the device it runs on.
For example a benchmark application that sends scores and device data
to a database owned by the maintainer.
``requires_network``
Set this to ``True`` to mark the the workload will fail without a network
connection, this enables it to fail early with a clear message.
``asset_directory``
Set this to specify a custom directory for assets to be pushed to, if
unset the working directory will be used.
``asset_files``
This can be used to automatically deploy additional assets to
the device. If required the attribute should contain a list of file
names that are required by the workload which will be attempted to be
found by the resource getters
methods
"""""""
.. method:: Workload.init_resources(context)
This method may be optionally overridden to implement dynamic
resource discovery for the workload. This method executes
early on, before the device has been initialized, so it
should only be used to initialize resources that do not
depend on the device to resolve. This method is executed
once per run for each workload instance.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.validate(context)
This method can be used to validate any assumptions your workload
makes about the environment (e.g. that required files are
present, environment variables are set, etc) and should raise a
:class:`wa.WorkloadError <wa.framework.exception.WorkloadError>`
if that is not the case. The base class implementation only makes
sure sure that the name attribute has been set.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.initialize(context)
This method is decorated with the ``@once_per_instance`` decorator,
(for more information please see
:ref:`Execution Decorators <execution-decorators>`)
therefore it will be executed exactly once per run (no matter
how many instances of the workload there are). It will run
after the device has been initialized, so it may be used to
perform device-dependent initialization that does not need to
be repeated on each iteration (e.g. as installing executables
required by the workload on the device).
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.setup(context)
Everything that needs to be in place for workload execution should
be done in this method. This includes copying files to the device,
starting up an application, configuring communications channels,
etc.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.setup_rerun(context)
Everything that needs to be in place for workload execution should
be done in this method. This includes copying files to the device,
starting up an application, configuring communications channels,
etc.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.run(context)
This method should perform the actual task that is being measured.
When this method exits, the task is assumed to be complete.
:param context: The :ref:`Context <context>` for the current run.
.. note:: Instruments are kicked off just before calling this
method and disabled right after, so everything in this
method is being measured. Therefore this method should
contain the least code possible to perform the operations
you are interested in measuring. Specifically, things like
installing or starting applications, processing results, or
copying files to/from the device should be done elsewhere if
possible.
.. method:: Workload.extract_results(context)
This method gets invoked after the task execution has finished and
should be used to extract metrics from the target.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.update_output(context)
This method should be used to update the output within the specified
execution context with the metrics and artifacts from this
workload iteration.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.teardown(context)
This could be used to perform any cleanup you may wish to do, e.g.
Uninstalling applications, deleting file on the device, etc.
:param context: The :ref:`Context <context>` for the current run.
.. method:: Workload.finalize(context)
This is the complement to ``initialize``. This will be executed
exactly once at the end of the run. This should be used to
perform any final clean up (e.g. uninstalling binaries installed
in the ``initialize``)
:param context: The :ref:`Context <context>` for the current run.
.. _apkworkload-api:
ApkWorkload
^^^^^^^^^^^^
The :class:`ApkWorkload` derives from the base :class:`Workload` class however
this associates the workload with a package allowing for an apk to be found for
the workload, setup and ran on the device before running the workload.
In addition to the attributes mentioned above ApkWorloads this class also
features the following attributes however this class does not present any new
methods.
``loading_time``
This is the time in seconds that WA will wait for the application to load
before continuing with the run. By default this will wait 10 second however
if your application under test requires additional time this values should
be increased.
``package_names``
This attribute should be a list of Apk packages names that are
suitable for this workload. Both the host (in the relevant resource
locations) and device will be searched for an application with a matching
package name.
``supported_versions``
This attribute should be a list of apk versions that are suitable for this
workload, if a specific apk version is not specified then any available
supported version may be chosen.
``activity``
This attribute can be optionally set to override the default activity that
will be extracted from the selected APK file which will be used when
launching the APK.
``view``
This is the "view" associated with the application. This is used by
instruments like ``fps`` to monitor the current framerate being generated by
the application.
``apk``
The is a :class:`PackageHandler`` which is what is used to store
information about the apk and manage the application itself, the handler is
used to call the associated methods to manipulate the application itself for
example to launch/close it etc.
``package``
This is a more convenient way to access the package name of the Apk
that was found and being used for the run.
.. _apkuiautoworkload-api:
ApkUiautoWorkload
^^^^^^^^^^^^^^^^^
The :class:`ApkUiautoWorkload` derives from :class:`ApkUIWorkload` which is an
intermediate class which in turn inherits from
:class:`ApkWorkload`, however in addition to associating an apk with the
workload this class allows for automating the application with UiAutomator.
This class define these additional attributes:
``gui``
This attribute will be an instance of a :class:`UiAutmatorGUI` which is
used to control the automation, and is what is used to pass parameters to the
java class for example ``gui.uiauto_params``.
.. _apkreventworkload-api:
ApkReventWorkload
^^^^^^^^^^^^^^^^^
The :class:`ApkReventWorkload` derives from :class:`ApkUIWorkload` which is an
intermediate class which in turn inherits from
:class:`ApkWorkload`, however in addition to associating an apk with the
workload this class allows for automating the application with
:ref:`Revent <revent_files_creation>`.
This class define these additional attributes:
``gui``
This attribute will be an instance of a :class:`ReventGUI` which is
used to control the automation
``setup_timeout``
This is the time allowed for replaying a recording for the setup stage.
``run_timeout``
This is the time allowed for replaying a recording for the run stage.
``extract_results_timeout``
This is the time allowed for replaying a recording for the extract results stage.
``teardown_timeout``
This is the time allowed for replaying a recording for the teardown stage.
.. _uiautoworkload-api:
UiautoWorkload
^^^^^^^^^^^^^^
The :class:`UiautoWorkload` derives from :class:`UIWorkload` which is an
intermediate class which in turn inherits from
:class:`Workload`, however this allows for providing generic automation using
UiAutomator without associating a particular application with the workload.
This class define these additional attributes:
``gui``
This attribute will be an instance of a :class:`UiAutmatorGUI` which is
used to control the automation, and is what is used to pass parameters to the
java class for example ``gui.uiauto_params``.
.. _reventworkload-api:
ReventWorkload
^^^^^^^^^^^^^^
The :class:`ReventWorkload` derives from :class:`UIWorkload` which is an
intermediate class which in turn inherits from
:class:`Workload`, however this allows for providing generic automation
using :ref:`Revent <revent_files_creation>` without associating with the
workload.
This class define these additional attributes:
``gui``
This attribute will be an instance of a :class:`ReventGUI` which is
used to control the automation
``setup_timeout``
This is the time allowed for replaying a recording for the setup stage.
``run_timeout``
This is the time allowed for replaying a recording for the run stage.
``extract_results_timeout``
This is the time allowed for replaying a recording for the extract results stage.
``teardown_timeout``
This is the time allowed for replaying a recording for the teardown stage.
================================================
FILE: doc/source/api.rst
================================================
Workload Automation API
=======================
.. toctree::
:maxdepth: 2
api/output
api/workload
================================================
FILE: doc/source/changes.rst
================================================
=================================
What's New in Workload Automation
=================================
***********
Version 3.3.1
***********
.. warning:: This is the last release supporting Python 3.5 and Python 3.6.
Subsequent releases will support Python 3.7+.
New Features:
==============
Commands:
---------
Instruments:
------------
- ``perf``: Add support for ``report-sample``.
Workloads:
----------------
- ``PCMark``: Add support for PCMark 3.0.
- ``Antutu``: Add support for 9.1.6.
- ``Geekbench``: Add support for Geekbench5.
- ``gfxbench``: Support the non corporate version.
Fixes/Improvements
==================
Framework:
----------
- Fix installation on systems without git installed.
- Avoid querying online cpus if hotplug is disabled.
Dockerfile:
-----------
- Update base image to Ubuntu 20.04.
Instruments:
------------
- ``perf``: Fix parsing csv with using interval-only-values.
- ``perf``: Improve error reporting of an invalid agenda.
Output Processors:
------------------
- ``postgres``: Fixed SQL command when creating a new event.
Workloads:
----------
- ``speedometer``: Fix adb reverse when rebooting a device.
- ``googleplaybook``: Support newer apk version.
- ``googlephotos``: Support newer apk version.
- ``gmail``: Support newer apk version.
Other:
------
- Upgrade Android Gradle to 7.2 and Gradle plugin to 4.2.
***********
Version 3.3
***********
New Features:
==============
Commands:
---------
- Add ``report`` command to provide a summary of a run.
Instruments:
------------
- Add ``proc_stat`` instrument to monitor CPU load using data from ``/proc/stat``.
Framework:
----------
- Add support for simulating atomic writes to prevent race conditions when running current instances of WA.
- Add support file transfer for SSH connections via SFTP and falling back to using SCP implementation.
- Support detection of logcat buffer overflow and present a warning if this occurs.
- Allow skipping all remaining jobs if a job had exhausted all of its retires.
- Add polling mechanism for file transfers rather than relying on timeouts.
- Add `run_completed` reboot policy to enable rebooting a target after a run has been completed.
Android Devices:
----------------
- Enable configuration of whether to keep the screen on while the device is plugged in.
Output Processors:
------------------
- Enable the use of cascading deletion in Postgres databases to clean up after deletion of a run entry.
Fixes/Improvements
==================
Framework:
----------
- Improvements to the ``process`` command to correctly handle skipped and in process jobs.
- Add support for deprecated parameters allowing for a warning to be raised when providing
a parameter that will no longer have an effect.
- Switch implementation of SSH connections to use Paramiko for greater stability.
- By default use sftp for file transfers with SSH connections, allow falling back to scp
by setting ``use_scp``.
- Fix callbacks not being disconnected correctly when requested.
- ``ApkInfo`` objects are now cached to reduce re-parsing of APK files.
- Speed up discovery of wa output directories.
- Fix merge handling of parameters from multiple files.
Dockerfile:
-----------
- Install additional instruments for use in the docker environment.
- Fix environment variables not being defined in non interactive environments.
Instruments:
------------
- ``trace_cmd`` additional fixes for python 3 support.
Output Processors:
------------------
- ``postgres``: Fixed SQL command when creating a new event.
Workloads:
----------
- ``aitutu``: Improve reliability of results extraction.
- ``androbench``: Enabling dismissing of additional popups on some devices.
- ``antutu``: Now supports major version 8 in additional to version 7.X.
- ``exoplayer``: Add support for Android 10.
- ``googlephotos``: Support newer apk version.
- ``gfxbench``: Allow user configuration for which tests should be ran.
- ``gfxbench``: Improved score detection for a wider range of devices.
- ``gfxbench``: Moved results extraction out of run stage.
- ``jankbench``: Support newer versions of Pandas for processing.
- ``pcmark``: Add support for handling additional popups and installation flows.
- ``pcmark``: No longer clear and re-download test data before each execution.
- ``speedometer``: Enable the workload to run offline and drops requirement for
UiAutomator. To support this root access is now required to run the workload.
- ``youtube``: Update to support later versions of the apk.
Other:
------
- ``cpustates``: Improved name handling for unknown idle states.
***********
Version 3.2
***********
.. warning:: This release only supports Python 3.5+. Python 2 support has now
been dropped.
Fixes/Improvements
==================
Framework:
----------
- ``TargetInfo`` now tracks installed modules and will ensure the cache is
also updated on module change.
- Migrated the build scripts for uiauto based workloads to Python 3.
- Uiauto applications now target SDK version 28 to prevent PlayProtect
blocking the installation of the automation apks on some devices.
- The workload metadata now includes the apk package name if applicable.
Instruments:
------------
- ``energy_instruments`` will now have their ``teardown`` method called
correctly.
- ``energy_instruments``: Added a ``keep_raw`` parameter to control whether
raw files generated during execution should be deleted upon teardown.
- Update relevant instruments to make use of the new devlib collector
interface, for more information please see the
`devlib documentation <https://devlib.readthedocs.io/en/latest/collectors.html>`_.
Output Processors:
------------------
- ``postgres``: If initialisation fails then the output processor will no
longer attempt to reconnect at a later point during the run.
- ``postgres``: Will now ensure that the connection to the database is
re-established if it is dropped e.g. due to a long expecting workload.
- ``postgres``: Change the type of the ``hostid`` field to ``Bigint`` to
allow a larger range of ids.
- ``postgres``: Bump schema version to 1.5.
- ``perf``: Added support for the ``simpleperf`` profiling tool for android
devices.
- ``perf``: Added support for the perf ``record`` command.
- ``cpustates``: Improve handling of situations where cpufreq and/or cpuinfo
data is unavailable.
Workloads:
----------
- ``adodereader``: Now support apk version 19.7.1.10709.
- ``antutu``: Supports dismissing of popup asking to create a shortcut on
the homescreen.
- ``gmail``: Now supports apk version 2019.05.26.252424914.
- ``googlemaps``: Now supports apk version 10.19.1.
- ``googlephotos``: Now supports apk version 4.28.0.
- ``geekbench``: Added support for versions 4.3.4, 4.4.0 and 4.4.2.
- ``geekbench-corporate``: Added support for versions 5.0.1 and 5.0.3.
- ``pcmark``: Now locks device orientation to portrait to increase
compatibility.
- ``pcmark``: Supports dismissing new Android 10 permission warnings.
Other:
------
- Improve documentation to help debugging module installation errors.
*************
Version 3.1.4
*************
.. warning:: This is the last release that supports Python 2. Subsequent versions
will be support Python 3.5+ only.
New Features:
==============
Framework:
----------
- ``ApkWorkload``: Allow specifying A maximum and minimum version of an APK
instead of requiring a specific version.
- ``TestPackageHandler``: Added to support running android applications that
are invoked via ``am instrument``.
- Directories can now be added as ``Artifacts``.
Workloads:
----------
- ``aitutu``: Executes the Aitutu Image Speed/Accuracy and Object
Speed/Accuracy tests.
- ``uibench``: Run a configurable activity of the UIBench workload suite.
- ``uibenchjanktests``: Run an automated and instrument version of the
UIBench JankTests.
- ``motionmark``: Run a browser graphical benchmark.
Other:
------
- Added ``requirements.txt`` as a reference for known working package versions.
Fixes/Improvements
==================
Framework:
----------
- ``JobOuput``: Added an ``augmentation`` attribute to allow listing of
enabled augmentations for individual jobs.
- Better error handling for misconfiguration job selection.
- All ``Workload`` classes now have an ``uninstall`` parameter to control whether
any binaries installed to the target should be uninstalled again once the
run has completed.
- The ``cleanup_assets`` parameter is now more consistently utilized across
workloads.
- ``ApkWorkload``: Added an ``activity`` attribute to allow for overriding the
automatically detected version from the APK.
- ``ApkWorkload`` Added support for providing an implicit activity path.
- Fixed retrieving job level artifacts from a database backend.
Output Processors:
------------------
- ``SysfsExtractor``: Ensure that the extracted directories are added as
``Artifacts``.
- ``InterruptStatsInstrument``: Ensure that the output files are added as
``Artifacts``.
- ``Postgres``: Fix missing ``system_id`` field from ``TargetInfo``.
- ``Postgres``: Support uploading directory ``Artifacts``.
- ``Postgres``: Bump the schema version to v1.3.
Workloads:
----------
- ``geekbench``: Improved apk version handling.
- ``geekbench``: Now supports apk version 4.3.2.
Other:
------
- ``Dockerfile``: Now installs all optional extras for use with WA.
- Fixed support for YAML anchors.
- Fixed building of documentation with Python 3.
- Changed shorthand of installing all of WA extras to `all` as per
the documentation.
- Upgraded the Dockerfile to use Ubuntu 18.10 and Python 3.
- Restricted maximum versions of ``numpy`` and ``pandas`` for Python 2.7.
*************
Version 3.1.3
*************
Fixes/Improvements
==================
Other:
------
- Security update for PyYAML to attempt prevention of arbitrary code execution
during parsing.
*************
Version 3.1.2
*************
Fixes/Improvements
==================
Framework:
----------
- Implement an explicit check for Devlib versions to ensure that versions
are kept in sync with each other.
- Added a ``View`` parameter to ApkWorkloads for use with certain instruments
for example ``fps``.
- Added ``"supported_versions"`` attribute to workloads to allow specifying a
list of supported version for a particular workload.
- Change default behaviour to run any available version of a workload if a
specific version is not specified.
Output Processors:
------------------
- ``Postgres``: Fix handling of ``screen_resoultion`` during processing.
Other
-----
- Added additional information to documentation
- Added fix for Devlib's ``KernelConfig`` refactor
- Added a ``"label"`` property to ``Metrics``
*************
Version 3.1.1
*************
Fixes/Improvements
==================
Other
-----
- Improve formatting when displaying metrics
- Update revent binaries to include latest fixes
- Update DockerImage to use new released version of WA and Devlib
- Fix broken package on PyPi
*************
Version 3.1.0
*************
New Features:
==============
Commands
---------
- ``create database``: Added :ref:`create subcommand <create-command>`
command in order to initialize a PostgresSQL database to allow for storing
WA output with the Postgres Output Processor.
Output Processors:
------------------
- ``Postgres``: Added output processor which can be used to populate a
Postgres database with the output generated from a WA run.
- ``logcat-regex``: Add new output processor to extract arbitrary "key"
"value" pairs from logcat.
Configuration:
--------------
- :ref:`Configuration Includes <config-include>`: Add support for including
other YAML files inside agendas and config files using ``"include#:"``
entries.
- :ref:`Section groups <section-groups>`: This allows for a ``group`` entry
to be specified for each section and will automatically cross product the
relevant sections with sections from other groups adding the relevant
classifiers.
Framework:
----------
- Added support for using the :ref:`OutputAPI <output_processing_api>` with a
Postgres Database backend. Used to retrieve and
:ref:`process <processing_output>` run data uploaded by the ``Postgres``
output processor.
Workloads:
----------
- ``gfxbench-corporate``: Execute a set of on and offscreen graphical benchmarks from
GFXBench including Car Chase and Manhattan.
- ``glbench``: Measures the graphics performance of Android devices by
testing the underlying OpenGL (ES) implementation.
Fixes/Improvements
==================
Framework:
----------
- Remove quotes from ``sudo_cmd`` parameter default value due to changes in
devlib.
- Various Python 3 related fixes.
- Ensure plugin names are converted to identifiers internally to act more
consistently when dealing with names containing ``-``'s etc.
- Now correctly updates RunInfo with project and run name information.
- Add versioning support for POD structures with the ability to
automatically update data structures / formats to new versions.
Commands:
---------
- Fix revent target initialization.
- Fix revent argument validation.
Workloads:
----------
- ``Speedometer``: Close open tabs upon workload completion.
- ``jankbench``: Ensure that the logcat monitor thread is terminated
correctly to prevent left over adb processes.
- UiAutomator workloads are now able to dismiss android warning that a
workload has not been designed for the latest version of android.
Other:
------
- Report additional metadata about target, including: system_id,
page_size_kb.
- Uses cache directory to reduce target calls, e.g. will now use cached
version of TargetInfo if local copy is found.
- Update recommended :ref:`installation <github>` commands when installing from
github due to pip not following dependency links correctly.
- Fix incorrect parameter names in runtime parameter documentation.
--------------------------------------------------
*************
Version 3.0.0
*************
WA3 is a more or less from-scratch re-write of WA2. We have attempted to
maintain configuration-level compatibility wherever possible (so WA2 agendas
*should* mostly work with WA3), however some breaks are likely and minor tweaks
may be needed.
It terms of the API, WA3 is completely different, and WA2 extensions **will not
work** with WA3 -- they would need to be ported into WA3 plugins.
For more information on migrating from WA2 to WA3 please see the
:ref:`migration-guide`.
Not all of WA2 extensions have been ported for the initial 3.0.0 release. We
have ported the ones we believe to be most widely used and useful. The porting
work will continue, and more of WA2's extensions will be in the future releases.
However, we do not intend to port absolutely everything, as some things we
believe to be no longer useful.
.. note:: If there a particular WA2 extension you would like to see in WA3 that
is not yet there, please let us know via the GitHub issues. (And, of
course, we always welcome pull requests, if you have the time to
do the port yourselves :-) ).
New Features
============
- Python 3 support. WA now runs on both Python 2 and Python 3.
.. warning:: Python 2 support should now be considered deprecated. Python 2
will still be fully supported up to the next major release
(v3.1). After that, Python 2 will be supported for existing
functionality, however there will be no guarantee that newly
added functionality would be compatible with Python 2. Support
for Python 2 will be dropped completely after release v3.2.
- There is a new Output API which can be used to aid in post processing a
run's output. For more information please see :ref:`output_processing_api`.
- All "augmentations" can now be enabled on a per workload basis (in WA2 this
was available for instruments, but not result processors).
- More portable runtime parameter specification. Runtime parameters now support
generic aliases, so instead of specifying ``a73_frequency: 1805000`` in your
agenda, and then having to modify this for another target, it is now possible
to specify ``big_frequency: max``.
- ``-c`` option can now be used multiple times to specify several config files
for a single run, allowing for a more fine-grained configuration management.
- It is now possible to disable all previously configured augmentations from an
agenda using ``~~``.
- Offline output processing with ``wa process`` command. It is now possible to
run processors on previously collected WA results, without the need for a
target connection.
- A lot more metadata is collected as part of the run, including much more
detailed information about the target, and MD5 hashes of all resources used
during the run.
- Better ``show`` command. ``wa show`` command now utilizes ``pandoc`` and
``man`` to produce easier-to-browse documentation format, and has been
enhanced to include documentation on general settings, runtime parameters, and
plugin aliases.
- Better logging. The default ``stdout`` output is now more informative.
The verbose output is much more detailed. Nested indentation is used for
different phases of execution to make log output easier to parse visually.
- Full ``ChromeOS`` target support. Including support for the Android container
apps.
- Implemented on top of devlib_. WA3 plugins can make use of devlib's enhanced
target API (much richer and more robust than WA2's Device API).
- All-new documentation. The docs have been revamped to be more useful and
complete.
.. _devlib: https://github.com/ARM-software/devlib
Changes
=======
- Configuration files ``config.py`` are now specified in YAML format in
``config.yaml``. WA3 has support for automatic conversion of the default
config file and will be performed upon first invocation of WA3.
- The "config" and "global" sections in an agenda are now interchangeable so can
all be specified in a "config" section.
- "Results Processors" are now known as "Output Processors" and can now be ran
offline.
- "Instrumentation" is now known as "Instruments" for more consistent naming.
- Both "Output Processor" and "Instrument" configuration have been merged into
"Augmentations" (support for the old naming schemes have been retained for
backwards compatibility)
================================================
FILE: doc/source/conf.py
================================================
# -*- coding: utf-8 -*-
# Copyright 2023 ARM Limited
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# WA3 documentation build configuration file.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import shlex
this_dir = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(this_dir, '..'))
sys.path.insert(0, os.path.join(this_dir, '../..'))
import wa
from build_plugin_docs import (generate_plugin_documentation,
generate_run_config_documentation,
generate_meta_config_documentation,
generate_target_documentation)
from build_instrument_method_map import generate_instrument_method_map
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['static/templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'wa'
copyright = u'2023, ARM Limited'
author = u'ARM Limited'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = wa.framework.version.get_wa_version()
# The full version, including alpha/beta/rc tags.
release = wa.framework.version.get_wa_version()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['../build', 'developer_information',
'user_information', 'run_config']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
'logo_only': True
}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'WA-logo-white.svg'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'wadoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'wa.tex', u'wa Documentation',
u'Arm Limited', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'wa', u'wa Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'wa', u'wa Documentation',
author, 'wa', 'A framework for automating workload execution on mobile devices.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
def setup(app):
module_dir = os.path.join('..', '..', 'wa')
excluded_extensions = [os.path.join(module_dir, 'framework'),
os.path.join(module_dir, 'tests')]
os.chdir(os.path.dirname(__file__))
generate_plugin_documentation(module_dir, 'plugins', excluded_extensions)
generate_target_documentation('plugins')
generate_run_config_documentation('run_config')
generate_meta_config_documentation('run_config')
generate_instrument_method_map(os.path.join('developer_information', 'developer_guide',
'instrument_method_map.rst'))
app.add_object_type('confval', 'confval',
objname='configuration value',
indextemplate='pair: %s; configuration value')
================================================
FILE: doc/source/developer_information/developer_guide/writing_plugins.rst
================================================
.. _writing-plugins:
Writing Plugins
================
Workload Automation offers several plugin points (or plugin types). The most
interesting of these are
:workloads: These are the tasks that get executed and measured on the device. These
can be benchmarks, high-level use cases, or pretty much anything else.
:targets: These are interfaces to the physical devices (development boards or end-user
devices, such as smartphones) that use cases run on. Typically each model of a
physical device would require its own interface class (though some functionality
may be reused by subclassing from an existing base).
:instruments: Instruments allow collecting additional data from workload execution (e.g.
system traces). Instruments are not specific to a particular workload. Instruments
can hook into any stage of workload execution.
:output processors: These are used to format the results of workload execution once they have been
collected. Depending on the callback used, these will run either after each
iteration and/or at the end of the run, after all of the results have been
collected.
You can create a plugin by subclassing the appropriate base class, defining
appropriate methods and attributes, and putting the .py file containing the
class into the "plugins" subdirectory under ``~/.workload_automation`` (or
equivalent) where it will be automatically picked up by WA.
Plugin Basics
--------------
This sub-section covers things common to implementing plugins of all types. It
is recommended you familiarize yourself with the information here before
proceeding onto guidance for specific plugin types.
.. _resource-resolution:
Dynamic Resource Resolution
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The idea is to decouple resource identification from resource discovery.
Workloads/instruments/devices/etc state *what* resources they need, and not
*where* to look for them -- this instead is left to the resource resolver that
is part of the execution context. The actual discovery of resources is
performed by resource getters that are registered with the resolver.
A resource type is defined by a subclass of
:class:`wa.framework.resource.Resource`. An instance of this class describes a
resource that is to be obtained. At minimum, a ``Resource`` instance has an
owner (which is typically the object that is looking for the resource), but
specific resource types may define other parameters that describe an instance of
that resource (such as file names, URLs, etc).
An object looking for a resource invokes a resource resolver with an instance of
``Resource`` describing the resource it is after. The resolver goes through the
getters registered for that resource type in priority order attempting to obtain
the resource; once the resource is obtained, it is returned to the calling
object. If none of the registered getters could find the resource,
``NotFoundError`` is raised (or ``None`` is returned instead, if invoked with
``strict=False``).
The most common kind of object looking for resources is a ``Workload``, and the
``Workload`` class defines
:py:meth:`wa.framework.workload.Workload.init_resources` method, which may be
overridden by subclasses to perform resource resolution. For example, a workload
looking for an executable file would do so like this::
from wa import Workload
from wa.import Executable
class MyBenchmark(Workload):
# ...
def init_resources(self, resolver):
resource = Executable(self, self.target.abi, 'my_benchmark')
host_exe = resolver.get(resource)
# ...
Currently available resource types are defined in :py:mod:`wa.framework.resources`.
.. _deploying-executables:
Deploying executables to a target
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some targets may have certain restrictions on where executable binaries may be
placed and how they should be invoked. To ensure your plugin works with as
wide a range of targets as possible, you should use WA APIs for deploying and
invoking executables on a target, as outlined below.
As with other resources, host-side paths to the executable binary to be deployed
should be obtained via the :ref:`resource resolver <resource-resolution>`. A
special resource type, ``Executable`` is used to identify a binary to be
deployed. This is similar to the regular ``File`` resource, however it takes an
additional parameter that specifies the ABI for which the executable was
compiled for.
In order for the binary to be obtained in this way, it must be stored in one of
the locations scanned by the resource resolver in a directory structure
``<root>/bin/<abi>/<binary>`` (where ``root`` is the base resource location to
be searched, e.g. ``~/.workload_automation/dependencies/<plugin name>``, and
``<abi>`` is the ABI for which the executable has been compiled, as returned by
``self.target.abi``).
Once the path to the host-side binary has been obtained, it may be deployed
using one of two methods from a
`Target <http://devlib.readthedocs.io/en/latest/target.html>`_ instance --
``install`` or ``install_if_needed``. The latter will check a version of that
binary has been previously deployed by WA and will not try to re-install.
.. code:: python
from wa import Executable
host_binary = context.get(Executable(self, self.target.abi, 'some_binary'))
target_binary = self.target.install_if_needed(host_binary)
.. note:: Please also note that the check is done based solely on the binary name.
For more information please see the devlib
`documentation <http://devlib.readthedocs.io/en/latest/target.html#Target.install_if_needed>`_.
Both of the above methods will return the path to the installed binary on the
target. The executable should be invoked *only* via that path; do **not** assume
that it will be in ``PATH`` on the target (or that the executable with the same
name in ``PATH`` is the version deployed by WA.
For more information on how to implement this, please see the
:ref:`how to guide <deploying-executables-example>`.
Deploying assets
-----------------
WA provides a generic mechanism for deploying assets during workload initialization.
WA will automatically try to retrieve and deploy each asset to the target's working directory
that is contained in a workloads ``deployable_assets`` attribute stored as a list.
If the parameter ``cleanup_assets`` is set then any asset deployed will be removed
again and the end of the run.
If the workload requires a custom deployment mechanism the ``deploy_assets``
method can be overridden for that particular workload, in which case, either
additional assets should have their on target paths added to the workload's
``deployed_assests`` attribute or the corresponding ``remove_assets`` method
should also be implemented.
.. _instrument-reference:
Adding an Instrument
---------------------
Instruments can be used to collect additional measurements during workload
execution (e.g. collect power readings). An instrument can hook into almost any
stage of workload execution. Any new instrument should be a subclass of
Instrument and it must have a name. When a new instrument is added to Workload
Automation, the methods of the new instrument will be found automatically and
hooked up to the supported signals. Once a signal is broadcasted, the
corresponding registered method is invoked.
Each method in ``Instrument`` must take two arguments, which are ``self`` and
``context``. Supported methods and their corresponding signals can be found in
the :ref:`Signals Documentation <instruments_method_map>`. To make
implementations easier and common, the basic steps to add new instrument is
similar to the steps to add new workload and an example can be found in the
:ref:`How To <adding-an-instrument-example>` section.
.. _instrument-api:
To implement your own instrument the relevant methods of the interface shown
below should be implemented:
:name:
The name of the instrument, this must be unique to WA.
:description:
A description of what the instrument can be used for.
:parameters:
A list of additional :class:`Parameters` the instrument can take.
:initialize(context):
This method will only be called once during the workload run
therefore operations that only need to be performed initially should
be performed here for example pushing the files to the target device,
installing them.
:setup(context):
This method is invoked after the workload is setup. All the
necessary setup should go inside this method. Setup, includes
operations like clearing logs, additional configuration etc.
:start(context):
It is invoked just before the workload start execution. Here is
where instrument measurement start being registered/taken.
:stop(context):
It is invoked just after the workload execution stops and where
the measurements should stop being taken/registered.
:update_output(context):
This method is invoked after the workload updated its result and
where the taken measures should be added to the result so it can be
processed by WA.
:teardown(context):
It is invoked after the workload is torn down. It is a good place
to clean any logs generated by the instrument.
:finalize(context):
This method is the complement to the initialize method and will also
only be called once so should be used to deleting/uninstalling files
pushed to the device.
This is similar to a ``Workload``, except all methods are optional. In addition to
the workload-like methods, instruments can define a number of other methods that
will get invoked at various points during run execution. The most useful of
which is perhaps ``initialize`` that gets invoked after the device has been
initialised for the first time, and can be used to perform one-time setup (e.g.
copying files to the device -- there is no point in doing that for each
iteration). The full list of available methods can be found in
:ref:`Signals Documentation <instruments_method_map>`.
.. _prioritization:
Prioritization
~~~~~~~~~~~~~~
Callbacks (e.g. ``setup()`` methods) for all instruments get executed at the
same point during workload execution, one after another. The order in which the
callbacks get invoked should be considered arbitrary and should not be relied
on (e.g. you cannot expect that just because instrument A is listed before
instrument B in the config, instrument A's callbacks will run first).
In some cases (e.g. in ``start()`` and ``stop()`` methods), it is important to
ensure that a particular instrument's callbacks run a closely as possible to the
workload's invocations in order to maintain accuracy of readings; or,
conversely, that a callback is executed after the others, because it takes a
long time and may throw off the accuracy of other instruments. You can do
this by using decorators on the appropriate methods. The available decorators are:
``very_slow``, ``slow``, ``normal``, ``fast``, ``very_fast``, with ``very_fast``
running closest to the workload invocation and ``very_slow`` running furtherest
away. For example::
from wa import very_fast
# ..
class PreciseInstrument(Instrument)
# ...
@very_fast
def start(self, context):
pass
@very_fast
def stop(self, context):
pass
# ...
``PreciseInstrument`` will be started after all other instruments (i.e.
*just* before the workload runs), and it will stopped before all other
instruments (i.e. *just* after the workload runs).
If more than one active instrument has specified fast (or slow) callbacks, then
their execution order with respect to each other is not guaranteed. In general,
having a lot of instruments enabled is going to negatively affect the
readings. The best way to ensure accuracy of measurements is to minimize the
number of active instruments (perhaps doing several identical runs with
different instruments enabled).
Example
^^^^^^^
Below is a simple instrument that measures the execution time of a workload::
class ExecutionTimeInstrument(Instrument):
"""
Measure how long it took to execute the run() methods of a Workload.
"""
name = 'execution_time'
def initialize(self, context):
self.start_time = None
self.end_time = None
@very_fast
def start(self, context):
self.start_time = time.time()
@very_fast
def stop(self, context):
self.end_time = time.time()
def update_output(self, context):
execution_time = self.end_time - self.start_time
context.add_metric('execution_time', execution_time, 'seconds')
.. include:: developer_information/developer_guide/instrument_method_map.rst
.. _adding-an-output-processor:
Adding an Output processor
----------------------------
A output processor is responsible for processing the results. This may
involve formatting and writing them to a file, uploading them to a database,
generating plots, etc. WA comes with a few output processors that output
results in a few common formats (such as csv or JSON).
You can add your own output processors by creating a Python file in
``~/.workload_automation/plugins`` with a class that derives from
:class:`wa.OutputProcessor <wa.framework.processor.OutputProcessor>`, and should
implement the relevant methods shown below, for more information and please
see the
:ref:`Adding an Output Processor <adding-an-output-processor-example>` section.
:name:
The name of the output processor, this must be unique to WA.
:description:
A description of what the output processor can be used for.
:parameters:
A list of additional :class:`Parameters` the output processor can take.
:initialize(context):
This method will only be called once during the workload run
therefore operations that only need to be performed initially should
be performed here.
:process_job_output(output, target_info, run_ouput):
This method should be used to perform the processing of the
output from an individual job output. This is where any
additional artifacts should be generated if applicable.
:export_job_output(output, target_info, run_ouput):
This method should be used to perform the exportation of the
existing data collected/generated for an individual job. E.g.
uploading them to a database etc.
:process_run_output(output, target_info):
This method should be used to perform the processing of the
output from the run as a whole. This is where any
additional artifacts should be generated if applicable.
:export_run_output(output, target_info):
This method should be used to perform the exportation of the
existing data collected/generated for the run as a whole. E.g.
uploading them to a database etc.
:finalize(context):
This method is the complement to the initialize method and will also
only be called once.
The method names should be fairly self-explanatory. The difference between
"process" and "export" methods is that export methods will be invoked after
process methods for all output processors have been generated. Process methods
may generate additional artifacts (metrics, files, etc.), while export methods
should not -- they should only handle existing results (upload them to a
database, archive on a filer, etc).
The output object passed to job methods is an instance of
:class:`wa.framework.output.JobOutput`, the output object passed to run methods
is an instance of :class:`wa.RunOutput <wa.framework.output.RunOutput>`.
Adding a Resource Getter
------------------------
A resource getter is a plugin that is designed to retrieve a resource
(binaries, APK files or additional workload assets). Resource getters are invoked in
priority order until one returns the desired resource.
If you want WA to look for resources somewhere it doesn't by default (e.g. you
have a repository of APK files), you can implement a getter for the resource and
register it with a higher priority than the standard WA getters, so that it gets
invoked first.
Instances of a resource getter should implement the following interface::
class ResourceGetter(Plugin):
name = None
def register(self, resolver):
raise NotImplementedError()
The getter should define a name for itself (as with all plugins), in addition it
should implement the ``register`` method. This involves registering a method
with the resolver that should used to be called when trying to retrieve a resource
(typically ``get``) along with it's priority (see `Getter Prioritization`_
below. That method should return an instance of the resource that
has been discovered (what "instance" means depends on the resource, e.g. it
could be a file path), or ``None`` if this getter was unable to discover
that resource.
Getter Prioritization
~~~~~~~~~~~~~~~~~~~~~
A priority is an integer with higher numeric values indicating a higher
priority. The following standard priority aliases are defined for getters:
:preferred: Take this resource in favour of the environment resource.
:local: Found somewhere under ~/.workload_automation/ or equivalent, or
from environment variables, external configuration files, etc.
These will override resource supplied with the package.
:lan: Resource will be retrieved from a locally mounted remote location
(such as samba share)
:remote: Resource will be downloaded from a remote location (such as an HTTP
server)
:package: Resource provided with the package.
These priorities are defined as class members of
:class:`wa.framework.resource.SourcePriority`, e.g. ``SourcePriority.preferred``.
Most getters in WA will be registered with either ``local`` or
``package`` priorities. So if you want your getter to override the default, it
should typically be registered as ``preferred``.
You don't have to stick to standard priority levels (though you should, unless
there is a good reason). Any integer is a valid priority. The standard priorities
range from 0 to 40 in increments of 10.
Example
~~~~~~~
The following is an implementation of a getter that searches for files in the
users dependencies directory, typically
``~/.workload_automation/dependencies/<workload_name>`` It uses the
``get_from_location`` method to filter the available files in the provided
directory appropriately::
import sys
from wa import settings,
from wa.framework.resource import ResourceGetter, SourcePriority
from wa.framework.getters import get_from_location
from wa.utils.misc import ensure_directory_exists as _d
class UserDirectory(ResourceGetter):
name = 'user'
def register(self, resolver):
resolver.register(self.get, SourcePriority.local)
def get(self, resource):
basepath = settings.dependencies_directory
directory = _d(os.path.join(basepath, resource.owner.name))
return get_from_location(directory, resource)
.. _adding_a_target:
Adding a Target
---------------
In WA3, a 'target' consists of a platform and a devlib target. The
implementations of the targets are located in ``devlib``. WA3 will instantiate a
devlib target passing relevant parameters parsed from the configuration. For
more information about devlib targets please see `the documentation
<http://devlib.readthedocs.io/en/latest/target.html>`_.
The currently available platforms are:
:generic: The 'standard' platform implementation of the target, this should
work for the majority of use cases.
:juno: A platform implementation specifically for the juno.
:tc2: A platform implementation specifically for the tc2.
:gem5: A platform implementation to interact with a gem5 simulation.
The currently available targets from devlib are:
:linux: A device running a Linux based OS.
:android: A device running Android OS.
:local: Used to run locally on a linux based host.
:chromeos: A device running ChromeOS, supporting an android container if available.
For an example of adding you own customized version of an existing devlib target,
please see the how to section :ref:`Adding a Custom Target <adding-custom-target-example>`.
Other Plugin Types
---------------------
In addition to plugin types covered above, there are few other, more
specialized ones. They will not be covered in as much detail. Most of them
expose relatively simple interfaces with only a couple of methods and it is
expected that if the need arises to extend them, the API-level documentation
that accompanies them, in addition to what has been outlined here, should
provide enough guidance.
:commands: This allows extending WA with additional sub-commands (to supplement
exiting ones outlined in the :ref:`invocation` section).
:modules: Modules are "plugins for plugins". They can be loaded by other
plugins to expand their functionality (for example, a flashing
module maybe loaded by a device in order to support flashing).
Packaging Your Plugins
----------------------
If your have written a bunch of plugins, and you want to make it easy to
deploy them to new systems and/or to update them on existing systems, you can
wrap them in a Python package. You can use ``wa create package`` command to
generate appropriate boiler plate. This will create a ``setup.py`` and a
directory for your package that you can place your plugins into.
For example, if you have a workload inside ``my_workload.py`` and an output
processor in ``my_output_processor.py``, and you want to package them as
``my_wa_exts`` package, first run the create command ::
wa create package my_wa_exts
This will create a ``my_wa_exts`` directory which contains a
``my_wa_exts/setup.py`` and a subdirectory ``my_wa_exts/my_wa_exts`` which is
the package directory for your plugins (you can rename the top-level
``my_wa_exts`` directory to anything you like -- it's just a "container" for the
setup.py and the package directory). Once you have that, you can then copy your
plugins into the package directory, creating
``my_wa_exts/my_wa_exts/my_workload.py`` and
``my_wa_exts/my_wa_exts/my_output_processor.py``. If you have a lot of
plugins, you might want to organize them into subpackages, but only the
top-level package directory is created by default, and it is OK to have
everything in there.
.. note:: When discovering plugins through this mechanism, WA traverses the
Python module/submodule tree, not the directory structure, therefore,
if you are going to create subdirectories under the top level directory
created for you, it is important that your make sure they are valid
Python packages; i.e. each subdirectory must contain a __init__.py
(even if blank) in order for the code in that directory and its
subdirectories to be discoverable.
At this stage, you may want to edit ``params`` structure near the bottom of
the ``setup.py`` to add correct author, license and contact information (see
"Writing the Setup Script" section in standard Python documentation for
details). You may also want to add a README and/or a COPYING file at the same
level as the setup.py. Once you have the contents of your package sorted,
you can generate the package by running ::
cd my_wa_exts
python setup.py sdist
This will generate ``my_wa_exts/dist/my_wa_exts-0.0.1.tar.gz`` package which
can then be deployed on the target system with standard Python package
management tools, e.g. ::
sudo pip install my_wa_exts-0.0.1.tar.gz
As part of the installation process, the setup.py in the package, will write the
package's name into ``~/.workoad_automation/packages``. This will tell WA that
the package contains plugin and it will load them next time it runs.
.. note:: There are no uninstall hooks in ``setuputils``, so if you ever
uninstall your WA plugins package, you will have to manually remove
it from ``~/.workload_automation/packages`` otherwise WA will complain
about a missing package next time you try to run it.
================================================
FILE: doc/source/developer_information/developer_guide.rst
================================================
.. _developer_guide:
***************
Developer Guide
***************
.. contents::
:depth: 3
:local:
.. include:: developer_information/developer_guide/writing_plugins.rst
================================================
FILE: doc/source/developer_information/developer_reference/contributing.rst
================================================
Contributing
============
Code
----
We welcome code contributions via GitHub pull requests. To help with
maintainability of the code line we ask that the code uses a coding style
consistent with the rest of WA code. Briefly, it is
- `PEP8 <https://www.python.org/dev/peps/pep-0008/>`_ with line length and block
comment rules relaxed (the wrapper for PEP8 checker inside ``dev_scripts``
will run it with appropriate configuration).
- Four-space indentation (*no tabs!*).
- Title-case for class names, underscore-delimited lower case for functions,
methods, and variables.
- Use descriptive variable names. Delimit words with ``'_'`` for readability.
Avoid shortening words, skipping vowels, etc (common abbreviations such as
"stats" for "statistics", "config" for "configuration", etc are OK). Do
*not* use Hungarian notation (so prefer ``birth_date`` over ``dtBirth``).
New extensions should also follow implementation guidelines specified in the
:ref:`writing-plugins` section of the documentation.
We ask that the following checks are performed on the modified code prior to
submitting a pull request:
.. note:: You will need pylint and pep8 static checkers installed::
pip install pep8
pip install pylint
It is recommended that you install via pip rather than through your
distribution's package manager because the latter is likely to
contain out-of-date version of these tools.
- ``./dev_scripts/pylint`` should be run without arguments and should produce no
output (any output should be addressed by making appropriate changes in the
code or adding a pylint ignore directive, if there is a good reason for
keeping the code as is).
- ``./dev_scripts/pep8`` should be run without arguments and should produce no
output (any output should be addressed by making appropriate changes in the
code).
- If the modifications touch core framework (anything under ``wa/framework``), unit
tests should be run using ``nosetests``, and they should all pass.
- If significant additions have been made to the framework, unit
tests should be added to cover the new functionality.
- If modifications have been made to the UI Automation source of a workload, the
corresponding APK should be rebuilt and submitted as part of the same pull
request. This can be done via the ``build.sh`` script in the relevant
``uiauto`` subdirectory.
- If modifications have been made to documentation (this includes description
attributes for Parameters and Extensions), documentation should be built to
make sure no errors or warning during build process, and a visual inspection
of new/updated sections in resulting HTML should be performed to ensure
everything renders as expected.
Once you have your contribution is ready, please follow instructions in `GitHub
documentation <https://help.github.com/articles/creating-a-pull-request/>`_ to
create a pull request.
--------------------------------------------------------------------------------
Documentation
-------------
Headings
~~~~~~~~
To allow for consistent headings to be used through out the document the
following character sequences should be used when creating headings
::
=========
Heading 1
=========
Only used for top level headings which should also have an entry in the
navigational side bar.
*********
Heading 2
*********
Main page heading used for page title, should not have a top level entry in the
side bar.
Heading 3
==========
Regular section heading.
Heading 4
---------
Sub-heading.
Heading 5
~~~~~~~~~
Heading 6
^^^^^^^^^
Heading 7
"""""""""
--------------------------------------------------------------------------------
Configuration Listings
~~~~~~~~~~~~~~~~~~~~~~
To keep a consistent style for presenting configuration options, the preferred
style is to use a `Field List`.
(See: http://docutils.sourceforge.net/docs/user/rst/quickref.html#field-lists)
Example::
:parameter: My Description
Will render as:
:parameter: My Description
--------------------------------------------------------------------------------
API Style
~~~~~~~~~
When documenting an API the currently preferred style is to provide a short
description of the class, followed by the attributes of the class in a
`Definition List` followed by the methods using the `method` directive.
(See: http://docutils.sourceforge.net/docs/user/rst/quickref.html#definition-lists)
Example::
API
===
:class:`MyClass`
----------------
:class:`MyClass` is an example class to demonstrate API documentation.
``attribute1``
The first attribute of the example class.
``attribute2``
Another attribute example.
methods
"""""""
.. method:: MyClass.retrieve_output(name)
Retrieve the output for ``name``.
:param name: The output that should be returned.
:return: An :class:`Output` object for ``name``.
:raises NotFoundError: If no output can be found.
Will render as:
:class:`MyClass` is an example class to demonstrate API documentation.
``attribute1``
The first attribute of the example class.
``attribute2``
Another attribute example.
methods
^^^^^^^
.. method:: MyClass.retrieve_output(name)
Retrieve the output for ``name``.
:param name: The output that should be returned.
:return: An :class:`Output` object for ``name``.
:raises NotFoundError: If no output can be found.
================================================
FILE: doc/source/developer_information/developer_reference/framework_overview.rst
================================================
Framework Overview
==================
Execution Model
---------------
At the high level, the execution model looks as follows:
.. image:: developer_information/developer_reference/WA_Execution.svg
:scale: 100 %
After some initial setup, the framework initializes the device, loads and
initialized instruments and output processors and begins executing jobs defined
by the workload specs in the agenda. Each job executes in basic stages:
initialize
Perform any once-per-run initialization of a workload instance, i.e.
binary resource resolution.
setup
Initial setup for the workload is performed. E.g. required assets are
deployed to the devices, required services or applications are launched,
etc. Run time configuration of the device for the workload is also
performed at this time.
setup_rerun (apk based workloads only)
For some apk based workloads the application is required to be started
twice. If the ``requires_rerun`` attribute of the workload is set to
``True`` then after the first setup method is called the application
will be killed and then restarted. This method can then be used to
perform any additional setup required.
run
This is when the workload actually runs. This is defined as the part of
the workload that is to be measured. Exactly what happens at this stage
depends entirely on the workload.
extract results
Extract any results that have been generated during the execution of the
workload from the device and back to that target. Any files pulled from
the devices should be added as artifacts to the run context.
update output
Perform any required parsing and processing of any collected results and
add any generated metrics to the run context.
teardown
Final clean up is performed, e.g. applications may closed, files
generated during execution deleted, etc.
Signals are dispatched (see :ref:`below <signal_dispatch>`) at each stage of
workload execution, which installed instruments can hook into in order to
collect measurements, alter workload execution, etc. Instruments implementation
usually mirrors that of workloads, defining initialization, setup, teardown and
output processing stages for a particular instrument. Instead of a ``run``
method instruments usually implement ``start`` and ``stop`` methods instead
which triggered just before and just after a workload run. However, the signal
dispatch mechanism gives a high degree of flexibility to instruments allowing
them to hook into almost any stage of a WA run (apart from the very early
initialization).
Metrics and artifacts generated by workloads and instruments are accumulated by
the framework and are then passed to active output processors. This happens
after each individual workload execution and at the end of the run. A output
processor may chose to act at either or both of these points.
Control Flow
------------
This section goes into more detail explaining the relationship between the major
components of the framework and how control passes between them during a run. It
will only go through the major transitions and interactions and will not attempt
to describe every single thing that happens.
.. note:: This is the control flow for the ``wa run`` command which is the main
functionality of WA. Other commands are much simpler and most of what
is described below does not apply to them.
#. :class:`wa.framework.entrypoint` parses the command from the arguments, creates a
:class:`wa.framework.configuration.execution.ConfigManager` and executes the run
command (:class:`wa.commands.run.RunCommand`) passing it the ConfigManger.
#. Run command initializes the output directory and creates a
:class:`wa.framework.configuration.parsers.AgendaParser` and will parser an
agenda and populate the ConfigManger based on the command line arguments.
Finally it instantiates a :class:`wa.framework.execution.Executor` and
passes it the completed ConfigManager.
#. The Executor uses the ConfigManager to create a
:class:`wa.framework.configuration.core.RunConfiguration` and fully defines the
configuration for the run (which will be serialised into ``__meta`` subdirectory
under the output directory).
#. The Executor proceeds to instantiate a TargetManager, used to handle the
device connection and configuration, and a
:class:`wa.framework.execution.ExecutionContext` which is used to track the
current state of the run execution and also serves as a means of
communication between the core framework and plugins. After this any required
instruments and output processors are initialized and installed.
#. Finally, the Executor instantiates a :class:`wa.framework.execution.Runner`,
initializes its job queue with workload specs from the RunConfiguration, and
kicks it off.
#. The Runner performs the run time configuration of the device and goes
through the workload specs (in the order defined by ``execution_order``
setting), running each spec according to the execution model described in the
previous section and sending signals (see below) at appropriate points during
execution.
#. At the end of the run, the control is briefly passed back to the Executor,
which outputs a summary for the run.
.. _signal_dispatch:
Signal Dispatch
---------------
WA uses the `louie <https://github.com/11craft/louie/>`_ (formerly,
pydispatcher) library for signal dispatch. Callbacks can be registered for
signals emitted during the run. WA uses a version of louie that has been
modified to introduce :ref:`priority <prioritization>` to registered callbacks
(so that callbacks that are know to be slow can be registered with a lower
priority and therefore do not interfere with other callbacks).
This mechanism is abstracted for instruments. Methods of an
:class:`wa.framework.Instrument` subclass automatically get hooked to
appropriate signals based on their names when the instrument is "installed"
for the run. Priority can then be specified by adding ``extremely_fast``,
``very_fast``, ``fast`` , ``slow``, ``very_slow`` or ``extremely_slow``
:ref:`decorators <instruments_method_map>` to the method definitions.
The full list of method names and the signals they map to may be seen at the
:ref:`instrument method map <instruments_method_map>`.
Signal dispatching mechanism may also be used directly, for example to
dynamically register callbacks at runtime or allow plugins other than
``Instruments`` to access stages of the run they are normally not aware of.
Signals can be either paired or non paired signals. Non paired signals are one
off signals that are sent to indicate special events or transitions in execution
stages have occurred for example ``TARGET_CONNECTED``. Paired signals are used to
signify the start and end of a particular event. If the start signal has been
sent the end signal is guaranteed to also be sent, whether the operation was a
successes or not, however in the case of correct operation an additional success
signal will also be sent. For example in the event of a successful reboot of the
the device, the following signals will be sent ``BEFORE_REBOOT``,
``SUCCESSFUL_REBOOT`` and ``AFTER_REBOOT``.
An overview of what signals are sent at which point during execution can be seen
below. Most of the paired signals have been removed from the diagram for clarity
and shown as being dispatched from a particular stage of execution, however in
reality these signals will be sent just before and just after these stages are
executed. As mentioned above for each of these signals there will be at least 2
and up to 3 signals sent. If the "BEFORE_X" signal (sent just before the stage
is ran) is sent then the "AFTER_X" (sent just after the stage is ran) signal is
guaranteed to also be sent, and under normal operation a "SUCCESSFUL_X" signal
is also sent just after stage has been completed. The diagram also lists the
conditional signals that can be sent at any time during execution if something
unexpected happens, for example an error occurs or the user aborts the run.
.. image:: developer_information/developer_reference/WA_Signal_Dispatch.svg
:scale: 100 %
For more information see :ref:`Instrumentation Signal-Method Mapping <instruments_method_map>`.
================================================
FILE: doc/source/developer_information/developer_reference/plugins.rst
================================================
.. plugins:
Plugins
=======
Workload Automation offers several plugin points (or plugin types). The most
interesting of these are
:workloads: These are the tasks that get executed and measured on the device. These
can be benchmarks, high-level use cases, or pretty much anything else.
:targets: These are interfaces to the physical devices (development boards or end-user
devices, such as smartphones) that use cases run on. Typically each model of a
physical device would require its own interface class (though some functionality
may be reused by subclassing from an existing base).
:instruments: Instruments allow collecting additional data from workload execution (e.g.
system traces). Instruments are not specific to a particular workload. Instruments
can hook into any stage of workload execution.
:output processors: These are used to format the results of workload execution once they have been
collected. Depending on the callback used, these will run either after each
iteration and/or at the end of the run, after all of the results have been
collected.
You can create a plugin by subclassing the appropriate base class, defining
appropriate methods and attributes, and putting the .py file containing the
class into the "plugins" subdirectory under ``~/.workload_automation`` (or
equivalent) where it will be automatically picked up by WA.
Plugin Basics
--------------
This section contains reference information common to plugins of all types.
.. _context:
The Context
~~~~~~~~~~~
.. note:: For clarification on the meaning of "workload specification" "spec", "job"
and "workload" and the distinction between them, please see the :ref:`glossary <glossary>`.
The majority of methods in plugins accept a context argument. This is an
instance of :class:`wa.framework.execution.ExecutionContext`. It contains
information about the current state of execution of WA and keeps track of things
like which workload is currently running.
Notable methods of the context are:
:context.get_resource(resource, strict=True):
This method should be used to retrieve a resource using the resource getters rather than using the ResourceResolver directly as this method additionally record any found resources hash in the output metadata.
:context.add_artifact(name, host_file_path, kind, description=None, classifier=None):
Plugins can add :ref:`artifacts <artifact>` of various kinds to the run
output directory for WA and associate them with a description and/or
:ref:`classifier <classifiers>`.
:context.add_metric(name, value, units=None, lower_is_better=False, classifiers=None):
This method should be used to add :ref:`metrics <metrics>` that have been
generated from a workload, this will allow WA to process the results
accordingly depending on which output processors are enabled.
Notable attributes of the context are:
:context.workload:
:class:`wa.framework.workload` object that is currently being executed.
:context.tm:
This is the target manager that can be used to access various information
about the target including initialization parameters.
:context.current_job:
This is an instance of :class:`wa.framework.job.Job` and contains all
the information relevant to the workload job currently being executed.
:context.current_job.spec:
The current workload specification being executed. This is an
instance of :class:`wa.framework.configuration.core.JobSpec`
and defines the workload and the parameters under which it is
being executed.
:context.current_job.current_iteration:
The current iteration of the spec that is being executed. Note that this
is the iteration for that spec, i.e. the number of times that spec has
been run, *not* the total number of all iterations have been executed so
far.
:context.job_output:
This is the output object for the current iteration which
is an instance of :class:`wa.framework.output.JobOutput`. It contains
the status of the iteration as well as the metrics and artifacts
generated by the job.
In addition to these, context also defines a few useful paths (see below).
Paths
~~~~~
You should avoid using hard-coded absolute paths in your plugins whenever
possible, as they make your code too dependent on a particular environment and
may mean having to make adjustments when moving to new (host and/or device)
platforms. To help avoid hard-coded absolute paths, WA defines a number of
standard locations. You should strive to define your paths relative
to one of these.
On the host
^^^^^^^^^^^
Host paths are available through the context object, which is passed to most
plugin methods.
context.run_output_directory
This is the top-level output directory for all WA results (by default,
this will be "wa_output" in the directory in which WA was invoked.
context.output_directory
This is the output directory for the current iteration. This will an
iteration-specific subdirectory under the main results location. If
there is no current iteration (e.g. when processing overall run results)
this will point to the same location as ``run_output_directory``.
Additionally, the global ``wa.settings`` object exposes on other location:
settings.dependency_directory
this is the root directory for all plugin dependencies (e.g. media
files, assets etc) that are not included within the plugin itself.
As per Python best practice, it is recommended that methods and values in
``os.path`` standard library module are used for host path manipulation.
On the target
^^^^^^^^^^^^^
Workloads and instruments have a ``target`` attribute, which is an interface to
the target used by WA. It defines the following location:
target.working_directory
This is the directory for all WA-related files on the target. All files
deployed to the target should be pushed to somewhere under this location
(the only exception being executables installed with ``target.install``
method).
Since there could be a mismatch between path notation used by the host and the
target, the ``os.path`` modules should *not* be used for on-target path
manipulation. Instead target has an equipment module exposed through
``target.path`` attribute. This has all the same attributes and behaves the
same way as ``os.path``, but is guaranteed to produce valid paths for the target,
irrespective of the host's path notation. For example:
.. code:: python
result_file = self.target.path.join(self.target.working_directory, "result.txt")
self.command = "{} -a -b -c {}".format(target_binary, result_file)
.. note:: Output processors, unlike workloads and instruments, do not have their
own target attribute as they are designed to be able to be run offline.
.. _plugin-parameters:
Parameters
~~~~~~~~~~~
All plugins can be parametrized. Parameters are specified using
``parameters`` class attribute. This should be a list of
:class:`wa.framework.plugin.Parameter` instances. The following attributes can be
specified on parameter creation:
:name:
This is the only mandatory argument. The name will be used to create a
corresponding attribute in the plugin instance, so it must be a valid
Python identifier.
:kind:
This is the type of the value of the parameter. This must be an
callable. Normally this should be a standard Python type, e.g. ``int``
or ``float``, or one the types defined in :mod:`wa.utils.types`.
If not explicitly specified, this will default to ``str``.
.. note:: Irrespective of the ``kind`` specified, ``None`` is always a
valid value for a parameter. If you don't want to allow
``None``, then set ``mandatory`` (see below) to ``True``.
:allowed_values:
A list of the only allowed values for this parameter.
.. note:: For composite types, such as ``list_of_strings`` or
``list_of_ints`` in :mod:`wa.utils.types`, each element of
the value will be checked against ``allowed_values`` rather
than the composite value itself.
:default:
The default value to be used for this parameter if one has not been
specified by the user. Defaults to ``None``.
:mandatory:
A ``bool`` indicating whether this parameter is mandatory. Setting this
to ``True`` will make ``None`` an illegal value for the parameter.
Defaults to ``False``.
.. note:: Specifying a ``default`` will mean that this parameter will,
effectively, be ignored (unless the user sets the param to ``None``).
.. note:: Mandatory parameters are *bad*. If at all possible, you should
strive to provide a sensible ``default`` or to make do without
the parameter. Only when the param is absolutely necessary,
and there really is no sensible default that could be given
(e.g. something like login credentials), should you consider
making it mandatory.
:constraint:
This is an additional constraint to be enforced on the parameter beyond
its type or fixed allowed values set. This should be a predicate (a function
that takes a single argument -- the user-supplied value -- and returns
a ``bool`` indicating whether the constraint has been satisfied).
:override:
A parameter name must be unique not only within an plugin but also
with that plugin's class hierarchy. If you try to declare a parameter
with the same name as already exists, you will get an error. If you do
want to override a parameter from further up in the inheritance
hierarchy, you can indicate that by setting ``override`` attribute to
``True``.
When overriding, you do not need to specify every other attribute of the
parameter, just the ones you what to override. Values for the rest will
be taken from the parameter in the base class.
Validation and cross-parameter constraints
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A plugin will get validated at some point after construction. When exactly
this occurs depends on the plugin type, but it *will* be validated before it
is used.
You can implement ``validate`` method in your plugin (that takes no arguments
beyond the ``self``) to perform any additional *internal* validation in your
plugin. By "internal", I mean that you cannot make assumptions about the
surrounding environment (e.g. that the device has been initialized).
The contract for ``validate`` method is that it should raise an exception
(either ``wa.framework.exception.ConfigError`` or plugin-specific exception type -- see
further on this page) if some validation condition has not, and cannot, been met.
If the method returns without raising an exception, then the plugin is in a
valid internal state.
Note that ``validate`` can be used not only to verify, but also to impose a
valid internal state. In particular, this where cross-parameter constraints can
be resolved. If the ``default`` or ``allowed_values`` of one parameter depend on
another parameter, there is no way to express that declaratively when specifying
the parameters. In that case the dependent attribute should be left unspecified
on creation and should instead be set inside ``validate``.
Logging
~~~~~~~
Every plugin class has it's own logger that you can access through
``self.logger`` inside the plugin's methods. Generally, a :class:`Target` will
log everything it is doing, so you shouldn't need to add much additional logging
for device actions. However you might what to log additional information, e.g.
what settings your plugin is using, what it is doing on the host, etc.
(Operations on the host will not normally be logged, so your plugin should
definitely log what it is doing on the host). One situation in particular where
you should add logging is before doing something that might take a significant
amount of time, such as downloading a file.
Documenting
~~~~~~~~~~~
All plugins and their parameter should be documented. For plugins
themselves, this is done through ``description`` class attribute. The convention
for an plugin description is that the first paragraph should be a short
summary description of what the plugin does and why one would want to use it
(among other things, this will get extracted and used by ``wa list`` command).
Subsequent paragraphs (separated by blank lines) can then provide a more
detailed description, including any limitations and setup instructions.
For parameters, the description is passed as an argument on creation. Please
note that if ``default``, ``allowed_values``, or ``constraint``, are set in the
parameter, they do not need to be explicitly mentioned in the description (wa
documentation utilities will automatically pull those). If the ``default`` is set
in ``validate`` or additional cross-parameter constraints exist, this *should*
be documented in the parameter description.
Both plugins and their parameters should be documented using reStructureText
markup (standard markup for Python documentation). See:
http://docutils.sourceforge.net/rst.html
Aside from that, it is up to you how you document your plugin. You should try
to provide enough information so that someone unfamiliar with your plugin is
able to use it, e.g. you should document all settings and parameters your
plugin expects (including what the valid values are).
Error Notification
~~~~~~~~~~~~~~~~~~
When you detect an error condition, you should raise an appropriate exception to
notify the user. The exception would typically be :class:`ConfigError` or
(depending the type of the plugin)
:class:`WorkloadError`/:class:`DeviceError`/:class:`InstrumentError`/:class:`OutputProcessorError`.
All these errors are defined in :mod:`wa.framework.exception` module.
A :class:`ConfigError` should be raised where there is a problem in configuration
specified by the user (either through the agenda or config files). These errors
are meant to be resolvable by simple adjustments to the configuration (and the
error message should suggest what adjustments need to be made. For all other
errors, such as missing dependencies, mis-configured environment, problems
performing operations, etc., the plugin type-specific exceptions should be
used.
If the plugin itself is capable of recovering from the error and carrying
on, it may make more sense to log an ERROR or WARNING level message using the
plugin's logger and to continue operation.
.. _metrics:
Metrics
~~~~~~~
This is what WA uses to store a single metric collected from executing a workload.
:name: the name of the metric. Uniquely identifies the metric
within the results.
:value: The numerical value of the metric for this execution of a
workload. This can be either an int or a float.
:units: Units for the collected value. Can be None if the value
has no units (e.g. it's a count or a standardised score).
:lower_is_better: Boolean flag indicating where lower values are
better than higher ones. Defaults to False.
:classifiers: A set of key-value pairs to further classify this
metric beyond current iteration (e.g. this can be used
to identify sub-tests).
Metrics can be added to WA output via the :ref:`context <context>`:
.. code-block:: python
context.add_metric("score", 9001)
context.add_metric("time", 2.35, "seconds", lower_is_better=True)
You only need to specify the name and the value for the metric. Units and
classifiers are optional, and, if not specified otherwise, it will be assumed
that higher values are better (``lower_is_better=False``).
The metric will be added to the result for the current job, if there is one;
otherwise, it will be added to the overall run result.
.. _artifact:
Artifacts
~~~~~~~~~
This is an artifact generated during execution/post-processing of a workload.
Unlike :ref:`metrics <metrics>`, this represents an actual artifact, such as a
file, generated. This may be "output", such as trace, or it could be "meta
data" such as logs. These are distinguished using the ``kind`` attribute, which
also helps WA decide how it should be handled. Currently supported kinds are:
:log: A log file. Not part of the "output" as such but contains
information about the run/workload execution that be useful for
diagnostics/meta analysis.
:meta: A file containing metadata. This is not part of the "output", but
contains information that may be necessary to reproduce the
results (contrast with ``log`` artifacts which are *not*
necessary).
:data: This file contains new data, not available otherwise and should
be considered part of the "output" generated by WA. Most traces
would fall into this category.
:export: Exported version of results or some other artifact. This
signifies that this artifact does not contain any new data
that is not available elsewhere and that it may be safely
discarded without losing information.
:raw: Signifies that this is a raw dump/log that is normally processed
to extract useful information and is then discarded. In a sense,
it is the opposite of ``export``, but in general may also be
discarded.
.. note:: whether a file is marked as ``log``/``data`` or ``raw``
depends on how important it is to preserve this file,
e.g. when archiving, vs how much space it takes up.
Unlike ``export`` artifacts which are (almost) always
ignored by other exporters as that would never result
in data loss, ``raw`` files *may* be processed by
exporters if they decided that the risk of losing
potentially (though unlikely) useful data is greater
than the time/space cost of handling the artifact (e.g.
a database uploader may choose to ignore ``raw``
artifacts, whereas a network filer archiver may choose
to archive them).
.. note: The kind parameter is intended to represent the logical
function of a particular artifact, not it's intended means of
processing -- this is left entirely up to the output
processors.
As with :ref:`metrics`, artifacts are added via the :ref:`context <context>`:
.. code-block:: python
context.add_artifact("benchmark-output", "bech-out.txt", kind="raw",
description="stdout from running the benchmark")
.. note:: The file *must* exist on the host by the point at which the artifact
is added, otherwise an error will be raised.
The artifact will be added to the result of the current job, if there is one;
otherwise, it will be added to the overall run result. In some situations, you
may wish to add an artifact to the overall run while being inside a job context,
this can be done with ``add_run_artifact``:
.. code-block:: python
context.add_run_artifact("score-summary", "scores.txt", kind="export",
description="""
Summary of the scores so far. Updated after
every job.
""")
In this case, you also need to make sure that the file represented by the
artifact is written to the output directory for the run and not the current job.
.. _metadata:
Metadata
~~~~~~~~
There may be additional data collected by your plugin that you want to record as
part of the result, but that does not fall under the definition of a "metric".
For example, you may want to record the version of the binary you're executing.
You can do this by adding a metadata entry:
.. code-block:: python
context.add_metadata("exe-version", 1.3)
Metadata will be added either to the current job result, or to the run result,
depending on the current context. Metadata values can be scalars or nested
structures of dicts/sequences; the only constraint is that all constituent
objects of the value must be POD (Plain Old Data) types -- see :ref:`WA POD
types <wa-pods>`.
There is special support for handling metadata entries that are dicts of values.
The following call adds a metadata entry ``"versions"`` who's value is
``{"my_exe": 1.3}``:
.. code-block:: python
context.add_metadata("versions", "my_exe", 1.3)
If you attempt to add a metadata entry that already exists, an error will be
raised, unless ``force=True`` is specified, in which case, it will be
overwritten.
Updating an existing entry whose value is a collection can be done with
``update_metadata``:
.. code-block:: python
context.update_metadata("ran_apps", "my_exe")
context.update_metadata("versions", "my_other_exe", "2.3.0")
The first call appends ``"my_exe"`` to the list at metadata entry
``"ran_apps"``. The second call updates the ``"versions"`` dict in the metadata
with an entry for ``"my_other_exe"``.
If an entry does not exit, ``update_metadata`` will create it, so it's
recommended to always use that for non-scalar entries, unless the intention is
specifically to ensure that the entry does not exist at the time of the call.
.. _classifiers:
Classifiers
~~~~~~~~~~~
Classifiers are key-value pairs of tags that can be attached to metrics,
artifacts, jobs, or the entire run. Run and job classifiers get propagated to
metrics and artifacts. Classifier keys should be strings, and their values
should be simple scalars (i.e. strings, numbers, or bools).
Classifiers can be thought of as "tags" that are used to annotate metrics and
artifacts, in order to make it easier to sort through them later. WA itself does
not do anything with them, however output processors will augment the output
they generate with them (for example, ``csv`` processor can add additional
columns for classifier keys).
Classifiers are typically added by the user to attach some domain-specific
information (e.g. experiment configuration identifier) to the results, see
:ref:`using classifiers <using-classifiers>`. However, plugins can also attach
additional classifiers, by specifying them in ``add_metric()`` and
``add_artifacts()`` calls.
Metadata vs Classifiers
~~~~~~~~~~~~~~~~~~~~~~~
Both metadata and classifiers are sets of essentially opaque key-value pairs
that get included in WA output. While they may seem somewhat similar and
interchangeable, they serve different purposes and are handled differently by
the framework.
Classifiers are used to annotate generated metrics and artifacts in order to
assist post-processing tools in sorting through them. Metadata is used to record
additional information that is not necessary for processing the results, but
that may be needed in order to reproduce them or to make sense of them in a
grander context.
These are specific differences in how they are handled:
- Classifiers are often provided by the user via the agenda (though can also be
added by plugins). Metadata in only created by the framework and plugins.
- Classifier values must be simple scalars; metadata values can be nested
collections, such as lists or dicts.
- Classifiers are used by output processors to augment the output the latter
generated; metadata typically isn't.
- Classifiers are essentially associated with the individual metrics and
artifacts (though in the agenda they're specified at workload, section, or
global run levels); metadata is associated with a particular job or run, and
not with metrics or artifacts.
--------------------
.. _execution-decorators:
Execution Decorators
---------------------
The following decorators are available for use in order to control how often a
method should be able to be executed.
For example, if we want to ensure that no matter how many iterations of a
particular workload are ran, we only execute the initialize method for that instance
once, we would use the decorator as follows:
.. code-block:: python
from wa.utils.exec_control import once
@once
def initialize(self, context):
# Perform one time initialization e.g. installing a binary to target
# ..
@once_per_instance
~~~~~~~~~~~~~~~~~~
The specified method will be invoked only once for every bound instance within
the environment.
@once_per_class
~~~~~~~~~~~~~~~
The specified method will be invoked only once for all instances of a class
within the environment.
@once
~~~~~
The specified method will be invoked only once within the environment.
.. warning:: If a method containing a super call is decorated, this will also cause
stop propagation up the hierarchy, unless this is the desired
effect, additional functionality should be implemented in a
separate decorated method which can then be called allowing for
normal propagation to be retained.
--------------------
Utils
-----
Workload Automation defines a number of utilities collected under
:mod:`wa.utils` subpackage. These utilities were created to help with the
implementation of the framework itself, but may be also be useful when
implementing plugins.
--------------------
Workloads
---------
All of the type inherit from the same base :class:`Workload` and its API can be
seen in the :ref:`API <workload-api>` section.
Workload methods (except for ``validate``) take a single argument that is a
:class:`wa.framework.execution.ExecutionContext` instance. This object keeps
track of the current execution state (such as the current workload, iteration
number, etc), and contains, among other things, a
:class:`wa.framework.output.JobOutput` instance that should be populated from
the ``update_output`` method with the results of the execution. For more
information please see `the context`_ documentation. ::
# ...
def update_output(self, context):
# ...
context.add_metric('energy', 23.6, 'Joules', lower_is_better=True)
# ...
.. _workload-types:
Workload Types
~~~~~~~~~~~~~~~~
There are multiple workload types that you can inherit from depending on the
purpose of your workload, the different types along with an output of their
intended use cases are outlined below.
.. _basic-workload:
Basic (:class:`wa.Workload <wa.framework.workload.Workload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This type of the workload is the simplest type of workload and is left the to
developer to implement its full functionality.
.. _apk-workload:
Apk (:class:`wa.ApkWorkload <wa.framework.workload.ApkWorkload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This workload will simply deploy and launch an android app in its basic form
with no UI interaction.
.. _uiautomator-workload:
UiAuto (:class:`wa.UiautoWorkload <wa.framework.workload.UiautoWorkload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This workload is for android targets which will use UiAutomator to interact with
UI elements without a specific android app, for example performing manipulation
of android itself. This is the preferred type of automation as the results are
more portable and reproducible due to being able to wait for UI elements to
appear rather than having to rely on human recordings.
.. _apkuiautomator-workload:
ApkUiAuto (:class:`wa.ApkUiautoWorkload <wa.framework.workload.ApkUiautoWorkload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The is the same as the UiAuto workload however it is also associated with an
android app e.g. AdobeReader and will automatically deploy and launch the
android app before running the automation.
.. _revent-workload:
Revent (:class:`wa.ReventWorkload <wa.framework.workload.ReventWorkload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Revent workloads are designed primarily for games as these are unable to be
automated with UiAutomator due to the fact that they are rendered within a
single UI element. They require a recording to be performed manually and
currently will need re-recording for each different device. For more
information on revent workloads been please see :ref:`revent_files_creation`
.. _apkrevent-workload:
APKRevent (:class:`wa.ApkReventWorkload <wa.framework.workload.ApkReventWorkload>`)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The is the same as the Revent workload however it is also associated with an
android app e.g. AngryBirds and will automatically deploy and launch the android
app before running the automation.
================================================
FILE: doc/source/developer_information/developer_reference/revent.rst
================================================
Revent Recordings
=================
Convention for Naming revent Files for Revent Workloads
-------------------------------------------------------------------------------
There is a convention for naming revent files which you should follow if you
want to record your own revent files. Each revent file must be called (case sensitive)
``<device name>.<stage>.revent``,
where ``<device name>`` is the name of your device (as defined by the model
name of your device which can be retrieved with
``adb shell getprop ro.product.model`` or by the ``name`` attribute of your
customized device class), and ``<stage>`` is one of the following currently
supported stages:
:setup: This stage is where the application is loaded (if present). It is
a good place to record an revent here to perform any tasks to get
ready for the main part of the workload to start.
:run: This stage is where the main work of the workload should be performed.
This will allow for more accurate results if the revent file for this
stage only records the main actions under test.
:extract_results: This stage is used after the workload has been completed
to retrieve any metrics from the workload e.g. a score.
:teardown: This stage is where any final actions should be performed to
clean up the workload.
Only the run stage is mandatory, the remaining stages will be replayed if a
recording is present otherwise no actions will be performed for that particular
stage.
All your custom revent files should reside at
``'$WA_USER_DIRECTORY/dependencies/WORKLOAD NAME/'``. So
typically to add a custom revent files for a device named "mydevice" and a
workload name "myworkload", you would need to add the revent files to the
directory ``~/.workload_automation/dependencies/myworkload/revent_files``
creating the directory structure if necessary. ::
mydevice.setup.revent
mydevice.run.revent
mydevice.extract_results.revent
mydevice.teardown.revent
Any revent file in the dependencies will always overwrit
gitextract_n5js309u/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ ├── question---support-.md
│ │ └── question.md
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .readthedocs.yml
├── LICENSE
├── MANIFEST.in
├── README.rst
├── dev_scripts/
│ ├── README
│ ├── clean_install
│ ├── clear_env
│ ├── get_apk_versions
│ ├── pep8
│ ├── pylint
│ ├── pylint_plugins.py
│ ├── rebuild_all_uiauto
│ └── update_copyrights
├── doc/
│ ├── Makefile
│ ├── build_instrument_method_map.py
│ ├── build_plugin_docs.py
│ ├── make.bat
│ ├── requirements.txt
│ └── source/
│ ├── api/
│ │ ├── output.rst
│ │ └── workload.rst
│ ├── api.rst
│ ├── changes.rst
│ ├── conf.py
│ ├── developer_information/
│ │ ├── developer_guide/
│ │ │ └── writing_plugins.rst
│ │ ├── developer_guide.rst
│ │ ├── developer_reference/
│ │ │ ├── contributing.rst
│ │ │ ├── framework_overview.rst
│ │ │ ├── plugins.rst
│ │ │ ├── revent.rst
│ │ │ └── serialization.rst
│ │ ├── developer_reference.rst
│ │ ├── how_to.rst
│ │ └── how_tos/
│ │ ├── adding_plugins.rst
│ │ └── processing_output.rst
│ ├── developer_information.rst
│ ├── faq.rst
│ ├── glossary.rst
│ ├── index.rst
│ ├── instrument_method_map.template
│ ├── migration_guide.rst
│ ├── plugins.rst
│ ├── user_information/
│ │ ├── how_to.rst
│ │ ├── how_tos/
│ │ │ ├── agenda.rst
│ │ │ ├── device_setup.rst
│ │ │ └── revent.rst
│ │ ├── installation.rst
│ │ ├── user_guide.rst
│ │ ├── user_reference/
│ │ │ ├── agenda.rst
│ │ │ ├── configuration.rst
│ │ │ ├── invocation.rst
│ │ │ ├── output_directory.rst
│ │ │ └── runtime_parameters.rst
│ │ └── user_reference.rst
│ └── user_information.rst
├── extras/
│ ├── Dockerfile
│ ├── README
│ ├── pylintrc
│ └── walog.vim
├── pytest.ini
├── requirements.txt
├── scripts/
│ ├── cpustates
│ └── wa
├── setup.py
├── tests/
│ ├── __init__.py
│ ├── ci/
│ │ └── idle_agenda.yaml
│ ├── data/
│ │ ├── bad-syntax-agenda.yaml
│ │ ├── extensions/
│ │ │ └── devices/
│ │ │ └── test_device.py
│ │ ├── includes/
│ │ │ ├── agenda.yaml
│ │ │ ├── configs/
│ │ │ │ └── test.yaml
│ │ │ ├── section-include.yaml
│ │ │ ├── sections/
│ │ │ │ ├── section1.yaml
│ │ │ │ └── section2.yaml
│ │ │ ├── user/
│ │ │ │ └── config.yaml
│ │ │ └── workloads.yaml
│ │ ├── interrupts/
│ │ │ ├── after
│ │ │ ├── before
│ │ │ └── result
│ │ ├── logcat.2.log
│ │ ├── logcat.log
│ │ ├── test-agenda.yaml
│ │ └── test-config.py
│ ├── test_agenda_parser.py
│ ├── test_config.py
│ ├── test_diff.py
│ ├── test_exec_control.py
│ ├── test_execution.py
│ ├── test_plugin.py
│ ├── test_runtime_param_utils.py
│ ├── test_signal.py
│ └── test_utils.py
└── wa/
├── __init__.py
├── assets/
│ └── bin/
│ ├── arm64/
│ │ └── revent
│ └── armeabi/
│ └── revent
├── commands/
│ ├── __init__.py
│ ├── create.py
│ ├── list.py
│ ├── postgres_schemas/
│ │ ├── postgres_schema.sql
│ │ ├── postgres_schema_update_v1.2.sql
│ │ ├── postgres_schema_update_v1.3.sql
│ │ ├── postgres_schema_update_v1.4.sql
│ │ ├── postgres_schema_update_v1.5.sql
│ │ └── postgres_schema_update_v1.6.sql
│ ├── process.py
│ ├── report.py
│ ├── revent.py
│ ├── run.py
│ ├── schema_changelog.rst
│ ├── show.py
│ └── templates/
│ ├── apk_workload
│ ├── apkrevent_workload
│ ├── apkuiauto_workload
│ ├── basic_workload
│ ├── revent_workload
│ ├── setup.template
│ ├── uiauto/
│ │ ├── UiAutomation.java
│ │ ├── uiauto_AndroidManifest.xml
│ │ ├── uiauto_build.gradle
│ │ ├── uiauto_build_script
│ │ └── uiauto_workload_template/
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ └── uiauto_workload
├── framework/
│ ├── __init__.py
│ ├── command.py
│ ├── configuration/
│ │ ├── __init__.py
│ │ ├── core.py
│ │ ├── default.py
│ │ ├── execution.py
│ │ ├── parsers.py
│ │ ├── plugin_cache.py
│ │ └── tree.py
│ ├── entrypoint.py
│ ├── exception.py
│ ├── execution.py
│ ├── getters.py
│ ├── host.py
│ ├── instrument.py
│ ├── job.py
│ ├── output.py
│ ├── output_processor.py
│ ├── plugin.py
│ ├── pluginloader.py
│ ├── resource.py
│ ├── run.py
│ ├── signal.py
│ ├── target/
│ │ ├── __init__.py
│ │ ├── assistant.py
│ │ ├── config.py
│ │ ├── descriptor.py
│ │ ├── info.py
│ │ ├── manager.py
│ │ ├── runtime_config.py
│ │ └── runtime_parameter_manager.py
│ ├── uiauto/
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── arm/
│ │ │ └── wa/
│ │ │ └── uiauto/
│ │ │ ├── ActionLogger.java
│ │ │ ├── ApplaunchInterface.java
│ │ │ ├── BaseUiAutomation.java
│ │ │ ├── UiAutoUtils.java
│ │ │ └── UxPerfUiAutomation.java
│ │ ├── build.gradle
│ │ ├── build.sh
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ ├── settings.gradle
│ │ └── uiauto.aar
│ ├── version.py
│ └── workload.py
├── instruments/
│ ├── __init__.py
│ ├── delay.py
│ ├── dmesg.py
│ ├── energy_measurement.py
│ ├── fps.py
│ ├── hwmon.py
│ ├── misc.py
│ ├── perf.py
│ ├── perfetto.py
│ ├── poller/
│ │ ├── Makefile
│ │ ├── __init__.py
│ │ ├── bin/
│ │ │ ├── arm64/
│ │ │ │ └── poller
│ │ │ └── armeabi/
│ │ │ └── poller
│ │ └── poller.c
│ ├── proc_stat/
│ │ ├── __init__.py
│ │ └── gather-load.sh
│ ├── screencap.py
│ ├── serialmon.py
│ └── trace_cmd.py
├── output_processors/
│ ├── __init__.py
│ ├── cpustates.py
│ ├── csvproc.py
│ ├── postgresql.py
│ ├── sqlite.py
│ ├── status.py
│ ├── targz.py
│ └── uxperf.py
├── tools/
│ └── revent/
│ ├── Makefile
│ └── revent.c
├── utils/
│ ├── __init__.py
│ ├── android.py
│ ├── cpustates.py
│ ├── diff.py
│ ├── doc.py
│ ├── exec_control.py
│ ├── formatter.py
│ ├── log.py
│ ├── misc.py
│ ├── postgres.py
│ ├── revent.py
│ ├── serializer.py
│ ├── terminalsize.py
│ ├── trace_cmd.py
│ └── types.py
└── workloads/
├── __init__.py
├── adobereader/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.adobereader.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── adobereader/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── aitutu/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.aitutu.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── aitutu/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── androbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.androbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── androbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── angrybirds_rio/
│ └── __init__.py
├── antutu/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.antutu.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── antutu/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── apache.py
├── applaunch/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.applaunch.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── applaunch/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── benchmarkpi/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.benchmarkpi.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── benchmarkpi/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── chrome/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.chrome.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── deepbench/
│ └── __init__.py
├── dhrystone/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── dhrystone
│ │ └── armeabi/
│ │ └── dhrystone
│ └── src/
│ ├── Makefile
│ └── dhrystone.c
├── drarm/
│ └── __init__.py
├── exoplayer/
│ └── __init__.py
├── geekbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.geekbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── geekbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gfxbench/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.gfxbench.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── gfxbench/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── glbenchmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.glbenchmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── glbenchmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gmail/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.gmail.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── gmail/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googlemaps/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googlemaps.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googlephotos/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googlephotos.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googlephotos/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googleplaybooks/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googleplaybooks.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googleplaybooks/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── googleslides/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.googleslides.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── googleslides/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── hackbench/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── hackbench
│ │ └── armeabi/
│ │ └── hackbench
│ └── src/
│ └── LICENSE
├── homescreen/
│ └── __init__.py
├── honorofkings/
│ └── __init__.py
├── hwuitest/
│ └── __init__.py
├── idle.py
├── jankbench/
│ └── __init__.py
├── lmbench/
│ ├── __init__.py
│ └── bin/
│ ├── COPYING
│ ├── COPYING-2
│ ├── README
│ ├── arm64/
│ │ ├── bw_mem
│ │ └── lat_mem_rd
│ └── armeabi/
│ ├── bw_mem
│ └── lat_mem_rd
├── manual/
│ └── __init__.py
├── meabo/
│ └── __init__.py
├── memcpy/
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ └── memcpy
│ │ └── armeabi/
│ │ └── memcpy
│ └── src/
│ ├── build.sh
│ └── memcopy.c
├── mongoperf/
│ └── __init__.py
├── motionmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.motionmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── motionmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── openssl/
│ └── __init__.py
├── pcmark/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.pcmark.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── pcmark/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── recentfling/
│ └── __init__.py
├── rt_app/
│ ├── LICENSE
│ ├── __init__.py
│ ├── bin/
│ │ ├── arm64/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── armeabi/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── ppc64le/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ ├── x86/
│ │ │ ├── README.rt-app
│ │ │ └── rt-app
│ │ └── x86_64/
│ │ ├── README.rt-app
│ │ └── rt-app
│ ├── use_cases/
│ │ ├── browser-long.json
│ │ ├── browser-short.json
│ │ ├── camera-long.json
│ │ ├── camera-short.json
│ │ ├── mp3-long.json
│ │ ├── mp3-short.json
│ │ ├── spreading-tasks.json
│ │ ├── taskset.json
│ │ ├── video-long.json
│ │ └── video-short.json
│ └── workgen
├── schbench/
│ ├── __init__.py
│ ├── bin/
│ │ └── arm64/
│ │ └── schbench
│ └── src/
│ └── LICENSE
├── shellscript/
│ └── __init__.py
├── speedometer/
│ ├── LICENSE
│ ├── __init__.py
│ ├── speedometer_archive-2.0.tar.lzma
│ ├── speedometer_archive-2.1.tar.lzma
│ └── speedometer_archive-3.0.tar.lzma
├── stress_ng/
│ ├── LICENSE
│ ├── __init__.py
│ └── bin/
│ ├── arm64/
│ │ └── stress-ng
│ └── armeabi/
│ └── stress-ng
├── sysbench/
│ ├── LICENSE
│ ├── __init__.py
│ └── bin/
│ ├── arm64/
│ │ └── sysbench
│ └── armeabi/
│ └── sysbench
├── templerun2/
│ └── __init__.py
├── the_chase/
│ └── __init__.py
├── uibench/
│ └── __init__.py
├── uibenchjanktests/
│ └── __init__.py
├── vellamo/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.vellamo.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── vellamo/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── youtube/
│ ├── __init__.py
│ ├── com.arm.wa.uiauto.youtube.apk
│ └── uiauto/
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/
│ │ └── com/
│ │ └── arm/
│ │ └── wa/
│ │ └── uiauto/
│ │ └── youtube/
│ │ └── UiAutomation.java
│ ├── build.gradle
│ ├── build.sh
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
└── youtube_playback/
└── __init__.py
SYMBOL INDEX (2654 symbols across 165 files)
FILE: dev_scripts/pylint_plugins.py
function register (line 16) | def register(linter):
function transform (line 20) | def transform(mod):
FILE: doc/build_instrument_method_map.py
function generate_instrument_method_map (line 28) | def generate_instrument_method_map(outfile):
FILE: doc/build_plugin_docs.py
function insert_contents_table (line 35) | def insert_contents_table(title='', depth=1):
function generate_plugin_documentation (line 48) | def generate_plugin_documentation(source_dir, outdir, ignore_paths):
function generate_target_documentation (line 74) | def generate_target_documentation(outdir):
function generate_run_config_documentation (line 111) | def generate_run_config_documentation(outdir):
function generate_meta_config_documentation (line 115) | def generate_meta_config_documentation(outdir):
function generate_config_documentation (line 119) | def generate_config_documentation(config, outdir):
FILE: doc/source/conf.py
function setup (line 310) | def setup(app):
FILE: setup.py
class sdist (line 123) | class sdist(orig_sdist):
method initialize_options (line 130) | def initialize_options(self):
method run (line 134) | def run(self):
FILE: tests/data/extensions/devices/test_device.py
class MockDevice (line 20) | class MockDevice(Plugin):
method __init__ (line 25) | def __init__(self, *args, **kwargs):
method boot (line 33) | def boot(self):
method push_file (line 36) | def push_file(self, source, dest):
method pull_file (line 39) | def pull_file(self, source, dest):
method execute (line 42) | def execute(self, command):
method set_sysfile_int (line 45) | def set_sysfile_int(self, file, value):
method close (line 48) | def close(self, command):
FILE: tests/test_agenda_parser.py
class AgendaTest (line 127) | class AgendaTest(TestCase):
method setUp (line 129) | def setUp(self):
method test_yaml_load (line 134) | def test_yaml_load(self):
method test_duplicate_id (line 138) | def test_duplicate_id(self):
method test_yaml_missing_field (line 148) | def test_yaml_missing_field(self):
method test_defaults (line 158) | def test_defaults(self):
method test_default_id_assignment (line 167) | def test_default_id_assignment(self):
method test_sections (line 175) | def test_sections(self):
method test_yaml_anchors (line 188) | def test_yaml_anchors(self):
method test_dup_sections (line 202) | def test_dup_sections(self):
method test_bad_syntax (line 207) | def test_bad_syntax(self):
class FakeTargetManager (line 211) | class FakeTargetManager:
method merge_runtime_parameters (line 213) | def merge_runtime_parameters(self, params):
method validate_runtime_parameters (line 216) | def validate_runtime_parameters(self, params):
class IncludesTest (line 220) | class IncludesTest(TestCase):
method test_includes (line 222) | def test_includes(self):
FILE: tests/test_config.py
class TestConfigUtils (line 23) | class TestConfigUtils(unittest.TestCase):
method test_merge_values (line 25) | def test_merge_values(self):
class TestConfigParser (line 44) | class TestConfigParser(unittest.TestCase):
method test_param_merge (line 46) | def test_param_merge(self):
FILE: tests/test_diff.py
class InterruptDiffTest (line 28) | class InterruptDiffTest(TestCase):
method test_interrupt_diff (line 30) | def test_interrupt_diff(self):
FILE: tests/test_exec_control.py
class MockClass (line 27) | class MockClass(object):
method __init__ (line 31) | def __init__(self):
method called_once (line 35) | def called_once(self):
method initilize_once (line 39) | def initilize_once(self):
method initilize_once_per_class (line 43) | def initilize_once_per_class(self):
method initilize_once_per_instance (line 47) | def initilize_once_per_instance(self):
method __repr__ (line 50) | def __repr__(self):
class SubClass (line 54) | class SubClass(MockClass):
method __init__ (line 56) | def __init__(self):
method initilize_once (line 60) | def initilize_once(self):
method initilize_once_per_class (line 65) | def initilize_once_per_class(self):
method initilize_once_per_instance (line 70) | def initilize_once_per_instance(self):
class SubSubClass (line 75) | class SubSubClass(SubClass):
method __init__ (line 77) | def __init__(self):
method initilize_once (line 81) | def initilize_once(self):
method initilize_once_per_class (line 86) | def initilize_once_per_class(self):
method initilize_once_per_instance (line 91) | def initilize_once_per_instance(self):
class AnotherClass (line 96) | class AnotherClass(object):
method __init__ (line 98) | def __init__(self):
method initilize_once (line 102) | def initilize_once(self):
method initilize_once_per_class (line 106) | def initilize_once_per_class(self):
method initilize_once_per_instance (line 110) | def initilize_once_per_instance(self):
class NamedClass (line 114) | class NamedClass:
method __init__ (line 118) | def __init__(self, name):
method initilize (line 122) | def initilize(self):
class AnotherSubClass (line 126) | class AnotherSubClass(MockClass):
method __init__ (line 128) | def __init__(self):
method initilize_once (line 132) | def initilize_once(self):
method initilize_once_per_class (line 137) | def initilize_once_per_class(self):
method initilize_once_per_instance (line 142) | def initilize_once_per_instance(self):
class EnvironmentManagementTest (line 147) | class EnvironmentManagementTest(TestCase):
method test_duplicate_environment (line 149) | def test_duplicate_environment(self):
method test_reset_missing_environment (line 153) | def test_reset_missing_environment(self):
method test_reset_current_environment (line 156) | def test_reset_current_environment(self):
method test_switch_environment (line 166) | def test_switch_environment(self):
method test_reset_environment_name (line 180) | def test_reset_environment_name(self):
class ParentOnlyOnceEvironmentTest (line 191) | class ParentOnlyOnceEvironmentTest(TestCase):
method test_sub_classes (line 192) | def test_sub_classes(self):
class OnlyOnceEnvironmentTest (line 202) | class OnlyOnceEnvironmentTest(TestCase):
method setUp (line 204) | def setUp(self):
method tearDown (line 207) | def tearDown(self):
method test_single_instance (line 210) | def test_single_instance(self):
method test_mulitple_instances (line 224) | def test_mulitple_instances(self):
method test_sub_classes (line 235) | def test_sub_classes(self):
class OncePerClassEnvironmentTest (line 257) | class OncePerClassEnvironmentTest(TestCase):
method setUp (line 259) | def setUp(self):
method tearDown (line 262) | def tearDown(self):
method test_single_instance (line 265) | def test_single_instance(self):
method test_mulitple_instances (line 279) | def test_mulitple_instances(self):
method test_sub_classes (line 290) | def test_sub_classes(self):
class OncePerInstanceEnvironmentTest (line 315) | class OncePerInstanceEnvironmentTest(TestCase):
method setUp (line 317) | def setUp(self):
method tearDown (line 320) | def tearDown(self):
method test_single_instance (line 323) | def test_single_instance(self):
method test_mulitple_instances (line 337) | def test_mulitple_instances(self):
method test_sub_classes (line 348) | def test_sub_classes(self):
class OncePerAttributeValueTest (line 370) | class OncePerAttributeValueTest(TestCase):
method setUp (line 372) | def setUp(self):
method tearDown (line 375) | def tearDown(self):
method test_once_attribute_value (line 378) | def test_once_attribute_value(self):
FILE: tests/test_execution.py
class MockConfigManager (line 35) | class MockConfigManager(Mock):
method jobs (line 38) | def jobs(self):
method loaded_config_sources (line 42) | def loaded_config_sources(self):
method plugin_cache (line 46) | def plugin_cache(self):
method __init__ (line 49) | def __init__(self, *args, **kwargs):
method to_pod (line 54) | def to_pod(self):
class MockPluginCache (line 58) | class MockPluginCache(Mock):
method list_plugins (line 60) | def list_plugins(self, kind=None):
class MockProcessorManager (line 64) | class MockProcessorManager(Mock):
method __init__ (line 66) | def __init__(self, *args, **kwargs):
method get_enabled (line 69) | def get_enabled(self):
class JobState_force_retry (line 73) | class JobState_force_retry(JobState):
method status (line 76) | def status(self):
method status (line 80) | def status(self, value):
method __init__ (line 90) | def __init__(self, to_retry, *args, **kwargs):
class Job_force_retry (line 98) | class Job_force_retry(Job):
method __init__ (line 102) | def __init__(self, to_retry, *args, **kwargs):
method initialize (line 108) | def initialize(self, context):
method finalize (line 112) | def finalize(self, context):
class TestRunState (line 117) | class TestRunState(TestCase):
method setUp (line 119) | def setUp(self):
method tearDown (line 126) | def tearDown(self):
method test_job_state_transitions_pass (line 135) | def test_job_state_transitions_pass(self):
method test_job_state_transitions_fail (line 146) | def test_job_state_transitions_fail(self):
method test_job_state_transitions_retry (line 157) | def test_job_state_transitions_retry(self):
method initialise_signals (line 168) | def initialise_signals(self):
method _verify_serialized_state (line 177) | def _verify_serialized_state(self, _):
class TestJobState (line 192) | class TestJobState(TestCase):
method test_job_retry_status (line 194) | def test_job_retry_status(self):
method test_skipped_job_state (line 211) | def test_skipped_job_state(self):
method test_normal_job_finalized (line 236) | def test_normal_job_finalized(self):
method test_skipped_job_finalized (line 253) | def test_skipped_job_finalized(self):
method test_failed_job_finalized (line 277) | def test_failed_job_finalized(self):
function get_context (line 300) | def get_context(path=None):
function get_jobspec (line 311) | def get_jobspec():
FILE: tests/test_plugin.py
class PluginLoaderTest (line 31) | class PluginLoaderTest(TestCase):
method setUp (line 33) | def setUp(self):
method test_load_device (line 36) | def test_load_device(self):
method test_list_by_kind (line 40) | def test_list_by_kind(self):
class MyBasePlugin (line 47) | class MyBasePlugin(Plugin):
method __init__ (line 56) | def __init__(self, **kwargs):
method virtual1 (line 62) | def virtual1(self):
method virtual2 (line 66) | def virtual2(self):
class MyAcidPlugin (line 70) | class MyAcidPlugin(MyBasePlugin):
method __init__ (line 80) | def __init__(self, **kwargs):
method virtual1 (line 85) | def virtual1(self):
method virtual2 (line 89) | def virtual2(self):
class MyOtherPlugin (line 93) | class MyOtherPlugin(MyBasePlugin):
class MyOtherOtherPlugin (line 102) | class MyOtherOtherPlugin(MyOtherPlugin):
class MyOverridingPlugin (line 111) | class MyOverridingPlugin(MyAcidPlugin):
class MyThirdTeerPlugin (line 120) | class MyThirdTeerPlugin(MyOverridingPlugin):
class MultiValueParamExt (line 125) | class MultiValueParamExt(Plugin):
class PluginMetaTest (line 135) | class PluginMetaTest(TestCase):
method test_propagation (line 137) | def test_propagation(self):
method test_duplicate_param_spec (line 142) | def test_duplicate_param_spec(self):
method test_param_override (line 148) | def test_param_override(self):
method test_invalid_param_spec (line 156) | def test_invalid_param_spec(self):
class ParametersTest (line 163) | class ParametersTest(TestCase):
method test_setting (line 165) | def test_setting(self):
method test_validation_ok (line 171) | def test_validation_ok(self):
method test_default_override (line 175) | def test_default_override(self):
method test_multivalue_param (line 181) | def test_multivalue_param(self):
method test_bad_multivalue_param (line 187) | def test_bad_multivalue_param(self):
method test_validation_no_mandatory (line 192) | def test_validation_no_mandatory(self):
method test_validation_no_mandatory_in_derived (line 197) | def test_validation_no_mandatory_in_derived(self):
method test_validation_bad_value (line 201) | def test_validation_bad_value(self):
FILE: tests/test_runtime_param_utils.py
class TestRuntimeParameterUtils (line 22) | class TestRuntimeParameterUtils(unittest.TestCase):
method test_resolve_cpu (line 24) | def test_resolve_cpu(self):
FILE: tests/test_signal.py
class Callable (line 24) | class Callable(object):
method __init__ (line 26) | def __init__(self, val):
method __call__ (line 29) | def __call__(self):
class TestSignalDisconnect (line 33) | class TestSignalDisconnect(unittest.TestCase):
method __init__ (line 35) | def __init__(self, *args, **kwargs):
method setUp (line 39) | def setUp(self):
method test_handler_disconnected (line 43) | def test_handler_disconnected(self):
method _call_me_once (line 47) | def _call_me_once(self):
class TestPriorityDispatcher (line 54) | class TestPriorityDispatcher(unittest.TestCase):
method setUp (line 56) | def setUp(self):
method test_ConnectNotify (line 61) | def test_ConnectNotify(self):
method test_wrap_propagate (line 83) | def test_wrap_propagate(self):
FILE: tests/test_utils.py
class TestPriorityList (line 28) | class TestPriorityList(TestCase):
method test_insert (line 30) | def test_insert(self):
method test_delete (line 45) | def test_delete(self):
method test_multiple (line 61) | def test_multiple(self):
method test_iterator_break (line 73) | def test_iterator_break(self):
method test_add_before_after (line 84) | def test_add_before_after(self):
class TestEnumLevel (line 98) | class TestEnumLevel(TestCase):
method test_enum_creation (line 100) | def test_enum_creation(self):
method test_enum_name_conflicts (line 110) | def test_enum_name_conflicts(self):
method test_enum_behavior (line 120) | def test_enum_behavior(self):
method test_serialize_level (line 141) | def test_serialize_level(self):
method test_deserialize_enum (line 147) | def test_deserialize_enum(self):
class TestToggleSet (line 154) | class TestToggleSet(TestCase):
method test_equality (line 156) | def test_equality(self):
method test_merge (line 164) | def test_merge(self):
method test_drop_all_previous (line 180) | def test_drop_all_previous(self):
method test_order_on_create (line 194) | def test_order_on_create(self):
FILE: wa/commands/create.py
function copy_tree (line 46) | def copy_tree(src, dst):
function copy_tree (line 57) | def copy_tree(src, dst):
class CreateDatabaseSubcommand (line 67) | class CreateDatabaseSubcommand(SubCommand):
method __init__ (line 78) | def __init__(self, *args, **kwargs):
method initialize (line 91) | def initialize(self, context):
method execute (line 123) | def execute(self, state, args): # pylint: disable=too-many-branches
method create_database (line 196) | def create_database(self):
method update_schema (line 208) | def update_schema(self):
method _update_schema_minors (line 219) | def _update_schema_minors(self, major, minor, meta_oid):
method _update_schema_major (line 236) | def _update_schema_major(self, current_major, current_minor, meta_oid):
method _validate_version (line 251) | def _validate_version(self):
method _get_database_schema_version (line 258) | def _get_database_schema_version(self):
method _check_database_existence (line 270) | def _check_database_existence(self):
method _create_database_postgres (line 285) | def _create_database_postgres(self):
method _apply_database_schema (line 296) | def _apply_database_schema(self, sql_commands, schema_major, schema_mi...
method _update_configuration_file (line 321) | def _update_configuration_file(self, config):
method _parse_args (line 331) | def _parse_args(self, args):
class CreateAgendaSubcommand (line 341) | class CreateAgendaSubcommand(SubCommand):
method initialize (line 349) | def initialize(self, context):
method execute (line 358) | def execute(self, state, args):
class CreateWorkloadSubcommand (line 410) | class CreateWorkloadSubcommand(SubCommand):
method initialize (line 416) | def initialize(self, context):
method execute (line 429) | def execute(self, state, args): # pylint: disable=R0201
class CreatePackageSubcommand (line 439) | class CreatePackageSubcommand(SubCommand):
method initialize (line 446) | def initialize(self, context):
method execute (line 456) | def execute(self, state, args): # pylint: disable=R0201
method create_extensions_package (line 461) | def create_extensions_package(self, location, name, setup_template_pat...
class CreateCommand (line 477) | class CreateCommand(ComplexCommand):
function create_workload (line 493) | def create_workload(name, kind='basic', where='local', check_name=True, ...
function create_template_workload (line 515) | def create_template_workload(path, name, kind, class_name):
function create_uiautomator_template_workload (line 521) | def create_uiautomator_template_workload(path, name, kind, class_name):
function create_uiauto_project (line 527) | def create_uiauto_project(path, name):
function render_template (line 570) | def render_template(name, params):
function get_class_name (line 578) | def get_class_name(name, postfix=''):
function touch (line 583) | def touch(path):
FILE: wa/commands/list.py
class ListCommand (line 24) | class ListCommand(Command):
method initialize (line 29) | def initialize(self, context):
method execute (line 51) | def execute(self, state, args):
function get_kinds (line 77) | def get_kinds():
function list_targets (line 86) | def list_targets():
function list_plugins (line 97) | def list_plugins(args, filters):
function check_platform (line 123) | def check_platform(plugin, platform):
FILE: wa/commands/postgres_schemas/postgres_schema.sql
type DatabaseMeta (line 31) | CREATE TABLE DatabaseMeta (
type Runs (line 38) | CREATE TABLE Runs (
type Jobs (line 62) | CREATE TABLE Jobs (
type Targets (line 77) | CREATE TABLE Targets (
type Events (line 104) | CREATE TABLE Events (
type Resource_Getters (line 115) | CREATE TABLE Resource_Getters (
type Augmentations (line 122) | CREATE TABLE Augmentations (
type Jobs_Augs (line 129) | CREATE TABLE Jobs_Augs (
type Metrics (line 136) | CREATE TABLE Metrics (
type LargeObjects (line 149) | CREATE TABLE LargeObjects (
type Artifacts (line 159) | CREATE TABLE Artifacts (
type Classifiers (line 179) | CREATE TABLE Classifiers (
type Parameters (line 190) | CREATE TABLE Parameters (
FILE: wa/commands/process.py
class ProcessContext (line 27) | class ProcessContext(object):
method __init__ (line 29) | def __init__(self):
method add_augmentation (line 34) | def add_augmentation(self, aug):
class ProcessCommand (line 38) | class ProcessCommand(Command):
method initialize (line 43) | def initialize(self, context):
method execute (line 72) | def execute(self, config, args): # pylint: disable=arguments-differ,t...
FILE: wa/commands/report.py
class ReportCommand (line 14) | class ReportCommand(Command):
method initialize (line 50) | def initialize(self, context):
method execute (line 58) | def execute(self, state, args):
class RunMonitor (line 95) | class RunMonitor:
method elapsed_time (line 98) | def elapsed_time(self):
method job_outputs (line 107) | def job_outputs(self):
method projected_duration (line 115) | def projected_duration(self):
method __init__ (line 120) | def __init__(self, ro):
method get_data (line 129) | def get_data(self):
method generate_run_header (line 138) | def generate_run_header(self):
method generate_job_summary (line 168) | def generate_job_summary(self):
method generate_job_detail (line 188) | def generate_job_detail(self):
method generate_run_detail (line 206) | def generate_run_detail(self):
method generate_output (line 214) | def generate_output(self, verbose):
function _seconds_as_smh (line 228) | def _seconds_as_smh(seconds):
function segment_jobs_by_state (line 236) | def segment_jobs_by_state(jobstates, max_retries, retry_status):
class _simple_formatter (line 264) | class _simple_formatter:
method __init__ (line 272) | def __init__(self):
method fit_term_width (line 276) | def fit_term_width(self, text):
method highlight_keyword (line 283) | def highlight_keyword(self, kw):
FILE: wa/commands/revent.py
class RecordCommand (line 28) | class RecordCommand(Command):
method __init__ (line 56) | def __init__(self, **kwargs):
method initialize (line 62) | def initialize(self, context):
method validate_args (line 88) | def validate_args(self, args):
method execute (line 103) | def execute(self, state, args):
method record (line 133) | def record(self, revent_file, name, output_path):
method manual_record (line 161) | def manual_record(self, args):
method package_record (line 168) | def package_record(self, args):
method workload_record (line 185) | def workload_record(self, args):
method _split_revent_location (line 218) | def _split_revent_location(self, output):
class ReplayCommand (line 232) | class ReplayCommand(Command):
method initialize (line 242) | def initialize(self, context):
method execute (line 251) | def execute(self, state, args):
class LightContext (line 287) | class LightContext(object):
method __init__ (line 289) | def __init__(self, tm):
method get_resource (line 294) | def get_resource(self, resource, strict=True):
method update_metadata (line 297) | def update_metadata(self, key, *args):
FILE: wa/commands/run.py
class RunCommand (line 32) | class RunCommand(Command):
method initialize (line 40) | def initialize(self, context):
method execute (line 87) | def execute(self, config, args): # pylint: disable=arguments-differ
method set_up_output_directory (line 123) | def set_up_output_directory(self, config, args):
FILE: wa/commands/show.py
class ShowCommand (line 38) | class ShowCommand(Command):
method initialize (line 43) | def initialize(self, context):
method execute (line 47) | def execute(self, state, args):
function get_target_description (line 102) | def get_target_description(name):
function get_rst_from_target (line 109) | def get_rst_from_target(target):
function get_rst_for_global_config (line 123) | def get_rst_for_global_config():
function get_rst_for_envars (line 135) | def get_rst_for_envars():
FILE: wa/commands/templates/uiauto/UiAutomation.java
class UiAutomation (line 24) | @RunWith(AndroidJUnit4.class)
method initialize (line 33) | @Before
method setup (line 41) | @Test
method runWorkload (line 47) | @Test
method extractResults (line 52) | @Test
method teardown (line 57) | @Test
FILE: wa/framework/command.py
function init_argument_parser (line 24) | def init_argument_parser(parser):
class SubCommand (line 34) | class SubCommand(object):
method __init__ (line 50) | def __init__(self, logger, subparsers):
method initialize (line 62) | def initialize(self, context):
method execute (line 69) | def execute(self, state, args):
class Command (line 84) | class Command(Plugin, SubCommand): # pylint: disable=abstract-method
method __init__ (line 95) | def __init__(self, subparsers):
class ComplexCommand (line 100) | class ComplexCommand(Command):
method __init__ (line 108) | def __init__(self, subparsers):
method initialize (line 112) | def initialize(self, context):
method execute (line 119) | def execute(self, state, args):
FILE: wa/framework/configuration/core.py
class RebootPolicy (line 48) | class RebootPolicy(object):
method from_pod (line 68) | def from_pod(pod):
method __init__ (line 71) | def __init__(self, policy):
method can_reboot (line 81) | def can_reboot(self):
method perform_initial_reboot (line 85) | def perform_initial_reboot(self):
method reboot_on_each_job (line 89) | def reboot_on_each_job(self):
method reboot_on_each_spec (line 93) | def reboot_on_each_spec(self):
method reboot_on_run_completion (line 97) | def reboot_on_run_completion(self):
method __str__ (line 100) | def __str__(self):
method __eq__ (line 105) | def __eq__(self, other):
method to_pod (line 111) | def to_pod(self):
class status_list (line 115) | class status_list(list):
method append (line 117) | def append(self, item):
class LoggingConfig (line 121) | class LoggingConfig(Podable, dict):
method from_pod (line 133) | def from_pod(pod):
method __init__ (line 140) | def __init__(self, config=None):
method to_pod (line 159) | def to_pod(self):
method _pod_upgrade_v1 (line 165) | def _pod_upgrade_v1(pod):
function expanded_path (line 170) | def expanded_path(path):
function get_type_name (line 177) | def get_type_name(kind):
class ConfigurationPoint (line 186) | class ConfigurationPoint(object):
method __init__ (line 193) | def __init__(self, name,
method match (line 288) | def match(self, name):
method set_value (line 295) | def set_value(self, obj, value=None, check_mandatory=True):
method validate (line 321) | def validate(self, obj, check_mandatory=True):
method validate_value (line 332) | def validate_value(self, name, value):
method validate_allowed_values (line 338) | def validate_allowed_values(self, name, value):
method validate_constraint (line 349) | def validate_constraint(self, name, value):
method __repr__ (line 361) | def __repr__(self):
function _to_pod (line 374) | def _to_pod(cfg_point, value):
class Configuration (line 383) | class Configuration(Podable):
method from_pod (line 393) | def from_pod(cls, pod):
method __init__ (line 406) | def __init__(self):
method set (line 411) | def set(self, name, value, check_mandatory=True):
method update_config (line 422) | def update_config(self, values, check_mandatory=True):
method validate (line 426) | def validate(self):
method to_pod (line 430) | def to_pod(self):
method _pod_upgrade_v1 (line 438) | def _pod_upgrade_v1(pod):
class MetaConfiguration (line 444) | class MetaConfiguration(Configuration):
method dependencies_directory (line 518) | def dependencies_directory(self):
method plugins_directory (line 522) | def plugins_directory(self):
method cache_directory (line 526) | def cache_directory(self):
method plugin_paths (line 530) | def plugin_paths(self):
method user_config_file (line 534) | def user_config_file(self):
method additional_packages_file (line 538) | def additional_packages_file(self):
method target_info_cache_file (line 542) | def target_info_cache_file(self):
method apk_info_cache_file (line 546) | def apk_info_cache_file(self):
method __init__ (line 549) | def __init__(self, environ=None):
class RunConfiguration (line 569) | class RunConfiguration(Configuration):
method from_pod (line 763) | def from_pod(cls, pod):
method __init__ (line 780) | def __init__(self):
method merge_device_config (line 788) | def merge_device_config(self, plugin_cache):
method add_augmentation (line 800) | def add_augmentation(self, aug):
method add_resource_getter (line 805) | def add_resource_getter(self, getter):
method to_pod (line 810) | def to_pod(self):
class JobSpec (line 818) | class JobSpec(Configuration):
method from_pod (line 883) | def from_pod(cls, pod):
method section_id (line 890) | def section_id(self):
method workload_id (line 895) | def workload_id(self):
method __init__ (line 899) | def __init__(self):
method to_pod (line 911) | def to_pod(self):
method update_config (line 916) | def update_config(self, source, check_mandatory=True): # pylint: disa...
method merge_workload_parameters (line 932) | def merge_workload_parameters(self, plugin_cache):
method merge_runtime_parameters (line 955) | def merge_runtime_parameters(self, plugin_cache, target_manager):
method finalize (line 974) | def finalize(self):
class JobGenerator (line 988) | class JobGenerator(object):
method enabled_instruments (line 993) | def enabled_instruments(self):
method enabled_processors (line 1004) | def enabled_processors(self):
method __init__ (line 1014) | def __init__(self, plugin_cache):
method set_global_value (line 1033) | def set_global_value(self, name, value):
method add_section (line 1039) | def add_section(self, section, workloads, group):
method add_workload (line 1045) | def add_workload(self, workload):
method disable_augmentations (line 1048) | def disable_augmentations(self, augmentations):
method update_augmentations (line 1060) | def update_augmentations(self, value):
method only_run_ids (line 1066) | def only_run_ids(self, ids):
method generate_job_specs (line 1071) | def generate_job_specs(self, target_manager):
function create_job_spec (line 1095) | def create_job_spec(workload_entry, sections, target_manager, plugin_cache,
function get_config_point_map (line 1124) | def get_config_point_map(params):
FILE: wa/framework/configuration/default.py
function _format_yaml_comment (line 31) | def _format_yaml_comment(param, short_description=False):
function _format_augmentations (line 41) | def _format_augmentations(output):
function generate_default_config (line 51) | def generate_default_config(path):
function write_param_yaml (line 59) | def write_param_yaml(entry, param, output):
FILE: wa/framework/configuration/execution.py
class CombinedConfig (line 33) | class CombinedConfig(Podable):
method from_pod (line 38) | def from_pod(pod):
method __init__ (line 44) | def __init__(self, settings=None, run_config=None): # pylint: disable...
method to_pod (line 49) | def to_pod(self):
method _pod_upgrade_v1 (line 56) | def _pod_upgrade_v1(pod):
class ConfigManager (line 61) | class ConfigManager(object):
method enabled_instruments (line 71) | def enabled_instruments(self):
method enabled_processors (line 75) | def enabled_processors(self):
method job_specs (line 79) | def job_specs(self):
method jobs (line 87) | def jobs(self):
method __init__ (line 94) | def __init__(self, settings=settings): # pylint: disable=redefined-ou...
method load_config_file (line 105) | def load_config_file(self, filepath):
method load_config (line 110) | def load_config(self, values, source):
method get_plugin (line 114) | def get_plugin(self, name=None, kind=None, *args, **kwargs):
method get_instruments (line 117) | def get_instruments(self, target):
method get_processors (line 128) | def get_processors(self):
method get_config (line 139) | def get_config(self):
method finalize (line 142) | def finalize(self):
method generate_jobs (line 149) | def generate_jobs(self, context):
function permute_by_workload (line 165) | def permute_by_workload(specs):
function permute_by_iteration (line 176) | def permute_by_iteration(specs):
function permute_by_section (line 203) | def permute_by_section(specs):
function permute_randomly (line 229) | def permute_randomly(specs):
function permute_iterations (line 251) | def permute_iterations(specs, exec_order):
FILE: wa/framework/configuration/parsers.py
class ConfigParser (line 34) | class ConfigParser(object):
method load_from_path (line 36) | def load_from_path(self, state, filepath):
method load (line 41) | def load(self, state, raw, source, wrap_exceptions=True): # pylint: d...
class AgendaParser (line 92) | class AgendaParser(object):
method load_from_path (line 94) | def load_from_path(self, state, filepath):
method load (line 99) | def load(self, state, raw, source):
method _populate_and_validate_config (line 129) | def _populate_and_validate_config(self, state, raw, source):
method _pop_sections (line 146) | def _pop_sections(self, raw):
method _pop_workloads (line 155) | def _pop_workloads(self, raw):
method _collect_ids (line 161) | def _collect_ids(self, sections, global_workloads):
method _process_global_workloads (line 178) | def _process_global_workloads(self, state, global_workloads, seen_wkl_...
method _process_sections (line 184) | def _process_sections(self, state, sections, seen_sect_ids, seen_wkl_i...
function pop_aliased_param (line 209) | def pop_aliased_param(cfg_point, d, default=None):
function _load_file (line 227) | def _load_file(filepath, error_name):
function _config_values_from_includes (line 241) | def _config_values_from_includes(filepath, include_path, error_name):
function _process_includes (line 271) | def _process_includes(raw, filepath, error_name):
function merge_augmentations (line 300) | def merge_augmentations(raw):
function _pop_aliased (line 342) | def _pop_aliased(d, names, entry_id):
function _construct_valid_entry (line 354) | def _construct_valid_entry(raw, seen_ids, prefix, jobs_config):
function _collect_valid_id (line 393) | def _collect_valid_id(entry_id, seen_ids, entry_type):
function _get_workload_entry (line 409) | def _get_workload_entry(workload):
function _process_workload_entry (line 417) | def _process_workload_entry(workload, seen_workload_ids, jobs_config):
FILE: wa/framework/configuration/plugin_cache.py
class PluginCache (line 31) | class PluginCache(object):
method __init__ (line 40) | def __init__(self, loader=pluginloader):
method add_source (line 56) | def add_source(self, source):
method add_global_alias (line 62) | def add_global_alias(self, alias, value, source):
method add_configs (line 73) | def add_configs(self, plugin_name, values, source):
method is_global_alias (line 105) | def is_global_alias(self, name):
method list_plugins (line 108) | def list_plugins(self, kind=None):
method get_plugin_config (line 111) | def get_plugin_config(self, plugin_name, generic_name=None, is_final=T...
method get_plugin (line 137) | def get_plugin(self, name, kind=None, *args, **kwargs):
method get_plugin_class (line 142) | def get_plugin_class(self, name, kind=None):
method get_plugin_parameters (line 146) | def get_plugin_parameters(self, name):
method resolve_alias (line 152) | def resolve_alias(self, name):
method _set_plugin_defaults (line 155) | def _set_plugin_defaults(self, plugin_name, config):
method _set_from_global_aliases (line 167) | def _set_from_global_aliases(self, plugin_name, config):
method _get_target_params (line 176) | def _get_target_params(self, name):
method _merge_using_priority_specificity (line 181) | def _merge_using_priority_specificity(self, specific_name,
method __getattr__ (line 236) | def __getattr__(self, name):
class MergeState (line 273) | class MergeState(object):
method __init__ (line 275) | def __init__(self):
function update_config_from_source (line 284) | def update_config_from_source(final_config, source, state):
FILE: wa/framework/configuration/tree.py
class JobSpecSource (line 23) | class JobSpecSource(object):
method __init__ (line 27) | def __init__(self, config, parent=None):
method id (line 33) | def id(self):
method name (line 37) | def name(self):
method _log_self (line 40) | def _log_self(self):
class WorkloadEntry (line 47) | class WorkloadEntry(JobSpecSource):
method name (line 51) | def name(self):
class SectionNode (line 58) | class SectionNode(JobSpecSource):
method name (line 63) | def name(self):
method is_leaf (line 70) | def is_leaf(self):
method __init__ (line 73) | def __init__(self, config, parent=None, group=None):
method add_section (line 79) | def add_section(self, section, group=None):
method add_workload (line 89) | def add_workload(self, workload_config):
method descendants (line 92) | def descendants(self):
method ancestors (line 98) | def ancestors(self):
method leaves (line 104) | def leaves(self):
FILE: wa/framework/entrypoint.py
function load_commands (line 49) | def load_commands(subparsers):
function split_joined_options (line 62) | def split_joined_options(argv):
function check_devlib_version (line 74) | def check_devlib_version():
function check_system_encoding (line 84) | def check_system_encoding():
function main (line 94) | def main():
FILE: wa/framework/exception.py
class WAError (line 22) | class WAError(Exception):
method message (line 25) | def message(self):
class NotFoundError (line 31) | class NotFoundError(WAError):
class ValidationError (line 35) | class ValidationError(WAError):
class ExecutionError (line 39) | class ExecutionError(WAError):
class WorkloadError (line 43) | class WorkloadError(WAError):
class JobError (line 47) | class JobError(WAError):
class InstrumentError (line 51) | class InstrumentError(WAError):
class OutputProcessorError (line 55) | class OutputProcessorError(WAError):
class ResourceError (line 59) | class ResourceError(WAError):
class CommandError (line 63) | class CommandError(WAError):
class ToolError (line 68) | class ToolError(WAError):
class ConfigError (line 73) | class ConfigError(WAError):
class SerializerSyntaxError (line 78) | class SerializerSyntaxError(Exception):
method message (line 83) | def message(self):
method __init__ (line 88) | def __init__(self, message, line=None, column=None):
method __str__ (line 93) | def __str__(self):
class PluginLoaderError (line 100) | class PluginLoaderError(WAError):
method __init__ (line 107) | def __init__(self, message, exc_info=None):
method __str__ (line 111) | def __str__(self):
class WorkerThreadError (line 125) | class WorkerThreadError(WAError):
method __init__ (line 136) | def __init__(self, thread, exc_info):
FILE: wa/framework/execution.py
class ExecutionContext (line 39) | class ExecutionContext(object):
method previous_job (line 42) | def previous_job(self):
method next_job (line 48) | def next_job(self):
method spec_changed (line 54) | def spec_changed(self):
method spec_will_change (line 62) | def spec_will_change(self):
method workload (line 70) | def workload(self):
method job_output (line 75) | def job_output(self):
method output (line 80) | def output(self):
method output_directory (line 86) | def output_directory(self):
method reboot_policy (line 90) | def reboot_policy(self):
method target_info (line 94) | def target_info(self):
method __init__ (line 97) | def __init__(self, cm, tm, output):
method start_run (line 111) | def start_run(self):
method end_run (line 120) | def end_run(self):
method finalize (line 135) | def finalize(self):
method start_job (line 138) | def start_job(self):
method end_job (line 146) | def end_job(self):
method set_status (line 153) | def set_status(self, status, force=False, write=True):
method set_job_status (line 158) | def set_job_status(self, job, status, force=False, write=True):
method extract_results (line 163) | def extract_results(self):
method move_failed (line 166) | def move_failed(self, job):
method skip_job (line 169) | def skip_job(self, job):
method skip_remaining_jobs (line 173) | def skip_remaining_jobs(self):
method write_config (line 179) | def write_config(self):
method write_state (line 182) | def write_state(self):
method write_output (line 185) | def write_output(self):
method write_job_specs (line 190) | def write_job_specs(self):
method add_augmentation (line 193) | def add_augmentation(self, aug):
method get_resource (line 196) | def get_resource(self, resource, strict=True):
method get_metric (line 209) | def get_metric(self, name):
method add_metric (line 217) | def add_metric(self, name, value, units=None, lower_is_better=False,
method get_artifact (line 224) | def get_artifact(self, name):
method get_artifact_path (line 232) | def get_artifact_path(self, name):
method add_artifact (line 240) | def add_artifact(self, name, path, kind, description=None, classifiers...
method add_run_artifact (line 243) | def add_run_artifact(self, name, path, kind, description=None,
method add_event (line 247) | def add_event(self, message):
method add_classifier (line 250) | def add_classifier(self, name, value, overwrite=False):
method add_metadata (line 255) | def add_metadata(self, key, *args, **kwargs):
method update_metadata (line 258) | def update_metadata(self, key, *args):
method take_screenshot (line 261) | def take_screenshot(self, filename):
method take_uiautomator_dump (line 267) | def take_uiautomator_dump(self, filename):
method record_ui_state (line 272) | def record_ui_state(self, basename):
method initialize_jobs (line 280) | def initialize_jobs(self):
method _load_resource_getters (line 306) | def _load_resource_getters(self):
method _get_unique_filepath (line 313) | def _get_unique_filepath(self, filename):
class Executor (line 332) | class Executor(object):
method __init__ (line 347) | def __init__(self):
method execute (line 353) | def execute(self, config_manager, output):
method do_execute (line 397) | def do_execute(self, context):
method execute_postamble (line 440) | def execute_postamble(self, context, output):
method _error_signalled_callback (line 463) | def _error_signalled_callback(self, _):
method _warning_signalled_callback (line 467) | def _warning_signalled_callback(self, _):
method __str__ (line 471) | def __str__(self):
class Runner (line 477) | class Runner(object):
method __init__ (line 486) | def __init__(self, context, pm):
method run (line 493) | def run(self):
method initialize_run (line 518) | def initialize_run(self):
method finalize_run (line 528) | def finalize_run(self):
method run_next_job (line 547) | def run_next_job(self, context):
method do_run_job (line 585) | def do_run_job(self, job, context):
method check_job (line 649) | def check_job(self, job):
method retry_job (line 675) | def retry_job(self, job):
method send (line 684) | def send(self, s):
method _error_signalled_callback (line 687) | def _error_signalled_callback(self, record):
method _warning_signalled_callback (line 690) | def _warning_signalled_callback(self, record):
method __str__ (line 693) | def __str__(self):
FILE: wa/framework/getters.py
function get_by_extension (line 47) | def get_by_extension(path, ext):
function get_generic_resource (line 60) | def get_generic_resource(resource, files):
function get_path_matches (line 73) | def get_path_matches(resource, files):
function get_from_location (line 82) | def get_from_location(basepath, resource):
class Package (line 111) | class Package(ResourceGetter):
method register (line 115) | def register(self, resolver):
method get (line 119) | def get(self, resource):
class UserDirectory (line 128) | class UserDirectory(ResourceGetter):
method register (line 132) | def register(self, resolver):
method get (line 136) | def get(self, resource):
class Http (line 142) | class Http(ResourceGetter):
method __init__ (line 208) | def __init__(self, **kwargs):
method register (line 213) | def register(self, resolver):
method get (line 216) | def get(self, resource):
method fetch_index (line 236) | def fetch_index(self):
method download_asset (line 250) | def download_asset(self, asset, owner_name):
method geturl (line 274) | def geturl(self, url, stream=False):
method resolve_apk (line 281) | def resolve_apk(self, resource):
method resolve_resource (line 295) | def resolve_resource(self, resource):
class Filer (line 317) | class Filer(ResourceGetter):
method register (line 342) | def register(self, resolver):
method get (line 345) | def get(self, resource):
method try_get_resource (line 362) | def try_get_resource(self, resource, remote_path, local_path):
FILE: wa/framework/host.py
function init_user_directory (line 33) | def init_user_directory(overwrite_existing=False): # pylint: disable=R0914
function init_config (line 66) | def init_config():
function convert_wa2_agenda (line 79) | def convert_wa2_agenda(filepath, output_path):
function format_parameter (line 145) | def format_parameter(param):
FILE: wa/framework/instrument.py
function get_priority (line 163) | def get_priority(func):
function priority (line 168) | def priority(priority): # pylint: disable=redefined-outer-name
function hostside (line 193) | def hostside(func):
function is_hostside (line 205) | def is_hostside(func):
function is_installed (line 212) | def is_installed(instrument):
function is_enabled (line 227) | def is_enabled(instrument):
function reset_failures (line 242) | def reset_failures():
function check_failures (line 247) | def check_failures():
class ManagedCallback (line 253) | class ManagedCallback(object):
method __init__ (line 260) | def __init__(self, instrument, callback):
method __call__ (line 265) | def __call__(self, context):
method __repr__ (line 290) | def __repr__(self):
function install (line 303) | def install(instrument, context):
function uninstall (line 351) | def uninstall(instrument):
function validate (line 356) | def validate():
function get_instrument (line 361) | def get_instrument(inst):
function disable_all (line 370) | def disable_all():
function enable_all (line 375) | def enable_all():
function enable (line 380) | def enable(to_enable):
function disable (line 388) | def disable(to_disable):
function _enable_instrument (line 396) | def _enable_instrument(inst):
function _disable_instrument (line 405) | def _disable_instrument(inst):
function get_enabled (line 412) | def get_enabled():
function get_disabled (line 416) | def get_disabled():
class Instrument (line 420) | class Instrument(TargetedPlugin):
method __init__ (line 426) | def __init__(self, *args, **kwargs):
FILE: wa/framework/job.py
class Job (line 29) | class Job(object):
method id (line 34) | def id(self):
method label (line 38) | def label(self):
method status (line 42) | def status(self):
method has_been_initialized (line 46) | def has_been_initialized(self):
method retries (line 50) | def retries(self):
method status (line 54) | def status(self, value):
method retries (line 61) | def retries(self, value):
method __init__ (line 64) | def __init__(self, spec, iteration, context):
method load (line 76) | def load(self, target, loader=pluginloader):
method set_output (line 88) | def set_output(self, output):
method initialize (line 92) | def initialize(self, context):
method configure_augmentations (line 101) | def configure_augmentations(self, context, pm):
method configure_target (line 130) | def configure_target(self, context):
method setup (line 135) | def setup(self, context):
method run (line 141) | def run(self, context):
method process_output (line 151) | def process_output(self, context):
method teardown (line 164) | def teardown(self, context):
method finalize (line 173) | def finalize(self, context):
method set_status (line 184) | def set_status(self, status, force=False):
method add_classifier (line 189) | def add_classifier(self, name, value, overwrite=False):
method __str__ (line 194) | def __str__(self):
method __repr__ (line 197) | def __repr__(self):
FILE: wa/framework/output.py
class Output (line 52) | class Output(object):
method resultfile (line 57) | def resultfile(self):
method event_summary (line 61) | def event_summary(self):
method status (line 72) | def status(self):
method status (line 78) | def status(self, value):
method metrics (line 82) | def metrics(self):
method artifacts (line 88) | def artifacts(self):
method classifiers (line 94) | def classifiers(self):
method classifiers (line 100) | def classifiers(self, value):
method events (line 107) | def events(self):
method metadata (line 113) | def metadata(self):
method __init__ (line 118) | def __init__(self, path):
method reload (line 122) | def reload(self):
method write_result (line 135) | def write_result(self):
method get_path (line 138) | def get_path(self, subpath):
method add_metric (line 141) | def add_metric(self, name, value, units=None, lower_is_better=False,
method add_artifact (line 145) | def add_artifact(self, name, path, kind, description=None, classifiers...
method add_event (line 156) | def add_event(self, message):
method get_metric (line 159) | def get_metric(self, name):
method get_artifact (line 162) | def get_artifact(self, name):
method get_artifact_path (line 165) | def get_artifact_path(self, name):
method add_classifier (line 169) | def add_classifier(self, name, value, overwrite=False):
method add_metadata (line 172) | def add_metadata(self, key, *args, **kwargs):
method update_metadata (line 175) | def update_metadata(self, key, *args):
method __repr__ (line 178) | def __repr__(self):
method __str__ (line 182) | def __str__(self):
class RunOutputCommon (line 186) | class RunOutputCommon(object):
method run_config (line 191) | def run_config(self):
method settings (line 196) | def settings(self):
method get_job_spec (line 200) | def get_job_spec(self, spec_id):
method list_workloads (line 206) | def list_workloads(self):
class RunOutput (line 214) | class RunOutput(Output, RunOutputCommon):
method logfile (line 219) | def logfile(self):
method metadir (line 223) | def metadir(self):
method infofile (line 227) | def infofile(self):
method statefile (line 231) | def statefile(self):
method configfile (line 235) | def configfile(self):
method targetfile (line 239) | def targetfile(self):
method jobsfile (line 243) | def jobsfile(self):
method raw_config_dir (line 247) | def raw_config_dir(self):
method failed_dir (line 251) | def failed_dir(self):
method augmentations (line 256) | def augmentations(self):
method __init__ (line 263) | def __init__(self, path):
method reload (line 278) | def reload(self):
method write_info (line 300) | def write_info(self):
method write_state (line 303) | def write_state(self):
method write_config (line 306) | def write_config(self, config):
method read_config (line 310) | def read_config(self):
method set_target_info (line 315) | def set_target_info(self, ti):
method write_job_specs (line 319) | def write_job_specs(self, job_specs):
method read_job_specs (line 324) | def read_job_specs(self):
method move_failed (line 330) | def move_failed(self, job_output):
class JobOutput (line 341) | class JobOutput(Output):
method __init__ (line 346) | def __init__(self, path, id, label, iteration, retry):
method augmentations (line 357) | def augmentations(self):
class Result (line 364) | class Result(Podable):
method from_pod (line 369) | def from_pod(pod):
method __init__ (line 379) | def __init__(self):
method add_metric (line 389) | def add_metric(self, name, value, units=None, lower_is_better=False,
method add_artifact (line 395) | def add_artifact(self, name, path, kind, description=None, classifiers...
method add_event (line 402) | def add_event(self, message):
method get_metric (line 405) | def get_metric(self, name):
method get_artifact (line 411) | def get_artifact(self, name):
method add_classifier (line 417) | def add_classifier(self, name, value, overwrite=False):
method add_metadata (line 432) | def add_metadata(self, key, *args, **kwargs):
method update_metadata (line 453) | def update_metadata(self, key, *args):
method to_pod (line 480) | def to_pod(self):
method _pod_upgrade_v1 (line 491) | def _pod_upgrade_v1(pod):
class Artifact (line 501) | class Artifact(Podable):
method from_pod (line 552) | def from_pod(pod):
method __init__ (line 561) | def __init__(self, name, path, kind, description=None, classifiers=None,
method to_pod (line 591) | def to_pod(self):
method _pod_upgrade_v1 (line 599) | def _pod_upgrade_v1(pod):
method _pod_upgrade_v2 (line 604) | def _pod_upgrade_v2(pod):
method __str__ (line 608) | def __str__(self):
method __repr__ (line 611) | def __repr__(self):
class Metric (line 616) | class Metric(Podable):
method from_pod (line 637) | def from_pod(pod):
method label (line 645) | def label(self):
method __init__ (line 650) | def __init__(self, name, value, units=None, lower_is_better=False,
method to_pod (line 659) | def to_pod(self):
method _pod_upgrade_v1 (line 669) | def _pod_upgrade_v1(pod):
method __str__ (line 673) | def __str__(self):
method __repr__ (line 680) | def __repr__(self):
class Event (line 688) | class Event(Podable):
method from_pod (line 698) | def from_pod(pod):
method summary (line 707) | def summary(self):
method __init__ (line 714) | def __init__(self, message):
method to_pod (line 719) | def to_pod(self):
method _pod_upgrade_v1 (line 726) | def _pod_upgrade_v1(pod):
method __str__ (line 730) | def __str__(self):
function init_run_output (line 736) | def init_run_output(path, wa_state, force=False):
function init_job_output (line 767) | def init_job_output(run_output, job):
function discover_wa_outputs (line 779) | def discover_wa_outputs(path):
function _save_raw_config (line 789) | def _save_raw_config(meta_dir, state):
class DatabaseOutput (line 801) | class DatabaseOutput(Output):
method resultfile (line 806) | def resultfile(self):
method _build_command (line 818) | def _build_command(columns, tables, conditions=None, joins=None):
method __init__ (line 827) | def __init__(self, conn, oid=None, reload=True): # pylint: disable=su...
method __repr__ (line 834) | def __repr__(self):
method __str__ (line 837) | def __str__(self):
method reload (line 840) | def reload(self):
method get_artifact_path (line 848) | def get_artifact_path(self, name):
method _read_dir_artifact (line 855) | def _read_dir_artifact(self, artifact):
method _read_file_artifact (line 862) | def _read_file_artifact(self, artifact):
method _read_db (line 868) | def _read_db(self, columns, tables, conditions=None, join=None, as_dic...
method _get_pod_version (line 902) | def _get_pod_version(self):
method _populate_classifers (line 912) | def _populate_classifers(self, pod, kind):
method _get_classifiers (line 918) | def _get_classifiers(self, oid, kind):
method _get_metrics (line 928) | def _get_metrics(self):
method _get_status (line 939) | def _get_status(self):
method _get_artifacts (line 949) | def _get_artifacts(self):
method _get_events (line 965) | def _get_events(self):
function kernel_config_from_db (line 972) | def kernel_config_from_db(raw):
class RunDatabaseOutput (line 980) | class RunDatabaseOutput(DatabaseOutput, RunOutputCommon):
method basepath (line 985) | def basepath(self):
method augmentations (line 990) | def augmentations(self):
method _db_infofile (line 998) | def _db_infofile(self):
method _db_targetfile (line 1009) | def _db_targetfile(self):
method _db_statefile (line 1030) | def _db_statefile(self):
method _db_jobsfile (line 1055) | def _db_jobsfile(self):
method _db_run_config (line 1073) | def _db_run_config(self):
method __init__ (line 1104) | def __init__(self,
method read_job_specs (line 1159) | def read_job_specs(self):
method connect (line 1165) | def connect(self):
method disconnect (line 1177) | def disconnect(self):
method reload (line 1181) | def reload(self):
method _get_oid (line 1205) | def _get_oid(self):
method _get_parameters (line 1216) | def _get_parameters(self, param_type):
method _get_job_augmentations (line 1230) | def _get_job_augmentations(self, job_oid):
method _list_runs (line 1239) | def _list_runs(self):
class JobDatabaseOutput (line 1270) | class JobDatabaseOutput(DatabaseOutput):
method __init__ (line 1274) | def __init__(self, conn, oid, job_id, label, iteration, retry):
method __repr__ (line 1284) | def __repr__(self):
method __str__ (line 1288) | def __str__(self):
method augmentations (line 1292) | def augmentations(self):
FILE: wa/framework/output_processor.py
class OutputProcessor (line 27) | class OutputProcessor(Plugin):
method __init__ (line 32) | def __init__(self, **kwargs):
method validate (line 36) | def validate(self):
method initialize (line 43) | def initialize(self, context):
method finalize (line 46) | def finalize(self, context):
class ProcessorManager (line 50) | class ProcessorManager(object):
method __init__ (line 52) | def __init__(self, loader=pluginloader):
method install (line 57) | def install(self, processor, context):
method disable_all (line 65) | def disable_all(self):
method enable_all (line 69) | def enable_all(self):
method enable (line 73) | def enable(self, to_enable):
method disable (line 80) | def disable(self, to_disable):
method get_output_processor (line 87) | def get_output_processor(self, processor):
method get_enabled (line 97) | def get_enabled(self):
method get_disabled (line 100) | def get_disabled(self):
method validate (line 103) | def validate(self):
method initialize (line 107) | def initialize(self, context):
method finalize (line 111) | def finalize(self, context):
method process_job_output (line 115) | def process_job_output(self, context):
method export_job_output (line 120) | def export_job_output(self, context):
method process_run_output (line 125) | def process_run_output(self, context):
method export_run_output (line 129) | def export_run_output(self, context):
method do_for_each_proc (line 133) | def do_for_each_proc(self, method_name, message, *args):
method _enable_output_processor (line 148) | def _enable_output_processor(self, inst):
method _disable_output_processor (line 154) | def _disable_output_processor(self, inst):
FILE: wa/framework/plugin.py
class AttributeCollection (line 37) | class AttributeCollection(object):
method values (line 49) | def values(self):
method __init__ (line 52) | def __init__(self, attrcls):
method add (line 56) | def add(self, p):
method __str__ (line 76) | def __str__(self):
method _to_attrcls (line 81) | def _to_attrcls(self, p):
method __iadd__ (line 88) | def __iadd__(self, other):
method __iter__ (line 93) | def __iter__(self):
method __contains__ (line 96) | def __contains__(self, p):
method __getitem__ (line 99) | def __getitem__(self, i):
method __len__ (line 102) | def __len__(self):
class AliasCollection (line 106) | class AliasCollection(AttributeCollection):
method __init__ (line 108) | def __init__(self):
method _to_attrcls (line 111) | def _to_attrcls(self, p):
class ListCollection (line 123) | class ListCollection(list):
method __init__ (line 125) | def __init__(self, attrcls): # pylint: disable=unused-argument
class Alias (line 129) | class Alias(object):
method __init__ (line 137) | def __init__(self, name, **kwargs):
method validate (line 142) | def validate(self, ext):
class PluginMeta (line 153) | class PluginMeta(type):
method __new__ (line 169) | def __new__(mcs, clsname, bases, attrs):
method _propagate_attributes (line 176) | def _propagate_attributes(mcs, bases, attrs, clsname): # pylint: disa...
method _setup_aliases (line 210) | def _setup_aliases(mcs, cls):
class Plugin (line 221) | class Plugin(with_metaclass(PluginMeta, object)):
method get_default_config (line 241) | def get_default_config(cls):
method dependencies_directory (line 245) | def dependencies_directory(self):
method _classname (line 249) | def _classname(self):
method __init__ (line 252) | def __init__(self, **kwargs):
method get_config (line 263) | def get_config(self):
method validate (line 273) | def validate(self):
method __getattr__ (line 291) | def __getattr__(self, name):
method load_modules (line 299) | def load_modules(self, loader):
method has (line 322) | def has(self, capability):
method _load_module (line 334) | def _load_module(self, loader, module_spec):
method _install_module (line 356) | def _install_module(self, module):
method __str__ (line 362) | def __str__(self):
method __repr__ (line 365) | def __repr__(self):
class TargetedPlugin (line 373) | class TargetedPlugin(Plugin):
method check_compatible (line 392) | def check_compatible(cls, target):
method __init__ (line 398) | def __init__(self, target, **kwargs):
class PluginLoaderItem (line 404) | class PluginLoaderItem(object):
method __init__ (line 406) | def __init__(self, ext_tuple):
class PluginLoader (line 413) | class PluginLoader(object):
method __init__ (line 423) | def __init__(self, packages=None, paths=None, ignore_paths=None,
method update (line 449) | def update(self, packages=None, paths=None, ignore_paths=None):
method clear (line 462) | def clear(self):
method reload (line 469) | def reload(self):
method get_plugin_class (line 476) | def get_plugin_class(self, name, kind=None):
method get_plugin (line 495) | def get_plugin(self, name=None, kind=None, *args, **kwargs): # pylint...
method get_default_config (line 507) | def get_default_config(self, name):
method list_plugins (line 518) | def list_plugins(self, kind=None):
method has_plugin (line 530) | def has_plugin(self, name, kind=None):
method resolve_alias (line 543) | def resolve_alias(self, alias_name):
method __getattr__ (line 561) | def __getattr__(self, name):
method _discover_from_packages (line 597) | def _discover_from_packages(self, packages):
method _discover_from_paths (line 608) | def _discover_from_paths(self, paths, ignore_paths):
method _discover_from_file (line 638) | def _discover_from_file(self, filepath):
method _discover_in_module (line 653) | def _discover_in_module(self, module): # NOQA pylint: disable=too-man...
method _add_found_plugin (line 678) | def _add_found_plugin(self, obj):
FILE: wa/framework/pluginloader.py
class __LoaderWrapper (line 18) | class __LoaderWrapper(object):
method kinds (line 21) | def kinds(self):
method kind_map (line 27) | def kind_map(self):
method __init__ (line 32) | def __init__(self):
method reset (line 35) | def reset(self):
method update (line 44) | def update(self, packages=None, paths=None, ignore_paths=None):
method reload (line 49) | def reload(self):
method list_plugins (line 54) | def list_plugins(self, kind=None):
method has_plugin (line 59) | def has_plugin(self, name, kind=None):
method get_plugin_class (line 64) | def get_plugin_class(self, name, kind=None):
method get_plugin (line 69) | def get_plugin(self, name=None, kind=None, *args, **kwargs): # pylint...
method get_default_config (line 74) | def get_default_config(self, name):
method resolve_alias (line 79) | def resolve_alias(self, name):
method __getattr__ (line 84) | def __getattr__(self, name):
FILE: wa/framework/resource.py
class __NullOwner (line 33) | class __NullOwner(object):
method __getattr__ (line 39) | def __getattr__(self, name):
method __str__ (line 42) | def __str__(self):
class Resource (line 51) | class Resource(object):
method __init__ (line 64) | def __init__(self, owner=NO_ONE):
method match (line 67) | def match(self, path):
method match_path (line 70) | def match_path(self, path):
method __str__ (line 73) | def __str__(self):
class File (line 77) | class File(Resource):
method __init__ (line 81) | def __init__(self, owner, path):
method match_path (line 85) | def match_path(self, path):
method __str__ (line 88) | def __str__(self):
class Executable (line 92) | class Executable(Resource):
method __init__ (line 96) | def __init__(self, owner, abi, filename):
method match_path (line 101) | def match_path(self, path):
method __str__ (line 104) | def __str__(self):
class ReventFile (line 108) | class ReventFile(Resource):
method __init__ (line 112) | def __init__(self, owner, stage, target):
method match_path (line 117) | def match_path(self, path):
class JarFile (line 128) | class JarFile(Resource):
method match_path (line 132) | def match_path(self, path):
class ApkFile (line 138) | class ApkFile(Resource):
method __init__ (line 142) | def __init__(self, owner, variant=None, version=None,
method match_path (line 155) | def match_path(self, path):
method match (line 159) | def match(self, path):
method __str__ (line 182) | def __str__(self):
class ResourceGetter (line 194) | class ResourceGetter(Plugin):
method register (line 217) | def register(self, resolver):
method initialize (line 220) | def initialize(self):
method __str__ (line 223) | def __str__(self):
class ResourceResolver (line 227) | class ResourceResolver(object):
method __init__ (line 234) | def __init__(self, loader=pluginloader):
method load (line 240) | def load(self):
method register (line 250) | def register(self, source, priority=SourcePriority.local):
method get (line 255) | def get(self, resource, strict=True):
function apk_version_matches (line 280) | def apk_version_matches(path, version):
function apk_version_matches_range (line 291) | def apk_version_matches_range(path, min_version=None, max_version=None):
function range_version_matching (line 296) | def range_version_matching(apk_version, min_version=None, max_version=No...
function loose_version_matching (line 312) | def loose_version_matching(config_version, apk_version):
function file_name_matches (line 325) | def file_name_matches(path, pattern):
function uiauto_test_matches (line 334) | def uiauto_test_matches(path, uiauto):
function package_name_matches (line 339) | def package_name_matches(path, package):
function apk_abi_matches (line 344) | def apk_abi_matches(path, supported_abi, exact_abi=False):
FILE: wa/framework/run.py
class RunInfo (line 28) | class RunInfo(Podable):
method from_pod (line 37) | def from_pod(pod):
method __init__ (line 50) | def __init__(self, run_name=None, project=None, project_stage=None,
method to_pod (line 61) | def to_pod(self):
method _pod_upgrade_v1 (line 72) | def _pod_upgrade_v1(pod):
class RunState (line 77) | class RunState(Podable):
method from_pod (line 85) | def from_pod(pod):
method num_completed_jobs (line 94) | def num_completed_jobs(self):
method __init__ (line 98) | def __init__(self):
method add_job (line 104) | def add_job(self, job):
method get_status_counts (line 107) | def get_status_counts(self):
method to_pod (line 113) | def to_pod(self):
method _pod_upgrade_v1 (line 121) | def _pod_upgrade_v1(pod):
class JobState (line 127) | class JobState(Podable):
method from_pod (line 132) | def from_pod(pod):
method output_name (line 141) | def output_name(self):
method __init__ (line 144) | def __init__(self, id, label, iteration, status):
method to_pod (line 154) | def to_pod(self):
method _pod_upgrade_v1 (line 165) | def _pod_upgrade_v1(pod):
FILE: wa/framework/signal.py
class Signal (line 36) | class Signal(object):
method __init__ (line 44) | def __init__(self, name, description='no description', invert_priority...
method __str__ (line 64) | def __str__(self):
method __hash__ (line 69) | def __hash__(self):
class _prioritylist_wrapper (line 190) | class _prioritylist_wrapper(prioritylist):
method append (line 198) | def append(self, *args, **kwargs):
function connect (line 202) | def connect(handler, signal, sender=dispatcher.Any, priority=0):
function disconnect (line 250) | def disconnect(handler, signal, sender=dispatcher.Any):
function send (line 268) | def send(signal, sender=dispatcher.Anonymous, *args, **kwargs):
function safe_send (line 291) | def safe_send(signal, sender=dispatcher.Anonymous,
function wrap (line 310) | def wrap(signal_name, sender=dispatcher.Anonymous, *args, **kwargs): # ...
function wrapped (line 333) | def wrapped(signal_name, sender=dispatcher.Anonymous, safe=False):
FILE: wa/framework/target/assistant.py
class LinuxAssistant (line 31) | class LinuxAssistant(object):
method __init__ (line 35) | def __init__(self, target):
method initialize (line 38) | def initialize(self):
method start (line 41) | def start(self):
method extract_results (line 44) | def extract_results(self, context):
method stop (line 47) | def stop(self):
method finalize (line 50) | def finalize(self):
class AndroidAssistant (line 54) | class AndroidAssistant(object):
method __init__ (line 94) | def __init__(self, target, logcat_poll_period=None, disable_selinux=Tr...
method initialize (line 108) | def initialize(self):
method start (line 114) | def start(self):
method stop (line 123) | def stop(self):
method finalize (line 127) | def finalize(self):
method extract_results (line 131) | def extract_results(self, context):
method dump_logcat (line 142) | def dump_logcat(self, outfile):
method clear_logcat (line 148) | def clear_logcat(self):
method _before_workload (line 154) | def _before_workload(self, _):
method _after_workload (line 160) | def _after_workload(self, _):
method _check_logcat_nowrap (line 163) | def _check_logcat_nowrap(self, outfile):
method insert_logcat_marker (line 175) | def insert_logcat_marker(self):
method do_disable_selinux (line 183) | def do_disable_selinux(self):
class LogcatPoller (line 192) | class LogcatPoller(threading.Thread):
method __init__ (line 194) | def __init__(self, target, period=60, timeout=30):
method run (line 212) | def run(self):
method stop (line 229) | def stop(self):
method clear_buffer (line 238) | def clear_buffer(self):
method write_log (line 244) | def write_log(self, outfile):
method close (line 252) | def close(self):
method poll (line 257) | def poll(self):
method insert_logcat_marker (line 262) | def insert_logcat_marker(self):
method check_logcat_nowrap (line 273) | def check_logcat_nowrap(self, outfile):
method start_logcat_wrap_detect (line 293) | def start_logcat_wrap_detect(self):
method stop_logcat_wrap_detect (line 298) | def stop_logcat_wrap_detect(self):
class ChromeOsAssistant (line 303) | class ChromeOsAssistant(LinuxAssistant):
method __init__ (line 307) | def __init__(self, target, logcat_poll_period=None, disable_selinux=Tr...
method start (line 315) | def start(self):
method extract_results (line 320) | def extract_results(self, context):
method stop (line 325) | def stop(self):
FILE: wa/framework/target/config.py
class TargetConfig (line 19) | class TargetConfig(dict):
method __init__ (line 24) | def __init__(self, config=None):
method set (line 34) | def set(self, name, value):
FILE: wa/framework/target/descriptor.py
function list_target_descriptions (line 34) | def list_target_descriptions(loader=pluginloader):
function get_target_description (line 48) | def get_target_description(name, loader=pluginloader):
function instantiate_target (line 55) | def instantiate_target(tdesc, params, connect=None, extra_platform_param...
function instantiate_assistant (line 101) | def instantiate_assistant(tdesc, params, target):
class TargetDescription (line 111) | class TargetDescription(object):
method __init__ (line 113) | def __init__(self, name, source, description=None, target=None, platfo...
method get_default_config (line 128) | def get_default_config(self):
method _set (line 138) | def _set(self, attr, vals):
class TargetDescriptor (line 150) | class TargetDescriptor(Plugin):
method get_descriptions (line 154) | def get_descriptions(self): # pylint: disable=no-self-use
class DefaultTargetDescriptor (line 679) | class DefaultTargetDescriptor(TargetDescriptor):
method get_descriptions (line 691) | def get_descriptions(self):
method _override_params (line 726) | def _override_params(self, params, overrides): # pylint: disable=no-se...
method _get_item (line 738) | def _get_item(self, item_tuple):
function create_target_description (line 747) | def create_target_description(name, *args, **kwargs):
function _get_target_defaults (line 771) | def _get_target_defaults(target):
function add_description_for_target (line 783) | def add_description_for_target(target, description=None, **kwargs):
class SimpleTargetDescriptor (line 810) | class SimpleTargetDescriptor(TargetDescriptor):
method get_descriptions (line 819) | def get_descriptions(self):
FILE: wa/framework/target/info.py
function cpuinfo_from_pod (line 29) | def cpuinfo_from_pod(pod):
function kernel_version_from_pod (line 42) | def kernel_version_from_pod(pod):
function kernel_config_from_pod (line 55) | def kernel_config_from_pod(pod):
class CpufreqInfo (line 68) | class CpufreqInfo(Podable):
method from_pod (line 73) | def from_pod(pod):
method __init__ (line 77) | def __init__(self, **kwargs):
method to_pod (line 85) | def to_pod(self):
method _pod_upgrade_v1 (line 91) | def _pod_upgrade_v1(pod):
method __repr__ (line 95) | def __repr__(self):
class IdleStateInfo (line 101) | class IdleStateInfo(Podable):
method from_pod (line 106) | def from_pod(pod):
method __init__ (line 110) | def __init__(self, **kwargs):
method to_pod (line 118) | def to_pod(self):
method _pod_upgrade_v1 (line 124) | def _pod_upgrade_v1(pod):
method __repr__ (line 128) | def __repr__(self):
class CpuidleInfo (line 134) | class CpuidleInfo(Podable):
method from_pod (line 139) | def from_pod(pod):
method num_states (line 149) | def num_states(self):
method __init__ (line 152) | def __init__(self):
method to_pod (line 158) | def to_pod(self):
method _pod_upgrade_v1 (line 166) | def _pod_upgrade_v1(pod):
method __repr__ (line 170) | def __repr__(self):
class CpuInfo (line 177) | class CpuInfo(Podable):
method from_pod (line 182) | def from_pod(pod):
method __init__ (line 192) | def __init__(self):
method to_pod (line 201) | def to_pod(self):
method _pod_upgrade_v1 (line 212) | def _pod_upgrade_v1(pod):
method __repr__ (line 216) | def __repr__(self):
function get_target_info (line 222) | def get_target_info(target):
function read_target_info_cache (line 278) | def read_target_info_cache():
function write_target_info_cache (line 286) | def write_target_info_cache(cache):
function get_target_info_from_cache (line 293) | def get_target_info_from_cache(system_id, cache=None):
function cache_target_info (line 309) | def cache_target_info(target_info, overwrite=False, cache=None):
class TargetInfo (line 318) | class TargetInfo(Podable):
method from_pod (line 323) | def from_pod(pod):
method __init__ (line 348) | def __init__(self):
method to_pod (line 368) | def to_pod(self):
method _pod_upgrade_v1 (line 394) | def _pod_upgrade_v1(pod):
method _pod_upgrade_v2 (line 407) | def _pod_upgrade_v2(pod):
method _pod_upgrade_v3 (line 413) | def _pod_upgrade_v3(pod):
method _pod_upgrade_v4 (line 421) | def _pod_upgrade_v4(pod):
method _pod_upgrade_v5 (line 425) | def _pod_upgrade_v5(pod):
FILE: wa/framework/target/manager.py
class TargetManager (line 33) | class TargetManager(object):
method __init__ (line 46) | def __init__(self, name, parameters, outdir):
method initialize (line 58) | def initialize(self):
method finalize (line 78) | def finalize(self):
method start (line 88) | def start(self):
method stop (line 91) | def stop(self):
method extract_results (line 94) | def extract_results(self, context):
method get_target_info (line 98) | def get_target_info(self):
method reboot (line 115) | def reboot(self, context, hard=False):
method merge_runtime_parameters (line 119) | def merge_runtime_parameters(self, parameters):
method validate_runtime_parameters (line 122) | def validate_runtime_parameters(self, parameters):
method commit_runtime_parameters (line 125) | def commit_runtime_parameters(self, parameters):
method verify_target_responsive (line 128) | def verify_target_responsive(self, context):
method _init_target (line 142) | def _init_target(self):
FILE: wa/framework/target/runtime_config.py
class RuntimeParameter (line 34) | class RuntimeParameter(Parameter):
method __init__ (line 35) | def __init__(self, name, setter, setter_params=None, **kwargs):
method set (line 40) | def set(self, obj, value):
class RuntimeConfig (line 45) | class RuntimeConfig(Plugin):
method supported_parameters (line 51) | def supported_parameters(self):
method core_names (line 55) | def core_names(self):
method __init__ (line 58) | def __init__(self, target, **kwargs):
method initialize (line 70) | def initialize(self):
method commit (line 73) | def commit(self):
method set_runtime_parameter (line 76) | def set_runtime_parameter(self, name, value):
method set_defaults (line 82) | def set_defaults(self):
method validate_parameters (line 87) | def validate_parameters(self):
method check_target (line 90) | def check_target(self):
method clear (line 93) | def clear(self):
class HotplugRuntimeConfig (line 97) | class HotplugRuntimeConfig(RuntimeConfig):
method set_num_cores (line 106) | def set_num_cores(obj, value, core):
method __init__ (line 126) | def __init__(self, target):
method initialize (line 130) | def initialize(self):
method check_target (line 176) | def check_target(self):
method validate_parameters (line 180) | def validate_parameters(self):
method commit (line 185) | def commit(self):
method clear (line 195) | def clear(self):
class SysfileValuesRuntimeConfig (line 199) | class SysfileValuesRuntimeConfig(RuntimeConfig):
method set_sysfile (line 205) | def set_sysfile(obj, values, core):
method __init__ (line 218) | def __init__(self, target):
method initialize (line 222) | def initialize(self):
method check_target (line 231) | def check_target(self):
method validate_parameters (line 234) | def validate_parameters(self):
method commit (line 237) | def commit(self):
method clear (line 241) | def clear(self):
method check_exists (line 244) | def check_exists(self, path):
class FreqValue (line 249) | class FreqValue(object):
method __init__ (line 251) | def __init__(self, values):
method __call__ (line 257) | def __call__(self, value):
method __str__ (line 279) | def __str__(self):
class CpufreqRuntimeConfig (line 283) | class CpufreqRuntimeConfig(RuntimeConfig):
method set_frequency (line 288) | def set_frequency(obj, value, core):
method set_max_frequency (line 292) | def set_max_frequency(obj, value, core):
method set_min_frequency (line 296) | def set_min_frequency(obj, value, core):
method set_governor (line 300) | def set_governor(obj, value, core):
method set_governor_tunables (line 304) | def set_governor_tunables(obj, value, core):
method set_param (line 308) | def set_param(obj, value, core, parameter):
method __init__ (line 317) | def __init__(self, target):
method initialize (line 323) | def initialize(self):
method check_target (line 547) | def check_target(self):
method validate_parameters (line 551) | def validate_parameters(self):
method commit (line 570) | def commit(self):
method clear (line 582) | def clear(self):
method configure_governor (line 585) | def configure_governor(self, cpu, governor=None, gov_tunables=None):
method configure_frequency (line 597) | def configure_frequency(self, cpu, freq=None, min_freq=None, max_freq=...
method _resolve_freq (line 611) | def _resolve_freq(self, value, cpu):
method _set_frequency (line 618) | def _set_frequency(self, cpu, freq, governor):
method _set_min_max_frequencies (line 635) | def _set_min_max_frequencies(self, cpu, min_freq, max_freq):
method _retrive_cpufreq_info (line 657) | def _retrive_cpufreq_info(self):
method _get_common_values (line 682) | def _get_common_values(self):
class IdleStateValue (line 702) | class IdleStateValue(object):
method __init__ (line 704) | def __init__(self, values):
method __call__ (line 710) | def __call__(self, value):
method _get_state_ID (line 731) | def _get_state_ID(self, value):
method __str__ (line 740) | def __str__(self):
class CpuidleRuntimeConfig (line 744) | class CpuidleRuntimeConfig(RuntimeConfig):
method set_idle_state (line 749) | def set_idle_state(obj, value, core):
method __init__ (line 756) | def __init__(self, target):
method initialize (line 761) | def initialize(self):
method check_target (line 820) | def check_target(self):
method validate_parameters (line 824) | def validate_parameters(self):
method clear (line 827) | def clear(self):
method commit (line 830) | def commit(self):
method _retrieve_device_idle_info (line 840) | def _retrieve_device_idle_info(self):
method _get_common_idle_values (line 844) | def _get_common_idle_values(self):
class AndroidRuntimeConfig (line 857) | class AndroidRuntimeConfig(RuntimeConfig):
method set_brightness (line 862) | def set_brightness(obj, value):
method set_airplane_mode (line 867) | def set_airplane_mode(obj, value):
method set_rotation (line 872) | def set_rotation(obj, value):
method set_screen_state (line 877) | def set_screen_state(obj, value):
method set_unlock_screen (line 882) | def set_unlock_screen(obj, value):
method __init__ (line 886) | def __init__(self, target):
method initialize (line 890) | def initialize(self):
method check_target (line 948) | def check_target(self):
method validate_parameters (line 954) | def validate_parameters(self):
method commit (line 957) | def commit(self):
method clear (line 998) | def clear(self):
FILE: wa/framework/target/runtime_parameter_manager.py
class RuntimeParameterManager (line 28) | class RuntimeParameterManager(object):
method __init__ (line 39) | def __init__(self, target):
method merge_runtime_parameters (line 62) | def merge_runtime_parameters(self, parameters):
method validate_runtime_parameters (line 71) | def validate_runtime_parameters(self, parameters):
method commit_runtime_parameters (line 78) | def commit_runtime_parameters(self, parameters):
method set_runtime_parameters (line 85) | def set_runtime_parameters(self, parameters):
method clear_runtime_parameters (line 93) | def clear_runtime_parameters(self):
method get_config_for_name (line 98) | def get_config_for_name(self, name):
method get_cfg_point (line 105) | def get_cfg_point(self, name):
FILE: wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/ActionLogger.java
class ActionLogger (line 39) | public class ActionLogger {
method ActionLogger (line 44) | public ActionLogger(String testTag, Bundle parameters) {
method start (line 49) | public void start() {
method stop (line 55) | public void stop() throws Exception {
FILE: wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/ApplaunchInterface.java
type ApplaunchInterface (line 28) | public interface ApplaunchInterface {
method getLaunchEndObject (line 34) | public UiObject getLaunchEndObject();
method runApplicationSetup (line 40) | public void runApplicationSetup() throws Exception;
method getLaunchCommand (line 46) | public String getLaunchCommand();
method setWorkloadParameters (line 49) | public void setWorkloadParameters(Bundle parameters);
method initialize_instrumentation (line 52) | public void initialize_instrumentation();
FILE: wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/BaseUiAutomation.java
class BaseUiAutomation (line 44) | public class BaseUiAutomation {
type FindByCriteria (line 46) | public enum FindByCriteria { BY_ID, BY_TEXT, BY_DESC }
type Direction (line 47) | public enum Direction { UP, DOWN, LEFT, RIGHT, NULL }
type ScreenOrientation (line 48) | public enum ScreenOrientation { RIGHT, NATURAL, LEFT, PORTRAIT, LANDSC...
type PinchType (line 49) | public enum PinchType { IN, OUT, NULL }
method initialize_instrumentation (line 61) | @Before
method setup (line 68) | @Test
method runWorkload (line 72) | @Test
method extractResults (line 76) | @Test
method teardown (line 80) | @Test
method sleep (line 84) | public void sleep(int second) {
method getPackageID (line 89) | public String getPackageID(Bundle parameters) {
method takeScreenshot (line 94) | public boolean takeScreenshot(String name) {
method waitText (line 105) | public void waitText(String text) throws UiObjectNotFoundException {
method waitText (line 109) | public void waitText(String text, int second) throws UiObjectNotFoundE...
method waitObject (line 116) | public void waitObject(UiObject obj) throws UiObjectNotFoundException {
method waitObject (line 120) | public void waitObject(UiObject obj, int second) throws UiObjectNotFou...
method waitUntilNoObject (line 127) | public boolean waitUntilNoObject(UiObject obj, int second) {
method clearLogcat (line 131) | public void clearLogcat() throws Exception {
method waitForLogcatText (line 135) | public void waitForLogcatText(String searchText, long timeout) throws ...
method registerWatcher (line 166) | public void registerWatcher(String name, UiWatcher watcher) {
method runWatchers (line 170) | public void runWatchers() {
method removeWatcher (line 174) | public void removeWatcher(String name) {
method setScreenOrientation (line 178) | public void setScreenOrientation(ScreenOrientation orientation) throws...
method unsetScreenOrientation (line 220) | public void unsetScreenOrientation() throws Exception {
method uiObjectPerformLongClick (line 224) | public void uiObjectPerformLongClick(UiObject view, int steps) throws ...
method getDisplayHeight (line 230) | public int getDisplayHeight() {
method getDisplayWidth (line 234) | public int getDisplayWidth() {
method getDisplayCentreWidth (line 238) | public int getDisplayCentreWidth() {
method getDisplayCentreHeight (line 242) | public int getDisplayCentreHeight() {
method tapDisplayCentre (line 246) | public void tapDisplayCentre() {
method tapDisplay (line 250) | public void tapDisplay(int x, int y) {
method pressEnter (line 254) | public void pressEnter() {
method pressHome (line 258) | public void pressHome() {
method pressBack (line 262) | public void pressBack() {
method uiObjectSwipe (line 266) | public void uiObjectSwipe(UiObject view, Direction direction, int step...
method uiDeviceSwipeVertical (line 287) | public void uiDeviceSwipeVertical(int startY, int endY, int xCoordinat...
method uiDeviceSwipeHorizontal (line 291) | public void uiDeviceSwipeHorizontal(int startX, int endX, int yCoordin...
method uiObjectVertPinchIn (line 295) | public void uiObjectVertPinchIn(UiObject view, int steps, int percent)...
method uiObjectVertPinchOut (line 321) | public void uiObjectVertPinchOut(UiObject view, int steps, int percent...
method uiObjectVertPinch (line 347) | public void uiObjectVertPinch(UiObject view, PinchType direction,
method uiDeviceSwipeUp (line 356) | public void uiDeviceSwipeUp(int steps) {
method uiDeviceSwipeDown (line 365) | public void uiDeviceSwipeDown(int steps) {
method uiDeviceSwipeLeft (line 374) | public void uiDeviceSwipeLeft(int steps) {
method uiDeviceSwipeRight (line 383) | public void uiDeviceSwipeRight(int steps) {
method uiDeviceSwipe (line 392) | public void uiDeviceSwipe(Direction direction, int steps) throws Excep...
method repeatClickUiObject (line 413) | public void repeatClickUiObject(UiObject view, int repeatCount, int in...
method clickUiObject (line 427) | public UiObject clickUiObject(FindByCriteria criteria, String matching...
method clickUiObject (line 431) | public UiObject clickUiObject(FindByCriteria criteria, String matching...
method clickUiObject (line 435) | public UiObject clickUiObject(FindByCriteria criteria, String matching...
method clickUiObject (line 439) | public UiObject clickUiObject(FindByCriteria criteria, String matching...
method getUiObjectByResourceId (line 466) | public UiObject getUiObjectByResourceId(String resourceId, String clas...
method getUiObjectByResourceId (line 470) | public UiObject getUiObjectByResourceId(String resourceId, String clas...
method getUiObjectByResourceId (line 480) | public UiObject getUiObjectByResourceId(String id) throws Exception {
method getUiObjectByDescription (line 489) | public UiObject getUiObjectByDescription(String description, String cl...
method getUiObjectByDescription (line 493) | public UiObject getUiObjectByDescription(String description, String cl...
method getUiObjectByDescription (line 503) | public UiObject getUiObjectByDescription(String desc) throws Exception {
method getUiObjectByText (line 512) | public UiObject getUiObjectByText(String text, String className) throw...
method getUiObjectByText (line 516) | public UiObject getUiObjectByText(String text, String className, long ...
method getUiObjectByText (line 526) | public UiObject getUiObjectByText(String text) throws Exception {
method selectGalleryFolder (line 536) | public void selectGalleryFolder(String directory) throws Exception {
method dismissAndroidPermissionPopup (line 579) | public void dismissAndroidPermissionPopup() throws Exception {
method dismissAndroidVersionPopup (line 594) | public void dismissAndroidVersionPopup() throws Exception {
method dismissChromePopup (line 613) | public void dismissChromePopup() throws Exception {
method getParams (line 636) | public Bundle getParams() {
method decode (line 656) | private Bundle decode(Bundle parameters, String key, String value) {
method decodeArray (line 690) | private Bundle decodeArray(Bundle parameters, String key, char type, S...
FILE: wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutoUtils.java
class UiAutoUtils (line 20) | public final class UiAutoUtils {
method createLaunchCommand (line 23) | public static String createLaunchCommand(Bundle parameters) {
FILE: wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/UxPerfUiAutomation.java
class UxPerfUiAutomation (line 26) | public class UxPerfUiAutomation {
type GestureType (line 30) | public enum GestureType { UIDEVICE_SWIPE, UIOBJECT_SWIPE, PINCH }
class GestureTestParams (line 32) | public static class GestureTestParams {
method GestureTestParams (line 39) | public GestureTestParams(GestureType gesture, Direction direction, i...
method GestureTestParams (line 47) | public GestureTestParams(GestureType gesture, PinchType pinchType, i...
FILE: wa/framework/version.py
function format_version (line 29) | def format_version(v):
function get_wa_version (line 37) | def get_wa_version():
function get_wa_version_with_commit (line 41) | def get_wa_version_with_commit():
function get_commit (line 50) | def get_commit():
FILE: wa/framework/workload.py
class Workload (line 38) | class Workload(TargetedPlugin):
method __init__ (line 75) | def __init__(self, target, **kwargs):
method init_resources (line 86) | def init_resources(self, context):
method initialize (line 99) | def initialize(self, context):
method setup (line 108) | def setup(self, context):
method run (line 122) | def run(self, context):
method extract_results (line 128) | def extract_results(self, context):
method update_output (line 133) | def update_output(self, context):
method teardown (line 140) | def teardown(self, context):
method finalize (line 144) | def finalize(self, context):
method deploy_assets (line 148) | def deploy_assets(self, context):
method remove_assets (line 161) | def remove_assets(self, context):
method __str__ (line 167) | def __str__(self):
class ApkWorkload (line 171) | class ApkWorkload(Workload):
method package (line 263) | def package(self):
method __init__ (line 266) | def __init__(self, target, **kwargs):
method validate (line 296) | def validate(self):
method initialize (line 303) | def initialize(self, context):
method setup (line 313) | def setup(self, context):
method setup_rerun (line 321) | def setup_rerun(self):
method teardown (line 327) | def teardown(self, context):
method deploy_assets (line 331) | def deploy_assets(self, context):
class ApkUIWorkload (line 336) | class ApkUIWorkload(ApkWorkload):
method __init__ (line 338) | def __init__(self, target, **kwargs):
method init_resources (line 342) | def init_resources(self, context):
method initialize (line 347) | def initialize(self, context):
method setup (line 351) | def setup(self, context):
method run (line 355) | def run(self, context):
method extract_results (line 359) | def extract_results(self, context):
method teardown (line 363) | def teardown(self, context):
method finalize (line 368) | def finalize(self, context):
class ApkUiautoWorkload (line 374) | class ApkUiautoWorkload(ApkUIWorkload):
method __init__ (line 387) | def __init__(self, target, **kwargs):
method setup (line 391) | def setup(self, context):
class ApkReventWorkload (line 398) | class ApkReventWorkload(ApkUIWorkload):
method __init__ (line 407) | def __init__(self, target, **kwargs):
class UIWorkload (line 416) | class UIWorkload(Workload):
method __init__ (line 418) | def __init__(self, target, **kwargs):
method init_resources (line 422) | def init_resources(self, context):
method initialize (line 427) | def initialize(self, context):
method setup (line 431) | def setup(self, context):
method run (line 435) | def run(self, context):
method extract_results (line 439) | def extract_results(self, context):
method teardown (line 443) | def teardown(self, context):
method finalize (line 448) | def finalize(self, context):
class UiautoWorkload (line 454) | class UiautoWorkload(UIWorkload):
method __init__ (line 469) | def __init__(self, target, **kwargs):
method setup (line 479) | def setup(self, context):
class ReventWorkload (line 485) | class ReventWorkload(UIWorkload):
method __init__ (line 494) | def __init__(self, target, **kwargs):
class UiAutomatorGUI (line 503) | class UiAutomatorGUI(object):
method __init__ (line 509) | def __init__(self, owner, package=None, klass='UiAutomation', timeout=...
method init_resources (line 520) | def init_resources(self, resolver):
method init_commands (line 526) | def init_commands(self):
method deploy (line 542) | def deploy(self):
method set (line 547) | def set(self, name, value):
method setup (line 550) | def setup(self, timeout=None):
method run (line 556) | def run(self, timeout=None):
method extract_results (line 561) | def extract_results(self, timeout=None):
method teardown (line 566) | def teardown(self, timeout=None):
method remove (line 571) | def remove(self):
method _execute (line 574) | def _execute(self, stage, timeout):
class ReventGUI (line 583) | class ReventGUI(object):
method __init__ (line 585) | def __init__(self, workload, target, setup_timeout, run_timeout,
method init_resources (line 605) | def init_resources(self, resolver):
method deploy (line 622) | def deploy(self):
method setup (line 625) | def setup(self):
method run (line 631) | def run(self):
method extract_results (line 639) | def extract_results(self):
method teardown (line 644) | def teardown(self):
method remove (line 649) | def remove(self):
method _check_revent_files (line 656) | def _check_revent_files(self):
class PackageHandler (line 672) | class PackageHandler(object):
method package (line 675) | def package(self):
method activity (line 681) | def activity(self):
method __init__ (line 689) | def __init__(self, owner, install_timeout=300, version=None, variant=N...
method initialize (line 717) | def initialize(self, context):
method setup (line 720) | def setup(self, context):
method resolve_package (line 728) | def resolve_package(self, context):
method resolve_package_from_host (line 760) | def resolve_package_from_host(self, context):
method resolve_package_from_target (line 791) | def resolve_package_from_target(self): # pylint: disable=too-many-bra...
method initialize_package (line 832) | def initialize_package(self, context):
method start_activity (line 859) | def start_activity(self):
method restart_activity (line 871) | def restart_activity(self):
method reset (line 875) | def reset(self, context): # pylint: disable=W0613
method install_apk (line 880) | def install_apk(self, context):
method pull_apk (line 893) | def pull_apk(self, package):
method teardown (line 905) | def teardown(self):
method _get_package_name (line 910) | def _get_package_name(self, apk_path):
method _get_package_error_msg (line 913) | def _get_package_error_msg(self, location):
class TestPackageHandler (line 928) | class TestPackageHandler(PackageHandler):
method __init__ (line 931) | def __init__(self, owner, instrument_args=None, raw_output=False,
method setup (line 946) | def setup(self, context):
method start_activity (line 966) | def start_activity(self):
method wait_instrument_over (line 969) | def wait_instrument_over(self):
method _start_instrument (line 976) | def _start_instrument(self):
method _get_package_name (line 980) | def _get_package_name(self, apk_path):
method instrument_output (line 984) | def instrument_output(self):
FILE: wa/instruments/delay.py
class DelayInstrument (line 26) | class DelayInstrument(Instrument):
method initialize (line 140) | def initialize(self, context):
method start (line 158) | def start(self, context):
method before_job (line 168) | def before_job(self, context):
method wait_for_temperature (line 184) | def wait_for_temperature(self, temperature):
method do_wait_for_temperature (line 192) | def do_wait_for_temperature(self, temperature):
method validate (line 203) | def validate(self):
method _discover_cooling_module (line 221) | def _discover_cooling_module(self):
FILE: wa/instruments/dmesg.py
class DmesgInstrument (line 25) | class DmesgInstrument(Instrument):
method initialize (line 41) | def initialize(self, context): # pylint: disable=unused-argument
method setup (line 46) | def setup(self, context):
method start (line 54) | def start(self, context):
method stop (line 62) | def stop(self, context):
method teardown (line 67) | def teardown(self, context): # pylint: disable=unused-argument
FILE: wa/instruments/energy_measurement.py
class EnergyInstrumentBackend (line 42) | class EnergyInstrumentBackend(Plugin):
method get_parameters (line 50) | def get_parameters(self):
method validate_parameters (line 53) | def validate_parameters(self, params):
method get_instruments (line 56) | def get_instruments(self, target, metadir, **kwargs):
class DAQBackend (line 66) | class DAQBackend(EnergyInstrumentBackend):
method validate_parameters (line 158) | def validate_parameters(self, params):
class EnergyProbeBackend (line 167) | class EnergyProbeBackend(EnergyInstrumentBackend):
method validate_parameters (line 208) | def validate_parameters(self, params):
class ArmEnergyProbeBackend (line 217) | class ArmEnergyProbeBackend(EnergyInstrumentBackend):
method get_instruments (line 249) | def get_instruments(self, target, metadir, **kwargs):
method validate_parameters (line 261) | def validate_parameters(self, params):
class AcmeCapeBackend (line 269) | class AcmeCapeBackend(EnergyInstrumentBackend):
method get_instruments (line 312) | def get_instruments(self, target, metadir,
class MonsoonBackend (line 338) | class MonsoonBackend(EnergyInstrumentBackend):
class JunoEnergyBackend (line 371) | class JunoEnergyBackend(EnergyInstrumentBackend):
class EnergyMeasurement (line 386) | class EnergyMeasurement(Instrument):
method __init__ (line 436) | def __init__(self, target, loader=pluginloader, **kwargs):
method initialize (line 455) | def initialize(self, context):
method setup (line 472) | def setup(self, context):
method start (line 478) | def start(self, context):
method stop (line 482) | def stop(self, context):
method update_output (line 486) | def update_output(self, context):
method extract_metrics (line 507) | def extract_metrics(self, context):
method teardown (line 538) | def teardown(self, context):
FILE: wa/instruments/fps.py
class FpsInstrument (line 26) | class FpsInstrument(Instrument):
method __init__ (line 101) | def __init__(self, target, **kwargs):
method setup (line 107) | def setup(self, context):
method start (line 130) | def start(self, context): # pylint: disable=unused-argument
method stop (line 135) | def stop(self, context): # pylint: disable=unused-argument
method update_output (line 140) | def update_output(self, context):
method check_for_crash (line 173) | def check_for_crash(self, context, fps, frames, exec_time):
FILE: wa/instruments/hwmon.py
class HwmonInstrument (line 25) | class HwmonInstrument(Instrument):
method initialize (line 44) | def initialize(self, context): # pylint: disable=unused-argument
method setup (line 47) | def setup(self, context): # pylint: disable=unused-argument
method start (line 51) | def start(self, context): # pylint: disable=unused-argument
method stop (line 55) | def stop(self, context): # pylint: disable=unused-argument
method update_output (line 58) | def update_output(self, context):
method teardown (line 88) | def teardown(self, context): # pylint: disable=unused-argument
FILE: wa/instruments/misc.py
class SysfsExtractor (line 50) | class SysfsExtractor(Instrument):
method initialize (line 85) | def initialize(self, context):
method setup (line 100) | def setup(self, context):
method start (line 129) | def start(self, context):
method stop (line 142) | def stop(self, context):
method update_output (line 154) | def update_output(self, context):
method teardown (line 186) | def teardown(self, context):
method finalize (line 189) | def finalize(self, context):
method validate (line 199) | def validate(self):
method _local_dir (line 203) | def _local_dir(self, directory):
class ExecutionTimeInstrument (line 207) | class ExecutionTimeInstrument(Instrument):
method __init__ (line 215) | def __init__(self, target, **kwargs):
method start (line 221) | def start(self, context):
method stop (line 225) | def stop(self, context):
method update_output (line 228) | def update_output(self, context):
class ApkVersion (line 233) | class ApkVersion(Instrument):
method __init__ (line 241) | def __init__(self, device, **kwargs):
method setup (line 245) | def setup(self, context):
method update_output (line 251) | def update_output(self, context):
class InterruptStatsInstrument (line 256) | class InterruptStatsInstrument(Instrument):
method __init__ (line 265) | def __init__(self, target, **kwargs):
method setup (line 271) | def setup(self, context):
method start (line 276) | def start(self, context):
method stop (line 280) | def stop(self, context):
method update_output (line 284) | def update_output(self, context):
class DynamicFrequencyInstrument (line 296) | class DynamicFrequencyInstrument(SysfsExtractor):
method setup (line 310) | def setup(self, context):
method validate (line 316) | def validate(self):
FILE: wa/instruments/perf.py
class PerfInstrument (line 30) | class PerfInstrument(Instrument):
method __init__ (line 118) | def __init__(self, target, **kwargs):
method validate (line 123) | def validate(self):
method initialize (line 131) | def initialize(self, context):
method setup (line 147) | def setup(self, context):
method start (line 152) | def start(self, context):
method stop (line 155) | def stop(self, context):
method update_output (line 158) | def update_output(self, context):
method teardown (line 167) | def teardown(self, context):
method _process_perf_output (line 170) | def _process_perf_output(self, context):
method _process_simpleperf_output (line 176) | def _process_simpleperf_output(self, context):
method _process_perf_stat_output (line 182) | def _process_perf_stat_output(self, context):
method _add_perf_stat_metric (line 202) | def _add_perf_stat_metric(line, label, context):
method _process_perf_record_output (line 215) | def _process_perf_record_output(self, context):
method _get_report_event_type (line 241) | def _get_report_event_type(words, event_type):
method _process_simpleperf_stat_output (line 249) | def _process_simpleperf_stat_output(self, context):
method _process_simpleperf_stat_from_csv (line 261) | def _process_simpleperf_stat_from_csv(stat_file, context, label):
method _process_simpleperf_stat_from_raw (line 274) | def _process_simpleperf_stat_from_raw(stat_file, context, label):
method _process_simpleperf_record_output (line 293) | def _process_simpleperf_record_output(self, context):
method _get_report_column_headers (line 323) | def _get_report_column_headers(column_headers, words, perf_type):
method _add_report_metric (line 337) | def _add_report_metric(column_headers, column_header_indeces, line, wo...
FILE: wa/instruments/perfetto.py
class PerfettoInstrument (line 28) | class PerfettoInstrument(Instrument):
method __init__ (line 62) | def __init__(self, target, **kwargs):
method initialize (line 66) | def initialize(self, context): # pylint: disable=unused-argument
method start (line 77) | def start(self, context): # pylint: disable=unused-argument
method stop (line 81) | def stop(self, context): # pylint: disable=unused-argument
method update_output (line 84) | def update_output(self, context):
method teardown (line 91) | def teardown(self, context): # pylint: disable=unused-argument
method finalize (line 94) | def finalize(self, context): # pylint: disable=unused-argument
method validate (line 97) | def validate(self):
FILE: wa/instruments/poller/__init__.py
class FilePoller (line 26) | class FilePoller(Instrument):
method validate (line 70) | def validate(self):
method initialize (line 76) | def initialize(self, context):
method start (line 112) | def start(self, context):
method stop (line 115) | def stop(self, context):
method update_output (line 118) | def update_output(self, context):
method teardown (line 134) | def teardown(self, context):
method _generate_labels (line 138) | def _generate_labels(self):
method _adjust_timestamps (line 153) | def _adjust_timestamps(self, context):
FILE: wa/instruments/poller/poller.c
function term (line 27) | void term(int signum)
function strip (line 32) | void strip(char *s) {
type poll_source_t (line 44) | typedef struct {
function write_trace_marker (line 50) | int write_trace_marker(char *marker, int size)
function main (line 66) | int main(int argc, char ** argv) {
FILE: wa/instruments/proc_stat/__init__.py
class ProcStatCollector (line 24) | class ProcStatCollector(Instrument):
method initialize (line 39) | def initialize(self, context): # pylint: disable=unused-argument
method setup (line 45) | def setup(self, context): # pylint: disable=unused-argument
method start (line 57) | def start(self, context): # pylint: disable=unused-argument
method stop (line 60) | def stop(self, context): # pylint: disable=unused-argument
method update_output (line 63) | def update_output(self, context):
method finalize (line 83) | def finalize(self, context): # pylint: disable=unused-argument
method _wait_for_script (line 88) | def _wait_for_script(self):
FILE: wa/instruments/screencap.py
class ScreenCaptureInstrument (line 23) | class ScreenCaptureInstrument(Instrument):
method __init__ (line 41) | def __init__(self, target, **kwargs):
method setup (line 45) | def setup(self, context):
method start (line 54) | def start(self, context): # pylint: disable=unused-argument
method stop (line 57) | def stop(self, context): # pylint: disable=unused-argument
FILE: wa/instruments/serialmon.py
class SerialMon (line 23) | class SerialMon(Instrument):
method __init__ (line 47) | def __init__(self, target, **kwargs):
method start_logging (line 51) | def start_logging(self, context, filename="serial.log"):
method stop_logging (line 60) | def stop_logging(self, context, identifier="job"):
method on_run_start (line 69) | def on_run_start(self, context):
method before_job_queue_execution (line 72) | def before_job_queue_execution(self, context):
method after_job_queue_execution (line 75) | def after_job_queue_execution(self, context):
method on_run_end (line 78) | def on_run_end(self, context):
method on_job_start (line 81) | def on_job_start(self, context):
method on_job_end (line 84) | def on_job_end(self, context):
method before_reboot (line 88) | def before_reboot(self, context):
FILE: wa/instruments/trace_cmd.py
class TraceCmdInstrument (line 36) | class TraceCmdInstrument(Instrument):
method __init__ (line 174) | def __init__(self, target, **kwargs):
method initialize (line 178) | def initialize(self, context):
method setup (line 208) | def setup(self, context):
method start (line 213) | def start(self, context):
method stop (line 218) | def stop(self, context):
method update_output (line 222) | def update_output(self, context): # NOQA pylint: disable=R0912
method teardown (line 238) | def teardown(self, context):
method validate (line 245) | def validate(self):
method mark_start (line 251) | def mark_start(self, context):
method mark_stop (line 255) | def mark_stop(self, context):
FILE: wa/output_processors/cpustates.py
function _get_cpustates_description (line 24) | def _get_cpustates_description():
class CpuStatesProcessor (line 44) | class CpuStatesProcessor(OutputProcessor):
method __init__ (line 88) | def __init__(self, *args, **kwargs):
method process_job_output (line 92) | def process_job_output(self, output, target_info, run_output): # pyli...
method process_run_output (line 121) | def process_run_output(self, output, target_info):
FILE: wa/output_processors/csvproc.py
class CsvReportProcessor (line 23) | class CsvReportProcessor(OutputProcessor):
method __init__ (line 52) | def __init__(self, *args, **kwargs):
method validate (line 57) | def validate(self):
method process_job_output (line 65) | def process_job_output(self, output, target_info, run_output):
method process_run_output (line 72) | def process_run_output(self, output, target_info): # pylint: disable=...
method _write_outputs (line 79) | def _write_outputs(self, outputs, output):
FILE: wa/output_processors/postgresql.py
class PostgresqlResultProcessor (line 41) | class PostgresqlResultProcessor(OutputProcessor):
method __init__ (line 116) | def __init__(self, *args, **kwargs):
method initialize (line 123) | def initialize(self, context):
method export_job_output (line 222) | def export_job_output(self, job_output, target_info, run_output): # ...
method export_run_output (line 305) | def export_run_output(self, run_output, target_info): # pylint: disab...
method sql_upload_resource_getters (line 352) | def sql_upload_resource_getters(self, output_object):
method sql_upload_events (line 369) | def sql_upload_events(self, output_object, job_uuid=None):
method sql_upload_job_augmentations (line 385) | def sql_upload_job_augmentations(self, output_object, job_uuid=None):
method sql_upload_augmentations (line 407) | def sql_upload_augmentations(self, output_object):
method sql_upload_metrics (line 427) | def sql_upload_metrics(self, output_object, record_in_added=False, che...
method sql_upload_artifacts (line 463) | def sql_upload_artifacts(self, output_object, record_in_added=False, c...
method sql_upload_parameters (line 478) | def sql_upload_parameters(self, parameter_type, parameter_dict, owner_...
method connect_to_database (line 511) | def connect_to_database(self):
method execute_sql_line_by_line (line 523) | def execute_sql_line_by_line(self, sql):
method verify_schema_versions (line 532) | def verify_schema_versions(self):
method _sql_write_file_lobject (line 544) | def _sql_write_file_lobject(self, source, lobject):
method _sql_write_dir_lobject (line 552) | def _sql_write_dir_lobject(self, source, lobject):
method _sql_update_artifact (line 557) | def _sql_update_artifact(self, artifact, output_object):
method _sql_create_artifact (line 565) | def _sql_create_artifact(self, artifact, output_object, record_in_adde...
FILE: wa/output_processors/sqlite.py
class SqliteResultProcessor (line 75) | class SqliteResultProcessor(OutputProcessor):
method __init__ (line 111) | def __init__(self, *args, **kwargs):
method export_job_output (line 118) | def export_job_output(self, job_output, target_info, run_output): # p...
method export_run_output (line 131) | def export_run_output(self, run_output, target_info): # pylint: disab...
method _init_run (line 146) | def _init_run(self, run_output):
method _init_db (line 167) | def _init_db(self):
method _validate_schema_version (line 172) | def _validate_schema_version(self):
method _update_run (line 184) | def _update_run(self, run_uuid):
method _update_spec (line 191) | def _update_spec(self, spec):
method _open_connection (line 204) | def _open_connection(self):
FILE: wa/output_processors/status.py
class StatusTxtReporter (line 26) | class StatusTxtReporter(OutputProcessor):
method process_run_output (line 34) | def process_run_output(self, output, target_info): # pylint: disable=...
FILE: wa/output_processors/targz.py
class TargzProcessor (line 23) | class TargzProcessor(OutputProcessor):
method initialize (line 59) | def initialize(self, context):
method export_run_output (line 64) | def export_run_output(self, run_output, target_info): # pylint: disab...
method delete_output_directory (line 74) | def delete_output_directory(self, context):
FILE: wa/output_processors/uxperf.py
class UxperfProcessor (line 21) | class UxperfProcessor(OutputProcessor):
method process_job_output (line 34) | def process_job_output(self, output, target_info, job_output):
FILE: wa/tools/revent/revent.c
type bool_t (line 58) | typedef enum {
type recording_mode_t (line 63) | typedef enum {
type revent_command_t (line 69) | typedef enum {
type absinfo_t (line 77) | typedef struct {
type device_info_t (line 82) | typedef struct {
type revent_args_t (line 93) | typedef struct {
type input_devices_t (line 101) | typedef struct {
type replay_event_t (line 108) | typedef struct {
type revent_record_desc_t (line 113) | typedef struct {
type revent_recording_t (line 118) | typedef struct {
function bool_t (line 131) | bool_t is_numeric(char *string)
function test_bit (line 146) | int test_bit(const char *mask, int bit) {
function count_bits (line 150) | int count_bits(const char *mask) {
function bool_t (line 170) | bool_t is_gamepad(device_info_t *dev)
function off_t (line 181) | off_t get_file_size(const char *filename) {
function get_device_info (line 190) | int get_device_info(int fd, device_info_t *info) {
function destroy_replay_device (line 228) | void destroy_replay_device(int fd)
function set_evbit (line 234) | inline void set_evbit(int fd, int bit)
function set_keybit (line 240) | inline void set_keybit(int fd, int bit)
function set_absbit (line 246) | inline void set_absbit(int fd, int bit)
function set_relbit (line 252) | inline void set_relbit(int fd, int bit)
function block_sigterm (line 258) | inline void block_sigterm(sigset_t *oldset)
function adjust_timestamps (line 268) | void adjust_timestamps(revent_recording_t *recording)
function write_record_header (line 286) | int write_record_header(int fd, const revent_record_desc_t *desc)
function read_record_header (line 311) | int read_record_header(int fd, revent_record_desc_t *desc)
function write_general_input_devices (line 346) | int write_general_input_devices(const input_devices_t *devices, FILE *fout)
function read_general_input_devices (line 373) | int read_general_input_devices(input_devices_t *devices, FILE *fin)
function write_input_id (line 410) | int write_input_id(FILE *fout, const struct input_id *id)
function read_input_id (line 422) | int read_input_id(FILE *fin, struct input_id *id)
function write_absinfo (line 434) | int write_absinfo(FILE *fout, const absinfo_t *info)
function read_absinfo (line 449) | int read_absinfo(FILE *fin, absinfo_t *info)
function write_device_info (line 464) | int write_device_info(FILE *fout, const device_info_t *info)
function read_device_info (line 499) | int read_device_info(FILE *fin, device_info_t *info)
function print_device_info (line 536) | void print_device_info(device_info_t *info)
function read_record_timestamps (line 567) | int read_record_timestamps(FILE *fin, revent_recording_t *recording)
function write_replay_event (line 589) | int write_replay_event(FILE *fout, const replay_event_t *ev)
function read_replay_event (line 623) | int read_replay_event(FILE *fin, replay_event_t *ev)
function read_legacy_replay_event (line 654) | int read_legacy_replay_event(int fdin, replay_event_t* ev)
function open_revent_recording (line 699) | int open_revent_recording(const char *filepath, revent_record_desc_t *de...
function FILE (line 715) | FILE *init_recording(const char *pathname, recording_mode_t mode)
function init_input_devices (line 728) | void init_input_devices(input_devices_t *devices)
function init_general_input_devices (line 736) | int init_general_input_devices(input_devices_t *devices)
function fini_general_input_devices (line 792) | void fini_general_input_devices(input_devices_t *devices)
function init_gamepad_input_devices (line 806) | int init_gamepad_input_devices(input_devices_t *devices, device_info_t *...
function fini_gamepad_input_devices (line 872) | void fini_gamepad_input_devices(input_devices_t *devices)
function init_revent_recording (line 877) | void init_revent_recording(revent_recording_t *recording)
function fini_revent_recording (line 887) | void fini_revent_recording(revent_recording_t *recording)
function open_general_input_devices_for_playback_or_die (line 906) | void open_general_input_devices_for_playback_or_die(input_devices_t *dev...
function create_replay_device_or_die (line 927) | int create_replay_device_or_die(const device_info_t *info)
function read_revent_recording_or_die (line 986) | inline void read_revent_recording_or_die(const char *filepath, revent_re...
function open_gamepad_input_devices_for_playback_or_die (line 1084) | void open_gamepad_input_devices_for_playback_or_die(input_devices_t *dev...
function exitHandler (line 1097) | void exitHandler(int z) {
function record (line 1101) | void record(const char *filepath, int delay, recording_mode_t mode)
function dump (line 1262) | void dump(const char *filepath)
function replay (line 1302) | void replay(const char *filepath)
function info (line 1391) | void info(void)
function usage (line 1420) | void usage()
function revent_args_init (line 1471) | void revent_args_init(revent_args_t **rargs, int argc, char** argv)
function revent_args_close (line 1563) | int revent_args_close(revent_args_t *rargs)
function main (line 1569) | int main(int argc, char** argv)
FILE: wa/utils/android.py
class LogcatEvent (line 39) | class LogcatEvent(object):
method __init__ (line 43) | def __init__(self, timestamp, pid, tid, level, tag, message):
method __repr__ (line 51) | def __repr__(self):
class LogcatParser (line 61) | class LogcatParser(object):
method parse (line 63) | def parse(self, filepath):
method parse_line (line 70) | def parse_line(self, line): # pylint: disable=no-self-use
class ApkInfo (line 94) | class ApkInfo(_ApkInfo, Podable):
method from_pod (line 100) | def from_pod(pod):
method __init__ (line 115) | def __init__(self, path=None):
method to_pod (line 119) | def to_pod(self):
method _pod_upgrade_v1 (line 135) | def _pod_upgrade_v1(pod):
class ApkInfoCache (line 140) | class ApkInfoCache:
method _check_env (line 143) | def _check_env():
method __init__ (line 147) | def __init__(self, path=settings.apk_info_cache_file):
method store (line 154) | def store(self, apk_info, apk_id, overwrite=True):
method get_info (line 163) | def get_info(self, key):
method _update_cache (line 170) | def _update_cache(self):
function get_cacheable_apk_info (line 179) | def get_cacheable_apk_info(path):
function build_apk_launch_command (line 202) | def build_apk_launch_command(package, activity=None, apk_args=None):
FILE: wa/utils/cpustates.py
class CorePowerTransitionEvent (line 34) | class CorePowerTransitionEvent(object):
method __init__ (line 39) | def __init__(self, timestamp, cpu_id, frequency=None, idle_state=None):
method __str__ (line 47) | def __str__(self):
method __repr__ (line 51) | def __repr__(self):
class CorePowerDroppedEvents (line 56) | class CorePowerDroppedEvents(object):
method __init__ (line 61) | def __init__(self, cpu_id):
method __str__ (line 64) | def __str__(self):
class TraceMarkerEvent (line 70) | class TraceMarkerEvent(object):
method __init__ (line 75) | def __init__(self, name):
method __str__ (line 78) | def __str__(self):
class CpuPowerState (line 82) | class CpuPowerState(object):
method is_idling (line 87) | def is_idling(self):
method is_active (line 91) | def is_active(self):
method __init__ (line 94) | def __init__(self, frequency=None, idle_state=None):
method __str__ (line 98) | def __str__(self):
class SystemPowerState (line 104) | class SystemPowerState(object):
method num_cores (line 109) | def num_cores(self):
method __init__ (line 112) | def __init__(self, num_cores, no_idle=False):
method copy (line 119) | def copy(self):
method __str__ (line 127) | def __str__(self):
class PowerStateProcessor (line 133) | class PowerStateProcessor(object):
method cpu_states (line 141) | def cpu_states(self):
method current_time (line 145) | def current_time(self):
method current_time (line 149) | def current_time(self, value):
method __init__ (line 152) | def __init__(self, cpus, wait_for_marker=True, no_idle=None):
method process (line 164) | def process(self, event_stream):
method update_power_state (line 178) | def update_power_state(self, event):
method _process_transition (line 197) | def _process_transition(self, event):
method _process_dropped_events (line 207) | def _process_dropped_events(self, event):
method _process_idle_entry (line 216) | def _process_idle_entry(self, event):
method _process_idle_exit (line 222) | def _process_idle_exit(self, event):
method _try_transition_to_idle_state (line 236) | def _try_transition_to_idle_state(self, cpu_id, idle_state):
method _can_enter_state (line 258) | def _can_enter_state(self, related_ids, state):
function stream_cpu_power_transitions (line 277) | def stream_cpu_power_transitions(events):
function gather_core_states (line 302) | def gather_core_states(system_state_stream, freq_dependent_idle_states=N...
function record_state_transitions (line 320) | def record_state_transitions(reporter, stream):
class PowerStateTransitions (line 327) | class PowerStateTransitions(object):
method __init__ (line 331) | def __init__(self, output_directory):
method update (line 337) | def update(self, timestamp, core_states): # NOQA
method record_transition (line 342) | def record_transition(self, transition):
method report (line 347) | def report(self):
method write (line 350) | def write(self):
class PowerStateTimeline (line 354) | class PowerStateTimeline(object):
method __init__ (line 358) | def __init__(self, output_directory, cpus):
method update (line 365) | def update(self, timestamp, core_states): # NOQA
method report (line 387) | def report(self):
method write (line 390) | def write(self):
class ParallelStats (line 394) | class ParallelStats(object):
method __init__ (line 396) | def __init__(self, output_directory, cpus, use_ratios=False):
method update (line 416) | def update(self, timestamp, core_states):
method report (line 432) | def report(self): # NOQA
class ParallelReport (line 464) | class ParallelReport(object):
method __init__ (line 468) | def __init__(self, filepath):
method add (line 472) | def add(self, value):
method write (line 475) | def write(self):
class PowerStateStats (line 481) | class PowerStateStats(object):
method __init__ (line 483) | def __init__(self, output_directory, cpus, use_ratios=False):
method update (line 493) | def update(self, timestamp, core_states): # NOQA
method report (line 515) | def report(self):
class PowerStateStatsReport (line 533) | class PowerStateStatsReport(object):
method __init__ (line 537) | def __init__(self, filepath, state_stats, core_names, precision=2):
method write (line 543) | def write(self):
class CpuUtilizationTimeline (line 555) | class CpuUtilizationTimeline(object):
method __init__ (line 559) | def __init__(self, output_directory, cpus):
method update (line 567) | def update(self, timestamp, core_states): # NOQA
method report (line 577) | def report(self):
method write (line 580) | def write(self):
function build_idle_state_map (line 584) | def build_idle_state_map(cpus):
function report_power_stats (line 597) | def report_power_stats(trace_file, cpus, output_basedir, use_ratios=Fals...
FILE: wa/utils/diff.py
function diff_interrupt_files (line 30) | def diff_interrupt_files(before, after, result): # pylint: disable=R0914
function diff_sysfs_dirs (line 72) | def diff_sysfs_dirs(before, after, result): # pylint: disable=R0914
FILE: wa/utils/doc.py
function get_summary (line 31) | def get_summary(aclass):
function get_description (line 42) | def get_description(aclass):
function get_type_name (line 56) | def get_type_name(obj):
function count_leading_spaces (line 78) | def count_leading_spaces(text):
function format_column (line 95) | def format_column(text, width):
function format_bullets (line 123) | def format_bullets(text, width, char='-', shift=3, outchar=None):
function format_simple_table (line 163) | def format_simple_table(rows, headers=None, align='>', show_borders=True...
function format_paragraph (line 195) | def format_paragraph(text, width):
function format_body (line 206) | def format_body(text, width):
function strip_inlined_text (line 225) | def strip_inlined_text(text):
function indent (line 250) | def indent(text, spaces=4):
function format_literal (line 261) | def format_literal(lit):
function get_params_rst (line 273) | def get_params_rst(parameters):
function get_aliases_rst (line 297) | def get_aliases_rst(aliases):
function underline (line 306) | def underline(text, symbol='='):
function line_break (line 310) | def line_break(length=10, symbol='-'):
function get_rst_from_plugin (line 315) | def get_rst_from_plugin(plugin):
FILE: wa/utils/exec_control.py
function activate_environment (line 21) | def activate_environment(name):
function init_environment (line 35) | def init_environment(name):
function reset_environment (line 49) | def reset_environment(name=None):
function once_per_instance (line 70) | def once_per_instance(method):
function once_per_class (line 88) | def once_per_class(method):
function once_per_attribute_value (line 108) | def once_per_attribute_value(attr_name):
function once (line 132) | def once(method):
FILE: wa/utils/formatter.py
class TextFormatter (line 23) | class TextFormatter(object):
method __init__ (line 35) | def __init__(self):
method add_item (line 38) | def add_item(self, new_data, item_title):
method format_data (line 47) | def format_data(self):
class DescriptionListFormatter (line 54) | class DescriptionListFormatter(TextFormatter):
method get_text_width (line 59) | def get_text_width(self):
method set_text_width (line 64) | def set_text_width(self, value):
method __init__ (line 69) | def __init__(self, title=None, width=None):
method add_item (line 76) | def add_item(self, new_data, item_title):
method format_data (line 81) | def format_data(self):
method _remove_newlines (line 110) | def _remove_newlines(self, new_data): # pylint: disable=R0201
method _break_lines (line 130) | def _break_lines(self, parag_list, line_width): # pylint: disable=R0201
FILE: wa/utils/log.py
function init (line 54) | def init(verbosity=logging.INFO, color=True, indent_with=4,
function set_level (line 95) | def set_level(level):
function add_file (line 100) | def add_file(filepath, level=logging.DEBUG,
function enable (line 116) | def enable(logs):
function disable (line 124) | def disable(logs):
function __enable_logger (line 132) | def __enable_logger(logger):
function __disable_logger (line 138) | def __disable_logger(logger):
function indent (line 145) | def indent():
function dedent (line 151) | def dedent():
function indentcontext (line 157) | def indentcontext():
function set_indent_level (line 166) | def set_indent_level(level):
function log_error (line 173) | def log_error(e, logger, critical=False):
class ErrorSignalHandler (line 220) | class ErrorSignalHandler(logging.Handler):
method emit (line 226) | def emit(self, record):
class InitHandler (line 233) | class InitHandler(logging.handlers.BufferingHandler):
method __init__ (line 239) | def __init__(self, capacity):
method emit (line 243) | def emit(self, record):
method flush (line 247) | def flush(self):
method add_target (line 252) | def add_target(self, target):
method flush_to_target (line 256) | def flush_to_target(self, target):
class LineFormatter (line 261) | class LineFormatter(logging.Formatter):
method format (line 267) | def format(self, record):
class ColorFormatter (line 284) | class ColorFormatter(LineFormatter):
method __init__ (line 297) | def __init__(self, fmt=None, datefmt=None):
method format (line 303) | def format(self, record):
method _set_color (line 307) | def _set_color(self, color):
class BaseLogWriter (line 311) | class BaseLogWriter(object):
method __init__ (line 313) | def __init__(self, name, level=logging.DEBUG):
method flush (line 335) | def flush(self):
method close (line 339) | def close(self):
method __del__ (line 345) | def __del__(self):
class LogWriter (line 350) | class LogWriter(BaseLogWriter):
method write (line 352) | def write(self, data):
class LineLogWriter (line 365) | class LineLogWriter(BaseLogWriter):
method write (line 367) | def write(self, data):
class StreamLogger (line 371) | class StreamLogger(threading.Thread):
method __init__ (line 377) | def __init__(self, name, stream, level=logging.DEBUG, klass=LogWriter):
method run (line 383) | def run(self):
FILE: wa/utils/misc.py
function diff_tokens (line 71) | def diff_tokens(before_token, after_token):
function prepare_table_rows (line 99) | def prepare_table_rows(rows):
function write_table (line 111) | def write_table(rows, wfh, align='>', headers=None): # pylint: disable=...
function get_null (line 139) | def get_null():
function get_traceback (line 144) | def get_traceback(exc=None):
function _check_remove_item (line 161) | def _check_remove_item(the_list, item):
function parse_value (line 189) | def parse_value(value_string):
function get_meansd (line 204) | def get_meansd(values):
function geomean (line 213) | def geomean(values):
function capitalize (line 218) | def capitalize(text):
function utc_to_local (line 226) | def utc_to_local(dt):
function local_to_utc (line 231) | def local_to_utc(dt):
function load_class (line 236) | def load_class(classpath):
function get_pager (line 248) | def get_pager():
function strip_bash_colors (line 261) | def strip_bash_colors(text):
function format_duration (line 265) | def format_duration(seconds, sep=' ', order=['day', 'hour', 'minute', 's...
function get_article (line 287) | def get_article(word):
function get_random_string (line 299) | def get_random_string(length):
function import_path (line 304) | def import_path(filepath, module_name=None):
function load_struct_from_python (line 336) | def load_struct_from_python(filepath):
function open_file (line 352) | def open_file(filepath):
function sha256 (line 365) | def sha256(path, chunk=2048):
function urljoin (line 376) | def urljoin(*parts):
function istextfile (line 381) | def istextfile(fileobj, blocksize=512):
function categorize (line 404) | def categorize(v):
function merge_config_values (line 418) | def merge_config_values(base, other):
function merge_sequencies (line 515) | def merge_sequencies(s1, s2):
function merge_maps (line 519) | def merge_maps(m1, m2):
function merge_dicts_simple (line 523) | def merge_dicts_simple(base, other):
function touch (line 530) | def touch(path):
function get_object_name (line 535) | def get_object_name(obj):
function resolve_cpus (line 550) | def resolve_cpus(name, target):
function resolve_unique_domain_cpus (line 603) | def resolve_unique_domain_cpus(name, target):
function format_ordered_dict (line 624) | def format_ordered_dict(od):
function atomic_write_path (line 635) | def atomic_write_path(path, mode='w'):
function safe_move (line 656) | def safe_move(src, dst):
function lock_file (line 692) | def lock_file(path, timeout=30):
FILE: wa/utils/postgres.py
function cast_level (line 49) | def cast_level(value, cur): # pylint: disable=unused-argument
function cast_vanilla (line 66) | def cast_vanilla(value, cur): # pylint: disable=unused-argument
function adapt_level (line 79) | def adapt_level(a_level):
class ListOfLevel (line 84) | class ListOfLevel(object):
method __init__ (line 87) | def __init__(self, a_level):
method return_original (line 90) | def return_original(self):
function adapt_ListOfX (line 94) | def adapt_ListOfX(adapt_X):
function return_as_is (line 151) | def return_as_is(adapt_X):
function adapt_vanilla (line 166) | def adapt_vanilla(param):
function create_iterable_adapter (line 173) | def create_iterable_adapter(array_columns, explicit_iterate=False):
function adapt_list (line 215) | def adapt_list(param):
function get_schema (line 227) | def get_schema(schemafilepath):
function get_database_schema_version (line 243) | def get_database_schema_version(conn):
function get_schema_versions (line 254) | def get_schema_versions(conn):
FILE: wa/utils/revent.py
function read_struct (line 51) | def read_struct(fh, struct_spec):
function read_string (line 56) | def read_string(fh):
function count_bits (line 62) | def count_bits(bitarr):
function is_set (line 66) | def is_set(bitarr, bit):
class UinputDeviceInfo (line 75) | class UinputDeviceInfo(object):
method __init__ (line 77) | def __init__(self, fh):
method __str__ (line 95) | def __str__(self):
class ReventEvent (line 99) | class ReventEvent(object):
method __init__ (line 101) | def __init__(self, fh, legacy=False):
method __str__ (line 112) | def __str__(self):
class ReventRecording (line 116) | class ReventRecording(object):
method duration (line 145) | def duration(self):
method events (line 164) | def events(self):
method __init__ (line 170) | def __init__(self, f, stream=True):
method close (line 197) | def close(self):
method _parse_header_and_devices (line 203) | def _parse_header_and_devices(self, fh):
method _read_devices (line 233) | def _read_devices(self, fh):
method _read_gamepad_info (line 238) | def _read_gamepad_info(self, fh):
method _iter_events (line 242) | def _iter_events(self):
method __iter__ (line 255) | def __iter__(self):
method __enter__ (line 259) | def __enter__(self):
method __exit__ (line 262) | def __exit__(self, *args):
method __del__ (line 265) | def __del__(self):
function get_revent_binary (line 269) | def get_revent_binary(abi):
class ReventRecorder (line 276) | class ReventRecorder(object):
method __init__ (line 281) | def __init__(self, target):
method deploy (line 288) | def deploy(self):
method remove (line 295) | def remove(self):
method start_record (line 299) | def start_record(self, revent_file):
method stop_record (line 304) | def stop_record(self):
method replay (line 307) | def replay(self, revent_file, timeout=None):
method _get_target_path (line 315) | def _get_target_path(target):
FILE: wa/utils/serializer.py
class WAJSONEncoder (line 112) | class WAJSONEncoder(_json.JSONEncoder):
method default (line 114) | def default(self, obj): # pylint: disable=method-hidden,arguments-differ
class WAJSONDecoder (line 127) | class WAJSONDecoder(_json.JSONDecoder):
method decode (line 129) | def decode(self, s, **kwargs): # pylint: disable=arguments-differ
class json (line 165) | class json(object):
method dump (line 168) | def dump(o, wfh, indent=4, *args, **kwargs):
method dumps (line 172) | def dumps(o, indent=4, *args, **kwargs):
method load (line 176) | def load(fh, *args, **kwargs):
method loads (line 183) | def loads(s, *args, **kwargs):
function _wa_dict_representer (line 196) | def _wa_dict_representer(dumper, data):
function _wa_regex_representer (line 200) | def _wa_regex_representer(dumper, data):
function _wa_level_representer (line 205) | def _wa_level_representer(dumper, data):
function _wa_cpu_mask_representer (line 210) | def _wa_cpu_mask_representer(dumper, data):
function _wa_regex_constructor (line 214) | def _wa_regex_constructor(loader, node):
function _wa_level_constructor (line 220) | def _wa_level_constructor(loader, node):
function _wa_cpu_mask_constructor (line 226) | def _wa_cpu_mask_constructor(loader, node):
class _WaYamlLoader (line 231) | class _WaYamlLoader(_yaml_loader): # pylint: disable=too-many-ancestors
method construct_mapping (line 233) | def construct_mapping(self, node, deep=False):
class yaml (line 261) | class yaml(object):
method dump (line 264) | def dump(o, wfh, *args, **kwargs):
method load (line 268) | def load(fh, *args, **kwargs):
class python (line 281) | class python(object):
method dump (line 284) | def dump(o, wfh, *args, **kwargs):
method load (line 288) | def load(cls, fh, *args, **kwargs):
method loads (line 292) | def loads(s, *args, **kwargs):
function read_pod (line 304) | def read_pod(source, fmt=None):
function write_pod (line 315) | def write_pod(pod, dest, fmt=None):
function dump (line 326) | def dump(o, wfh, fmt='json', *args, **kwargs):
function load (line 337) | def load(s, fmt='json', *args, **kwargs):
function _read_pod (line 341) | def _read_pod(fh, fmt=None):
function _write_pod (line 360) | def _write_pod(pod, wfh, fmt=None):
function is_pod (line 373) | def is_pod(obj):
class Podable (line 387) | class Podable(object):
method from_pod (line 392) | def from_pod(cls, pod):
method _upgrade_pod (line 399) | def _upgrade_pod(cls, pod):
method __init__ (line 407) | def __init__(self):
method to_pod (line 410) | def to_pod(self):
FILE: wa/utils/terminalsize.py
function get_terminal_size (line 26) | def get_terminal_size():
function _get_terminal_size_windows (line 47) | def _get_terminal_size_windows():
function _get_terminal_size_tput (line 68) | def _get_terminal_size_tput():
function _get_terminal_size_linux (line 79) | def _get_terminal_size_linux():
FILE: wa/utils/trace_cmd.py
class TraceCmdEvent (line 29) | class TraceCmdEvent(object):
method __init__ (line 42) | def __init__(self, thread, cpu_id, ts, name, body, parser=None):
method __getattr__ (line 79) | def __getattr__(self, name):
method __str__ (line 85) | def __str__(self):
class DroppedEventsEvent (line 91) | class DroppedEventsEvent(object):
method __init__ (line 95) | def __init__(self, cpu_id):
method __getattr__ (line 103) | def __getattr__(self, name):
method __str__ (line 109) | def __str__(self):
function try_convert_to_numeric (line 115) | def try_convert_to_numeric(v):
function default_body_parser (line 125) | def default_body_parser(event, text):
function regex_body_parser (line 145) | def regex_body_parser(regex, flags=0):
function sched_switch_parser (line 172) | def sched_switch_parser(event, text):
function sched_stat_parser (line 190) | def sched_stat_parser(event, text):
function sched_wakeup_parser (line 198) | def sched_wakeup_parser(event, text):
class TraceCmdParser (line 233) | class TraceCmdParser(object):
method __init__ (line 239) | def __init__(self, filter_markers=True, check_for_markers=True, events...
method parse (line 261) | def parse(self, filepath): # pylint: disable=too-many-branches,too-ma...
function trace_has_marker (line 331) | def trace_has_marker(filepath, max_lines_to_check=2000000):
FILE: wa/utils/types.py
function list_of_strs (line 48) | def list_of_strs(value):
function list_of_ints (line 61) | def list_of_ints(value):
function list_of_numbers (line 74) | def list_of_numbers(value):
function list_of_bools (line 85) | def list_of_bools(value, interpret_strings=True):
function list_of (line 103) | def list_of(type_):
function list_or_string (line 136) | def list_or_string(value):
function list_or_caseless_string (line 151) | def list_or_caseless_string(value):
function list_or (line 166) | def list_or(type_):
function regex (line 195) | def regex(value):
function version_tuple (line 207) | def version_tuple(v):
function module_name_set (line 216) | def module_name_set(l): # noqa: E741
function reset_counter (line 233) | def reset_counter(name=None, value=0):
function reset_all_counters (line 237) | def reset_all_counters(value=0):
function counter (line 242) | def counter(name=None):
class arguments (line 256) | class arguments(list):
method __init__ (line 262) | def __init__(self, value=None):
method append (line 273) | def append(self, value):
method extend (line 276) | def extend(self, values):
method __str__ (line 279) | def __str__(self):
class prioritylist (line 283) | class prioritylist(object):
method __init__ (line 285) | def __init__(self):
method add (line 297) | def add(self, new_element, priority=0):
method add_before (line 307) | def add_before(self, new_element, element):
method add_after (line 311) | def add_after(self, new_element, element):
method index (line 315) | def index(self, element):
method remove (line 318) | def remove(self, element):
method _priority_index (line 322) | def _priority_index(self, element):
method _to_list (line 328) | def _to_list(self):
method _add_element (line 335) | def _add_element(self, element, priority, index=None):
method _delete (line 345) | def _delete(self, priority, priority_index):
method __iter__ (line 352) | def __iter__(self):
method __getitem__ (line 357) | def __getitem__(self, index):
method __delitem__ (line 360) | def __delitem__(self, index):
method __len__ (line 389) | def __len__(self):
class toggle_set (line 393) | class toggle_set(set):
method from_pod (line 403) | def from_pod(pod):
method merge (line 407) | def merge(dest, source):
method __init__ (line 423) | def __init__(self, *args):
method merge_with (line 439) | def merge_with(self, other):
method merge_into (line 442) | def merge_into(self, other):
method add (line 445) | def add(self, item):
method values (line 455) | def values(self):
method conflicts_with (line 461) | def conflicts_with(self, other):
method to_pod (line 479) | def to_pod(self):
class ID (line 483) | class ID(str):
method merge_with (line 485) | def merge_with(self, other):
method merge_into (line 488) | def merge_into(self, other):
class obj_dict (line 492) | class obj_dict(MutableMapping):
method from_pod (line 502) | def from_pod(pod):
method __init__ (line 506) | def __init__(self, values=None, not_in_dict=None):
method to_pod (line 510) | def to_pod(self):
method __getitem__ (line 513) | def __getitem__(self, key):
method __setitem__ (line 519) | def __setitem__(self, key, value):
method __delitem__ (line 522) | def __delitem__(self, key):
method __len__ (line 525) | def __len__(self):
method __iter__ (line 528) | def __iter__(self):
method __repr__ (line 533) | def __repr__(self):
method __str__ (line 536) | def __str__(self):
method __setattr__ (line 539) | def __setattr__(self, name, value):
method __delattr__ (line 542) | def __delattr__(self, name):
method __getattr__ (line 548) | def __getattr__(self, name):
class level (line 558) | class level(object):
method from_pod (line 566) | def from_pod(pod):
method __init__ (line 570) | def __init__(self, name, value):
method to_pod (line 574) | def to_pod(self):
method __str__ (line 577) | def __str__(self):
method __repr__ (line 580) | def __repr__(self):
method __hash__ (line 583) | def __hash__(self):
method __eq__ (line 586) | def __eq__(self, other):
method __lt__ (line 594) | def __lt__(self, other):
method __ne__ (line 602) | def __ne__(self, other):
class _EnumMeta (line 611) | class _EnumMeta(type):
method __str__ (line 613) | def __str__(cls):
method __getattr__ (line 616) | def __getattr__(cls, name):
function enum (line 622) | def enum(args, start=0, step=1):
class ParameterDict (line 691) | class ParameterDict(dict):
method _get_prefix (line 701) | def _get_prefix(obj):
method _encode (line 718) | def _encode(obj):
method _decode (line 734) | def _decode(string):
method __init__ (line 757) | def __init__(self, *args, **kwargs):
method __setitem__ (line 762) | def __setitem__(self, name, value):
method __getitem__ (line 765) | def __getitem__(self, name):
method __contains__ (line 768) | def __contains__(self, item):
method __iter__ (line 771) | def __iter__(self):
method iteritems (line 774) | def iteritems(self):
method get (line 777) | def get(self, name):
method pop (line 780) | def pop(self, key):
method popitem (line 783) | def popitem(self):
method iter_encoded_items (line 787) | def iter_encoded_items(self):
method get_encoded_value (line 790) | def get_encoded_value(self, name):
method values (line 793) | def values(self):
method update (line 796) | def update(self, *args, **kwargs):
class cpu_mask (line 802) | class cpu_mask(object):
method from_pod (line 810) | def from_pod(pod):
method __init__ (line 813) | def __init__(self, cpus):
method __bool__ (line 830) | def __bool__(self):
method __repr__ (line 836) | def __repr__(self):
method list (line 841) | def list(self):
method mask (line 845) | def mask(self, prefix=True):
method ranges (line 852) | def ranges(self):
method to_pod (line 856) | def to_pod(self):
FILE: wa/workloads/adobereader/__init__.py
class AdobeReader (line 23) | class AdobeReader(ApkUiautoWorkload):
method __init__ (line 66) | def __init__(self, target, **kwargs):
method init_resources (line 73) | def init_resources(self, context):
method setup (line 81) | def setup(self, context):
FILE: wa/workloads/adobereader/uiauto/app/src/main/java/com/arm/wa/uiauto/adobereader/UiAutomation.java
class UiAutomation (line 47) | @RunWith(AndroidJUnit4.class)
method initialize (line 59) | @Before
method setup (line 67) | @Test
method runWorkload (line 72) | @Test
method teardown (line 80) | @Test
method runApplicationSetup (line 85) | public void runApplicationSetup() throws Exception {
method getLaunchCommand (line 91) | public String getLaunchCommand() {
method setWorkloadParameters (line 98) | public void setWorkloadParameters(Bundle workload_parameters) {
method getLaunchEndObject (line 104) | public UiObject getLaunchEndObject() {
method dismissWelcomeView (line 112) | private void dismissWelcomeView() throws Exception {
method openFile (line 172) | private void openFile(final String filename) throws Exception {
method findFileObject (line 190) | private UiObject findFileObject(String filename) throws Exception {
method gesturesTest (line 252) | private void gesturesTest() throws Exception {
method searchPdfTest (line 306) | private void searchPdfTest(final String[] searchStrings) throws Except...
method exitDocument (line 357) | private void exitDocument() throws Exception {
FILE: wa/workloads/aitutu/__init__.py
class Aitutu (line 21) | class Aitutu(ApkUiautoWorkload):
method __init__ (line 45) | def __init__(self, target, **kwargs):
method update_output (line 49) | def update_output(self, context):
FILE: wa/workloads/aitutu/uiauto/app/src/main/java/com/arm/wa/uiauto/aitutu/UiAutomation.java
class UiAutomation (line 39) | @RunWith(AndroidJUnit4.class)
method setup (line 44) | @Test
method runWorkload (line 50) | @Test
method extractResults (line 55) | @Test
method clearPopups (line 60) | public void clearPopups() throws Exception {
method downloadAssets (line 79) | public void downloadAssets() throws Exception {
method runBenchmark (line 92) | public void runBenchmark() throws Exception {
method getScores (line 103) | public void getScores() throws Exception {
FILE: wa/workloads/androbench/__init__.py
class Androbench (line 21) | class Androbench(ApkUiautoWorkload):
method update_output (line 42) | def update_output(self, context):
FILE: wa/workloads/androbench/uiauto/app/src/main/java/com/arm/wa/uiauto/androbench/UiAutomation.java
class UiAutomation (line 39) | @RunWith(AndroidJUnit4.class)
method setup (line 44) | @Test
method dismissPermissions (line 50) | @Test
method runWorkload (line 60) | @Test
method extractResults (line 65) | @Test
method runBenchmark (line 70) | public void runBenchmark() throws Exception {
method getScores (line 93) | public void getScores() throws Exception {
FILE: wa/workloads/angrybirds_rio/__init__.py
class AngryBirdsRio (line 20) | class AngryBirdsRio(ApkReventWorkload):
FILE: wa/workloads/antutu/__init__.py
class Antutu (line 22) | class Antutu(ApkUiautoWorkload):
method __init__ (line 114) | def __init__(self, device, **kwargs):
method initialize (line 118) | def initialize(self, context):
method setup (line 126) | def setup(self, context):
method extract_scores (line 130) | def extract_scores(self, context, regex_version):
method update_output (line 176) | def update_output(self, context):
class AntutuBDP (line 188) | class AntutuBDP(ApkWorkload):
method initialize (line 203) | def initialize(self, context):
method setup (line 212) | def setup(self, context):
method run (line 228) | def run(self, context):
method update_output (line 246) | def update_output(self, context):
method teardown (line 251) | def teardown(self, context):
FILE: wa/workloads/antutu/uiauto/app/src/main/java/com/arm/wa/uiauto/antutu/UiAutomation.java
class UiAutomation (line 38) | @RunWith(AndroidJUnit4.class)
method initialize (line 48) | @Before
method setup (line 54) | @Test
method runWorkload (line 60) | @Test
method extractResults (line 66) | @Test
method hitTest (line 77) | public void hitTest() throws Exception {
method clearPopups (line 84) | public void clearPopups() throws Exception {
method waitforCompletion (line 100) | public void waitforCompletion() throws Exception {
method getScoresv7 (line 106) | public void getScoresv7() throws Exception {
method getScoresv8 (line 168) | public void getScoresv8() throws Exception {
method getScoresv9 (line 278) | public void getScoresv9() throws Exception {
FILE: wa/workloads/apache.py
class ApacheBenchmark (line 29) | class ApacheBenchmark(Workload):
method initialize (line 71) | def initialize(self, context):
method setup (line 83) | def setup(self, context):
method run (line 92) | def run(self, context):
method extract_results (line 96) | def extract_results(self, context):
method update_output (line 102) | def update_output(self, context): # pylint: disable=too-many-locals
function get_line (line 139) | def get_line(fh, text):
FILE: wa/workloads/applaunch/__init__.py
class Applaunch (line 21) | class Applaunch(ApkUiautoWorkload):
method init_resources (line 92) | def init_resources(self, context):
method pass_parameters (line 105) | def pass_parameters(self):
method setup (line 116) | def setup(self, context):
method finalize (line 122) | def finalize(self, context):
FILE: wa/workloads/applaunch/uiauto/app/src/main/java/com/arm/wa/uiauto/applaunch/UiAutomation.java
class UiAutomation (line 38) | @RunWith(AndroidJUnit4.class)
method initialize (line 56) | @Before
method setup (line 105) | @Test
method runWorkload (line 113) | @Test
method teardown (line 125) | @Test
method runApplaunchIteration (line 134) | public void runApplaunchIteration(Integer iteration_count) throws Exce...
class AppLaunch (line 151) | private class AppLaunch {
method AppLaunch (line 158) | public AppLaunch(String testTag, String launchCommand) {
method startLaunch (line 165) | public void startLaunch() throws Exception{
method launchMain (line 171) | public void launchMain() throws Exception{
method launchValidate (line 177) | public void launchValidate(Process launch_p) throws Exception {
method endLaunch (line 186) | public void endLaunch() throws Exception{
method closeApplication (line 194) | public void closeApplication() throws Exception{
method killApplication (line 205) | public void killApplication() throws Exception{
method killBackground (line 214) | public void killBackground() throws Exception{
method dropCaches (line 222) | public void dropCaches() throws Exception{
FILE: wa/workloads/benchmarkpi/__init__.py
class BenchmarkPi (line 22) | class BenchmarkPi(ApkUiautoWorkload):
method update_output (line 51) | def update_output(self, context):
FILE: wa/workloads/benchmarkpi/uiauto/app/src/main/java/com/arm/wa/uiauto/benchmarkpi/UiAutomation.java
class UiAutomation (line 31) | @RunWith(AndroidJUnit4.class)
method setup (line 39) | @Test
method runWorkload (line 44) | @Test
method extractResults (line 50) | @Test
method startTest (line 58) | public void startTest() throws Exception{
method waitForResults (line 65) | public void waitForResults() throws Exception{
FILE: wa/workloads/chrome/__init__.py
class Chrome (line 20) | class Chrome(ApkUiautoWorkload):
method requires_network (line 65) | def requires_network(self):
method requires_rerun (line 69) | def requires_rerun(self):
method __init__ (line 73) | def __init__(self, target, **kwargs):
method initialize (line 79) | def initialize(self, context):
method setup_rerun (line 84) | def setup_rerun(self):
FILE: wa/workloads/chrome/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java
class UiAutomation (line 40) | @RunWith(AndroidJUnit4.class)
method initialize (line 48) | @Before
method setup (line 54) | @Test
method navigateToPage (line 60) | public void navigateToPage(String url, boolean from_new_tab) throws Ex...
method newTab (line 78) | public void newTab() throws Exception {
method followTextLink (line 102) | public void followTextLink(String text) throws Exception {
method runWorkload (line 108) | @Test
method teardown (line 151) | @Test
method runApplicationSetup (line 156) | public void runApplicationSetup() throws Exception {
method getLaunchEndObject (line 173) | public UiObject getLaunchEndObject() {
method getLaunchCommand (line 178) | public String getLaunchCommand() {
method setWorkloadParameters (line 183) | public void setWorkloadParameters(Bundle workload_parameters) {
FILE: wa/workloads/deepbench/__init__.py
class Deepbench (line 27) | class Deepbench(Workload):
method initialize (line 92) | def initialize(self, context):
method setup (line 101) | def setup(self, context):
method run (line 104) | def run(self, context):
method extract_results (line 113) | def extract_results(self, context):
method update_output (line 120) | def update_output(self, context):
method finalize (line 137) | def finalize(self, context):
function numeric_best_effort (line 144) | def numeric_best_effort(value):
function read_result_table (line 151) | def read_result_table(filepath):
FILE: wa/workloads/dhrystone/__init__.py
class Dhrystone (line 26) | class Dhrystone(Workload):
method initialize (line 77) | def initialize(self, context):
method setup (line 82) | def setup(self, context):
method run (line 103) | def run(self, context):
method extract_results (line 113) | def extract_results(self, context):
method update_output (line 120) | def update_output(self, context):
method finalize (line 155) | def finalize(self, context):
method validate (line 159) | def validate(self):
FILE: wa/workloads/dhrystone/src/dhrystone.c
type Enumeration (line 448) | typedef int Enumeration;
type Enumeration (line 450) | typedef enum {Ident1, Ident2, Ident3, Ident4, Ident5} Enumeration;
type OneToThirty (line 453) | typedef int OneToThirty;
type OneToFifty (line 454) | typedef int OneToFifty;
type CapitalLetter (line 455) | typedef char CapitalLetter;
type Record (line 460) | struct Record
type RecordType (line 469) | typedef struct Record RecordType;
type RecordType (line 470) | typedef RecordType * RecordPtr;
type boolean (line 471) | typedef int boolean;
type tms (line 660) | struct tms
type rusage (line 668) | struct rusage
type rusage (line 669) | struct rusage
type timeval (line 670) | struct timeval
function Enumeration (line 899) | Enumeration Func1(CharPar1, CharPar2)
function boolean (line 914) | boolean Func2(StrParI1, StrParI2)
function boolean (line 944) | boolean Func3(EnumParIn)
FILE: wa/workloads/drarm/__init__.py
class DrArm (line 23) | class DrArm(ApkWorkload):
method apk_arguments (line 62) | def apk_arguments(self):
method run (line 85) | def run(self, context):
method update_output (line 88) | def update_output(self, context):
FILE: wa/workloads/exoplayer/__init__.py
class ExoPlayer (line 54) | class ExoPlayer(ApkWorkload):
method validate (line 117) | def validate(self):
method _find_host_video_file (line 124) | def _find_host_video_file(self):
method init_resources (line 159) | def init_resources(self, context): # pylint: disable=unused-argument
method setup (line 167) | def setup(self, context):
method run (line 187) | def run(self, context):
method update_output (line 213) | def update_output(self, context):
method teardown (line 225) | def teardown(self, context):
FILE: wa/workloads/geekbench/__init__.py
class Geekbench (line 30) | class Geekbench(ApkUiautoWorkload):
method initialize (line 87) | def initialize(self, context):
method setup (line 99) | def setup(self, context):
method update_output (line 103) | def update_output(self, context):
method validate (line 110) | def validate(self):
method update_result_2 (line 114) | def update_result_2(self, context):
method update_result_3 (line 119) | def update_result_3(self, context):
method update_result (line 141) | def update_result(self, context):
class GBWorkload (line 170) | class GBWorkload(object):
method __init__ (line 189) | def __init__(self, wlid, name, pmac_g5_st_score, pmac_g5_mt_score):
method add_result (line 206) | def add_result(self, value, units):
method convert_to_kilo (line 209) | def convert_to_kilo(self, value, units):
method clear (line 212) | def clear(self):
method get_scores (line 215) | def get_scores(self):
method _calculate (line 238) | def _calculate(self, values, scale_factor):
method __str__ (line 241) | def __str__(self):
class GBScoreCalculator (line 247) | class GBScoreCalculator(object):
method __init__ (line 290) | def __init__(self):
method parse (line 293) | def parse(self, filepath):
method update_results (line 314) | def update_results(self, context):
class GeekbenchCorproate (line 359) | class GeekbenchCorproate(Geekbench): # pylint: disable=too-many-ancestors
function namemify (line 372) | def namemify(basename, i):
class GeekbenchCmdline (line 376) | class GeekbenchCmdline(Workload):
method __init__ (line 474) | def __init__(self, target, **kwargs):
method init_resources (line 486) | def init_resources(self, context):
method initialize (line 510) | def initialize(self, context):
method setup (line 525) | def setup(self, context):
method run (line 564) | def run(self, context):
method update_output (line 576) | def update_output(self, context):
method extract_results (line 594) | def extract_results(self, context):
method finalize (line 601) | def finalize(self, context):
FILE: wa/workloads/geekbench/uiauto/app/src/main/java/com/arm/wa/uiauto/geekbench/UiAutomation.java
class UiAutomation (line 37) | @RunWith(AndroidJUnit4.class)
method initialize (line 51) | @Before
method setup (line 62) | @Test
method runWorkload (line 72) | @Test
method dismissEula (line 118) | public void dismissEula() throws Exception {
method runBenchmarks (line 129) | public void runBenchmarks() throws Exception {
method runCpuBenchmarks (line 139) | public void runCpuBenchmarks(boolean isCorporate) throws Exception {
method waitForResultsv2 (line 155) | public void waitForResultsv2() throws Exception {
method waitForResultsv3onwards (line 163) | public void waitForResultsv3onwards() throws Exception {
method scrollThroughResults (line 173) | public void scrollThroughResults() throws Exception {
method shareResults (line 184) | public void shareResults() throws Exception {
method scrollPage (line 194) | public void scrollPage() throws Exception {
FILE: wa/workloads/gfxbench/__init__.py
class Gfxbench (line 21) | class Gfxbench(ApkUiautoWorkload):
method __init__ (line 58) | def __init__(self, target, **kwargs):
method update_output (line 64) | def update_output(self, context):
class GfxbenchCorporate (line 105) | class GfxbenchCorporate(Gfxbench): # pylint: disable=too-many-ancestors
FILE: wa/workloads/gfxbench/uiauto/app/src/main/java/com/arm/wa/uiauto/gfxbench/UiAutomation.java
class UiAutomation (line 37) | @RunWith(AndroidJUnit4.class)
method initialize (line 49) | @Before
method setup (line 57) | @Test
method runWorkload (line 96) | @Test
method extractResults (line 101) | @Test
method teardown (line 106) | @Test
method clearFirstRun (line 111) | public void clearFirstRun() throws Exception {
method runBenchmark (line 139) | public void runBenchmark() throws Exception {
method getScores (line 156) | public void getScores() throws Exception {
method toggleTest (line 189) | public void toggleTest(String testname) throws Exception {
FILE: wa/workloads/glbenchmark/__init__.py
class Glb (line 36) | class Glb(ApkUiautoWorkload):
method initialize (line 108) | def initialize(self, context):
method update_output (line 125) | def update_output(self, context):
FILE: wa/workloads/glbenchmark/uiauto/app/src/main/java/com/arm/wa/uiauto/glbenchmark/UiAutomation.java
class UiAutomation (line 36) | @RunWith(AndroidJUnit4.class)
method initialize (line 49) | @Before
method setup (line 58) | @Test
method runWorkload (line 64) | @Test
method extractResults (line 70) | @Test
method goToPreformanceTestsMenu (line 75) | public void goToPreformanceTestsMenu() throws Exception {
method selectUseCase (line 82) | public void selectUseCase(String version, String useCase, String type)...
method hitStart (line 121) | public void hitStart() throws Exception {
method waitForResults (line 127) | public void waitForResults(String version, String useCase, int timeout...
method extractBenchmarkResults (line 156) | public void extractBenchmarkResults() throws Exception {
FILE: wa/workloads/gmail/__init__.py
class Gmail (line 22) | class Gmail(ApkUiautoWorkload):
method requires_network (line 71) | def requires_network(self):
method requires_rerun (line 75) | def requires_rerun(self):
method __init__ (line 79) | def __init__(self, target, **kwargs):
method initialize (line 86) | def initialize(self, context):
method init_resources (line 91) | def init_resources(self, context):
method setup_rerun (line 104) | def setup_rerun(self):
FILE: wa/workloads/gmail/uiauto/app/src/main/java/com/arm/wa/uiauto/gmail/UiAutomation.java
class UiAutomation (line 36) | @RunWith(AndroidJUnit4.class)
method initialize (line 49) | @Before
method setup (line 59) | @Test
method runWorkload (line 65) | @Test
method teardown (line 75) | @Test
method runApplicationSetup (line 80) | public void runApplicationSetup() throws Exception {
method getLaunchEndObject (line 85) | public UiObject getLaunchEndObject() {
method getLaunchCommand (line 92) | public String getLaunchCommand() {
method setWorkloadParameters (line 99) | public void setWorkloadParameters(Bundle workload_parameters) {
method clearFirstRunDialogues (line 104) | public void clearFirstRunDialogues() throws Exception {
method clickNewMail (line 205) | public void clickNewMail() throws Exception {
method attachImage (line 217) | public void attachImage() throws Exception {
method setToField (line 296) | public void setToField(String recipient) throws Exception {
method setSubjectField (line 311) | public void setSubjectField() throws Exception {
method setComposeField (line 324) | public void setComposeField() throws Exception {
method clickSendButton (line 343) | public void clickSendButton() throws Exception {
FILE: wa/workloads/googlemaps/__init__.py
class GoogleMaps (line 19) | class GoogleMaps(ApkUiautoWorkload):
method requires_network (line 55) | def requires_network(self):
method requires_rerun (line 59) | def requires_rerun(self):
method __init__ (line 63) | def __init__(self, target, **kwargs):
method initialize (line 69) | def initialize(self, context):
method init_resources (line 74) | def init_resources(self, context):
method setup_rerun (line 78) | def setup_rerun(self):
FILE: wa/workloads/googlemaps/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutomation.java
class UiAutomation (line 42) | @RunWith(AndroidJUnit4.class)
method initialize (line 51) | @Before
method setup (line 58) | @Test
method runWorkload (line 64) | @Test
method search (line 123) | public void search(String query, String box) throws Exception {
method selectSearchResultContaining (line 137) | public void selectSearchResultContaining(String str) throws Exception {
method getDirectionsFromLocation (line 146) | public void getDirectionsFromLocation() throws Exception {
method dismissLocationTutorial (line 154) | public void dismissLocationTutorial() throws Exception {
method viewRouteSteps (line 162) | public void viewRouteSteps() throws Exception {
method previewRoute (line 170) | public void previewRoute() throws Exception {
method previewNextRouteStep (line 175) | public void previewNextRouteStep() throws Exception {
method teardown (line 180) | @Test
method runApplicationSetup (line 185) | public void runApplicationSetup() throws Exception {
FILE: wa/workloads/googlephotos/__init__.py
class Googlephotos (line 24) | class Googlephotos(ApkUiautoWorkload):
method __init__ (line 62) | def __init__(self, target, **kwargs):
method init_resources (line 66) | def init_resources(self, context):
method deploy_assets (line 73) | def deploy_assets(self, context):
method remove_assets (line 97) | def remove_assets(self, context):
FILE: wa/workloads/googlephotos/uiauto/app/src/main/java/com/arm/wa/uiauto/googlephotos/UiAutomation.java
class UiAutomation (line 47) | @RunWith(AndroidJUnit4.class)
method initialize (line 55) | @Before
method setup (line 61) | @Test
method runWorkload (line 66) | @Test
method teardown (line 91) | @Test
method runApplicationSetup (line 98) | public void runApplicationSetup() throws Exception {
method getLaunchCommand (line 109) | public String getLaunchCommand() {
method setWorkloadParameters (line 116) | public void setWorkloadParameters(Bundle workload_parameters) {
method getLaunchEndObject (line 122) | public UiObject getLaunchEndObject() {
method dismissWelcomeView (line 128) | public void dismissWelcomeView() throws Exception {
method closePromotionPopUp (line 172) | public void closePromotionPopUp() throws Exception {
method closeMissingOutPopUp (line 180) | public void closeMissingOutPopUp() throws Exception {
method selectFirstImage (line 189) | public void selectFirstImage() throws Exception {
method closeAndReturn (line 210) | public void closeAndReturn(final boolean dontsave) throws Exception {
method navigateUp (line 239) | public void navigateUp() throws Exception {
method gesturesTest (line 249) | private void gesturesTest() throws Exception {
type Position (line 288) | public enum Position { LEFT, RIGHT, CENTRE }
class PositionPair (line 290) | private class PositionPair {
method PositionPair (line 294) | PositionPair(final Position start, final Position end) {
method editPhotoColorTest (line 300) | private void editPhotoColorTest() throws Exception {
method cropPhotoTest (line 361) | private void cropPhotoTest() throws Exception {
method rotatePhotoTest (line 393) | private void rotatePhotoTest() throws Exception {
method clickCropRotateButton (line 413) | private void clickCropRotateButton() throws Exception {
method seekBarTest (line 427) | private void seekBarTest(final UiObject view, final Position start, fi...
method slideBarTest (line 466) | private void slideBarTest(final UiObject view, final Position pos, fin...
FILE: wa/workloads/googleplaybooks/__init__.py
class Googleplaybooks (line 19) | class Googleplaybooks(ApkUiautoWorkload):
method init_resources (line 91) | def init_resources(self, context):
FILE: wa/workloads/googleplaybooks/uiauto/app/src/main/java/com/arm/wa/uiauto/googleplaybooks/UiAutomation.java
class UiAutomation (line 50) | @RunWith(AndroidJUnit4.class)
method initialize (line 65) | @Before
method setup (line 79) | @Test
method runWorkload (line 92) | @Test
method teardown (line 105) | @Test
method runApplicationSetup (line 112) | public void runApplicationSetup() throws Exception {
method getLaunchCommand (line 121) | public String getLaunchCommand() {
method setWorkloadParameters (line 128) | public void setWorkloadParameters(Bundle workload_parameters) {
method getLaunchEndObject (line 134) | public UiObject getLaunchEndObject() {
method chooseAccount (line 144) | private void chooseAccount(String account) throws Exception {
method clearFirstRunDialogues (line 175) | private void clearFirstRunDialogues() throws Exception {
method dismissSendBooksAsGiftsDialog (line 199) | private void dismissSendBooksAsGiftsDialog() throws Exception {
method dismissSync (line 207) | private void dismissSync() throws Exception {
method searchForBook (line 217) | private void searchForBook(final String bookTitle) throws Exception {
method addToLibrary (line 277) | private void addToLibrary() throws Exception {
method openMyLibrary (line 306) | private void openMyLibrary() throws Exception {
method openBook (line 337) | private void openBook(final String bookTitle) throws Exception {
method createPopUpWatcher (line 373) | private UiWatcher createPopUpWatcher() throws Exception {
method selectChapter (line 398) | private void selectChapter(final int chapterPageNumber) throws Excepti...
method gesturesTest (line 415) | private void gesturesTest() throws Exception {
method addNote (line 459) | private void addNote(final String text) throws Exception {
method removeNote (line 493) | private void removeNote() throws Exception {
method searchForWord (line 520) | private void searchForWord(final String text) throws Exception {
method switchPageStyles (line 559) | private void switchPageStyles() throws Exception {
method aboutBook (line 597) | private void aboutBook(final String bookTitle) throws Exception {
method waitForPage (line 621) | private UiObject waitForPage() throws Exception {
method getDropdownMenu (line 640) | private void getDropdownMenu() throws Exception {
method hideDropDownMenu (line 673) | private void hideDropDownMenu() throws Exception {
method searchPage (line 686) | private UiObject searchPage(final UiObject view, final int pagenum, fi...
method dismissNightLight (line 708) | private void dismissNightLight() throws Exception {
FILE: wa/workloads/googleslides/__init__.py
class GoogleSlides (line 22) | class GoogleSlides(ApkUiautoWorkload):
method __init__ (line 103) | def __init__(self, target, **kwargs):
method init_resources (line 108) | def init_resources(self, context):
FILE: wa/workloads/googleslides/uiauto/app/src/main/java/com/arm/wa/uiauto/googleslides/UiAutomation.java
class UiAutomation (line 42) | @RunWith(AndroidJUnit4.class)
method initialize (line 59) | @Before
method setup (line 71) | @Test
method runWorkload (line 86) | @Test
method teardown (line 94) | @Test
method dismissWorkOfflineBanner (line 99) | public void dismissWorkOfflineBanner() throws Exception {
method dismissUpdateDialog (line 107) | public void dismissUpdateDialog() throws Exception {
method enterTextInSlide (line 115) | public void enterTextInSlide(String viewName, String textToEnter) thro...
method insertSlide (line 132) | public void insertSlide(String slideLayout) throws Exception {
method insertImage (line 157) | public void insertImage(String workingDirectoryName) throws Exception {
method insertShape (line 214) | public void insertShape(String shapeName) throws Exception {
method modifyShape (line 232) | public void modifyShape(String shapeName) throws Exception {
method openDocument (line 257) | public void openDocument(String docName, String workingDirectoryName) ...
method newDocument (line 312) | public void newDocument() throws Exception {
method saveDocument (line 322) | public void saveDocument(String docName) throws Exception {
method deleteDocument (line 366) | public void deleteDocument(String docName) throws Exception {
method skipWelcomeScreen (line 420) | protected void skipWelcomeScreen() throws Exception {
method enablePowerpointCompat (line 428) | protected void enablePowerpointCompat() throws Exception {
method testEditNewSlidesDocument (line 442) | protected void testEditNewSlidesDocument(String docName, String workin...
method testSlideshowFromStorage (line 488) | protected void testSlideshowFromStorage(int slideCount) throws Excepti...
method waitForProgress (line 577) | protected boolean waitForProgress(int timeout) throws Exception {
method changeAckTimeout (line 586) | private long changeAckTimeout(long newTimeout) {
method tapOpenArea (line 593) | private void tapOpenArea() throws Exception {
method windowApplication (line 600) | public void windowApplication() throws Exception {
method showRoots (line 608) | private void showRoots() throws Exception {
FILE: wa/workloads/hackbench/__init__.py
class Hackbench (line 36) | class Hackbench(Workload):
method initialize (line 64) | def initialize(self, context):
method setup (line 68) | def setup(self, context):
method run (line 75) | def run(self, context):
method extract_results (line 78) | def extract_results(self, context):
method update_output (line 83) | def update_output(self, context):
method teardown (line 92) | def teardown(self, context):
method finalize (line 97) | def finalize(self, context):
FILE: wa/workloads/homescreen/__init__.py
class HomeScreen (line 21) | class HomeScreen(Workload):
method setup (line 36) | def setup(self, context):
method run (line 40) | def run(self, context):
FILE: wa/workloads/honorofkings/__init__.py
class HoK (line 21) | class HoK(ApkReventWorkload):
method setup (line 50) | def setup(self, context):
FILE: wa/workloads/hwuitest/__init__.py
class HWUITest (line 31) | class HWUITest(Workload):
method __init__ (line 59) | def __init__(self, target, *args, **kwargs):
method initialize (line 64) | def initialize(self, context):
method run (line 70) | def run(self, context):
method extract_results (line 77) | def extract_results(self, context):
method update_output (line 85) | def update_output(self, context):
method finalize (line 122) | def finalize(self, context):
FILE: wa/workloads/idle.py
class IdleWorkload (line 21) | class IdleWorkload(Workload):
method initialize (line 53) | def initialize(self, context):
method setup (line 64) | def setup(self, context):
method run (line 72) | def run(self, context):
method teardown (line 81) | def teardown(self, context):
FILE: wa/workloads/jankbench/__init__.py
class Jankbench (line 38) | class Jankbench(ApkWorkload):
method setup (line 92) | def setup(self, context):
method run (line 107) | def run(self, context):
method extract_results (line 116) | def extract_results(self, context):
method update_output (line 125) | def update_output(self, context): # NOQA
method extract_metrics_from_db (line 132) | def extract_metrics_from_db(self, context): # pylint: disable=no-self...
method extract_metrics_from_logcat (line 153) | def extract_metrics_from_logcat(self, context):
method _build_command (line 189) | def _build_command(self):
class JankbenchRunMonitor (line 201) | class JankbenchRunMonitor(threading.Thread):
method __init__ (line 205) | def __init__(self, device):
method run (line 217) | def run(self):
method stop (line 231) | def stop(self):
method wait_for_run_end (line 235) | def wait_for_run_end(self, timeout):
FILE: wa/workloads/lmbench/__init__.py
class Lmbench (line 25) | class Lmbench(Workload):
method setup (line 92) | def setup(self, context):
method run (line 106) | def run(self, context):
method extract_results (line 111) | def extract_results(self, context):
method teardown (line 119) | def teardown(self, context):
method _setup_lat_mem_rd (line 126) | def _setup_lat_mem_rd(self):
method _setup_bw_mem (line 139) | def _setup_bw_mem(self):
method _setup_common (line 150) | def _setup_common(self):
FILE: wa/workloads/manual/__init__.py
class ManualWorkload (line 22) | class ManualWorkload(Workload):
method validate (line 65) | def validate(self):
method setup (line 77) | def setup(self, context):
method run (line 85) | def run(self, context):
FILE: wa/workloads/meabo/__init__.py
class Meabo (line 29) | class Meabo(Workload):
method validate (line 236) | def validate(self):
method initialize (line 241) | def initialize(self, context):
method setup (line 245) | def setup(self, context):
method run (line 248) | def run(self, context):
method update_output (line 252) | def update_output(self, context):
method finalize (line 285) | def finalize(self, context):
method _build_command (line 289) | def _build_command(self):
method _install_executable (line 311) | def _install_executable(self, context):
method _uninstall_executable (line 317) | def _uninstall_executable(self):
FILE: wa/workloads/memcpy/__init__.py
class Memcpy (line 32) | class Memcpy(Workload):
method initialize (line 66) | def initialize(self, context):
method setup (line 72) | def setup(self, context):
method run (line 78) | def run(self, context):
method extract_results (line 81) | def extract_results(self, context):
method finalize (line 88) | def finalize(self, context):
FILE: wa/workloads/memcpy/src/memcopy.c
function set_affinity (line 31) | int set_affinity(size_t cpus_size, int* cpus)
function main (line 44) | int main(int argc, char** argv)
FILE: wa/workloads/mongoperf/__init__.py
class Mongoperf (line 26) | class Mongoperf(Workload):
method validate (line 97) | def validate(self):
method initialize (line 104) | def initialize(self, context):
method setup (line 110) | def setup(self, context):
method run (line 125) | def run(self, context):
method extract_results (line 130) | def extract_results(self, context):
method update_output (line 135) | def update_output(self, context):
method teardown (line 156) | def teardown(self, context):
FILE: wa/workloads/motionmark/__init__.py
class Motionmark (line 24) | class Motionmark(UiautoWorkload):
method __init__ (line 52) | def __init__(self, target, **kwargs):
method setup (line 56) | def setup(self, context):
method update_output (line 60) | def update_output(self, context):
FILE: wa/workloads/motionmark/uiauto/app/src/main/java/com/arm/wa/uiauto/motionmark/UiAutomation.java
class UiAutomation (line 35) | @RunWith(AndroidJUnit4.class)
method initialize (line 43) | @Before
method setup (line 48) | @Test
method runWorkload (line 53) | @Test
method teardown (line 58) | @Test
method clearFirstRun (line 64) | public void clearFirstRun() throws Exception {
method runBenchmark (line 78) | public void runBenchmark() throws Exception {
method clearTabs (line 172) | public void clearTabs() throws Exception {
FILE: wa/workloads/openssl/__init__.py
class Openssl (line 33) | class Openssl(Workload):
method initialize (line 70) | def initialize(self, context):
method setup (line 88) | def setup(self, context):
method run (line 96) | def run(self, context):
method extract_results (line 99) | def extract_results(self, context):
method update_output (line 108) | def update_output(self, context):
method finalize (line 158) | def finalize(self, context):
FILE: wa/workloads/pcmark/__init__.py
class PcMark (line 24) | class PcMark(ApkUiautoWorkload):
method __init__ (line 68) | def __init__(self, target, **kwargs):
method initialize (line 72) | def initialize(self, context):
method extract_results (line 76) | def extract_results(self, context):
method update_output (line 89) | def update_output(self, context):
FILE: wa/workloads/pcmark/uiauto/app/src/main/java/com/arm/wa/uiauto/pcmark/UiAutomation.java
class UiAutomation (line 34) | @RunWith(AndroidJUnit4.class)
method initialize (line 42) | @Before
method setup (line 47) | @Test
method runWorkload (line 56) | @Test
method teardown (line 61) | @Test
method clearPopups (line 66) | private void clearPopups() throws Exception{
method loadBenchmarks (line 83) | private void loadBenchmarks() throws Exception {
method installBenchmark (line 102) | private void installBenchmark() throws Exception {
method runBenchmark (line 141) | private void runBenchmark() throws Exception {
FILE: wa/workloads/recentfling/__init__.py
class Recentfling (line 26) | class Recentfling(Workload):
method initialize (line 69) | def initialize(self, context): # pylint: disable=no-self-use
method setup (line 79) | def setup(self, context):
method run (line 93) | def run(self, context):
method update_output (line 101) | def update_output(self, context):
method finalize (line 121) | def finalize(self, context):
method _kill_recentfling (line 125) | def _kill_recentfling(self):
FILE: wa/workloads/rt_app/__init__.py
class RtApp (line 40) | class RtApp(Workload):
method initialize (line 147) | def initialize(self, context):
method setup (line 159) | def setup(self, context):
method run (line 171) | def run(self, context):
method update_output (line 179) | def update_output(self, context):
method finalize (line 215) | def finalize(self, context):
method _deploy_rt_app_binary_if_necessary (line 221) | def _deploy_rt_app_binary_if_necessary(self):
method _load_json_config (line 231) | def _load_json_config(self, context):
method _get_raw_json_config (line 250) | def _get_raw_json_config(self, resolver):
method _generate_workgen_config (line 258) | def _generate_workgen_config(self, user_file, output_directory):
method _update_rt_app_config (line 272) | def _update_rt_app_config(self, config_data):
method _pull_rt_app_logs (line 279) | def _pull_rt_app_logs(self, context):
FILE: wa/workloads/schbench/__init__.py
class Schbench (line 35) | class Schbench(Workload):
method initialize (line 68) | def initialize(self, context):
method setup (line 73) | def setup(self, context):
method run (line 85) | def run(self, context):
method extract_results (line 89) | def extract_results(self, context):
method update_output (line 96) | def update_output(self, context):
method finalize (line 107) | def finalize(self, context):
FILE: wa/workloads/shellscript/__init__.py
class ShellScript (line 24) | class ShellScript(Workload):
method initialize (line 46) | def initialize(self, context):
method setup (line 57) | def setup(self, context):
method run (line 62) | def run(self, context):
method extract_results (line 65) | def extract_results(self, context):
method teardown (line 69) | def teardown(self, context):
FILE: wa/workloads/speedometer/__init__.py
class Speedometer (line 35) | class Speedometer(Workload):
method __init__ (line 135) | def __init__(self, target, **kwargs):
method initialize (line 141) | def initialize(self, context):
method setup (line 179) | def setup(self, context):
method run (line 248) | def run(self, context):
method target_file_was_created (line 273) | def target_file_was_created(self, f):
method wait_for_benchmark_to_complete (line 281) | def wait_for_benchmark_to_complete(self, report_end_id):
method read_score (line 338) | def read_score(self):
method update_output (line 353) | def update_output(self, context):
method teardown (line 378) | def teardown(self, context):
method finalize (line 397) | def finalize(self, context):
class ArchiveServerThread (line 404) | class ArchiveServerThread(threading.Thread):
method __init__ (line 407) | def __init__(self, httpd):
method run (line 411) | def run(self):
class DifferentDirectoryHTTPRequestHandler (line 415) | class DifferentDirectoryHTTPRequestHandler(SimpleHTTPRequestHandler):
method translate_path (line 421) | def translate_path(self, path):
method log_message (line 429) | def log_message(self, format, *args):
class ArchiveServer (line 433) | class ArchiveServer(object):
method __init__ (line 434) | def __init__(self):
method start (line 437) | def start(self, document_root):
method stop (line 448) | def stop(self):
method expose_to_device (line 452) | def expose_to_device(self, target):
method hide_from_device (line 455) | def hide_from_device(self, target):
method get_port (line 458) | def get_port(self):
FILE: wa/workloads/stress_ng/__init__.py
class StressNg (line 25) | class StressNg(Workload):
method initialize (line 79) | def initialize(self, context):
method setup (line 87) | def setup(self, context):
method run (line 99) | def run(self, context):
method extract_results (line 103) | def extract_results(self, context):
method update_output (line 114) | def update_output(self, context):
method validate (line 128) | def validate(self):
method finalize (line 133) | def finalize(self, context):
FILE: wa/workloads/sysbench/__init__.py
class Sysbench (line 26) | class Sysbench(Workload):
method validate (line 95) | def validate(self):
method initialize (line 107) | def initialize(self, context):
method setup (line 112) | def setup(self, context):
method run (line 123) | def run(self, context):
method extract_results (line 126) | def extract_results(self, context):
method update_output (line 131) | def update_output(self, context):
method teardown (line 149) | def teardown(self, context):
method finalize (line 154) | def finalize(self, context):
method _build_command (line 158) | def _build_command(self, **parameters):
function find_line_with (line 173) | def find_line_with(text, fh):
function extract_metric (line 181) | def extract_metric(metric, line, output, prefix='', lower_is_better=True):
function extract_threads_fairness_metric (line 205) | def extract_threads_fairness_metric(metric, line, output):
FILE: wa/workloads/templerun2/__init__.py
class TempleRun2 (line 20) | class TempleRun2(ApkReventWorkload):
FILE: wa/workloads/the_chase/__init__.py
class TheChase (line 20) | class TheChase(ApkWorkload):
method run (line 41) | def run(self, context):
FILE: wa/workloads/uibench/__init__.py
class Uibench (line 18) | class Uibench(ApkWorkload):
method run (line 50) | def run(self, context):
FILE: wa/workloads/uibenchjanktests/__init__.py
class Uibenchjanktests (line 22) | class Uibenchjanktests(ApkWorkload):
method __init__ (line 76) | def __init__(self, target, **kwargs):
method validate (line 111) | def validate(self):
method initialize (line 115) | def initialize(self, context):
method run (line 144) | def run(self, context):
method update_output (line 165) | def update_output(self, context):
method teardown (line 176) | def teardown(self, context):
FILE: wa/workloads/vellamo/__init__.py
class Vellamo (line 27) | class Vellamo(ApkUiautoWorkload):
method setup (line 68) | def setup(self, context):
method initialize (line 76) | def initialize(self, context):
method update_output (line 85) | def update_output(self, context):
method update_output_v3 (line 98) | def update_output_v3(self, context):
method update_output_v3_2 (line 128) | def update_output_v3_2(self, context):
method non_root_update_output (line 145) | def non_root_update_output(self, context):
class VellamoResult (line 165) | class VellamoResult(object):
method __init__ (line 167) | def __init__(self, name):
method add_metric (line 172) | def add_metric(self, data):
class VellamoResultParser (line 182) | class VellamoResultParser(HTMLParser):
class StopParsingException (line 184) | class StopParsingException(Exception):
method __init__ (line 187) | def __init__(self):
method feed (line 196) | def feed(self, data):
method handle_starttag (line 202) | def handle_starttag(self, tag, attrs):
method handle_endtag (line 210) | def handle_endtag(self, tag):
method handle_data (line 219) | def handle_data(self, data):
method error (line 234) | def error(self, message):
FILE: wa/workloads/vellamo/uiauto/app/src/main/java/com/arm/wa/uiauto/vellamo/UiAutomation.java
class UiAutomation (line 37) | @RunWith(AndroidJUnit4.class)
method initialize (line 52) | @Before
method setup (line 63) | @Test
method runWorkload (line 77) | @Test
method extractResults (line 100) | @Test
method startTest (line 108) | public void startTest() throws Exception {
method startBrowserTest (line 122) | public void startBrowserTest(int browserToUse, String version) throws ...
method startTestV3 (line 165) | public void startTestV3(int run, String version) throws Exception {
method proccessTest (line 210) | public void proccessTest(String metric) throws Exception{
method getScore (line 222) | public void getScore(String metric, String resourceID) throws Exception {
method waitForTestCompletion (line 233) | public void waitForTestCompletion(int timeout, String resourceID) thro...
method dismissEULA (line 242) | public void dismissEULA() throws Exception {
method dissmissWelcomebanner (line 252) | public void dissmissWelcomebanner() throws Exception {
method dismissLetsRoll (line 262) | public void dismissLetsRoll() throws Exception {
method dismissArrow (line 279) | public void dismissArrow() throws Exception {
method dismissNetworkConnectionDialogIfNecessary (line 289) | public void dismissNetworkConnectionDialogIfNecessary() throws Excepti...
method dismissExplanationDialogIfNecessary (line 300) | public void dismissExplanationDialogIfNecessary() throws Exception {
FILE: wa/workloads/youtube/__init__.py
class Youtube (line 20) | class Youtube(ApkUiautoWorkload):
method __init__ (line 79) | def __init__(self, device, **kwargs):
method validate (line 83) | def validate(self):
FILE: wa/workloads/youtube/uiauto/app/src/main/java/com/arm/wa/uiauto/youtube/UiAutomation.java
class UiAutomation (line 37) | @RunWith(AndroidJUnit4.class)
method initialize (line 52) | @Before
method setup (line 58) | @Test
method runWorkload (line 64) | @Test
method teardown (line 76) | @Test
method runApplicationInitialization (line 82) | public void runApplicationInitialization() throws Exception {
method getLaunchEndObject (line 88) | public UiObject getLaunchEndObject() {
method clearFirstRunDialogues (line 94) | public void clearFirstRunDialogues() throws Exception {
method disableAutoplay (line 124) | public void disableAutoplay() throws Exception {
method playFirstVideo (line 154) | private void playFirstVideo() throws Exception {
method testPlayVideo (line 162) | public void testPlayVideo(String source, String searchTerm) throws Exc...
method dismissAdvert (line 213) | public void dismissAdvert() throws Exception {
method checkPlayerError (line 226) | public void checkPlayerError() throws Exception {
method pausePlayVideo (line 236) | public void pausePlayVideo() throws Exception {
method checkVideoInfo (line 245) | public void checkVideoInfo() throws Exception {
method scrollRelated (line 257) | public void scrollRelated() throws Exception {
FILE: wa/workloads/youtube_playback/__init__.py
class YoutubePlayback (line 21) | class YoutubePlayback(ApkWorkload):
method setup (line 44) | def setup(self, context):
method run (line 49) | def run(self, context):
Condensed preview — 534 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,632K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 283,
"preview": "---\nname: Bug report\nabout: Create a report to help resolve an issue.\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Descri"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 415,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is"
},
{
"path": ".github/ISSUE_TEMPLATE/question---support-.md",
"chars": 123,
"preview": "---\nname: 'Question / Support '\nabout: Ask a question or reqeust support\ntitle: ''\nlabels: question\nassignees: ''\n\n---\n\n"
},
{
"path": ".github/ISSUE_TEMPLATE/question.md",
"chars": 173,
"preview": "---\nname: Question\nabout: Ask a question\ntitle: ''\nlabels: question\nassignees: ''\n\n---\n\n**Describe you query**\nWhat woul"
},
{
"path": ".github/workflows/main.yml",
"chars": 3010,
"preview": "name: WA Test Suite\n\non:\n push:\n branches: [ master ]\n pull_request:\n branches: [ master ]\n types: [opened, s"
},
{
"path": ".gitignore",
"chars": 524,
"preview": "*.egg-info\n*.pyc\n*.bak\n*.o\n*.cmd\n*.iml\nModule.symvers\nmodules.order\n*~\ntags\nbuild/\ndist/\n.ropeproject/\nwa_output/\ndoc/so"
},
{
"path": ".readthedocs.yml",
"chars": 591,
"preview": "# .readthedocs.yml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html fo"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MANIFEST.in",
"chars": 75,
"preview": "recursive-include scripts *\nrecursive-include doc *\nrecursive-include wa *\n"
},
{
"path": "README.rst",
"chars": 2872,
"preview": "[DEPRECATED] Workload Automation\n++++++++++++++++++++++++++++++++++++++++++++\n\n⚠️ **Development of this project has move"
},
{
"path": "dev_scripts/README",
"chars": 1280,
"preview": "This directory contains scripts that aid the development of Workload Automation.\nThey were written to work as part of WA"
},
{
"path": "dev_scripts/clean_install",
"chars": 919,
"preview": "#!/usr/bin/env python\nimport os\nimport sys\nimport shutil\nimport logging\n\n\nlogging.basicConfig(level=logging.INFO)\n\n\ndef "
},
{
"path": "dev_scripts/clear_env",
"chars": 89,
"preview": "#!/bin/bash\n# Clear workload automation user environment.\nrm -rf ~/.workload_automation/\n"
},
{
"path": "dev_scripts/get_apk_versions",
"chars": 3378,
"preview": "#!/usr/bin/env python\nimport os\nimport sys\nimport re\nimport logging\nimport subprocess\nimport argparse\n\nsys.path.append(o"
},
{
"path": "dev_scripts/pep8",
"chars": 680,
"preview": "#!/bin/bash\n\nDEFAULT_DIRS=(\n wa\n)\n\nEXCLUDE=wa/tests,wa/framework/target/descriptor.py\nEXCLUDE_COMMA=\nIGNORE=E501,"
},
{
"path": "dev_scripts/pylint",
"chars": 1543,
"preview": "#!/bin/bash\nDEFAULT_DIRS=(\n\twa\n)\n\ntarget=$1\n\ncompare_versions() {\n if [[ $1 == $2 ]]; then\n return 0\n fi\n\n "
},
{
"path": "dev_scripts/pylint_plugins.py",
"chars": 1722,
"preview": "import sys\n\nfrom astroid import MANAGER\nfrom astroid import scoped_nodes\n\n\nIGNORE_ERRORS = {\n ('attribute-defined"
},
{
"path": "dev_scripts/rebuild_all_uiauto",
"chars": 697,
"preview": "#!/bin/bash\n#\n# This script rebuilds all uiauto APKs as well as the base uiauto.arr. This is\n# useful when changes have "
},
{
"path": "dev_scripts/update_copyrights",
"chars": 8643,
"preview": "#!/usr/bin/env python\n#\n# Script to put copyright headers into source files.\n#\nimport argparse\nimport logging\nimport os\n"
},
{
"path": "doc/Makefile",
"chars": 6105,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "doc/build_instrument_method_map.py",
"chars": 1751,
"preview": "#!/usr/bin/env python\n# Copyright 2015-2019 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "doc/build_plugin_docs.py",
"chars": 4531,
"preview": "#!/usr/bin/env python\n# Copyright 2014-2019 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "doc/make.bat",
"chars": 7244,
"preview": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\n"
},
{
"path": "doc/requirements.txt",
"chars": 127,
"preview": "nose\nnumpy\npandas\nsphinx_rtd_theme==1.0.0\nsphinx==4.2\ndocutils<0.18\ndevlib @ git+https://github.com/ARM-software/devlib@"
},
{
"path": "doc/source/api/output.rst",
"chars": 25698,
"preview": ".. _output_processing_api:\n\nOutput\n======\n\nA WA output directory can be accessed via a :class:`RunOutput` object. There "
},
{
"path": "doc/source/api/workload.rst",
"chars": 10542,
"preview": ".. _workloads-api:\n\nWorkloads\n~~~~~~~~~\n.. _workload-api:\n\nWorkload\n^^^^^^^^\n\nThe base :class:`Workload` interface is as"
},
{
"path": "doc/source/api.rst",
"chars": 113,
"preview": "Workload Automation API\n=======================\n\n.. toctree::\n :maxdepth: 2\n\n api/output\n\n api/workload\n"
},
{
"path": "doc/source/changes.rst",
"chars": 19096,
"preview": "=================================\nWhat's New in Workload Automation\n=================================\n\n***********\nVersi"
},
{
"path": "doc/source/conf.py",
"chars": 11132,
"preview": "# -*- coding: utf-8 -*-\n# Copyright 2023 ARM Limited\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "doc/source/developer_information/developer_guide/writing_plugins.rst",
"chars": 24890,
"preview": ".. _writing-plugins:\n\n\nWriting Plugins\n================\n\nWorkload Automation offers several plugin points (or plugin typ"
},
{
"path": "doc/source/developer_information/developer_guide.rst",
"chars": 182,
"preview": ".. _developer_guide:\n\n***************\nDeveloper Guide\n***************\n\n.. contents::\n :depth: 3\n :local:\n\n.. include"
},
{
"path": "doc/source/developer_information/developer_reference/contributing.rst",
"chars": 5739,
"preview": "Contributing\n============\n\nCode\n----\n\nWe welcome code contributions via GitHub pull requests. To help with\nmaintainabili"
},
{
"path": "doc/source/developer_information/developer_reference/framework_overview.rst",
"chars": 8373,
"preview": "Framework Overview\n==================\n\nExecution Model\n---------------\n\nAt the high level, the execution model looks as "
},
{
"path": "doc/source/developer_information/developer_reference/plugins.rst",
"chars": 29177,
"preview": ".. plugins:\n\n\nPlugins\n=======\n\nWorkload Automation offers several plugin points (or plugin types). The most\ninteresting "
},
{
"path": "doc/source/developer_information/developer_reference/revent.rst",
"chars": 16336,
"preview": "Revent Recordings\n=================\n\nConvention for Naming revent Files for Revent Workloads\n---------------------------"
},
{
"path": "doc/source/developer_information/developer_reference/serialization.rst",
"chars": 3656,
"preview": ".. _serialization:\n\nSerialization\n=============\n\nOverview of Serialization\n-------------------------\n\nWA employs a seria"
},
{
"path": "doc/source/developer_information/developer_reference.rst",
"chars": 566,
"preview": ".. _developer_reference:\n\n********************\nDeveloper Reference\n********************\n\n.. contents::\n :depth: 3\n :"
},
{
"path": "doc/source/developer_information/how_to.rst",
"chars": 201,
"preview": "*******\nHow Tos\n*******\n\n.. contents:: Contents\n :depth: 4\n :local:\n\n.. include:: developer_information/how_tos/addi"
},
{
"path": "doc/source/developer_information/how_tos/adding_plugins.rst",
"chars": 29954,
"preview": ".. _deploying-executables-example:\n\nDeploying Executables\n=====================\n\nInstalling binaries for a particular pl"
},
{
"path": "doc/source/developer_information/how_tos/processing_output.rst",
"chars": 15343,
"preview": ".. _processing_output:\n\nProcessing WA Output\n====================\n\nThis section will illustrate the use of WA's :ref:`ou"
},
{
"path": "doc/source/developer_information.rst",
"chars": 337,
"preview": "=====================\nDeveloper Information\n=====================\n\n.. contents:: Contents\n :depth: 4\n :local:\n\n-----"
},
{
"path": "doc/source/faq.rst",
"chars": 6967,
"preview": ".. _faq:\n\nFAQ\n===\n\n.. contents::\n :depth: 1\n :local:\n\n--------------------------------------------------------------"
},
{
"path": "doc/source/glossary.rst",
"chars": 5764,
"preview": ".. _glossary:\n\nGlossary\n========\n\n.. glossary::\n\n Agenda\n An agenda specifies what is to be done during a Work"
},
{
"path": "doc/source/index.rst",
"chars": 1927,
"preview": ".. Workload Automation 3 documentation master file,\n\n================================================\nWelcome to Documen"
},
{
"path": "doc/source/instrument_method_map.template",
"chars": 1487,
"preview": ".. _instruments_method_map:\n\nInstrumentation Signal-Method Mapping\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nInstrument met"
},
{
"path": "doc/source/migration_guide.rst",
"chars": 10842,
"preview": ".. _migration-guide:\n\nMigration Guide\n================\n\n.. contents:: Contents\n :depth: 4\n :local:\n\nUsers\n\"\"\"\"\"\n\nCon"
},
{
"path": "doc/source/plugins.rst",
"chars": 1070,
"preview": ".. _plugin-reference:\n\n=================\nPlugin Reference\n=================\n\nThis section lists Plugins that currently c"
},
{
"path": "doc/source/user_information/how_to.rst",
"chars": 226,
"preview": "*******\nHow Tos\n*******\n\n.. contents:: Contents\n :depth: 4\n :local:\n\n.. include:: user_information/how_tos/agenda.rs"
},
{
"path": "doc/source/user_information/how_tos/agenda.rst",
"chars": 33622,
"preview": ".. _agenda:\n\nDefining Experiments With an Agenda\n===================================\n\nAn agenda specifies what is to be "
},
{
"path": "doc/source/user_information/how_tos/device_setup.rst",
"chars": 12700,
"preview": ".. _setting-up-a-device:\n\nSetting Up A Device\n===================\n\nWA should work with most Android devices out-of-the b"
},
{
"path": "doc/source/user_information/how_tos/revent.rst",
"chars": 7209,
"preview": ".. _revent_files_creation:\n\nAutomating GUI Interactions With Revent\n=======================================\n\nOverview an"
},
{
"path": "doc/source/user_information/installation.rst",
"chars": 11999,
"preview": ".. _installation:\n\n************\nInstallation\n************\n\n.. contents:: Contents\n :depth: 2\n :local:\n\n\n.. module:: "
},
{
"path": "doc/source/user_information/user_guide.rst",
"chars": 18743,
"preview": ".. _user-guide:\n\n**********\nUser Guide\n**********\n\nThis guide will show you how to quickly start running workloads using"
},
{
"path": "doc/source/user_information/user_reference/agenda.rst",
"chars": 10428,
"preview": ".. _agenda-reference:\n\nAgenda\n------\n\n\nAn agenda can be thought of as a way to define an experiment as it specifies\nwhat"
},
{
"path": "doc/source/user_information/user_reference/configuration.rst",
"chars": 6554,
"preview": ".. _configuration-specification:\n\n\nConfiguration\n=============\n\n.. include:: user_information/user_reference/agenda.rst\n"
},
{
"path": "doc/source/user_information/user_reference/invocation.rst",
"chars": 15609,
"preview": ".. _invocation:\n\nCommands\n========\n\nInstalling the wa package will add ``wa`` command to your system,\nwhich you can run "
},
{
"path": "doc/source/user_information/user_reference/output_directory.rst",
"chars": 5636,
"preview": ".. _output_directory_structure:\n\nOutput Directory Structure\n==========================\n\nThis is an overview of WA output"
},
{
"path": "doc/source/user_information/user_reference/runtime_parameters.rst",
"chars": 11251,
"preview": ".. _runtime-parameters:\n\nRuntime Parameters\n------------------\n\n.. contents:: Contents\n :local:\n\nRuntime parameters ar"
},
{
"path": "doc/source/user_information/user_reference.rst",
"chars": 351,
"preview": ".. _user_reference:\n\n***************\nUser Reference\n***************\n\n\n.. contents:: Contents\n :depth: 2\n :local:\n\n.."
},
{
"path": "doc/source/user_information.rst",
"chars": 282,
"preview": "================\nUser Information\n================\n\n.. contents:: Contents\n :depth: 4\n :local:\n\n.. include:: user_in"
},
{
"path": "extras/Dockerfile",
"chars": 5267,
"preview": "# This Dockerfile creates an image for use with Workload Automation\n# and/or devlib.\n#\n# To build this Docker image, ple"
},
{
"path": "extras/README",
"chars": 853,
"preview": "This directory is intended for miscellaneous extra stuff that may be\nuseful while developing Workload Automation. It sho"
},
{
"path": "extras/pylintrc",
"chars": 2611,
"preview": "#\n# pylint configuration for Workload Automation.\n#\n# To install pylint run\n#\n# sudo apt-get install pylint\n#\n# cop"
},
{
"path": "extras/walog.vim",
"chars": 901,
"preview": "\" Copy this into ~/.vim/syntax/ and add the following to your ~/.vimrc:\n\" au BufRead,BufNewFile run.log set filetype"
},
{
"path": "pytest.ini",
"chars": 65,
"preview": "[pytest]\nfilterwarnings=\n ignore::DeprecationWarning:past[.*]\n"
},
{
"path": "requirements.txt",
"chars": 459,
"preview": "bcrypt==4.0.1\ncertifi==2024.7.4\ncffi==1.15.1\ncharset-normalizer==3.1.0\ncolorama==0.4.6\ncryptography==44.0.1\ndevlib==1.3."
},
{
"path": "scripts/cpustates",
"chars": 645,
"preview": "#!/usr/bin/env python\n# Copyright 2015 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "scripts/wa",
"chars": 655,
"preview": "#!/usr/bin/env python\n# Copyright 2013-2015 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "setup.py",
"chars": 4959,
"preview": "# Copyright 2013-2015 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/ci/idle_agenda.yaml",
"chars": 557,
"preview": "config:\n iterations: 1\n augmentations:\n - ~~\n - status\n device: generic_local\n device_config:\n"
},
{
"path": "tests/data/bad-syntax-agenda.yaml",
"chars": 102,
"preview": "config:\n # tab on the following line\n reboot_policy: never\n workloads:\n - antutu\n\n"
},
{
"path": "tests/data/extensions/devices/test_device.py",
"chars": 1339,
"preview": "# Copyright 2013-2017 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/data/includes/agenda.yaml",
"chars": 190,
"preview": "config:\n augmentations: [~execution_time]\n include#: configs/test.yaml\nsections:\n - include#: sections/section1"
},
{
"path": "tests/data/includes/configs/test.yaml",
"chars": 36,
"preview": "augmentations: [cpufreq, trace-cmd]\n"
},
{
"path": "tests/data/includes/section-include.yaml",
"chars": 32,
"preview": "classifiers:\n included: true\n"
},
{
"path": "tests/data/includes/sections/section1.yaml",
"chars": 32,
"preview": "classifiers: {'section': 'one'}\n"
},
{
"path": "tests/data/includes/sections/section2.yaml",
"chars": 66,
"preview": "classifiers: {'section': 'two'}\ninclude#: ../section-include.yaml\n"
},
{
"path": "tests/data/includes/user/config.yaml",
"chars": 33,
"preview": "augmentations: [execution_time]\n\n"
},
{
"path": "tests/data/includes/workloads.yaml",
"chars": 88,
"preview": "workloads:\n - dhrystone\n - name: memcpy\n classifiers:\n memcpy: True\n"
},
{
"path": "tests/data/interrupts/after",
"chars": 11538,
"preview": " CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 \n 65: 0 "
},
{
"path": "tests/data/interrupts/before",
"chars": 11424,
"preview": " CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 \n 65: 0 "
},
{
"path": "tests/data/interrupts/result",
"chars": 8428,
"preview": " CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 \n 65: 0 0 0 0 0 "
},
{
"path": "tests/data/logcat.2.log",
"chars": 419,
"preview": "--------- beginning of /dev/log/main\r\nD/TextView( 2468): 7:07\r\nD/TextView( 2468): 7:07\r\nD/TextView( 2468): Thu, June 27\r"
},
{
"path": "tests/data/logcat.log",
"chars": 294,
"preview": "--------- beginning of /dev/log/main\n--------- beginning of /dev/log/system\nD/TextView( 2462): 5:05\nD/TextView( 2462): 5"
},
{
"path": "tests/data/test-agenda.yaml",
"chars": 692,
"preview": "global: \n iterations: 8\n boot_parameters:\n os_mode: mp_a15_bootcluster\n runtime_para"
},
{
"path": "tests/data/test-config.py",
"chars": 603,
"preview": "# Copyright 2013-2017 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/test_agenda_parser.py",
"chars": 7590,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/test_config.py",
"chars": 2062,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "tests/test_diff.py",
"chars": 1420,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/test_exec_control.py",
"chars": 9540,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/test_execution.py",
"chars": 10044,
"preview": "# Copyright 2020 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "tests/test_plugin.py",
"chars": 5160,
"preview": "# Copyright 2014-2017 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "tests/test_runtime_param_utils.py",
"chars": 2604,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "tests/test_signal.py",
"chars": 2935,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "tests/test_utils.py",
"chars": 6724,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/__init__.py",
"chars": 2330,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/commands/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "wa/commands/create.py",
"chars": 24528,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/commands/list.py",
"chars": 4542,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema.sql",
"chars": 5436,
"preview": "--!VERSION!1.6!ENDVERSION!\nCREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";\nCREATE EXTENSION IF NOT EXISTS \"lo\";\n\n-- In futur"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema_update_v1.2.sql",
"chars": 1242,
"preview": "ALTER TABLE resourcegetters RENAME TO resource_getters;\n\nALTER TABLE classifiers ADD COLUMN job_oid uuid references Jobs"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema_update_v1.3.sql",
"chars": 97,
"preview": "ALTER TABLE targets ADD COLUMN system_id text;\n\nALTER TABLE artifacts ADD COLUMN is_dir boolean;\n"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema_update_v1.4.sql",
"chars": 48,
"preview": "ALTER TABLE targets ADD COLUMN modules text[];\n\n"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema_update_v1.5.sql",
"chars": 46,
"preview": "ALTER TABLE targets ALTER hostid TYPE BIGINT;\n"
},
{
"path": "wa/commands/postgres_schemas/postgres_schema_update_v1.6.sql",
"chars": 2876,
"preview": "ALTER TABLE jobs\n DROP CONSTRAINT jobs_run_oid_fkey,\n ADD CONSTRAINT jobs_run_oid_fkey\n FOREIGN KEY (run_oi"
},
{
"path": "wa/commands/process.py",
"chars": 6757,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/commands/report.py",
"chars": 10243,
"preview": "from collections import Counter\nfrom datetime import datetime, timedelta\nimport logging\nimport os\n\nfrom wa import Comman"
},
{
"path": "wa/commands/revent.py",
"chars": 12921,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/commands/run.py",
"chars": 6770,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/commands/schema_changelog.rst",
"chars": 1133,
"preview": "# 1\n## 1.0\n- First version\n## 1.1\n- LargeObjects table added as a substitute for the previous plan to\n use the filesyst"
},
{
"path": "wa/commands/show.py",
"chars": 5573,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/commands/templates/apk_workload",
"chars": 2403,
"preview": "from wa import Parameter, ApkWorkload\n\n\nclass ${class_name}(ApkWorkload):\n\n name = '${name}'\n description = \"This "
},
{
"path": "wa/commands/templates/apkrevent_workload",
"chars": 2415,
"preview": "from wa import Parameter, ApkReventWorkload\n\n\nclass ${class_name}(ApkReventWorkload):\n\n name = '${name}'\n descript"
},
{
"path": "wa/commands/templates/apkuiauto_workload",
"chars": 2415,
"preview": "from wa import Parameter, ApkUiautoWorkload\n\n\nclass ${class_name}(ApkUiautoWorkload):\n\n name = '${name}'\n descript"
},
{
"path": "wa/commands/templates/basic_workload",
"chars": 2144,
"preview": "from wa import Parameter, Workload\n\n\nclass ${class_name}(Workload):\n\n name = '${name}'\n description = \"This is an "
},
{
"path": "wa/commands/templates/revent_workload",
"chars": 2161,
"preview": "from wa import Parameter, ReventWorkload\n\n\nclass ${class_name}(ReventWorkload):\n\n name = '${name}'\n description = "
},
{
"path": "wa/commands/templates/setup.template",
"chars": 2932,
"preview": "import os\nimport sys\nimport warnings\nfrom multiprocessing import Process\n\ntry:\n from setuptools.command.install impor"
},
{
"path": "wa/commands/templates/uiauto/UiAutomation.java",
"chars": 1684,
"preview": "package ${package_name};\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport org.junit.Test;\nimport org.junit"
},
{
"path": "wa/commands/templates/uiauto/uiauto_AndroidManifest.xml",
"chars": 353,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "wa/commands/templates/uiauto/uiauto_build.gradle",
"chars": 852,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 28\n buildToolsVersion '28.0.0'\n defaultCo"
},
{
"path": "wa/commands/templates/uiauto/uiauto_build_script",
"chars": 1175,
"preview": "#!/bin/bash\n\n# CD into build dir if possible - allows building from any directory\nscript_path='.'\nif `readlink -f $$0 &>"
},
{
"path": "wa/commands/templates/uiauto/uiauto_workload_template/build.gradle",
"chars": 532,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "wa/commands/templates/uiauto/uiauto_workload_template/gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Wed May 03 15:42:44 BST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "wa/commands/templates/uiauto/uiauto_workload_template/gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "wa/commands/templates/uiauto/uiauto_workload_template/gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "wa/commands/templates/uiauto/uiauto_workload_template/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "wa/commands/templates/uiauto_workload",
"chars": 2272,
"preview": "from wa import Parameter, UiautoWorkload\n\n\nclass ${class_name}(UiautoWorkload):\n\n name = '${name}'\n description = "
},
{
"path": "wa/framework/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "wa/framework/command.py",
"chars": 4456,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/configuration/__init__.py",
"chars": 827,
"preview": "# Copyright 2013-2017 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/configuration/core.py",
"chars": 44662,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/configuration/default.py",
"chars": 2087,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/configuration/execution.py",
"chars": 8536,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/configuration/parsers.py",
"chars": 16506,
"preview": "# Copyright 2015-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/configuration/plugin_cache.py",
"chars": 13957,
"preview": "# Copyright 2016-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/configuration/tree.py",
"chars": 3092,
"preview": "# Copyright 2016-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/entrypoint.py",
"chars": 6288,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/exception.py",
"chars": 4563,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/execution.py",
"chars": 25400,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/getters.py",
"chars": 14177,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/host.py",
"chars": 5978,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/instrument.py",
"chars": 15143,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/job.py",
"chars": 7510,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/output.py",
"chars": 46868,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/output_processor.py",
"chars": 5616,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/plugin.py",
"chars": 26405,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/pluginloader.py",
"chars": 2812,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/resource.py",
"chars": 11214,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/run.py",
"chars": 5202,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/signal.py",
"chars": 14564,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/target/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "wa/framework/target/assistant.py",
"chars": 11615,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/config.py",
"chars": 1095,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/descriptor.py",
"chars": 32746,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/info.py",
"chars": 13766,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/manager.py",
"chars": 6282,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/runtime_config.py",
"chars": 39383,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/target/runtime_parameter_manager.py",
"chars": 4369,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/framework/uiauto/app/build.gradle",
"chars": 539,
"preview": "apply plugin: 'com.android.library'\n\nandroid {\n compileSdkVersion 28\n buildToolsVersion '28.0.3'\n defaultConfig"
},
{
"path": "wa/framework/uiauto/app/src/main/AndroidManifest.xml",
"chars": 279,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.arm.wa.uiauto\">\n\n <uses-permiss"
},
{
"path": "wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/ActionLogger.java",
"chars": 2127,
"preview": "/* Copyright 2014-2018 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/ApplaunchInterface.java",
"chars": 1724,
"preview": "/* Copyright 2013-2017 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/BaseUiAutomation.java",
"chars": 27213,
"preview": "/* Copyright 2013-2018 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/UiAutoUtils.java",
"chars": 1276,
"preview": "/* Copyright 2013-2017 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "wa/framework/uiauto/app/src/main/java/com/arm/wa/uiauto/UxPerfUiAutomation.java",
"chars": 1817,
"preview": "/* Copyright 2013-2017 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "wa/framework/uiauto/build.gradle",
"chars": 529,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "wa/framework/uiauto/build.sh",
"chars": 1032,
"preview": "#!/bin/bash\n# Copyright 2013-2017 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "wa/framework/uiauto/gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Wed May 03 15:42:44 BST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "wa/framework/uiauto/gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "wa/framework/uiauto/gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "wa/framework/uiauto/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "wa/framework/version.py",
"chars": 1653,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/framework/workload.py",
"chars": 40218,
"preview": "# Copyright 2014-2019 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "wa/instruments/delay.py",
"chars": 10646,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/dmesg.py",
"chars": 2592,
"preview": "# Copyright 2014-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/energy_measurement.py",
"chars": 21222,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/fps.py",
"chars": 8206,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/instruments/hwmon.py",
"chars": 3690,
"preview": "# Copyright 2017-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/misc.py",
"chars": 13577,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/perf.py",
"chars": 16420,
"preview": "# Copyright 2013-2015 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/perfetto.py",
"chars": 4238,
"preview": "# Copyright 2023 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/instruments/poller/Makefile",
"chars": 231,
"preview": "# CROSS_COMPILE=aarch64-linux-gnu- make\n#\nCC=gcc\n\nifdef DEBUG\n\tCFLAGS=-static -lc -g\nelse\n\tCFLAGS=-static -s -lc -O2\nend"
},
{
"path": "wa/instruments/poller/__init__.py",
"chars": 7812,
"preview": "# Copyright 2015-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/instruments/poller/poller.c",
"chars": 6753,
"preview": "/* Copyright 2018 ARM Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "wa/instruments/proc_stat/__init__.py",
"chars": 3653,
"preview": "# Copyright 2020 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/instruments/proc_stat/gather-load.sh",
"chars": 592,
"preview": "#!/bin/sh\nBUSYBOX=$1\nOUTFILE=$2\nPERIOD=$3\nSTOP_SIGNAL_FILE=$4\n\nif [ \"$#\" != \"4\" ]; then\n echo \"USAGE: gather-load.sh "
},
{
"path": "wa/instruments/screencap.py",
"chars": 2040,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/instruments/serialmon.py",
"chars": 3178,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/instruments/trace_cmd.py",
"chars": 10960,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/output_processors/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "wa/output_processors/cpustates.py",
"chars": 6879,
"preview": "# Copyright 2015-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/output_processors/csvproc.py",
"chars": 4571,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/output_processors/postgresql.py",
"chars": 26943,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/output_processors/sqlite.py",
"chars": 8356,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/output_processors/status.py",
"chars": 2190,
"preview": "# Copyright 2013-2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not u"
},
{
"path": "wa/output_processors/targz.py",
"chars": 2946,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/output_processors/uxperf.py",
"chars": 2663,
"preview": "# Copyright 2018 ARM Limited\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use th"
},
{
"path": "wa/tools/revent/Makefile",
"chars": 228,
"preview": "# CROSS_COMPILE=aarch64-linux-gnu- make\n#\nCC=gcc\n\nifdef DEBUG\n\tCFLAGS=-static -lc -g\nelse\n\tCFLAGS=-static -lc -O2\nendif\n"
}
]
// ... and 334 more files (download for full content)
About this extraction
This page contains the full source code of the ARM-software/workload-automation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 534 files (2.4 MB), approximately 649.5k tokens, and a symbol index with 2654 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.