Skip to content

Commit 165afd8

Browse files
trflynn89gmta
authored andcommitted
test-web: Do not clear the WebContent crash handler between tests
Clearing the callback opens a window for the WebContent process to crash while we do not have a callback set. In practice, we see this with ASAN crashes, where the crash occurs after we've already signaled that the test has completed. We now set the crash handler once during init. This required moving the clearing of other callbacks to the test completion handler (we were clearing these callbacks in several different ways anyways, so now we will at least be consistent).
1 parent 59c963f commit 165afd8

File tree

2 files changed

+30
-53
lines changed

2 files changed

+30
-53
lines changed

Tests/LibWeb/test-web/TestWeb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <AK/String.h>
1515
#include <AK/Time.h>
1616
#include <AK/Vector.h>
17+
#include <LibCore/Forward.h>
1718
#include <LibCore/Promise.h>
1819
#include <LibGfx/Forward.h>
1920

@@ -59,6 +60,8 @@ struct Test {
5960

6061
RefPtr<Gfx::Bitmap const> actual_screenshot {};
6162
RefPtr<Gfx::Bitmap const> expectation_screenshot {};
63+
64+
RefPtr<Core::Timer> timeout_timer {};
6265
};
6366

6467
struct TestCompletion {

Tests/LibWeb/test-web/main.cpp

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace TestWeb {
3838

3939
static RefPtr<Core::Promise<Empty>> s_all_tests_complete;
4040
static Vector<ByteString> s_skipped_tests;
41-
static HashMap<WebView::ViewImplementation const*, Test const*> s_test_by_view;
41+
static HashMap<WebView::ViewImplementation const*, Test*> s_test_by_view;
4242

4343
static constexpr StringView test_result_to_string(TestResult result)
4444
{
@@ -152,13 +152,6 @@ static ErrorOr<void> collect_crash_tests(Application const& app, Vector<Test>& t
152152
return {};
153153
}
154154

155-
static void clear_test_callbacks(TestWebView& view)
156-
{
157-
view.on_load_finish = {};
158-
view.on_test_finish = {};
159-
view.on_web_content_crashed = {};
160-
}
161-
162155
static String generate_wait_for_test_string(StringView wait_class)
163156
{
164157
return MUST(String::formatted(R"(
@@ -195,12 +188,7 @@ static auto wait_for_reftest_completion = generate_wait_for_test_string("reftest
195188

196189
static void run_dump_test(TestWebView& view, Test& test, URL::URL const& url, int timeout_in_milliseconds)
197190
{
198-
auto timer = Core::Timer::create_single_shot(timeout_in_milliseconds, [&view, &test]() {
199-
view.on_load_finish = {};
200-
view.on_test_finish = {};
201-
view.on_set_test_timeout = {};
202-
view.reset_zoom();
203-
191+
test.timeout_timer = Core::Timer::create_single_shot(timeout_in_milliseconds, [&view, &test]() {
204192
view.on_test_complete({ test, TestResult::Timeout });
205193
});
206194

@@ -259,24 +247,13 @@ static void run_dump_test(TestWebView& view, Test& test, URL::URL const& url, in
259247
return TestResult::Fail;
260248
};
261249

262-
auto on_test_complete = [&view, &test, timer, handle_completed_test]() {
263-
view.reset_zoom();
264-
clear_test_callbacks(view);
265-
timer->stop();
266-
250+
auto on_test_complete = [&view, &test, handle_completed_test]() {
267251
if (auto result = handle_completed_test(); result.is_error())
268252
view.on_test_complete({ test, TestResult::Fail });
269253
else
270254
view.on_test_complete({ test, result.value() });
271255
};
272256

273-
view.on_web_content_crashed = [&view, &test, timer]() {
274-
clear_test_callbacks(view);
275-
timer->stop();
276-
277-
view.on_test_complete({ test, TestResult::Crashed });
278-
};
279-
280257
if (test.mode == TestMode::Layout) {
281258
view.on_load_finish = [&view, &test, url, on_test_complete = move(on_test_complete)](auto const& loaded_url) {
282259
// We don't want subframe loads to trigger the test finish.
@@ -342,25 +319,18 @@ static void run_dump_test(TestWebView& view, Test& test, URL::URL const& url, in
342319
};
343320
}
344321

345-
view.on_set_test_timeout = [timer, timeout_in_milliseconds](double milliseconds) {
346-
if (milliseconds <= timeout_in_milliseconds)
347-
return;
348-
timer->stop();
349-
timer->start(milliseconds);
322+
view.on_set_test_timeout = [&test, timeout_in_milliseconds](double milliseconds) {
323+
if (milliseconds > timeout_in_milliseconds)
324+
test.timeout_timer->restart(milliseconds);
350325
};
351326

352327
view.load(url);
353-
timer->start();
328+
test.timeout_timer->start();
354329
}
355330

356331
static void run_ref_test(TestWebView& view, Test& test, URL::URL const& url, int timeout_in_milliseconds)
357332
{
358333
auto timer = Core::Timer::create_single_shot(timeout_in_milliseconds, [&view, &test]() {
359-
view.on_load_finish = {};
360-
view.on_test_finish = {};
361-
view.on_set_test_timeout = {};
362-
view.reset_zoom();
363-
364334
view.on_test_complete({ test, TestResult::Timeout });
365335
});
366336

@@ -394,23 +364,13 @@ static void run_ref_test(TestWebView& view, Test& test, URL::URL const& url, int
394364
return TestResult::Fail;
395365
};
396366

397-
auto on_test_complete = [&view, &test, timer, handle_completed_test]() {
398-
clear_test_callbacks(view);
399-
timer->stop();
400-
367+
auto on_test_complete = [&view, &test, handle_completed_test]() {
401368
if (auto result = handle_completed_test(); result.is_error())
402369
view.on_test_complete({ test, TestResult::Fail });
403370
else
404371
view.on_test_complete({ test, result.value() });
405372
};
406373

407-
view.on_web_content_crashed = [&view, &test, timer]() {
408-
clear_test_callbacks(view);
409-
timer->stop();
410-
411-
view.on_test_complete({ test, TestResult::Crashed });
412-
};
413-
414374
view.on_load_finish = [&view](auto const&) {
415375
view.run_javascript(wait_for_reftest_completion);
416376
};
@@ -483,11 +443,9 @@ static void run_ref_test(TestWebView& view, Test& test, URL::URL const& url, int
483443
view.load(URL::Parser::basic_parse(reference_to_load).release_value());
484444
};
485445

486-
view.on_set_test_timeout = [timer, timeout_in_milliseconds](double milliseconds) {
487-
if (milliseconds <= timeout_in_milliseconds)
488-
return;
489-
timer->stop();
490-
timer->start(milliseconds);
446+
view.on_set_test_timeout = [&test, timeout_in_milliseconds](double milliseconds) {
447+
if (milliseconds > timeout_in_milliseconds)
448+
test.timeout_timer->restart(milliseconds);
491449
};
492450

493451
view.load(url);
@@ -580,6 +538,11 @@ static void set_ui_callbacks_for_tests(TestWebView& view)
580538
// For tests, just close the alert right away to unblock JS execution.
581539
view.alert_closed();
582540
};
541+
542+
view.on_web_content_crashed = [&view]() {
543+
if (auto test = s_test_by_view.get(&view); test.has_value())
544+
view.on_test_complete({ *test.value(), TestResult::Crashed });
545+
};
583546
}
584547

585548
static ErrorOr<int> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize window_size)
@@ -699,6 +662,17 @@ static ErrorOr<int> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePix
699662
};
700663

701664
view->test_promise().when_resolved([&, run_next_test, view_id](auto result) {
665+
view->on_load_finish = {};
666+
view->on_test_finish = {};
667+
view->on_reference_test_metadata = {};
668+
view->on_set_test_timeout = {};
669+
view->reset_zoom();
670+
671+
if (result.test.timeout_timer) {
672+
result.test.timeout_timer->stop();
673+
result.test.timeout_timer.clear();
674+
}
675+
702676
result.test.end_time = UnixDateTime::now();
703677
s_test_by_view.remove(view);
704678

0 commit comments

Comments
 (0)