Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Migration of Chromium Chronicle articles & Add float-(left|right) #215

Merged
merged 6 commits into from Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions .eleventy.js
Expand Up @@ -21,7 +21,7 @@ const {glitch} = require('./site/_shortcodes/glitch');
const {img} = require('./site/_shortcodes/img');
const {video} = require('./site/_shortcodes/video');
const {youtube} = require('./site/_shortcodes/youtube');
const {columns} = require('./site/_shortcodes/columns');
const {columns, column} = require('./site/_shortcodes/columns');
const {Compare, CompareCaption} = require('./site/_shortcodes/Compare');

// Transforms
Expand All @@ -45,7 +45,7 @@ const extensionsReferenceCollection = require('./site/_collections/reference');

// Create a helpful environment flags
const isProduction = process.env.NODE_ENV === 'production';
const isCI = true || process.env.CI;
const isCI = process.env.CI;

module.exports = eleventyConfig => {
// Tell 11ty to use the .eleventyignore and ignore our .gitignore file
Expand Down Expand Up @@ -106,6 +106,7 @@ module.exports = eleventyConfig => {
eleventyConfig.addShortcode('video', video);
eleventyConfig.addShortcode('youtube', youtube);
eleventyConfig.addPairedShortcode('columns', columns);
eleventyConfig.addPairedShortcode('column', column);
eleventyConfig.addPairedShortcode('Compare', Compare);
eleventyConfig.addPairedShortcode('CompareCaption', CompareCaption);

Expand Down
3 changes: 3 additions & 0 deletions site/_data/i18n/tags.yml
Expand Up @@ -11,6 +11,9 @@ accessibility:
amp:
en: AMP

chromium-chronicle:
robdodson marked this conversation as resolved.
Show resolved Hide resolved
en: Chromium Chronicle

devices:
en: Devices

Expand Down
5 changes: 4 additions & 1 deletion site/_data/supportedTags.json
Expand Up @@ -11,6 +11,9 @@
"amp": {
"title": "i18n.tags.amp"
},
"chromium-chronicle": {
robdodson marked this conversation as resolved.
Show resolved Hide resolved
"title": "i18n.tags.chromium-chronicle"
},
"devices": {
"title": "i18n.tags.devices"
},
Expand All @@ -35,4 +38,4 @@
"html": {
"title": "i18n.tags.html"
}
}
}
2 changes: 1 addition & 1 deletion site/_includes/layouts/blog-post.njk
Expand Up @@ -31,7 +31,7 @@

{% include 'partials/draft.njk' %}

<div class="stack type center-images">
<div class="stack stack--block type center-images">
{{ content | safe }}
</div>
</article>
Expand Down
2 changes: 1 addition & 1 deletion site/_includes/layouts/doc-post.njk
Expand Up @@ -26,7 +26,7 @@
{% include 'partials/toc-inner.njk' %}
{% include 'partials/draft.njk' %}

<div class="stack type center-images">
<div class="stack stack--block type center-images">
{{ content | safe }}
</div>
</article>
Expand Down
8 changes: 8 additions & 0 deletions site/_scss/blocks/_columns.scss
Expand Up @@ -4,6 +4,14 @@
grid-auto-flow: row;

@include media-query('md') {
grid-auto-columns: 1fr;
grid-auto-flow: column;
}
}

.columns__column {
@include media-query('md') {
display: flex;
flex-direction: column;
}
}
7 changes: 7 additions & 0 deletions site/_scss/blocks/_stack.scss
Expand Up @@ -29,6 +29,13 @@
}
/* purgecss end ignore */

// The default .stack class uses flexbox, and flexbox ignores floats.
// Authors like to use floats in blog posts and docs so this exception can be
// used on those stacks to enable floats.
.stack--block {
display: block;
}

// Use the stack-exception class to change the top AND bottom margin
// around an individual element.
// These exceptions follow the rest of our size scale.
Expand Down
1 change: 1 addition & 0 deletions site/_scss/main.scss
Expand Up @@ -66,6 +66,7 @@
// Utilities
@import 'utilities/center-margin';
@import 'utilities/center-images';
@import 'utilities/floats';
@import 'utilities/elevation';
@import 'utilities/hairline';
@import 'utilities/colors';
Expand Down
20 changes: 20 additions & 0 deletions site/_scss/utilities/_floats.scss
@@ -0,0 +1,20 @@
.float-left {
@include media-query('lg') {
float: left;
margin-right: get-size(600) !important;
}
}

.float-right {
@include media-query('lg') {
float: right;
margin-left: get-size(600) !important;
}
}

.float-left,
.float-right {
@include media-query('lg') {
max-width: calc((100% - #{get-size(600)}) / 2);
}
}
6 changes: 5 additions & 1 deletion site/_shortcodes/columns.js
Expand Up @@ -33,4 +33,8 @@ ${content}
</div>`;
};

module.exports = {columns};
const column = content => {
return `<div class="columns__column">${content}</div>`;
};

module.exports = {columns, column};
113 changes: 113 additions & 0 deletions site/en/blog/chromium-chronicle-1/index.md
@@ -0,0 +1,113 @@
---
title: "The Chromium Chronicle #1: Task Scheduling Best Practices"
description: >
The Chrome team is proud to introduce the Chromium Chronicle, a monthly
series geared specifically to Chromium developers - the developers who
build the browser. This month, we take a look at task scheduling best
practices.
layout: 'layouts/blog-post.njk'
date: 2019-04-16
hero: 'image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/hgu6uTktp2ipmuODZZhP.jpg'
alt: >
Chromium Chronicle image
tags:
- chromium-chronicle
---

The Chrome team is proud to introduce the Chromium Chronicle, a monthly
series geared specifically to Chromium developers, developers who build the
browser.

The Chromium Chronicle will primarily focus on spreading technical knowledge
and best practices to write, build, and test Chrome. Our plan is to feature
topics that are relevant and useful to Chromium developers, such as code
health, helpful tools, unit testing, accessibility and much more! Each article
will be written and edited by Chrome engineers.

We are excited about this new series, and hope you are too! Ready to dive in?
Take a look at our first episode below!

## Task Scheduling Best Practices

**Episode 1:** by Gabriel Charette in Montréal, PQ (April, 2019)<br>
[Previous episodes](/tags/chromium-chronicle/)

Chrome code that needs in-process asynchronous execution typically posts tasks
to sequences. Sequences are chrome-managed “virtual threads” and are
[preferred to creating your own thread][prefer-sequences]. How does an object
know which sequence to post to?

{% Compare 'worse' %}

The old paradigm is to receive a SequencedTaskRunner from the creator:

```cpp/0
Foo::Foo(scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
: backend_task_runner_(std::move(backend_task_runner)) {}
```

{% endCompare %}

{% Compare 'better' %}

The preferred paradigm is to create an independent SequencedTaskRunner:

```cpp/2-3
Foo::Foo()
: backend_task_runner_(
base::CreateSequencedTaskRunnerWithTraits({
base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}
```

{% endCompare %}

This is easier to read and write as all the information is local and there’s
no risk of inter-dependency with unrelated tasks.

This paradigm is also better when it comes to testing. Instead of injecting
task runners manually, tests can **instantiate a controlled task environment**
to manage Foo’s tasks:

```cpp/4
class FooTest : public testing::Test {
public
(...)
protected:
base::test::TaskEnvironment task_environment_;
Foo foo_;
};
```

Having **TaskEnvironment first in the fixture** naturally ensures it
manages the task environment throughout Foo’s lifetime. The TaskEnvironment
will capture Foo’s request-on-construction to create a SequencedTaskRunner and
will manage its tasks under each FooTest.

To test the result of asynchronous execution, **use the
`RunLoop::Run()+QuitClosure()` paradigm**:

```cpp
TEST_F(FooTest, TestAsyncWork) {
RunLoop run_loop;
foo_.BeginAsyncWork(run_loop.QuitClosure());
run_loop.Run();
EXPECT_TRUE(foo_.work_done());
}
```

This is preferred to RunUntilIdle(), which can be flaky if the asynchronous
workload involves a task outside of the TaskEnvironment’s purview,
e.g. a system event, so use [`RunUntilIdle()` with care][run-until-idle-w-care].

!!!.aside.aside
Pro-tip: Use TaskEnvironment’s `MOCK_TIME` mode to reliably test delayed
tasks.
!!!

**Want to learn more?** Read our documentation on [threading and tasks][threading-and-tasks]
or get involved in the [migration to TaskEnvironment][task-env]!

[prefer-sequences]: https://chromium.googlesource.com/chromium/src/+/lkgr/docs/threading_and_tasks.md#Prefer-Sequences-to-Threads
[threading-and-tasks]: https://chromium.googlesource.com/chromium/src/+/master/docs/threading_and_tasks.md
[task-env]: https://docs.google.com/document/d/1QabRo8c7D9LsYY3cEcaPQbOCLo8Tu-6VLykYXyl3Pkk/edit
[run-until-idle-w-care]: https://cs.chromium.org/chromium/src/base/test/task_environment.h?type=cs&q="void+RunUntilIdle()"+WARNING+case:yes&sq=package:chromium&g=0
62 changes: 62 additions & 0 deletions site/en/blog/chromium-chronicle-10/index.md
@@ -0,0 +1,62 @@
---
title: "The Chromium Chronicle #10: Catching UI Regressions with Pixel Tests"
description: >
Chrome’s testing strategy relies heavily on automated functional correctness
tests and manual testing, but neither of these reliably catch minor UI
regressions. Use pixel tests to automate testing your desktop browser UI.
layout: 'layouts/blog-post.njk'
date: 2020-02-05
hero: 'image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/hgu6uTktp2ipmuODZZhP.jpg'
alt: >
Chromium Chronicle image
tags:
- chromium-chronicle
---

**Episode 10:** by Sven Zheng in Bellevue, WA (January, 2020)<br>
[Previous episodes](/tags/chromium-chronicle/)

Chrome’s testing strategy relies heavily on automated functional correctness
tests and manual testing, but neither of these reliably catch minor UI
regressions. **Use pixel tests to automate testing your desktop browser UI.**

When writing a pixel test, avoid flakiness by: (1) disabling animation,
(2) using mock data, and (3) testing the minimum possible surface area.

Here is a sample image used to verify pixel correctness for the omnibox:

{% img src="image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/WdIk74i8zUDGYrHX44FP.png", alt="Omnibox image used for pixel comparison." %}

And the code to verify the browser matches this image:

```cpp
IN_PROC_BROWSER_TEST_F(SkiaGoldDemoPixelTest, TestOmnibox) {
// Always disable animation for stability.
ui::ScopedAnimationDurationScaleMode disable_animation(
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
GURL url("chrome://bookmarks");
AddTabAtIndex(0, url, ui::PageTransition::PAGE_TRANSITION_FIRST);
auto* const browser_view = BrowserView::GetBrowserViewForBrowser(browser());
// CompareScreenshot() takes a screenshot and compares it with the
// golden image, which was previously human-approved, is stored
// server-side, and is managed by Skia Gold. If any pixels differ, the
// test will fail and output a link for the author to triage the
// new image.
bool ret = GetPixelDiff().CompareScreenshot("omnibox",
browser_view->GetLocationBarView());
EXPECT_TRUE(ret);
}
```

This code lives at [chrome/test/pixel/demo/skia_gold_demo_pixeltest.cc][1].
The relevant headers are `skia_gold_pixel_diff.h` for unit tests and
`browser_skia_gold_pixel_diff.h` for browser tests.

The pixel diff and approval process is powered by Skia Gold. **Skia Gold pixel
tests provide a visual approval workflow, and allow developers to accept
small flakes by approving multiple gold images.**

Currently the test suite is running on the Windows FYI bot. Browser tests
and Views unit tests are supported.

[1]: https://chromium.googlesource.com/chromium/src.git/+/refs/heads/master/chrome/test/pixel/demo/
78 changes: 78 additions & 0 deletions site/en/blog/chromium-chronicle-13/index.md
@@ -0,0 +1,78 @@
---
title: "The Chromium Chronicle #13: Time-Travel Debugging with RR"
description: >
Do you find yourself running the same test over and over in the debugger,
trying to figure out how the code got in a bad state? We have a tool for
you! RR will record an execution trace, making it easy to step backwards,
run backwards, see where variables changed their value or when a function
was last called on an object.
layout: 'layouts/blog-post.njk'
date: 2020-03-18
hero: 'image/0g2WvpbGRGdVs0aAPc6ObG7gkud2/hgu6uTktp2ipmuODZZhP.jpg'
alt: >
Chromium Chronicle image
tags:
- chromium-chronicle
---

**Episode 13:** by Christian Biesinger in Madison, WI (March, 2020)<br>
[Previous episodes](/tags/chromium-chronicle/)

Do you find yourself **running the same test over and over** in the debugger,
trying to figure out how the code got in a bad state? **We have a tool for you!**
Easy to install and setup, it will record an execution trace, and that gives
magical new powers to `gdb`. **Step backwards, run backwards**, see where
variables changed their value or when a function was last called on an object
(using conditional breakpoints).

On Linux, you can **use rr**. Install using `sudo apt-get install rr` or
from <https://rr-project.org/>.

This is not officially supported, but very useful. The way `rr` works is that
you **first record a trace**, then **replay it**.

```bash
rr record .../content_shell --no-sandbox --disable-hang-monitor --single-process
# record the trace. --single-process is optional, see below. The other flags are required.
rr replay # This will replay the last trace
(gdb) # rr uses GDB to let you replay traces
```

Conveniently, timing and pointer addresses stay the same every time you replay
the same trace. **Traces can be made portable** using `rr pack` so that you
can copy them to another machine and replay there, or replay even after
recompiling. Run your program using `continue`. You can use all regular
GDB commands `-b`, `next`, `watch`, etc. However, you can also use
**reverse-next** (`rn`), **reverse-cont** (`rc`), **reverse-step** (`rs`),
**reverse-fin**.

These still respect any breakpoints you’ve set. For example:

```text
(gdb) c # Execute to the end
(gdb) break blink::LayoutFlexibleBox::UpdateLayout
(gdb) rc # Run back to the last layout call
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
this=0x121672224010)
(gdb) # Inspect anything you want here. To find the previous Layout call on this object:
(gdb) cond 1 this == 0x121672224010
(gdb) rc
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
this=0x121672224010)
(gdb) watch -l style_.ptr_ # Or find the last time the style_ was changed
(gdb) rc
Thread 5 hit Hardware watchpoint 2: -location style_.ptr_

Old value = (const blink::ComputedStyle *) 0x1631ad3dbb0
New value = (const blink::ComputedStyle *) 0x0
0x00007f68cabcf78e in std::__Cr::swap&lt;blink::ComputedStyle const*&gt; (
```

In this example, I have used `--single-process` for simplicity, but that’s
not necessary. **RR can trace multiple processes**; after recording, you can
see a list using `rr ps` and pick one to replay with `rr replay -f PID`.

There are lots of ways RR can be useful. There are **other commands you can use**,
such as when to find out at which event number you are at, or `rr replay -M`
to annotate `stdout` with a process ID and event number for each line. See
the [RR website and documentation](https://rr-project.org/) for more details.