| # User guide for CTF |
| |
| This user guide provides a comprehensive overview of Compatibility Testing |
| for Fuchsia (CTF), a mechanism for freezing artifacts on release branches |
| and loading them on the `main` branch for testing purposes. |
| |
| The most common use case of CTF is to freeze a test on a release branch and |
| then run that test against components on the `main` branch in CI/CQ. This |
| prevents backwards-incompatible changes that would break pre-built clients. |
| |
| To learn more about CTF as a whole, see the [overview] and [motivation] |
| documents. |
| |
| ## Basic usage |
| |
| This section describes how to use CTF and how to handle common scenarios. |
| |
| ### Freezing a Fuchsia Package |
| |
| To freeze a Fuchsia package called {{ '<var>' }}my-package{{ '</var>' }}, do the following: |
| |
| 1. Change the package from `fuchsia_package` to `ctf_fuchsia_package`. |
| 2. Include the `{PACKAGE_NAME}_archive` target in |
| [//sdk/ctf/tests:tests](https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/ctf/tests/BUILD.gn#7). |
| |
| Example: |
| |
| ```gn |
| # Old src/{{ '<var>' }}my-package{{ '</var>' }}/BUILD.gn |
| import("//build/components/fuchsia_package.gni") |
| |
| fuchsia_package("{{ '<var>' }}my-package{{ '</var>' }}") { |
| # ... |
| } |
| ``` |
| |
| Change your file to this: |
| |
| ```gn |
| # New src/{{ '<var>' }}my-package{{ '</var>' }}/BUILD.gn |
| import("//sdk/ctf/build/ctf.gni") |
| |
| ctf_fuchsia_package("{{ '<var>' }}my-package{{ '</var>' }}") { |
| # ... |
| } |
| ``` |
| |
| And update `//sdk/ctf/tests/BUILD.gn`: |
| |
| ```gn |
| group("tests") { |
| deps = [ |
| # ... |
| "//src/{{ '<var>' }}my-package{{ '</var>' }}:{{ '<var>' }}my-package{{ '</var>' }}_archive", |
| ] |
| } |
| ``` |
| |
| You can also create a `group("ctf_tests")` in your local `BUILD.gn`, |
| and reference that in `//sdk/ctf/tests/BUILD.gn`. |
| |
| This will result in your package being compiled and stored in |
| `ctf-artifacts` |
| when the next Fuchsia milestone is released. After completing this step, you |
| **must** include instructions for loading your package (see next section). |
| |
| ### Loading a Fuchsia Package |
| |
| To load a frozen Fuchsia package you need to update |
| [`generate_ctf_tests.gni`][generate_ctf_tests] |
| to include instructions for loading your package. |
| |
| You will need to define a new template in the `generate_ctf_tests.gni` |
| file that is named `generate_{{ '<var>' }}my-package{{ '</var>' |
| }}`, and this template must expand to a Fuchsia test package. |
| |
| The template will receive a parameter called `test_info` which |
| includes the downloaded package's label as `test_info.target_label`. |
| |
| For example: |
| |
| ```gn |
| template("generate_{{ '<var>' }}my-package{{ '</var>' }}") { |
| forward_variables_from(invoker, [ "test_info" ]) |
| fuchsia_package_with_test(target_name) { |
| test_component = "//src/{{ '<var>' }}my-package{{ '</var>' }}:{{ '<var>' }}my-package{{ '</var>' }}-test-root", |
| test_component_name = "test-root.cm" |
| subpackages = [ |
| test_info.target_label, # prebuilt version of the test suite. |
| # other packages needed to implement the test, such as a RealmFactory. |
| ] |
| } |
| } |
| ``` |
| |
| ### Freezing a host test |
| |
| To freeze a host test do the following: |
| |
| 1. Change the build rule from `host_test` to `ctf_host_test`. |
| 2. Include that target in |
| [//sdk/ctf/tests:tests](https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/ctf/tests/BUILD.gn#7). |
| |
| Example: |
| |
| ```gn |
| # Old src/{{ '<var>' }}my-host-test{{ '</var>' }}/BUILD.gn |
| import("//build/testing/host_test.gni") |
| |
| host_test("{{ '<var>' }}my-host-test{{ '</var>' }}") { |
| # ... |
| } |
| ``` |
| |
| Change your file to this: |
| |
| ```gn |
| # New src/{{ '<var>' }}my-host-test{{ '</var>' }}/BUILD.gn |
| import("//sdk/ctf/build/ctf.gni") |
| |
| ctf_host_test("{{ '<var>' }}my-host-test{{ '</var>' }}") { |
| # ... |
| } |
| ``` |
| |
| And update `//sdk/ctf/tests/BUILD.gn`: |
| |
| ```gn |
| group("tests") { |
| deps = [ |
| # ... |
| "//src/{{ '<var>' }}my-host-test{{ '</var>' }}:{{ '<var>' }}my-host-test{{ '</var>' }}", |
| ] |
| } |
| ``` |
| |
| You can also create a `group("ctf_tests")` in your local `BUILD.gn`, |
| and reference that in `//sdk/ctf/tests/BUILD.gn`. |
| |
| This will result in your host test and its dependencies being bundled |
| in `ctf-artifacts` when the next Fuchsia milestone is released. |
| After completing this step, your test will automatically run in CTF |
| using any arguments you pass to `ctf_host_test`. |
| |
| ## Basic concepts |
| |
| CTF consists of two mechanisms: |
| |
| 1. Build rules to freeze an artifact and upload it to [CIPD]. |
| 1. [Build rules][generate_ctf_tests] to thaw that artifact and turn |
| it into a test. |
| |
| The freezing and loading process is exercised at the tip of the `fuchsia.git` |
| repository for local tests through the `//sdk/ctf` build target. Including |
| `--with-test //sdk/ctf` in your `fx set` args results in the following |
| build output: |
| |
| ```bash |
| {{ '<var>' }}$FUCHSIA_DIR/out/default{{ '</var>' }}/cts/host_test_manifest.json |
| {{ '<var>' }}$FUCHSIA_DIR/out/default{{ '</var>' }}/cts/package_archives.json |
| {{ '<var>' }}$FUCHSIA_DIR/out/default{{ '</var>' }}/cts/*.far # Packages referenced in manifest |
| {{ '<var>' }}$FUCHSIA_DIR/out/default{{ '</var>' }}/cts/host_x64/* # Host tests referenced in manifest |
| ``` |
| |
| This results in both the original tests and the thawed version of those tests |
| being included in your build: |
| |
| ```bash |
| $ fx test --dry |
| ... |
| fuchsia-pkg://fuchsia.com/fuchsia-diagnostics-tests-latest#meta/fuchsia-diagnostics-tests-root.cm |
| fuchsia-pkg://fuchsia.com/fuchsia-driver-test_tests-package#meta/test-root.cm |
| ... |
| fuchsia-pkg://fuchsia.com/fuchsia-diagnostics-tests_ctf_in_development#meta/fuchsia-diagnostics-tests-root.cm |
| fuchsia-pkg://fuchsia.com/fuchsia-driver-test_tests_ctf_in_development#meta/test-root.cm |
| ``` |
| |
| Rules defined in [`generate_ctf_tests.gni`][generate_ctf_tests] are |
| responsible for thawing packages referenced in `package_archives.json` |
| by turning them into normal Fuchsia test packages. Since these |
| packages were thawed from the CTF build at the tip of tree, they |
| all have a `ctf_in_development` suffix. All of these tests can be |
| run using `fx test`. |
| |
| Each Fuchsia milestone release (for example, F16 and F17) is |
| associated with a release branch in git (for example, |
| [`refs/heads/releases/F16`][release-f16]. The process above happens |
| for each change to a release branch, resulting in a new `ctf` |
| directory containing packages and host tests referenced in manifests. |
| On release branches, however, the resulting directory is zipped and |
| uploaded to [CIPD] where it is downloaded as a prebuilt by |
| `jiri run-hooks`. You can find these downloaded prebuilts in your |
| `fuchsia.git` checkout at `prebuilt/ctf/f*`, where there is one |
| directory per Fuchsia milestone release. The source of truth for |
| which milestones' prebuilts are downloaded is |
| [`version_history.json`][version-history], which lists `supported` |
| API levels to test. |
| |
| The build target defined at `//sdk/ctf/release:tests` iterates over |
| the downloaded prebuilts and applies the |
| [`generate_ctf_tests.gni`][generate_ctf_tests] rules to thaw each |
| downloaded package in the same way that the in-development packages |
| were thawed. They can be included using `--with-test |
| //sdk/ctf/release:tests` in your `fx set` args. |
| |
| This will add new tests for each supported level to your build: |
| |
| ```bash |
| $ fx test --dry |
| ... |
| fuchsia-pkg://fuchsia.com/fuchsia-diagnostics-tests_ctf18#meta/fuchsia-diagnostics-tests-root.cm |
| fuchsia-pkg://fuchsia.com/fuchsia-driver-test_tests_ctf18#meta/test-root.cm |
| ... |
| fuchsia-pkg://fuchsia.com/fuchsia-diagnostics-tests_ctf19#meta/fuchsia-diagnostics-tests-root.cm |
| fuchsia-pkg://fuchsia.com/fuchsia-driver-test_tests_ctf19#meta/test-root.cm |
| ``` |
| |
| Each thawed test has a suffix indicating the release branch where |
| the frozen package originated (e.g. ctf18, ctf19 for F18 and F19 |
| respectively). All of these tests can be run using `fx test`. |
| |
| ## Troubleshooting failures |
| |
| CTF tests are designed to fail when there is an incompatibility |
| between the frozen package and packages produced at tip of |
| `fuchsia.git`, and this can cause the `core.x64-debug-ctf` builder |
| to fail during CL submission. See the dedicated |
| [troubleshooting guide][troubleshooting] for detailed instructions |
| on handling failure scenarios to unblock CL submission. |
| |
| [CIPD]: https://chrome-infra-packages.appspot.com/p/fuchsia/cts/linux-amd64 |
| [generate_ctf_tests]: https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/ctf/build/generate_ctf_tests.gni |
| [motivation]: /docs/development/testing/ctf/compatibility_testing.md#motivation |
| [overview]: /docs/development/testing/ctf/overview.md |
| [troubleshooting]: /docs/development/testing/ctf/troubleshooting.md |
| [version-history]: https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/version_history.json |
| [release-f16]: https://fuchsia.googlesource.com/fuchsia/+/refs/heads/releases/f16 |