Page MenuHomePhabricator

Intermittent CI failure: TypeError: Set is not a constructor
Closed, ResolvedPublic

Description

12:42:42 LOG: 'Exception in module-execute in module vue:'
12:42:42 WARN: TypeError: Set is not a constructor
12:42:42 TypeError: Set is not a constructor
12:42:42     at http://localhost:9876/load.php?debug=2&modules=vue&version=ztntf:1076:26
12:42:42     at resources/lib/vue/vue.js (http://localhost:9876/load.php?debug=2&modules=vue&version=ztntf:18460:2)
12:42:42     at require (http://127.0.0.1:9413//index.php?title=Special:JavaScriptTest/qunit/export:1127:5)
12:42:42     at http://localhost:9876/load.php?debug=2&modules=vue&version=ztntf:6:14
12:42:42     at resources/src/vue/index.js (http://localhost:9876/load.php?debug=2&modules=vue&version=ztntf:104:2)
12:42:42     at runScript (http://127.0.0.1:9413//index.php?title=Special:JavaScriptTest/qunit/export:1360:6)
12:42:42     at execute (http://127.0.0.1:9413//index.php?title=Special:JavaScriptTest/qunit/export:1476:4)
12:42:42     at doPropagation (http://127.0.0.1:9413//index.php?title=Special:JavaScriptTest/qunit/export:867:6)

Seen for example in https://integration.wikimedia.org/ci/job/wmf-quibble-vendor-mysql-php81-docker/2345/console for extension WikimediaMessages

Event Timeline

Change 891295 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/core@master] Revert "qunit: Enable debug=2 by default for SpecialJavaScriptTest"

https://gerrit.wikimedia.org/r/891295

Krinkle triaged this task as High priority.
Krinkle edited projects, added Performance-Team, MediaWiki-Core-Tests; removed Vue.js.
Krinkle moved this task from Inbox to QUnit on the MediaWiki-Core-Tests board.

Change 891295 merged by jenkins-bot:

[mediawiki/core@master] Revert "qunit: Enable debug=2 by default for SpecialJavaScriptTest"

https://gerrit.wikimedia.org/r/891295

The other one [this task] is happening because something somewhere is performing untracked load of Vue during whilst the tests continue to run. There is a test where we test a Set polyfill, and despite having no concurrency in test execution, Vue happens to execute right in the middle of the test that very briefly unsets window.Set. Details on at T330293.

In general, we wait for all code to load before starting test execution. Yet, it seems something is triggering (outside any test) a lazy load for Vue.js. This is getting unluckily coincided with a unit test for mw.loader where window.Set is briefly (intentionally) undefined.

The output is as follows:

  • INFO [launcher]: Starting browser ChromeHeadless
  • Requesting …
  • Fetching …

Until all test suits and their depended-on source code is ready, and then tests begin:

  • ✔ testrunner
  • ✔ ext.echo.mobile

And then a number of surprise web requests "enter the chat":

  • Requesting /load.php?debug=2&modules=mw.cx.init
  • Requesting /load.php?debug=2&modules=ext.visualEditor.desktopArticleTarget

Which continue during ✔ ext.eventLogging/log:

  • Requesting /extensions/Wikibase/view/lib/wikibase-data-values-value-view/src/experts/TimeInput.css
  • Requesting /load.php?debug=2&modules=vue
  • Requesting /load.php?debug=2&modules=wikibase.tainted-ref

Until ✔ mw.loader reaches its ES6 polyfil test cases:

  • ✔ .using() [StringSet default]
  • ✔ .using() [StringSet shim] — this temporarily mocks window.Set = undefined;
 LOG: 'Exception in module-execute in module vue:'
TypeError: Set is not a constructor
     at http://localhost:9876/load.php?debug=2&modules=vue&version=ztntf#L1076
     at resources/lib/vue/vue.js
     at resources/src/vue/index.js

... and that line just so happens to be:

vue.js
class ReactiveEffect {

const oldTarget = 
              ? 
              : new Set(target)

I suspect the culprit is wikibase.tainted-ref. This module depends on vue, and is not loaded as dependency:

Wikibase/view/resources.php:

		'wikibase.view.ControllerViewFactory' => 
			 // T326405

				// the tainted-ref dependency is temporarily moved to ControllerViewFactory.js (T298001),
				// because tainted-ref is (transitively) es6-only and we don’t want this module to be es6-only yet;
				// this can probably be reverted at some point, once we fully drop Wikibase IE11 support
				// 'wikibase.tainted-ref',

And view/resources/wikibase/view/ControllerViewFactory.js

// dynamically load wikibase.tainted-ref, originally added as dependency of this module in change I9a244a36fe (commit 5fed25ce15);
// it’s not directly related to ControllerViewFactory, but we want to load it at the same time,
// and the dependency can’t be in resources.php because then TR’s es6-ness “infects” regular Wikibase (T298001)
mw.loader.using( 'wikibase.tainted-ref' )
  

CC @LucasWerkmeister as having added this for T298001 in change 748719.

Can this be limited to a conditional like if ( !window.QUnit ) or some such to avoid untracked async stacks for page view contexts starting off in the background during a unit test?

Sounds fine to me, I doubt we have QUnit tests relying on tainted refs.

Change 891563 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/extensions/Wikibase@master] Don’t load Tainted References during QUnit tests

https://gerrit.wikimedia.org/r/891563

Sounds fine to me, I doubt we have QUnit tests relying on tainted refs.

If you do, you can load it either as a dependency defined with the test module, or by using mw.loader.using() within the test that needs it. It's fine to load things during the test, so long as it is tracked as part of that test. That way, no other tests are running at the same time in that browser tab.

Change 891563 merged by jenkins-bot:

[mediawiki/extensions/Wikibase@master] Don’t load Tainted References during QUnit tests

https://gerrit.wikimedia.org/r/891563