blob: 272430a2d4b81b8fa602740788e8d3e98da732ab [file] [log] [blame] [view]
Kent Tamura59ffb022018-11-27 05:30:561# Web Test Baseline Fallback
Robert Ma06f7acc2017-11-14 17:55:472
3
4*** promo
Kent Tamura59ffb022018-11-27 05:30:565Read [Web Test Expectations and Baselines](web_test_expectations.md) first
Robert Ma06f7acc2017-11-14 17:55:476if you have not.
7***
8
9Baselines can vary by platforms, in which case we need to check in multiple
10versions of a baseline. Meanwhile, we would like to avoid storing identical
11baselines by allowing a platform to fall back to another. This document first
12introduces how platform-specific baselines are structured and how we search for
13a baseline (the fallback mechanism), and then goes into the details of baseline
14optimization and rebaselining.
15
16[TOC]
17
18## Terminology
19
20* **Root directory**:
Kent Tamura59ffb022018-11-27 05:30:5621 [`//src/third_party/blink/web_tests`](../../third_party/blink/web_tests)
22 is the root directory (of all the web tests and baselines). All relative
Robert Ma06f7acc2017-11-14 17:55:4723 paths in this document start from this directory.
24* **Test name**: the name of a test is its relative path from the root
25 directory (e.g. `html/dom/foo/bar.html`).
26* **Baseline name**: replacing the extension of a test name with
27 `-expected.{txt,png,wav}` gives the corresponding baseline name.
28* **Virtual tests**: tests can have virtual variants. For example,
29 `virtual/gpu/html/dom/foo/bar.html` is the virtual variant of
30 `html/dom/foo/bar.html` in the `gpu` suite. Only the latter file exists on
31 disk, and is called the base of the virtual test. See
Kent Tamura59ffb022018-11-27 05:30:5632 [Web Tests#Testing Runtime Flags](web_tests.md#testing-runtime-flags)
Robert Ma06f7acc2017-11-14 17:55:4733 for more details.
34* **Platform directory**: each directory under
Kent Tamura59ffb022018-11-27 05:30:5635 [`platform/`](../../third_party/blink/web_tests/platform) is a platform
Robert Ma06f7acc2017-11-14 17:55:4736 directory that contains baselines (no tests) for that platform. Directory
37 names are in the form of `PLATFORM-VERSION` (e.g. `mac-mac10.12`), except
38 for the latest version of a platform which is just `PLATFORM` (e.g. `mac`).
39
40## Baseline fallback
41
42Each platform has a pre-configured fallback when a baseline cannot be found in
43this platform directory. A general rule is to have older versions of an OS
44falling back to newer versions. Besides, Android falls back to Linux, which then
45falls back to Windows. Eventually, all platforms fall back to the root directory
46(i.e. the generic baselines that live alongside tests). The rules are configured
47by `FALLBACK_PATHS` in each Port class in
Kent Tamura01019442018-05-01 22:06:5848[`//src/third_party/blink/tools/blinkpy/web_tests/port`](../../third_party/blink/tools/blinkpy/web_tests/port).
Robert Ma06f7acc2017-11-14 17:55:4749
50All platforms can be organized into a tree based on their fallback relations (we
51are not considering virtual test suites yet). See the lower half (the
52non-virtual subtree) of this
53[graph](https://docs.google.com/drawings/d/13l3IUlSE99RoKjDwEWuY1O77simAhhF6Wi0fZdkSaMA/).
54Walking from a platform to the root gives the **search path** of that platform.
55We check each directory on the search path in order and see if "directory +
56baseline name" points to a file on disk (note that baseline names are relative
57paths), and stop at the first one found.
58
59### Virtual test suites
60
61Now we add virtual test suites to the picture, using a test named
62`virtual/gpu/html/dom/foo/bar.html` as an example to demonstrate the process.
63The baseline search process for a virtual test consists of two passes:
64
651. Treat the virtual test name as a regular test name and search for the
66 corresponding baseline name using the same search path, which means we are in
67 fact searching in directories like `platform/*/virtual/gpu/...`, and
68 eventually `virtual/gpu/...` (a.k.a. the virtual root).
692. If no baseline can be found so far, we retry with the non-virtual (base) test
70 name `html/dom/foo/bar.html` and walk the search path again.
71
72The [graph](https://docs.google.com/drawings/d/13l3IUlSE99RoKjDwEWuY1O77simAhhF6Wi0fZdkSaMA/)
73visualizes the full picture. Note that the two passes are in fact the same with
74different test names, so the virtual subtree is a mirror of the non-virtual
75subtree. The two trees are connected by the virtual root that has different
76ancestors (fallbacks) depending on which platform we start from; this is the
77result of the two-pass baseline search.
78
79*** promo
80__Note:__ there are in fact two more places to be searched before everything
81else: additional directories given via command line arguments and flag-specific
82baseline directories. They are maintained manually and are not discussed in this
83document.
84***
85
86## Tooling implementation
87
88This section describes the implications the fallback mechanism has on the
Kent Tamurab53757e2018-04-20 17:54:4889implementation details of tooling, namely `blink_tool.py`. If you are not
90hacking `blinkpy`, you can stop here.
Robert Ma06f7acc2017-11-14 17:55:4791
92### Optimization
93
94We can remove a baseline if it is the same as its fallback. An extreme example
95is that if all platforms have the same result, we can just have a single generic
96baseline. Here is the algorithm used by
Kent Tamura01019442018-05-01 22:06:5897[`blink_tool.py optimize-baselines`](../../third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py)
Robert Ma06f7acc2017-11-14 17:55:4798to optimize the duplication away.
99
100Notice from the previous section that the virtual and non-virtual parts are two
101identically structured subtrees. Trees are easy to work with: we can simply
102traverse the tree from leaves up to the root, and if there are two identical
103baselines on two nodes on the path with no other nodes in between or all nodes
104in between have no baselines, keep the one closer to the root (delete the
105baseline on the node further from the root).
106
107The virtual root is special because it has multiple parents. Yet if we can cut
108the edges between the two subtrees (i.e. to make the virtual subtree
109self-contained), we can apply the same algorithm to both of them. A subtree is
110self-contained when it does not need to fallback to ancestors, which can be
111guaranteed by placing a baseline on its root. If the virtual root already has a
112baseline, we can simply ignore these edges without doing anything; otherwise, we
113need to make sure all children of the virtual root have baselines by copying
114the non-virtual fallbacks to the ones that do not (we cannot copy the generic
115baseline to the virtual root because virtual platforms may have different
116results).
117
Robert Ma89eeaa52017-12-02 01:34:47118In addition, the optimizer also removes redundant all-PASS testharness.js
119results. Such baselines are redundant when there are no other fallbacks later
120on the search path (including if the all-PASS baselines are at root), because
Kent Tamuraa045a7f2018-04-25 05:08:11121`run_web_tests.py` assumes all-PASS testharness.js results when baselines can
Robert Ma89eeaa52017-12-02 01:34:47122not be found for a platform.
123
Robert Ma06f7acc2017-11-14 17:55:47124### Rebaseline
125
Kent Tamurab53757e2018-04-20 17:54:48126The fallback mechanism also affects the rebaseline tool (`blink_tool.py
Robert Ma06f7acc2017-11-14 17:55:47127rebaseline{-cl}`). When asked to rebaseline a test on some platforms, the tool
128downloads results from corresponding try bots and put them into the respective
129platform directories. This is potentially problematic. Because of the fallback
130mechanism, the new baselines may affect some other platforms that are not being
131rebaselining but fall back to the rebaselined platforms.
132
133The solution is to copy the current baselines from the to-be-rebaselined
134platforms to all the platforms that immediately fall back to them (i.e. down one
135level in the fallback tree) before downloading new baselines. This is done in a
136hidden internal command
Kent Tamurab53757e2018-04-20 17:54:48137[`blink_tool.py copy-existing-baselines`](../../third_party/blink/tools/blinkpy/tool/commands/copy_existing_baselines.py),
138which is always executed by `blink_tool.py rebaseline`.
Robert Ma06f7acc2017-11-14 17:55:47139
Kent Tamurab53757e2018-04-20 17:54:48140Finally, `blink_tool.py rebaseline{-cl}` also does optimization in the end by
Robert Ma06f7acc2017-11-14 17:55:47141default.