| # Autotest Documentation For Enterprise |
| To provide all the information needed about the current state of Enterprise |
| autotest automation. Current coverage, location of tests, how to execute |
| the tests, what machine to run the tests on, test breakdown, etc. |
| |
| [TOC] |
| |
| ## Current coverage |
| |
| Calculating coverage could be tricky as there are many different ways |
| it could be done. We were using two ways to do it: |
| |
| * By policy: |
| * Look at this recently updated [spreadsheet](http://go/ent-pol-auto): |
| There are 265 policies available for ChromeOS via C/D Panel. We have |
| 96 policies automated, 75 of those are in C/D Panel. So that’s |
| 75/264 = %28 coverage + 21 more tests covering various other policies. |
| * By section: |
| * Refer to this recently updated [spreadsheet](http://go/ent-sec-auto) |
| in which we list out current coverage. |
| |
| ## Test Location |
| |
| * Tests that automate user policies are located [here](http://go/usr-pol-loc). |
| * Tests that automate device policies are located [here](http://go/dev-pol-loc). |
| * Most of Enterprise tests start with *policy_* but there are some |
| that begin with *enterprise_*. |
| |
| ## Test Results |
| |
| * The best way to view test results is by using stainless: |
| * Go to https://stainless.corp.google.com/ |
| * Click on Test History Matrix |
| * In the Test dropdown, select “policy_*” |
| * Hit Search and you should see the results like so: |
| ![Results](https://screenshot.googleplex.com/UxMiYrVMDdF.png) |
| |
| ## Running a test |
| |
| A test can be executed using this command from chroot: |
| ```sh |
| test_that --board=$BOARD_NAME $IP_ADDRESS FULL_TEST_NAME* |
| ``` |
| Example: |
| ```sh |
| /trunk/src/scripts $ test_that --board=hana 100.107.106.138 |
| policy_DeviceServer.AllowBluetooth_true |
| ``` |
| |
| **--board** - should be the board that you have setup locally. You only need to |
| setup the board ones and you shouldn’t have to touch it again for a long time. |
| The board that you setup on your workstation doesn’t have to match the |
| DUT(device under test) board that you’re executing the test on. To set up the |
| board please follow instructions [here](http://go/run-autotest). You will also |
| need to run the build_packages command. |
| |
| **IP_ADDRESS** - IP of the DUT. If you have a device locally, it needs to be |
| plugged into the test network and not corp network. You can also use a device |
| in the lab. To reserve a device from the lab please follow these steps: |
| |
| * Setup skylab using go/skylab-tools-guide (Advanced users: Manual |
| installation) |
| * "Lease" a dut go/skylab-dut-locking |
| * Grab the host name, for example: chromeos15-row3-rack13-host2. Do not |
| include the prefix (e.g. "crossk") |
| * Use this as the IP: chromeos15-row3-rack13-host2**.cros**. |
| |
| Full test name - test name can be grabbed from the control file. |
| [Example](http://go/control-file-name). |
| |
| You can check other options for test_that by running: *test_that --help*. |
| |
| ## Setting up a local DUT |
| |
| To run a test on a local DUT you need to make sure the DUT has been |
| properly setup with a test build. You can use this helpful |
| [tool](http://go/crosdl-usage). Execute from [here](https://cs.corp.google.com/chromeos_public/src/platform/crostestutils/provingground/crosdl.py) |
| Run this command to put the build on a USB stick: |
| ```sh |
| *./crosdl.py -c dev -t -b 12503.0.0 -p sarien --to_stick /dev/sda* |
| ``` |
| Or this command to update the DUT directly(flaky): |
| ```sh |
| *./crosdl.py -c dev -t -b 12105.54.0 -p sarien --to_ip $IP_ADDRESS* |
| ``` |
| Note: The DUT must be reachable via SSH for this to work. |
| |
| |
| To find out the right build number, please use [goldeneye](http://go/goldeneye) |
| and search for the right build for your board. |
| |
| ## Test Breakdown |
| |
| See the [Autotest Best Practices](https://chromium.googlesource.com/chromiumos/third_party/autotest/+/refs/heads/master/docs/best-practices.md#control-files) for general autotest information. |
| This section will provide details on how Enterprise autotests are written. |
| Each test will require the following: |
| * A control file |
| * Control files for each test configuration |
| * A .py defining the test, which inherits test.test |
| |
| ### Control files |
| |
| [Control files](https://chromium.googlesource.com/chromiumos/third_party/autotest/+/refs/heads/master/docs/best-practices.md#control-files) are used as the entry point to a test. |
| A typical dir for a user policy (client) test will consist of control file(s) |
| and, along with .py test file(s). A control file will contain basic description of the |
| test as well as options such as these: |
| ``` python |
| AUTHOR = 'name' |
| NAME = 'full_test_name' |
| ATTRIBUTES = 'suite:ent-nightly, suite:policy' |
| TIME = 'SHORT' |
| TEST_CATEGORY = 'General' |
| TEST_CLASS = 'enterprise' |
| TEST_TYPE = 'client' |
| ``` |
| |
| On a user policy (client) test, there will be a base control file, plus an |
| additional file for each test configuration. [Example](https://cs.corp.google.com/aosp-android10/external/autotest/client/site_tests/policy_AllowDinosaurEasterEgg/) |
| In this example there is the "base" control file, with no args specified, which |
| is simply named "control". Additionally there is a control file for each |
| configuration of the test (.allow, .disallow, .not_set). The args to be |
| passed to the test (.py) are specified in the final line of each of those |
| control files. Example: |
| ``` python |
| job.run_test('policy_AllowDinosaurEasterEgg', |
| case=True) |
| ```` |
| |
| ### Test file |
| |
| Example of a basic [test](http://go/basic-ent-test). |
| The class name of the test, ```policy_ShowHomeButton``` has to match the name |
| of the .py file, and should ideally match the directory name as well. |
| |
| **run_once** - The function that gets called first. Parameters from the |
| control passed into this function. |
| |
| **setup_case** - sets up DMS, logs in, verifies policies values and various |
| other login arguments. Defined: [enterprise_policy_base](http://go/ent-pol-base). Explained in detail below. |
| |
| **start_ui_root** - needed if you’re planning on interacting with UI objects |
| during your test. Defined:[ui_utils](http://go/ent-ui-utils). |
| This [CL](http://crrev.com/c/1531141) describes what ui_utils is based off |
| and the usefulness of it. |
| |
| **check_home_button** - Function that verifies the presence of the Home button |
| in this test. Depending on the policy setting, the test is using |
| *ui.item_present* to verify the status of the Home button. |
| |
| Every enterprise test will require a run_once function and will most likely |
| require setup_case. You will need to pass in a dictionary with the policy |
| name and value into setup_case. |
| |
| ### Useful utility |
| |
| This [utils.py](http://go/ent_util) file which contains many useful functions |
| that you’ll come across in tests. |
| |
| **Some examples:** |
| |
| * **poll_for_condition** - keeps checking for condition to be true until a |
| timeout is reached at which point an error is raised. |
| * **run** - runs a shell command on the DUT. |
| |
| ### Difference between device policy test and user policy test |
| |
| To run test device policies the DUT will need to be fully enrolled, starting |
| with a cleared TPM (thus a reboot). Client tests do not support rebooting the |
| device before/during/after a test. |
| |
| In order to support clearing the TPM & rebooting, all device policies must be |
| written as a ["server"](https://chromium.googlesource.com/chromiumos/third_party/autotest/+/refs/heads/master/docs/best-practices.md#when_why-to-write-a-server_side-test) test. |
| Server tests (for Enterprise) will need a "server" control & test, in addition |
| to having a client control file and a .py test file. The server test will do |
| any server operations (reboot, servo control, wifi cell control, etc) |
| |
| Below is an example of testing a device |
| [Example](http://go/ent-cont-example) of the server control file. This will |
| run the server test [policy_DeviceServer](http://go/ent-test-example) and pass the parameters specified. |
| The server test will clear the tpm, create an autotest client of the DUT, then |
| run the autotest specified in the control file policy_DeviceAllowBluetooth. |
| |
| **Note** The parameterization control files are all of the server control |
| files. The Client side [control file](http://go/ent-device-client-example) is only a |
| pass through for the parameters from the control file, and does not set any new |
| behavior. |
| |
| ### Debugging an autotest |
| |
| Unfortunately there's no good debugging tool in autotest and you can't use pdb |
| so you're left with using time.sleep and logging. With time.sleep you can pause |
| the test and see what's going on in the actual device. When using logging you |
| can run 'logging.info("what you want to log")' and then when the test is done |
| running you can check the results here: |
| /tmp/test_that_latest/results-1-TESTNAME/TESTNAME/debug/TESTNAME.INFO |
| |
| If a test is failing remotely, on stainless, you can view the logs there by |
| clicking on the Logs link. You can also see the screenshot of the screen |
| when a test errored/failed. |
| |
| ### Using Servo board with Autotests |
| |
| Some tests require the use of the [Servo Board](http://go/servo-ent). |
| If you want to get ahold of a servo board you need to reach out to crosdistros@ |
| and request one. You can either get a Servo type A or Servo type C, in case |
| your test involves controlling the power to the DUT. |
| |
| Setting up the servo, hopefully you'll find this |
| [screenshot](https://screenshot.googleplex.com/PcZGhW5eqk3) useful. You can see |
| that two cables on the left go to the DUT and the cable on the right goes into |
| the host machine. If you're going to be feeding the power to the DUT you will |
| also need to connect a Type-C charger to the Servo by plugging it into the |
| slot marked "Dut Power". Note: if you grabbed the micro usb -> USB A cables |
| in the tech stop make sure that the light on the switch glows orange and not |
| green. If it's green the tests will not work. |
| |
| Starting the servo, from chroot run: "sudo servo_updater" make sure everything |
| is up to date. Then run "sudo servod -b BOARD_NAME" BOARD_NAME being the board |
| you have built on your server. While this is running, in another terminal tab |
| you can now execute dut-control commands such as |
| "dut-control servo_v4_role:scr". |
| |
| With the servod running you can now execute local tests using the servo board. |
| [Example test using servo](http://go/servo-ent-example-test). |
| |
| ## Enterprise Autotest Infra |
| |
| This section will focus on a basic explination of the [Enterprise base class](http://go/ent-pol-base) |
| used for autotest, along with commonly used calls, APIs, etc. |
| |
| ### Base class overview: |
| |
| The enterprise base class currently supports the following: |
| * Enrolling with a fake account & DMS through the full OOBE flow. Commonly |
| used for device policy testing) |
| * Kiosk enrollment with fake account |
| * Enrolling for user policies (not requiring OOBE flow). |
| * Enterprise ARC tests |
| * Logging in with a real account/DMS |
| * Enrolling with a real account- currently broken see http://crbug.com/1019320 |
| * Configuring User/Device/Extension policies with a fake DMS |
| * Obtaining policies through an API |
| * Verifying policies |
| * UI interaction |
| |
| In addition to the features above, the base class will setup chrome for |
| testing. This includes passing in username/password, browser flags, ARC |
| settings, etc. |
| |
| |
| ### Policy Management |
| |
| Policy Managing with a fake DMS is mostly handled via the [policy_manager](http://go/ent-pol-manager). |
| |
| The Enterprise base class uses the policy manager to configure policies, |
| set the policies with the fake DMS server, obtain policies from a DUT, and |
| verify they are properly set (ie match the configured). In addition the policy |
| manager handles features such as adding/updating/removing policies once after |
| the initial setup, and make complex testing, such as extension of obfuscated |
| policies easier to test. |
| |
| If a test is to fail with "Policy <POLICY_NAME> value was not set correctly.", |
| the verification within the policy_manager is failing. This means the policy |
| that was configured via the policy_manager does not match the value obtained |
| from the DUT. |
| |
| When using the fake DMS (see [enterprise_fake_dmserver](http://go/fake-ent-dms)and [policy_testserver](http://go/fake-policy-server), |
| policies are provided to the fDMS via a json blob which is created by the |
| policy_manager. |
| |
| Policies from the DUT are obtained via an autotestprivate API, called via |
| the [enterprise_policy_utils](http://go/ent-pol-utils) ```get_all_policies``` |
| and policies are refreshed (ie force a refetch from the DMS) via |
| ```refresh_policies```. |
| |
| ### Enrollment and Kiosk Mode |
| |
| Enterprise autotest uses the autotest [enrollment](http://go/ent-at-enrollment) to support |
| device enrollment. |
| |
| This class has the ability to enroll both real and fake accounts, including |
| walking through the enrollment OOBE flow. The actual interaction with the |
| UI/APIs for login is acomplished by calling telemetry. |
| |
| Additionally Kiosk mode is also supported. |
| |
| |
| ### Chrome |
| |
| Tests interact with chrome (ie launch, define plugins, ARC settings, etc) via |
| [chrome.py](http://go/autotest-chrome). chrome.py is built upon telemetry |
| for browser interactions. The base class will handle chrome |
| interaction for you, however there are specific examples such as the |
| enrollment retainment test, that will interact with chrome.py directly. |
| |
| |
| ### Common Issues and possible solutions |
| |
| * Historically there have been issues with DUT enrollment via APIs. As of |
| R80-x, this should be resolved. Typically enrollment issues have an error |
| message along the lines of: |
| ```test did not pass (reason: Unhandled TimeoutException: Timed out while waiting 60s for _EnterpriseWebviewVisible.).``` |
| If this error is seen, it is typically related to something during the OOBE |
| flow, when waiting for the enterprise enrollment screen. |
| * Some of the Enterprise Autotests use UI interaction/reading for the tests. |
| These UI elements change somewhat often, and will occasionally cause these |
| tests to break. UI based errors usually have a traceback leading to |
| ui.utils, and can often be fixed by simply update the UI element the test |
| is looking for. |
| * Errors from chrome.py can also lead to Enterprise tests failing. This |
| package is not directly owned by Enterprise, or anyone other group, but |
| is a shared resource. If a test fails due to this package, it is likely |
| up to the test owner to fix, but they should be cognisant of other teams |
| using the package. |
| * inspector_backend timeouts occasionally occur (<0.5% of all tests.) |
| The problem is traces backto a inspector backend crash/disconnect between |
| telemetry and the DUT.This error is well outside the scope of Enterprise |
| autotest. Rerunning the test is likely the easiest solution |
| |
| |