Skip to content

Commit 4baef7c

Browse files
crjohnsCQ Bot
authored andcommitted
[docs][ctf] Update introduction for CTF
Bug: 339893257 Change-Id: I8129153984d0524c9d24cd6b65ba2092392bdb02 Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1054553 Reviewed-by: Kyo Lee <kyol@google.com> Commit-Queue: Christopher Johnson <crjohns@google.com> Fuchsia-Auto-Submit: Christopher Johnson <crjohns@google.com>
1 parent 0d0bf88 commit 4baef7c

File tree

2 files changed

+181
-18
lines changed

2 files changed

+181
-18
lines changed

docs/development/testing/ctf/_toc.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
toc:
99
- title: "Overview"
1010
path: /docs/development/testing/ctf/overview.md
11-
- title: "Introduction"
12-
path: /docs/development/testing/ctf/compatibility_testing.md
11+
- title: "Getting started"
12+
section:
13+
- title: "Introduction"
14+
path: /docs/development/testing/ctf/compatibility_testing.md
1315
- title: "Contributing"
1416
section:
1517
- title: "Contributing Tests"

docs/development/testing/ctf/compatibility_testing.md

Lines changed: 177 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,195 @@ CTF fundamentally consists of the following parts:
2323
FIDL methods and syscalls are tested for compatibility across
2424
versions.
2525

26-
CTF was originally proposed as [RFC
27-
0015](/docs/contribute/governance/rfcs/0015_cts.md), and the project
28-
code is located at
29-
[//sdk/ctf](https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/sdk/ctf/).
26+
CTF was originally proposed as [RFC 0015][rfc-0015], and the project
27+
code is located at [`//sdk/ctf`][sdk-ctf-directory].
3028

31-
## Background, motivation, and goals
29+
## Motivation
3230

33-
The CTF exists to prevent breaking changes to the implemented Fuchsia
31+
The Fuchsia platform defines a surface area consisting of a number of
32+
FIDL protocols which are exposed in the Fuchsia SDK. Developers may
33+
download and use the Fuchsia SDK to write software targeting Fuchsia systems
34+
at a specific *API level*.
35+
36+
As the Fuchsia platform surface area evolves over time, changes are
37+
represented through availability annotations on FIDL protocols:
38+
39+
```fidl
40+
protocol Entry {
41+
@available(added=12)
42+
SetValue(struct { value string; });
43+
44+
@available(added=20)
45+
GetTimestamp() -> (struct { timestamp int64; });
46+
47+
@available(added=13, removed=20)
48+
Encrypt();
49+
};
50+
```
51+
52+
In the above example, the protocol `Entry` has three methods:
53+
54+
- `SetValue`, which was added at API level 12
55+
- `GetTimestamp`, which was added at API level 20
56+
- `Encrypt`, which was added at API level 13 but removed at API level
57+
20 when it was found to not be needed any longer.
58+
59+
Components built using the Fuchsia SDK must declare the API level
60+
they target, affecting which definitions are visible. Consider the following
61+
scenarios:
62+
63+
- A component is built targeting API level 19:
64+
- `SetValue` and `Encrypt` are visible.
65+
- `GetTimestamp` is absent, because it did not yet exist at API level 19.
66+
- A component is built targeting API level 21:
67+
- `SetValue` and `GetTimestamp` are visible.
68+
- `Encrypt` is absent, because it was removed at API level 20.
69+
70+
Not all API levels are currently supported by the Fuchsia Platform.
71+
The canonical list of [supported API levels][version-history] is checked
72+
in to the `fuchsia.git` repository and is used to determine which API
73+
levels will be supported in releases of the Fuchsia SDK.
74+
75+
Targeting a supported API level ensures that a client can connect
76+
only to protocols that are supported and guaranteed to be implemented,
77+
but it does not provide a guarantee that the behavior of the platform
78+
will remain consistent for pre-built components targeting that API
79+
level.
80+
81+
Ensuring consistent behavior is important to support components
82+
built outside of the `fuchsia.git` repository, especially when those
83+
components are downloaded as pre-built binaries and assembled into
84+
product images.
85+
86+
### Example: A compatibility problem
87+
88+
Consider a simplified version of the `Entry` protocol above:
89+
90+
```fidl
91+
protocol Entry {
92+
@available(added=20)
93+
GetTimestamp() -> (struct { timestamp int64; });
94+
};
95+
```
96+
97+
The `GetTimestamp` method returns the timestamp of an `Entry` *in seconds*.
98+
99+
We can test it as follows:
100+
101+
```c++
102+
TEST(Timestamp) {
103+
EntrySyncPtr entry = CreateEntryAtMidnightJan1stUTC();
104+
ASSERT_EQ(entry.GetTimestamp(), 1704067200);
105+
}
106+
```
107+
108+
Suppose that we decide we actually want nanosecond granularity. We
109+
will change the *implementation* of `GetTimestamp` to return
110+
nanoseconds, but note that the *FIDL definition* does not change.
111+
112+
We would update our test as follows:
113+
114+
```diff
115+
TEST(Timestamp) {
116+
EntrySyncPtr entry = CreateEntryAtMidnightJan1stUTC();
117+
- ASSERT_EQ(entry.GetTimestamp(), 17040672000);
118+
+ ASSERT_EQ(entry.GetTimestamp(), 17040672000000000);
119+
}
120+
```
121+
122+
This will pass all checks in `fuchsia.git` and submit, but we have now
123+
introduced a **compatibility breakage to the Fuchsia Platform**.
124+
125+
#### Failure timeline
126+
127+
Let's look at a complete timeline that leads to a breakage.
128+
129+
1. **Before the SDK change**: Suppose the FooWidget team wants to
130+
implement their FooWidget for Fuchsia. They download the latest
131+
Fuchsia SDK and build their component targeting API level 20. This
132+
component uses the `Entry` protocol and calls the `GetTimestamp`
133+
method. At this point in time, `GetTimestamp` returns seconds.
134+
135+
This works for them, so the FooWidget team will publish a Fuchsia
136+
package called `foo-widget`. Upon inspection, users of this package
137+
see it targets API level 20.
138+
139+
1. **FooWidget is included in a Fuchsia product**: A Fuchsia product
140+
is assembled that includes the `foo-widget` package and the Fuchsia
141+
platform from an SDK. The `foo-widget` package was ingested as
142+
a pre-built binary without source code access, but product assembly
143+
sees that the package was built targeting API level 20 and that the
144+
Fuchsia platform image supports API level 20.
145+
146+
1. **The SDK change is rolled**: At this point, the change we defined
147+
above lands in `fuchsia.git`, a new SDK is produced, and it is
148+
released.
149+
150+
1. **The product is assembled with the new SDK**: The product
151+
repository rolls to the new SDK and assembles the product using
152+
a new Fuchsia platform image combined with the existing pre-built
153+
`foo-widget`.
154+
155+
1. **FooWidget is broken on that product**: When the `foo-widget`
156+
component calls `GetTimestamp()`, the results will be in nanoseconds
157+
rather than seconds, which can have very strange results.
158+
For instance, the FooWidget UI may start displaying times millions
159+
of years in the future because it is treating nanoseconds as
160+
seconds!
161+
162+
It is dangerous to change the behavior of platform functionality
163+
when pre-existing software depends on the old behavior.
164+
165+
### Catching compatibility problems
166+
167+
CTF tests simulate the above scenario by taking advantage of Fuchsia's
168+
release branching process. If a CTF test fails, it means that
169+
pre-built components targeting an old Fuchsia platform implementation
170+
will fail when targeting the latest platform implementation. It works
171+
as follows:
172+
173+
1. Each Fuchsia [milestone release][milestone-release] has an
174+
associated release branch in `fuchsia.git`. This represents the
175+
state of Fuchsia's platform implementation at the time of release.
176+
1. That platform implementation passes the set of tests on that
177+
release branch.
178+
1. A set of artifacts are included in a *CTF Artifacts* bundle for
179+
that release branch.
180+
1. When the release branch is created and/or modified, the CTF
181+
Artifacts for that branch are compiled and uploaded to CIPD.
182+
1. The CTF Artifacts for each supported API level are downloaded as
183+
pre-builts on the `main` branch and are *thawed* by turning them
184+
into test packages.
185+
1. Those test packages are run against the latest Fuchsia platform
186+
on the `main` branch, which will block CL submission if they fail.
187+
188+
This exactly maps to the scenario in which a component is built
189+
against an old Fuchsia SDK and platform, and then is run as a
190+
pre-built against the current Fuchsia platform.
191+
192+
## Background and history
193+
194+
CTF exists to prevent breaking changes to the implemented Fuchsia
34195
API and ABI from landing in the platform.
35196

36197
CTF originally was designed to provide confidence that an arbitrary
37198
Fuchsia system correctly implemented the platform surface area for
38-
a particular ABI revision. This would mean that components build
199+
a particular ABI revision. This would mean that components built
39200
for that revision would work on the system, and that the system is
40201
backwards compatible with that revision.
41202

42203
The current purpose of CTF is to provide a mechanism for freezing
43-
and "thawing" test artifacts across release branches. For example,
44-
a test on the `f18` release branch is downloaded as a prebuilt at
45-
the top of the `main` branch. This test can then be executed against
46-
the Fuchsia platform as it exists today; a failure indicates that
47-
the Fuchsia platform broke compatibility with F18 in some way, which
48-
means downstream platform integrators may run in to unexpected
49-
failures if they try to run a pre-compiled binary on this new
50-
platform image.
204+
and "thawing" test artifacts across release branches.
51205

52206
This mechanism can be applied to ensure the current Fuchsia platform
53207
supports the old API and ABI behavior for each version that is
54208
supposed to be supported. Additionally, the frozen tests may be
55209
applied to arbitrary Fuchsia images to achieve the original goal
56-
of CTF if desired.
210+
of CTF if desired.
211+
212+
<!-- Reference links -->
213+
214+
[rfc-0015]: /docs/contribute/governance/rfcs/0015_cts.md
215+
[sdk-ctf-directory]: https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/sdk/ctf/
216+
[version-history]: https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/version_history.json
217+
[milestone-release]: /docs/concepts/versioning/release.md#milestone

0 commit comments

Comments
 (0)