Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: enable native unittesting #20293

Merged
merged 7 commits into from Oct 3, 2019
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
22 changes: 22 additions & 0 deletions .circleci/config.yml
Expand Up @@ -331,6 +331,14 @@ step-electron-build: &step-electron-build
cd src
ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES

step-native-unittests-build: &step-native-unittests-build
run:
name: Build native test targets
no_output_timeout: 30m
command: |
cd src
ninja -C out/Default shell_browser_ui_unittests -j $NUMBER_OF_NINJA_PROCESSES

step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run:
name: Strip electron binaries
Expand Down Expand Up @@ -402,6 +410,11 @@ step-nodejs-headers-store: &step-nodejs-headers-store
path: src/out/Default/gen/node_headers.tar.gz
destination: node_headers.tar.gz

step-native-unittests-store: &step-native-unittests-store
store_artifacts:
path: src/out/Default/shell_browser_ui_unittests
destination: shell_browser_ui_unittests

step-electron-publish: &step-electron-publish
run:
name: Publish Electron Dist
Expand All @@ -422,6 +435,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
# Build artifacts
- src/out/Default/dist.zip
- src/out/Default/mksnapshot.zip
- src/out/Default/shell_browser_ui_unittests
- src/out/Default/gen/node_headers
- src/out/ffmpeg/ffmpeg.zip
- src/electron
Expand Down Expand Up @@ -822,6 +836,10 @@ steps-electron-build: &steps-electron-build
- *step-electron-dist-store
- *step-ninja-summary

# Native test targets
- *step-native-unittests-build
- *step-native-unittests-store

# Node.js headers
- *step-nodejs-headers-build
- *step-nodejs-headers-store
Expand Down Expand Up @@ -892,6 +910,10 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
- *step-electron-dist-store
- *step-ninja-summary

# Native test targets
- *step-native-unittests-build
- *step-native-unittests-store

# Node.js headers
- *step-nodejs-headers-build
- *step-nodejs-headers-store
Expand Down
67 changes: 54 additions & 13 deletions BUILD.gn
Expand Up @@ -4,6 +4,7 @@ import("//build/config/win/manifest.gni")
import("//content/public/app/mac_helpers.gni")
import("//pdf/features.gni")
import("//printing/buildflags/buildflags.gni")
import("//testing/test.gni")
import("//third_party/ffmpeg/ffmpeg_options.gni")
import("//tools/generate_library_loader/generate_library_loader.gni")
import("//tools/grit/grit_rule.gni")
Expand Down Expand Up @@ -60,6 +61,10 @@ config("branding") {
]
}

config("electron_lib_config") {
include_dirs = [ "." ]
}

# We geneate the definitions twice here, once in //electron/electron.d.ts
# and once in $target_gen_dir
# The one in $target_gen_dir is used for the actual TSC build later one
Expand Down Expand Up @@ -333,7 +338,10 @@ source_set("electron_lib") {
configs += [ "//v8:external_startup_data" ]
configs += [ "//third_party/electron_node:node_internals" ]

public_configs = [ ":branding" ]
public_configs = [
":branding",
":electron_lib_config",
]

deps = [
":atom_js2c",
Expand Down Expand Up @@ -475,6 +483,19 @@ source_set("electron_lib") {
"//content/common:mac_helpers",
"//ui/accelerated_widget_mac",
]

libs = [
"AVFoundation.framework",
"Carbon.framework",
"LocalAuthentication.framework",
"QuartzCore.framework",
"Quartz.framework",
"Security.framework",
"SecurityInterface.framework",
"ServiceManagement.framework",
"StoreKit.framework",
]

sources += [
"shell/browser/ui/views/autofill_popup_view.cc",
"shell/browser/ui/views/autofill_popup_view.h",
Expand Down Expand Up @@ -774,6 +795,7 @@ if (is_mac) {
"Libraries",
]
public_deps = [
":electron_framework_libraries",
":electron_lib",
]
deps = [
Expand All @@ -795,18 +817,6 @@ if (is_mac) {
include_dirs = [ "." ]
sources = filenames.framework_sources

libs = [
"AVFoundation.framework",
"Carbon.framework",
"LocalAuthentication.framework",
"QuartzCore.framework",
"Quartz.framework",
"Security.framework",
"SecurityInterface.framework",
"ServiceManagement.framework",
"StoreKit.framework",
]

if (enable_osr) {
libs += [ "IOSurface.framework" ]
}
Expand Down Expand Up @@ -1189,6 +1199,37 @@ if (is_mac) {
}
}

test("shell_browser_ui_unittests") {
sources = [
"//electron/shell/browser/ui/accelerator_util_unittests.cc",
"//electron/shell/browser/ui/run_all_unittests.cc",
]

configs += [ ":electron_lib_config" ]

deps = [
":electron_lib",
"//base",
"//base/test:test_support",
"//testing/gmock",
"//testing/gtest",
"//ui/base",
"//ui/strings",
]

if (is_mac) {
# Resolve paths owing to different test executable locations
ldflags = [
"-F",
rebase_path("external_binaries", root_build_dir),
"-rpath",
"@loader_path",
"-rpath",
"@executable_path/" + rebase_path("external_binaries", root_build_dir),
]
}
}

template("dist_zip") {
_runtime_deps_target = "${target_name}__deps"
_runtime_deps_file =
Expand Down
2 changes: 2 additions & 0 deletions appveyor.yml
Expand Up @@ -83,10 +83,12 @@ build_script:
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- ninja -C out/Default electron:electron_mksnapshot_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- appveyor PushArtifact out/Default/dist.zip
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
- appveyor PushArtifact out/Default/chromedriver.zip
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
- 7z a node_headers.zip out\Default\gen\node_headers
Expand Down
8 changes: 8 additions & 0 deletions azure-pipelines-woa.yml
Expand Up @@ -18,6 +18,14 @@ steps:
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)

- powershell: |
$localArtifactPath = "$pwd\src\out\Default\shell_browser_ui_unittests.exe"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/shell_browser_ui_unittests.exe"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
displayName: 'Download and extract native test executables for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)

- powershell: |
$localArtifactPath = "$pwd\ffmpeg.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip"
Expand Down
2 changes: 1 addition & 1 deletion script/lib/utils.js
Expand Up @@ -27,7 +27,7 @@ function getOutDir (shouldLog) {
if (process.env.ELECTRON_OUT_DIR) {
return process.env.ELECTRON_OUT_DIR
} else {
for (const buildType of ['Debug', 'Testing', 'Release']) {
for (const buildType of ['Debug', 'Testing', 'Release', 'Default']) {
const outPath = path.resolve(SRC_DIR, 'out', buildType)
if (fs.existsSync(outPath)) {
if (shouldLog) console.log(`OUT_DIR is: ${buildType}`)
Expand Down
3 changes: 3 additions & 0 deletions script/native-test-targets.json
@@ -0,0 +1,3 @@
[
"shell_browser_ui_unittests"
]
59 changes: 56 additions & 3 deletions script/spec-runner.js
Expand Up @@ -12,7 +12,8 @@ const pass = '✓'.green
const fail = '✗'.red

const args = require('minimist')(process.argv, {
string: ['runners'],
string: ['runners', 'target'],
boolean: ['buildNativeTests'],
unknown: arg => unknownFlags.push(arg)
})

Expand All @@ -34,7 +35,8 @@ const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx'

const runners = new Map([
['main', { description: 'Main process specs', run: runMainProcessElectronTests }],
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }]
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }],
['native', { description: 'Native specs', run: runNativeElectronTests }]
])

const specHashPath = path.resolve(__dirname, '../spec/.hash')
Expand All @@ -48,7 +50,7 @@ if (args.runners) {
}
console.log('Only running:', runnersToRun)
} else {
console.log(`Triggering both ${[...runners.keys()].join(' and ')} runners`)
console.log(`Triggering runners: ${[...runners.keys()].join(', ')}`)
}

async function main () {
Expand Down Expand Up @@ -141,6 +143,57 @@ async function runRemoteBasedElectronTests () {
console.log(`${pass} Electron remote process tests passed.`)
}

async function runNativeElectronTests () {
let testTargets = require('./native-test-targets.json')
const outDir = `out/${utils.getOutDir(false)}`

// If native tests are being run, only one arg would be relevant
if (args.target && !testTargets.includes(args.target)) {
console.log(`${fail} ${args.target} must be a subset of [${[testTargets].join(', ')}]`)
process.exit(1)
}

// Optionally build all native test targets
if (args.buildNativeTests) {
for (const target of testTargets) {
const build = childProcess.spawnSync('ninja', ['-C', outDir, target], {
cwd: path.resolve(__dirname, '../..'),
stdio: 'inherit'
})

// Exit if test target failed to build
if (build.status !== 0) {
console.log(`${fail} ${target} failed to build.`)
process.exit(1)
}
}
}

// If a specific target was passed, only build and run that target
if (args.target) testTargets = [args.target]

// Run test targets
const failures = []
for (const target of testTargets) {
console.info('\nRunning native test for target:', target)
const testRun = childProcess.spawnSync(`./${outDir}/${target}`, {
cwd: path.resolve(__dirname, '../..'),
stdio: 'inherit'
})

// Collect failures and log at end
if (testRun.status !== 0) failures.push({ target })
}

// Exit if any failures
if (failures.length > 0) {
console.log(`${fail} Electron native tests failed for the following targets: `, failures)
process.exit(1)
}

console.log(`${pass} Electron native tests passed.`)
}

async function runMainProcessElectronTests () {
let exe = path.resolve(BASE, utils.getElectronExec())
const runnerArgs = ['electron/spec-main', ...unknownArgs.slice(2)]
Expand Down
29 changes: 29 additions & 0 deletions shell/browser/ui/accelerator_util_unittests.cc
@@ -0,0 +1,29 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/ui/accelerator_util.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace accelerator_util {

TEST(AcceleratorUtilTest, StringToAccelerator) {
struct {
const std::string& description;
bool expected_success;
} keys[] = {
{"♫♫♫♫♫♫♫", false}, {"Cmd+Plus", true}, {"Ctrl+Space", true},
{"CmdOrCtrl", false}, {"Alt+Tab", true}, {"AltGr+Backspace", true},
{"Super+Esc", true}, {"Super+X", true}, {"Shift+1", true},
};

for (const auto& key : keys) {
// Initialize empty-but-not-null accelerator
ui::Accelerator out = ui::Accelerator(ui::VKEY_UNKNOWN, ui::EF_NONE);
bool success = StringToAccelerator(key.description, &out);
EXPECT_EQ(success, key.expected_success);
}
}

} // namespace accelerator_util
15 changes: 15 additions & 0 deletions shell/browser/ui/run_all_unittests.cc
@@ -0,0 +1,15 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/test_suite.h"
#include "build/build_config.h"

int main(int argc, char** argv) {
base::TestSuite test_suite(argc, argv);
return base::LaunchUnitTests(
argc, argv,
base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
}
9 changes: 9 additions & 0 deletions vsts-arm-test-steps.yml
Expand Up @@ -53,6 +53,15 @@ steps:
env:
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)

- bash: |
export NATIVE_UNITTESTS_DEST=$PWD/src/out/Default
cd src/electron
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=shell_browser_ui_unittests --dest=$NATIVE_UNITTESTS_DEST
chmod +x $NATIVE_UNITTESTS_DEST/shell_browser_ui_unittests
codebytere marked this conversation as resolved.
Show resolved Hide resolved
displayName: 'Download native unittest executables'
env:
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)

- bash: |
sh -e /etc/init.d/xvfb start
displayName: Setup for headless testing
Expand Down