diff options
author | Omari Stephens <xsdg@android.com> | 2013-04-19 00:45:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-19 00:45:22 +0000 |
commit | df3e4389cc6ad5a07a6595a2b07cead847b0bead (patch) | |
tree | d62dbc5b0bf99fdda4c4a7cc4b1d7dfb2ded9f30 | |
parent | 72caad47afbe9b325a7ff276bdb82296b82a007a (diff) | |
parent | 46bdf0d2a9fd21d9979fe96f0e98fc1da8243969 (diff) | |
download | source.android.com-df3e4389cc6ad5a07a6595a2b07cead847b0bead.tar.gz |
Merge "Bring TF docs up-to-date and make them useful" into jb-mr1.1-docs
21 files changed, 722 insertions, 74 deletions
@@ -6,8 +6,9 @@ LOCAL_MODULE_CLASS:=JAVA_LIBRARIES LOCAL_DROIDDOC_HTML_DIR:=src # Droiddoc needs java source to run. Just pointing to a dummy location # and deleting output later in delete-ref target -LOCAL_ADDITIONAL_JAVA_DIR:=frameworks/base/core/java/android/annotation -LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sac +LOCAL_ADDITIONAL_JAVA_DIR := frameworks/base/core/java/android/annotation +# FIXME FIXME FIXME LOCAL_ADDITIONAL_DEPENDENCIES := tradefed-docs +LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sac LOCAL_MODULE := online-sac LOCAL_DROIDDOC_OPTIONS:= \ -toroot / \ @@ -31,3 +32,4 @@ setup-tradefed-ref: $(hide) rm -rf $(OUT_DOCS)/online-sac/reference $(hide) cp -R ../tradefed/out/target/common/docs/tradefed/reference $(OUT_DOCS)/online-sac $(hide) cp ../tradefed/out/target/common/docs/tradefed/navtree_data.js $(OUT_DOCS)/online-sac/navtree_data.js + diff --git a/scripts/micro-httpd.py b/scripts/micro-httpd.py index 1cffa089..2292abca 100755 --- a/scripts/micro-httpd.py +++ b/scripts/micro-httpd.py @@ -19,7 +19,7 @@ import SocketServer import os -outdir = os.path.join(os.path.dirname(__file__), '..', 'out') +outdir = os.environ.get('OUTDIR', os.path.join(os.path.dirname(__file__), '..', 'out')) os.chdir(outdir) PORT = int(os.environ.get('HTTP_PORT', 8080)) Handler = SimpleHTTPServer.SimpleHTTPRequestHandler diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs index d0796034..adbd573d 100644 --- a/src/devices/devices_toc.cs +++ b/src/devices/devices_toc.cs @@ -166,9 +166,68 @@ </a> </div> <ul> - <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/tutorial.html">Tutorial</a></li> - <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/commandfile_format.html">Command File Format</a></li> - <li id="tradefed-tree-list" class="nav-section"> + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/index.html"> + <span class="en">Start Here</span> + </a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/machine_setup.html" + >Machine Setup</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/devices.html" + >Working with Devices</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/lifecycle.html" + >Test Lifecycle</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/options.html" + >Option Handling</a></li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/developer/index.html"> + <span class="en">Developer Docs</span> + </a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/developer/unit_tests.html" + >Unit Testing TF Components</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/developer/utility_classes.html" + >Handy Utility Classes</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/developer/implementation.html" + >How To Write an I-Whatever</a></li> + </ul> + </li> + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/integrator/index.html"> + <span class="en">Integrator Docs</span> + </a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/integrator/config_xml_spec.html" + >XML Config Format Spec</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/integrator/commandfile_format.html" + >Command File Format</a></li> + </ul> + </li> + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/runner/index.html"> + <span class="en">Test Runner Docs</span> + </a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/runner/cli.html" + >Command Line Interaction</a></li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/runner/debug.html" + >Debugging Unexpected Results</a></li> + </ul> + </li> + <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/full_example.html" + >An End-to-End Example</a></li> + <li id="tradefed-tree-list" class="nav-section"> <div class="nav-section-header"> <a href="<?cs var:toroot ?>reference/packages.html"> <span class="en">Reference</span> @@ -181,4 +240,4 @@ </ul> </li> -</ul>
\ No newline at end of file +</ul> diff --git a/src/devices/tech/test_infra/tradefed/developer/implementation.jd b/src/devices/tech/test_infra/tradefed/developer/implementation.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/developer/implementation.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/developer/index.jd b/src/devices/tech/test_infra/tradefed/developer/index.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/developer/index.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/developer/unit_tests.jd b/src/devices/tech/test_infra/tradefed/developer/unit_tests.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/developer/unit_tests.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/developer/utility_classes.jd b/src/devices/tech/test_infra/tradefed/developer/utility_classes.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/developer/utility_classes.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/tutorial.jd b/src/devices/tech/test_infra/tradefed/full_example.jd index eb42aa09..9d33e876 100644 --- a/src/devices/tech/test_infra/tradefed/tutorial.jd +++ b/src/devices/tech/test_infra/tradefed/full_example.jd @@ -1,4 +1,4 @@ -page.title=Tutorial +page.title=End-to-End Test Example @jd:body <!-- @@ -16,19 +16,26 @@ page.title=Tutorial See the License for the specific language governing permissions and limitations under the License. --> + <p>This tutorial guides you through the construction of a "hello world" Trade Federation test configuration, and gives you a hands-on introduction to the Trade Federation framework. Starting -from the Tf development environment, it guides you through the process of creating a simple Trade +from the TF development environment, it guides you through the process of creating a simple Trade Federation config and gradually adding more features to it.</p> + <p>The tutorial presents the TF test development process as a set of exercises, each consisting of several steps. The exercises demonstrate how to gradually build and refine your configuration, and -provide all the sample code you need to complete the test configuration.</p> +provide all the sample code you need to complete the test configuration. The title of each +exercise is annotated with a letter describing which roles are involved in that step: "D" for +Developer, "I" for Integrator, and/or "T" for Test Runner.</p> + <p>When you are finished with the tutorial, you will have created a functioning TF configuration and will have learned many of the most important concepts in the TF framework.</p> -<h2 id="set-up-tradefederation-development-environment">Set up TradeFederation development environment</h2> + +<h2>Set up TradeFederation development environment</h2> <p>See (FIXME: link) for how to setup the development environment. The rest of this tutorial assumes you have a shell open that has been initialized to the TradeFederation environment. </p> <p>For simplicity, this tutorial will illustrate adding a configuration and its classes to the TradeFederation framework core library. Later tutorials/documentation will show how to create your own library that extends TradeFederation.</p> -<h2 id="creating-a-test-class">Creating a test class</h2> + +<h2>Creating a test class (D)</h2> <p>Lets create a hello world test that just dumps a message to stdout. A TradeFederation test must implement the (FIXME: link) IRemoteTest interface.</p> <p>Here's an implementation for the HelloWorldTest:</p> diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd b/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd new file mode 100644 index 00000000..c7d3da8d --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd @@ -0,0 +1,58 @@ +page.title=Working with Devices +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Trade Federation uses an abstraction called +<code><a href="/reference/com/android/tradefed/device/ITestDevice.html">ITestDevice</a></code> to +run tests. This abstraction objectifies the lowest-common-denominator Android device:</p> +<ul> +<li>It has a serial number</li> +<li>It has a state: Online, Available, Recovery, or Not Available</li> +<li>It has some notion of reliability. For instance, if we run a command, we can differentiate + between the case where the command hasn't finished yet, the case where the device doesn't support + running commands, and the case where the device has become unresponsive while running the + command.</li> +</ul> + +<h2>Different Classes of Devices</h2> +<p>The three primary implementations of <code>ITestDevice</code> represent three common +usecases.</p> + +<h3>Physical Device</h3> +<p>This is an actual piece of hardware, connected to the TF host machine either by USB, or by using +adb's TCP feature. The <a href="/reference/com/android/tradefed/device/TestDevice.html" +>TestDevice</a> class sits atop the ddmlib library, which is a Java interface to adb. So any +physical device listed in <code>adb devices</code> can be instantiated and used as a +<code>TestDevice</code>. +</p> + +<h3>Emulator</h3> +<p>Emulators are handled specially by TF because they live in another process. To interact with an +Emulator, specify the <code>--emulator</code> argument for the command. See +<a href="/reference/com/android/tradefed/build/LocalSdkBuildProvider.html" +>LocalSdkBuildProvider</a> and +<a href="/reference/com/android/tradefed/targetprep/SdkAvdPreparer.html" +>SdkAvdPreparer</a> for more info.</p> + +<h3>No Device</h3> +<p>Suppose you have a test that doesn't interact with a device at all. For instance, it might just +download a file from some service and verify that the file itself is valid. The +<a href="/reference/com/android/tradefed/device/NullDevice.html" +>NullDevice</a> is an <code>ITestDevice</code> that is just a stub. It has a serial number like +<code>null-device-N</code>, and most attempted operations either no-op silently or throw. +</p> diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/index.jd b/src/devices/tech/test_infra/tradefed/fundamentals/index.jd new file mode 100644 index 00000000..ce1d27a0 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/fundamentals/index.jd @@ -0,0 +1,70 @@ +page.title=Getting Started with TF +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Trade Federation is a large test infrastructure that can be adapted to a great variety of +different usecases, and most people will probably only need some subset of its functionality. First +off, we envision that TF users will fulfill any of three primary roles: Developer, Integrator, and +Test Runner. A particular individual might wear any (or all) of those three hats, but we feel the +distinction will help make it easier to navigate the documentation.</p> + +<h2>Developers</h2> +<p>Developers spend the majority of their time creating TF modules that are written in Java. +They may write configurations and execute tests, but will typically only do so to verify that their +modules are being invoked properly and are functioning as expected.</p> + +<h2>Integrators</h2> +<p>Integrators spend the majority of their time creating XML test configurations, or command +files (which are written in a simple shell-like language). They tie together TF modules written +by the Developer with specific configurations that are required for particular test requirements and +goals.</p> + +<h2>Test Runners</h2> +<p>Test Runners spend the majority of their time executing tests and generally making sure +that test results are being generated, and that the generated test results are relevant, +reproducible, and accurate. They spend the majority of their time interacting with tradefed's +command line interface, and will also verify that the results make sense.</p> + + +<p>In order to get the most out of Trade Federation, all three roles will need to be represented. +It will take Developers and Integrators to make TF interoperate with other pieces of infrastructure, +like build systems and test result repositories. It will take Integrators and Test Runners to get +TF to actually run the desired tests and produce the desired test results. It will take Test +Runners to identify results that don't make sense, and to work with the Developers and +Integrators to figure out where the bugs may lie and get them fixed.</p> + +<h2>What's Next</h2> +<p>People in all three roles should at least glance through all of the common docs in this +section. +<a href="/devices/tech/test_infra/tradefed/fundamentals/machine_setup.html" +>Machine Setup</a> will get you to the point where you can run TF. +<a href="/devices/tech/test_infra/tradefed/fundamentals/devices.html" +>Working with Devices</a> will explain how to run tests with a physical device, with an emulator, or +with no device at all. The +<a href="/devices/tech/test_infra/tradefed/fundamentals/lifecycle.html" +>Test Lifecycle</a> page will explain from a theoretical perspective how the roles of the +Developer, Integrator, and Test Runner interact, and then +<a href="/devices/tech/test_infra/tradefed/fundamentals/options.html" +>Option Handling</a> will demonstrate how to put that theory into practice.</p> + + +<p>After that, the three named documentation sections will each provide details that are pertinent +for that particular role. Finally, the +<a href="/devices/tech/test_infra/tradefed/full_example.html" +>End-to-End Example</a> takes you through the development, integration, +and deployment of a sample test. It involves aspects of each role.</p> diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd b/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd new file mode 100644 index 00000000..2b8664de --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd @@ -0,0 +1,60 @@ +page.title=Test Lifecycle +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>The lifecycle of a test executed using TradeFederation is composed of four separate stages, designed +around formally defined interfaces.</p> +<ul> +<li><a href="/reference/com/android/tradefed/build/IBuildProvider.html" + >Build Provider</a>: Provides a build to test, downloading appropriate files if necessary</li> +<li><a href="/reference/com/android/tradefed/targetprep/ITargetPreparer.html" + >Target Preparer</a>: Prepares the test environment, possibly including software installation and + device configuration</li> +<li><a href="/reference/com/android/tradefed/testtype/IRemoteTest.html" + >Test</a>: Executes test(s) and gathers test results. This may be any JUnit Test, although our + <a href="/reference/com/android/tradefed/testtype/IRemoteTest.html" + >IRemoteTest</a> interface is specifically designed to work well in the Trade Federation + environment.</li> +<li><a href="/reference/com/android/tradefed/result/ITestInvocationListener.html" + >Test Invocation Listener</a>: Listens for test results, usually for the purpose of forwarding the + test results to a repository or displaying them to the Test Runner</li> +</ul> + +<p>The fundamental testing entity in TF is a <b>Configuration</b> (config). A config is an XML file +that declares the lifecycle components of a test.</p> + +<p>This separation of the test's lifecycle is intended to allow for reuse. Using this design, the +Developer can create a Test once, and then the Integrator can create different Configurations to +run that Test in different environments. For example, +they could create a Configuration that will run a test on a local machine and dump the result to +stdout. They could then create a second Configuration that would execute that same test, but use a +different Test Invocation Listener to store the test results in a database. A third Configuration +might be designed run that test continuously from a test lab somewhere.</p> + +<p>It's convenient to note here that a Configuration along with its command-line arguments (as +provided by the Test Runner) is known as a <b>Command</b>. When TF takes pairs a Command with an +<code>ITestDevice</code> and executes it, the subsequent object is known as an <b>Invocation</b>. +In short, an Invocation encompasses a complete TF test execution, across its entire lifecycle.</p> + +<h3>Additional Components of a Configuration</h3> +<ul> +<li><a href="/reference/com/android/tradefed/device/IDeviceRecovery.html" + >Device Recovery</a>: mechanism to recover device communication if lost</li> +<li><a href="/reference/com/android/tradefed/log/package-summary.html">Logger</a>: collects tradefed logging data</li> +</ul> + diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd b/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd new file mode 100644 index 00000000..112d3591 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd @@ -0,0 +1,55 @@ +page.title=Development Environment +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>The Trade Federation source is stored in git along with the rest of the Android platform, and +uses the Android platform build system to create its binary. First and foremost, +<a href="/source/initializing.html">follow these instructions</a> to set up your machine to be +able to compile and run things from the Android tree.</p> + +<h2>Getting the Source</h2> +<p>The TF source lives in the Android codebase, but you need to specify an extra option to get at it. +<a href="/source/downloading.html">Follow these instructions</a> to download the source, but use +the branch <code>tradefed</code> to actually pull down the Trade Federation source. The actual +command you run should look something like</p> +<pre><code>$ repo init -u https://…/manifest -b tradefed</code></pre> + +<h3>Building</h3> +<p>Trade Federation is set up in a lightweight "unbundled" branch that uses slightly different build +commands from the platform source. In particular, unbundled branches use the <code>tapas</code> +command to set up the build environment, rather than the <code>lunch</code> command. So starting +from the root directory of the source tree you checked out, try:</p> +<pre><code>$ . build/envsetup.sh +$ tapas tradefed-all +$ m -j8 +</pre></code> + +Note that once the <code>$ . build/envsetup.sh</code> step is done, the other two commands will run +equally well from anywhere in the tree. + +<h2>Running from Command Line</h2> +<p>First and foremost, tradefed requires the <code>adb</code> utility to be in your current +<code>$PATH</code>.</p> +<pre><code>$ export PATH=$PATH:<path to adb></pre></code> + +<p>Building TF using the steps mentioned above will add the <code>tradefed.sh</code> launcher script +to your path. So to launch the TF console, run</p> +<pre><code>$ tradefed.sh</pre></code> + +<p>At this point, your environment is set up for Trade Federation.</p> + diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/options.jd b/src/devices/tech/test_infra/tradefed/fundamentals/options.jd new file mode 100644 index 00000000..930be9e0 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/fundamentals/options.jd @@ -0,0 +1,100 @@ +page.title=Option Handling +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Option handling lies at the heart of Trade Federation's modular approach. In particular, options +are the mechanism by which the Developer, Integrator, and Test Runner can work together without +having to duplicate each-other's work. Put simply, our implementation of option handling allows the +Developer to mark a Java class member as being configurable, at which point the value of that member +may be augmented or overridden by the Integrator, and may be subsequently augmented or overridden by +the Test Runner. This mechanism works for all Java intrinsic types, as well as for any +<code>Map</code>s or <code>Collection</code>s of intrinsic types.</p> + +<p><em>Note:</em> the option-handling mechanism only works for classes implementing one of the +interfaces included in the <a href="lifecycle.html">Test Lifecycle</a>, and only when that class is +<em>instantiated</em> by the lifecycle machinery.</p> + +<h2>Developer</h2> +<p>To start off, the developer marks a member with the +<code><a href="https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/config/Option.java" +>@Option</a></code> annotation. <!-- note: javadoc for the Option class is broken --> +They specify (at a minimum) the <code>name</code> and <code>description</code> values, which +specify the argument name associated with that Option, and the description that will be displayed on +the TF console when the command is run with <code>--help</code> or <code>--help-all</code>.</p> + +<p>As an example, let's say we want to build a functional phone test which will dial a variety of +phone numbers, and will expect to receive a sequence of DTMF tones from each number after it +connects.</p> +<code><pre>public class PhoneCallFuncTest extends IRemoteTest { + @Option(name = "timeout", description = "How long to wait for connection, in millis") + private long mWaitTime = 30 * 1000; // 30 seconds + + @Option(name = "call", description = "Key: Phone number to attempt. " + + "Value: DTMF to expect. May be repeated.") + private Map<String, String> mCalls = new HashMap<String, String>; + + public PhoneCallFuncTest() { + mCalls.add("123-456-7890", "01134"); // default + }</pre></code> + +<p>That's all that's required for the Developer to set up two points of configuration for that +test. They could then go off and use <code>mWaitTime</code> and <code>mCalls</code> as normal, +without paying much attention to the fact that they're configurable. Because the +<code>@Option</code> fields are set after the class is instantiated, but before the +<code>run</code> method is called, that provides an easy way for implementors to set up defaults for +or perform some kind of filtering on <code>Map</code> and <code>Collection</code> fields, which are +otherwise append-only.</p> + +<h2>Integrator</h2> +<p>The Integrator works in the world of Configurations, which are written in XML. The config format +allows the Integrator to set (or append) a value for any <code>@Option</code> field. For instance, +suppose the Integrator wanted to define a lower-latency test that calls the default number, as well +as a long-running test that calls a variety of numbers. They could create a pair of configurations +that might look like the following:</p> + +<code><pre><?xml version="1.0" encoding="utf-8"?> +<configuration description="low-latency default test; low-latency.xml"> + <test class="com.example.PhoneCallFuncTest"> + <option name="timeout" value="5000" /> + </test> +</configuration></pre></code> + +<code><pre><?xml version="1.0" encoding="utf-8"?> +<configuration description="call a bunch of numbers; many-numbers.xml"> + <test class="com.example.PhoneCallFuncTest"> + <option name="call" key="111-111-1111" value="#*#*TEST1*#*#" /> + <option name="call" key="222-222-2222" value="#*#*TEST2*#*#" /> + <!-- ... --> + </test> +</configuration></pre></code> + +<h2>Test Runner</h2> +<p>The Test Runner also has access to these configuration points via the Trade Federation console. +First and foremost, they will run a Command (that is, a config and all of its arguments) with the +<code>run command <name></code> instruction (or <code>run <name></code> for short). +Beyond that, they can specify any list of arguments are part of the command, which may replace or +append to fields specified by Lifecycle Objects within each config.</p> + +<p>To run the low-latency test with the <code>many-numbers</code> phone numbers, the Test Runner +could execute:</p> +<code><pre>tf >run low-latency.xml --call 111-111-1111 #*#*TEST1*#*# --call 222-222-2222 #*#*TEST2*#*#</pre></code> + +<p>Or, to get a similar effect from the opposite direction, the Test Runner could reduce the wait time +for the <code>many-numbers</code> test:</p> +<code><pre>tf >run many-numbers.xml --timeout 5000</code></pre> + diff --git a/src/devices/tech/test_infra/tradefed/index.jd b/src/devices/tech/test_infra/tradefed/index.jd index 93313698..add9521b 100644 --- a/src/devices/tech/test_infra/tradefed/index.jd +++ b/src/devices/tech/test_infra/tradefed/index.jd @@ -16,37 +16,31 @@ page.title=Trade Federation Overview See the License for the specific language governing permissions and limitations under the License. --> -<p>TradeFederation (tradefed or TF for short) is a continuous test framework designed for running tests -on Android devices. Its a Java application which runs on a host computer, and communicates to one or +<p>Trade Federation (tradefed or TF for short) is a continuous test framework designed for running tests +on Android devices. It's a Java application which runs on a host computer, and communicates to one or more Android devices using ddmlib (the library behind DDMS) over adb.</p> -<h2 id="features">Features</h2> + +<h2>Features</h2> <ul> -<li>modular, flexible design</li> -<li>has built in support for running many different types of Android tests: instrumentation, native/gtest, host-based JUnit, etc</li> -<li>provides reliability and recovery mechanism on top of adb</li> +<li>modular, flexible, scalable design</li> +<li>has built in support for running many different types of Android tests: + <a href="http://developer.android.com/tools/testing/testing_android.html#Instrumentation">instrumentation</a>, + <a href="http://developer.android.com/tools/testing/testing_ui.html">uiautomator</a>, + native/gtest, host-based JUnit, etc</li> +<li>provides reliability and recovery mechanisms on top of adb</li> <li>supports scheduling and running tests on multiple devices in parallel</li> </ul> -<h2 id="fundamentals">Fundamentals</h2> -<p>The lifecycle of a test executed using TradeFederation is composed of four separate stages, designed -around formally defined interfaces.</p> -<ul> -<li><a href="bp.html">Build provider</a>: Provides a build to test, downloading appropriate files if necessary</li> -<li><a href="tp.html">Target preparer</a>: Prepares the test environment, e.g. software installation and setup</li> -<li><a href="test.html">Test</a>: Executes test(s) and gathers test results</li> -<li><a href="result.html">Result reporter</a>: Listens for test results, usually for the purpose of forwarding - test results to a repository</li> -</ul> -<p>The fundamental entity in TradeFederation is a Configuration. A Configuration is an XML file that -declares the lifecycle components of a test.</p> -<p>This separation of the test's lifecycle is intended to allow for reuse. Using this design, you can -create a Test, and then different Configurations to run it in different environments. For example, -you could create a Configuration that will run a test on your local machine, and dump the result to -stdout. You could then create a second Configuration that would execute that same test, but use a -different Result reporter to store the test results in a database.</p> -<h3 id="additional-components-of-a-configuration">Additional components of a configuration</h3> + +<h2>Sample Trade Federation Usecases</h2> +<p><b>FIXME</b>: can these be dynamically expandable?</p> <ul> -<li><a href="recovery.html">Device recovery</a>: mechanism to recover device communication if lost</li> -<li><a href="logger.html">Logger</a>: collects tradefed logging data</li> +<li class="collapsible"> + <div class="section-header"> + <span class="en">Device OEM</span> + </div> + <p>A device OEM will be interested in some things and will need some bits of extra infrastructure</p> +</li> +<li>Platform Integrator</li> +<li>App Developer</li> +<li>Test Service Builder</li> </ul> -<p>A complete TradeFederation test execution, across its entire lifecycle, is referred to as an -Invocation.</p>
\ No newline at end of file diff --git a/src/devices/tech/test_infra/tradefed/commandfile_format.jd b/src/devices/tech/test_infra/tradefed/integrator/commandfile_format.jd index cd5102ae..cd5102ae 100644 --- a/src/devices/tech/test_infra/tradefed/commandfile_format.jd +++ b/src/devices/tech/test_infra/tradefed/integrator/commandfile_format.jd diff --git a/src/devices/tech/test_infra/tradefed/integrator/config_xml_spec.jd b/src/devices/tech/test_infra/tradefed/integrator/config_xml_spec.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/integrator/config_xml_spec.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/integrator/index.jd b/src/devices/tech/test_infra/tradefed/integrator/index.jd new file mode 100644 index 00000000..69fc41b2 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/integrator/index.jd @@ -0,0 +1,24 @@ +page.title=Getting Started as a Developer +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/runner/cli.jd b/src/devices/tech/test_infra/tradefed/runner/cli.jd new file mode 100644 index 00000000..d5e9265b --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/runner/cli.jd @@ -0,0 +1,26 @@ +page.title=Command Line Interaction +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Talk about the difference between the command line command line +and the TF cmdline. This should specifically mention useful features +for running TF synchronously.</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/runner/debug.jd b/src/devices/tech/test_infra/tradefed/runner/debug.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/runner/debug.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + diff --git a/src/devices/tech/test_infra/tradefed/getting_started.jd b/src/devices/tech/test_infra/tradefed/runner/index.jd index 8219ee71..f541ac43 100644 --- a/src/devices/tech/test_infra/tradefed/getting_started.jd +++ b/src/devices/tech/test_infra/tradefed/runner/index.jd @@ -17,19 +17,23 @@ page.title=Getting Started limitations under the License. --> <h2 id="using-the-console">Using the console</h2> -<p>TF is based around an interactive console. You can fire up the console by going to the -<code>tools/tradefederation/</code> directory and running</p> +<p>Trade Federation is based around an interactive console. You can fire up the console by +downloading TF or building it from source, and then going to the <code>tradefederation/</code> +directory and running</p> <pre><code>$ ./tradefed.sh </code></pre> <p>You should end up at a <code>tf ></code> prompt.</p> <p>The console is self-documenting. Try entering "help"</p> <pre><code>tf >help -Enter 'q' or 'exit' to exit +Enter 'q' or 'exit' to exit. Use '--wait-for-command|-c' to exit only after all commands have executed. Enter 'kill' to attempt to forcibly exit, by shutting down adb -Enter 'help list' for help with 'list' commands +Enter 'help all' to see all embedded documentation at once. + +Enter 'help list' for help with 'list' commands [...] </code></pre> + <p>As the help text suggests, the help menus are organized hierarchically</p> <pre><code>tf >help list l(?:ist)? help: @@ -37,23 +41,29 @@ l(?:ist)? help: d[evices] List all detected or known devices [...] </code></pre> + <p>The majority of commands have a convenient short form, which the help text displays. The <code>l(?:ist)?</code> is a regular expression. As an example, here are the four equivalent ways to list invocations: -<em> <code>list invocations</code> -</em> <code>list i</code> -<em> <code>l invocations</code> -</em> <code>l i</code></p> -<h2 id="running-a-configcommand">Running a config/command</h2> +<ul> +<li><code>list invocations</code></li> +<li><code>list i</code></li> +<li><code>l invocations</code></li> +<li><code>l i</code></li> +</ul> + +<h2 id="running-a-command">Running a command</h2> <p>This is documented by the <code>help run</code> command in the console.</p> -<p>As a reminder, a command is a config along with all of its command-line arguments. A command <em>must</em> +<p>As a reminder, a <em>command</em> is a config along with all of its command-line arguments. A command <em>must</em> begin with the name of the respective config.</p> + <p>As a quick example, you could run the calculator unit tests like so:</p> -<pre><code>$./tradefed.sh +<pre><code>$ ./tradefed.sh tf >run instrument --package com.android.calculator2.tests </code></pre> -<p>As a shortcut, if you specify any arguments to <code>tradefed.sh</code>, it will attempt to execute them as if -they were typed on the commandline. So the short version of the above would be</p> + +<p>As a shortcut, if you specify any arguments to the <code>tradefed.sh</code> script, it will attempt to execute them as if +they were typed on the commandline. So a shorter version of the above would be</p> <pre><code>$./tradefed.sh run instrument --package com.android.calculator2.tests </code></pre> <p>In both of these cases, the name of the config is "instrument", and @@ -67,11 +77,12 @@ will only show "important" arguments, and "--help-all" will show all arguments, whether they've been marked as "important" or not. To take the final step, you can tell TF to print the contents of any config (compiled-in or local) with the <code>dump config <configname></code> console command.</p> -<h3 id="so-lets-say-you-want-to-run-the-calculator-instrumentation-tests-but-dont-know-where-to-start">So, let's say you want to run the calculator instrumentation tests, but don't know where to start.</h3> + +<h3 id="run-tests-self-help">So, let's say you want to run the calculator instrumentation tests, but don't know where to start.</h3> <p>You could try something like this sequence of steps. First, look for a config that looks like it might do what you want:</p> <pre><code>tf >list configs -Use 'run command --help <configuration_name>' to get list of options for a configuration +Use 'run command <configuration_name> --help' to get list of options for a configuration Use 'dump config <configuration_name>' to display the configuration's XML content. Available configurations include: @@ -79,8 +90,9 @@ Available configurations include: instrument: Runs a single Android instrumentation test on an existing device [...] </code></pre> + <p>Now that you've found something reasonable-looking, see what options it takes. The <code>list configs</code> output suggests trying <code>run command instrument --help</code></p> -<pre><code>tf >run command --help instrument +<pre><code>tf >run command instrument --help 'instrument' configuration: Runs a single Android instrumentation test on an existing device Printing help for only the important options. To see help for all options, use the --help-all flag @@ -88,27 +100,31 @@ Printing help for only the important options. To see help for all options, use t 'instrumentation' test options: -p, --package The manifest package name of the Android test application to run. </code></pre> + <p>As the message suggests, if you need more options, use the "--help-all" flag instead of "--help". In this case, we've got all we need. You could figure out the package by checking with <code>runtest</code>, or reading testdefs.xml directly. We use <code>runtest -n</code> to simply show what would be run without actually running it:</p> -<pre><code>$runtest -n calculator +<pre><code>$ runtest -n calculator adb root -ONE_SHOT_MAKEFILE="packages/apps/Calculator/Android.mk" make -j4 -C "/srv/xsdg/master2" files -adb sync +ONE_SHOT_MAKEFILE="packages/apps/Calculator/Android.mk" make -j4 -C "/path/to/tree" all_modules adb shell am instrument -w com.android.calculator2.tests/android.test.InstrumentationTestRunner </code></pre> + <p>The argument to <code>am instrument</code> that comes before the slash is the manifest package. <code>android.test.InstrumentationTestRunner</code> is the default runner, so no need to set it if that's the right one. Otherwise, using "--help-all" will tell you about the "--runner" argument, which you can -use to specify an alternate runner. Ok, so at this point, we've got the following command, which -you'll recognize from above</p> +use to specify an alternate runner.</p> + +<p>Ok, finally, we've come up with the following command, which you'll recognize from above.</p> <pre><code>tf >run instrument --package com.android.calculator2.tests </code></pre> + <h2 id="interacting-with-a-device">Interacting with a device</h2> <h3 id="generic-device-behavior-in-tf">Generic device behavior in TF</h3> -<p>The running version of a command is called in <code>invocation</code>. First and foremost, every invocation +<p>The running version of a command is called an <code>invocation</code>. First and foremost, every invocation requires a device before it can run. In addition to physical Android devices, TF can run tests with -a mock device (by specifying the "-n" argument for the command), or with the Android emulator (by +a mock device (by specifying the "-n" argument for the command), or with an Android emulator instance (by specifying the "-e" argument").</p> + <p>The primary console command to figure out what devices are up to is <code>list devices</code>:</p> -<pre><code>$./tradefed.sh +<pre><code>$ ./tradefed.sh 06-07 17:03:22 I/: Detected new device 016B756E03018007 06-07 17:03:22 I/: Detected new device 1700614743c14397 06-07 17:03:22 I/: Detected new device 3531C342606300EC @@ -119,13 +135,15 @@ Serial State Product Variant Build Battery 3531C342606300EC Available herring crespo4g MASTER 92 </code></pre> <p>As far as the invocations are concerned, there are three device states: available, unavailable, and -allocated. An <code>Available</code> device is ready to be allocated for an invocation. An <code>Unavailable</code> +allocated. An <em>Available</em> device is ready to be allocated for an invocation. An <em>Unavailable</em> device is not ready for allocation, for any of a variety of reasons — TF may have deemed to the device as unstable, the device may be critically low on storage, or something else may be amiss. -Finally, an <code>Allocated</code> device is a device that is already being used by an invocation.</p> +Finally, an <em>Allocated</em> device is a device that is already being used by an invocation.</p> + <p>When you start TF, all detected physical devices will be checked for responsiveness with a simple shell command. If the command completes successfully, the device will be listed as Available. If the command fails, the device state will be shown as Unavailable. Thereafter, a device will typically bounce between the Available and Allocated states as invocation requirements dictate.</p> + <p>Finally, once invocations are already underway, you can see what's going on with the <code>list invocations</code> command</p> <pre><code>tf >run instrument --package com.android.calculator2.tests @@ -141,17 +159,18 @@ tf >l i Command Id Exec Time Device State 1 0m:02 1700614743c14397 running stub on build 0 </code></pre> + <h3 id="running-invocations-on-specific-devices">Running invocations on specific devices</h3> <p>TF supports a number of filtering mechanisms for specifying which device or devices to use for a -particular invocation. Since the filtering mechanisms are run before a command turns into an +particular invocation. Since the filtering mechanisms are evaluated before a command turns into an invocation, you can find all of the filtering options in the help for any config:</p> -<p>tf >run instrument --help-all +<pre><code>tf >run instrument --help-all [...] device_requirements options: -s, --serial run this test on a specific device with given serial number(s). --exclude-serial run this test on any device except those with this serial number(s). --product-type run this test on device with this product type(s). May also filter by variant using product:variant. - --property run this test on device with this property value. Expected format <propertyname>=<propertyvalue>. + --property run this test on device with this property value. Expected format <propertyname>=<propertyvalue>. -e, --[no-]emulator force this test to run on emulator. Default: false. -d, --[no-]device force this test to run on a physical device, not an emulator. Default: false. --[no-]new-emulator allocate a placeholder emulator. Should be used when config intends to launch an emulator Default: false. @@ -159,10 +178,11 @@ invocation, you can find all of the filtering options in the help for any config do not allocate a device for this test. Default: false. --min-battery only run this test on a device whose battery level is at least the given amount. Scale: 0-100 --max-battery only run this test on a device whose battery level is strictly less than the given amount. Scale: 0-100 -[...]</p> -<p>The built-in help should be pretty self-explanatory. All of the filtering options excluding "-n", +[...]</code></pre> + +<p>The built-in help will hopefully be pretty self-explanatory. All of the filtering options excluding "-n", "-e", and "-d" may be specified as many times as needed. So, for instance, to run an invocation -using any Verizon Galaxy Nexus, you could do the following:</p> +using any Verizon Galaxy Nexus, you could do the following:</p> <!-- FIXME probably use Mako here --> <pre><code>tf >run instrument --package com.android.calculator2.tests --product-type tuna:toro </code></pre> <p>As another example, to run on a GSM device with a SIM, you could do the following:</p> @@ -173,6 +193,7 @@ excludes devices that aren't in the list of required serials, and --exclude-seri that <em>are</em> in its list. As such, an argument like --exclude-serial XXX --serial XXX will simply make the respective command un-runnable — it will never match any device, since all devices are excluded.</p> + <h2 id="logging">Logging</h2> <p>There are a few different aspects to logging in TF. First and foremost, TF has a built-in logging infrastructure that's based on DDMLib's Log class. For the common case, where the log tag is just @@ -184,20 +205,24 @@ private static final LOG_TAG = "ClassName"; Log.v(LOG_TAG, "This is a simple verbose log message"); Log.w(LOG_TAG, String.format("This warning message brought to you by the number %d", 17)); </code></pre> + <p>You can now accomplish the same thing with the shim like this:</p> <pre><code>class ClassName { [...] CLog.v("This is a simple verbose log message"); CLog.w("This warning message brought to you by the number %d", 17); </code></pre> + <p>Each Invocation has its own ThreadGroup. Any host-side logging that happens inside of that thread group is associated with the Invocation, and will be reported as that invocation's "host_log" after the Invocation completes.</p> -<p>Device logging is performed as part of TradeFed's device wrapper. We keep a buffer of up to 20 MB + +<p>Device logging is performed as part of TF's device wrapper. We keep a buffer of up to 20 MB that captures log data as the device churns it out. In particular, we are not limited by the size of the on-device logcat buffer.</p> + <p>The next important piece is the ITestInvocationListener. This is one of the components of an -Invocation that handles results reporting. Each reporter has the option to implement the #testLog +Invocation that handles results reporting. Each reporter has the option to implement the <code>#testLog</code> method, which will be used to pass logfiles to that result reporter. Among the files that are passed by TF itself will be the aforementioned host_log, as well as the device logcat for the device associated with the Invocation.</p> diff --git a/src/devices/tech/test_infra/tradefed/template.jd b/src/devices/tech/test_infra/tradefed/template.jd new file mode 100644 index 00000000..3d6677f3 --- /dev/null +++ b/src/devices/tech/test_infra/tradefed/template.jd @@ -0,0 +1,24 @@ +page.title=Template +@jd:body + +<!-- + Copyright 2013 The Android Open Source Project + + 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. +--> + +<p>Write some stuff</p> + +<h2>Hey, it's a header!</h2> +<p>Write some more stuff</p> + |