mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Merge pull request #1619 from jamesr/trim_mojo_dart
Remove unused code in //mojo/dart, we only want //mojo/dart/embedder
This commit is contained in:
commit
1dcecefb40
8
.gitignore
vendored
8
.gitignore
vendored
@ -66,13 +66,5 @@ Thumbs.db
|
||||
/examples/**/packages
|
||||
/examples/**/pubspec.lock
|
||||
/mojo/common/dart/packages
|
||||
/mojo/dart/apptest/packages
|
||||
/mojo/dart/http_load_test/bin/packages
|
||||
/mojo/dart/http_load_test/packages/
|
||||
/mojo/dart/mojo_services/packages
|
||||
/mojo/dart/mojo_services/pubspec.lock
|
||||
/mojo/dart/mojom/bin/packages
|
||||
/mojo/dart/mojom/packages
|
||||
/mojo/dart/mojom/test/packages
|
||||
/sky/packages/**/packages
|
||||
/sky/packages/sky_services/lib/
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
# Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
group("dart") {
|
||||
deps = [
|
||||
"//mojo/dart/dart_snapshotter($host_toolchain)",
|
||||
"//mojo/dart/http_load_test",
|
||||
"//mojo/dart/mojo_services",
|
||||
"//mojo/dart/observatory_test",
|
||||
]
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
# Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
executable("dart_snapshotter") {
|
||||
sources = [
|
||||
"main.cc",
|
||||
"vm.cc",
|
||||
"vm.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//build/config/sanitizers:deps",
|
||||
"//dart/runtime/vm:libdart_platform",
|
||||
"//dart/runtime:libdart",
|
||||
"//mojo/common",
|
||||
"//mojo/dart/embedder:dart_snapshot_cc",
|
||||
"//mojo/edk/system",
|
||||
"//mojo/environment:chromium",
|
||||
"//mojo/public/cpp/system",
|
||||
"//mojo/public/cpp/utility",
|
||||
"//mojo/public/interfaces/application",
|
||||
"//third_party/zlib",
|
||||
"//tonic",
|
||||
]
|
||||
}
|
||||
@ -1,101 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "base/at_exit.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/process/memory.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "mojo/dart/dart_snapshotter/vm.h"
|
||||
#include "mojo/edk/embedder/embedder.h"
|
||||
#include "mojo/edk/embedder/simple_platform_support.h"
|
||||
#include "tonic/dart_error.h"
|
||||
#include "tonic/dart_isolate_scope.h"
|
||||
#include "tonic/dart_library_loader.h"
|
||||
#include "tonic/dart_library_provider_files.h"
|
||||
#include "tonic/dart_script_loader_sync.h"
|
||||
#include "tonic/dart_state.h"
|
||||
|
||||
const char kHelp[] = "help";
|
||||
const char kPackageRoot[] = "package-root";
|
||||
const char kSnapshot[] = "snapshot";
|
||||
|
||||
const uint8_t magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
|
||||
|
||||
void Usage() {
|
||||
std::cerr << "Usage: dart_snapshotter"
|
||||
<< " --" << kPackageRoot << " --" << kSnapshot
|
||||
<< " <dart-app>" << std::endl;
|
||||
}
|
||||
|
||||
void WriteSnapshot(base::FilePath path) {
|
||||
uint8_t* buffer;
|
||||
intptr_t size;
|
||||
CHECK(!tonic::LogIfError(Dart_CreateScriptSnapshot(&buffer, &size)));
|
||||
|
||||
intptr_t magic_number_len = sizeof(magic_number);
|
||||
CHECK_EQ(base::WriteFile(
|
||||
path, reinterpret_cast<const char*>(magic_number), sizeof(magic_number)),
|
||||
magic_number_len);
|
||||
CHECK(base::AppendToFile(
|
||||
path, reinterpret_cast<const char*>(buffer), size));
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
base::AtExitManager exit_manager;
|
||||
base::EnableTerminationOnHeapCorruption();
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (command_line.HasSwitch(kHelp) || command_line.GetArgs().empty()) {
|
||||
Usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize mojo.
|
||||
// TODO(vtl): Use make_unique when C++14 is available.
|
||||
mojo::embedder::Init(std::unique_ptr<mojo::embedder::PlatformSupport>(
|
||||
new mojo::embedder::SimplePlatformSupport()));
|
||||
|
||||
InitDartVM();
|
||||
|
||||
CHECK(command_line.HasSwitch(kPackageRoot)) << "Need --package-root";
|
||||
CHECK(command_line.HasSwitch(kSnapshot)) << "Need --snapshot";
|
||||
auto args = command_line.GetArgs();
|
||||
CHECK(args.size() == 1);
|
||||
|
||||
Dart_Isolate isolate = CreateDartIsolate();
|
||||
CHECK(isolate);
|
||||
|
||||
tonic::DartIsolateScope scope(isolate);
|
||||
tonic::DartApiScope api_scope;
|
||||
|
||||
auto isolate_data = SnapshotterDartState::Current();
|
||||
CHECK(isolate_data != nullptr);
|
||||
|
||||
// Use tonic's library tag handler.
|
||||
CHECK(!tonic::LogIfError(Dart_SetLibraryTagHandler(
|
||||
tonic::DartLibraryLoader::HandleLibraryTag)));
|
||||
|
||||
// Use tonic's file system library provider.
|
||||
isolate_data->set_library_provider(
|
||||
new tonic::DartLibraryProviderFiles(
|
||||
command_line.GetSwitchValuePath(kPackageRoot)));
|
||||
|
||||
// Load script.
|
||||
tonic::DartScriptLoaderSync::LoadScript(args[0],
|
||||
isolate_data->library_provider());
|
||||
|
||||
// Write snapshot.
|
||||
WriteSnapshot(command_line.GetSwitchValuePath(kSnapshot));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
SNAPSHOT_TEST_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
|
||||
SNAPSHOT_TEST_DIR))))
|
||||
DART_DIR = os.path.join(SRC_ROOT, 'dart')
|
||||
|
||||
VM_SNAPSHOT_FILES=[
|
||||
# Header files.
|
||||
'datastream.h',
|
||||
'object.h',
|
||||
'raw_object.h',
|
||||
'snapshot.h',
|
||||
'snapshot_ids.h',
|
||||
'symbols.h',
|
||||
# Source files.
|
||||
'dart.cc',
|
||||
'dart_api_impl.cc',
|
||||
'object.cc',
|
||||
'raw_object.cc',
|
||||
'raw_object_snapshot.cc',
|
||||
'snapshot.cc',
|
||||
'symbols.cc',
|
||||
]
|
||||
|
||||
def makeSnapshotHashString():
|
||||
vmhash = hashlib.md5()
|
||||
for vmfilename in VM_SNAPSHOT_FILES:
|
||||
vmfilepath = os.path.join(DART_DIR, 'runtime', 'vm', vmfilename)
|
||||
with open(vmfilepath) as vmfile:
|
||||
vmhash.update(vmfile.read())
|
||||
return vmhash.hexdigest()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Tests Dart snapshotting')
|
||||
parser.add_argument("--build-dir",
|
||||
dest="build_dir",
|
||||
metavar="<build-directory>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The directory containing the Mojo build.")
|
||||
args = parser.parse_args()
|
||||
dart_snapshotter = os.path.join(args.build_dir, 'dart_snapshotter')
|
||||
package_root = os.path.join(args.build_dir, 'gen', 'dart-pkg', 'packages')
|
||||
main_dart = os.path.join(
|
||||
args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_hello', 'lib', 'main.dart')
|
||||
snapshot = tempfile.mktemp()
|
||||
|
||||
if not os.path.isfile(dart_snapshotter):
|
||||
print "file not found: " + dart_snapshotter
|
||||
return 1
|
||||
subprocess.check_call([
|
||||
dart_snapshotter,
|
||||
main_dart,
|
||||
'--package-root=%s' % package_root,
|
||||
'--snapshot=%s' % snapshot,
|
||||
])
|
||||
if not os.path.isfile(snapshot):
|
||||
return 1
|
||||
|
||||
expected_hash = makeSnapshotHashString()
|
||||
actual_hash = ""
|
||||
with open(snapshot) as snapshot_file:
|
||||
snapshot_file.seek(20)
|
||||
actual_hash = snapshot_file.read(32)
|
||||
if not actual_hash == expected_hash:
|
||||
print ('wrong hash: actual = %s, expected = %s'
|
||||
% (actual_hash, expected_hash))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -1,44 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "mojo/dart/dart_snapshotter/vm.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "tonic/dart_error.h"
|
||||
#include "tonic/dart_state.h"
|
||||
|
||||
namespace mojo {
|
||||
namespace dart {
|
||||
extern const uint8_t* vm_isolate_snapshot_buffer;
|
||||
extern const uint8_t* isolate_snapshot_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* kDartArgs[] = {
|
||||
"--enable_mirrors=false",
|
||||
};
|
||||
|
||||
void InitDartVM() {
|
||||
CHECK(Dart_SetVMFlags(arraysize(kDartArgs), kDartArgs));
|
||||
CHECK(Dart_Initialize(mojo::dart::vm_isolate_snapshot_buffer, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr) == nullptr);
|
||||
}
|
||||
|
||||
Dart_Isolate CreateDartIsolate() {
|
||||
CHECK(mojo::dart::isolate_snapshot_buffer);
|
||||
char* error = nullptr;
|
||||
auto isolate_data = new SnapshotterDartState();
|
||||
CHECK(isolate_data != nullptr);
|
||||
Dart_Isolate isolate = Dart_CreateIsolate("dart:snapshot",
|
||||
"main",
|
||||
mojo::dart::isolate_snapshot_buffer,
|
||||
nullptr,
|
||||
isolate_data,
|
||||
&error);
|
||||
CHECK(isolate) << error;
|
||||
Dart_ExitIsolate();
|
||||
isolate_data->SetIsolate(isolate);
|
||||
return isolate;
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_DART_DART_SNAPSHOTTER_VM_H_
|
||||
#define MOJO_DART_DART_SNAPSHOTTER_VM_H_
|
||||
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "tonic/dart_library_provider.h"
|
||||
#include "tonic/dart_state.h"
|
||||
|
||||
class SnapshotterDartState : public tonic::DartState {
|
||||
public:
|
||||
SnapshotterDartState() : library_provider_(nullptr) {
|
||||
};
|
||||
|
||||
tonic::DartLibraryProvider* library_provider() const {
|
||||
return library_provider_.get();
|
||||
}
|
||||
|
||||
void set_library_provider(tonic::DartLibraryProvider* library_provider) {
|
||||
library_provider_.reset(library_provider);
|
||||
DCHECK(library_provider_.get() == library_provider);
|
||||
}
|
||||
|
||||
static SnapshotterDartState* From(Dart_Isolate isolate) {
|
||||
return reinterpret_cast<SnapshotterDartState*>(DartState::From(isolate));
|
||||
}
|
||||
|
||||
static SnapshotterDartState* Current() {
|
||||
return reinterpret_cast<SnapshotterDartState*>(DartState::Current());
|
||||
}
|
||||
|
||||
static SnapshotterDartState* Cast(void* data) {
|
||||
return reinterpret_cast<SnapshotterDartState*>(data);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<tonic::DartLibraryProvider> library_provider_;
|
||||
};
|
||||
|
||||
void InitDartVM();
|
||||
Dart_Isolate CreateDartIsolate();
|
||||
|
||||
#endif // MOJO_DART_DART_SNAPSHOTTER_VM_H_
|
||||
@ -1,20 +0,0 @@
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//mojo/public/dart/rules.gni")
|
||||
|
||||
dart_pkg("http_load_test") {
|
||||
apps = [ [
|
||||
"dart_http_load_test",
|
||||
"lib/main.dart",
|
||||
] ]
|
||||
sources = [
|
||||
"lib/src/part0.dart",
|
||||
"pubspec.yaml",
|
||||
]
|
||||
deps = [
|
||||
"//mojo/public/dart",
|
||||
"//mojo/dart/mojo_services",
|
||||
]
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
library http_load_test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
class Launcher {
|
||||
/// Launch [executable] with [arguments]. Returns a [String] containing
|
||||
/// the standard output from the launched executable.
|
||||
static Future<String> launch(String executable,
|
||||
List<String> arguments) async {
|
||||
var process = await Process.start(executable, arguments);
|
||||
|
||||
// Completer completes once the child process exits.
|
||||
var completer = new Completer();
|
||||
String output = '';
|
||||
process.stdout.transform(UTF8.decoder)
|
||||
.transform(new LineSplitter()).listen((line) {
|
||||
output = '$output\n$line';
|
||||
print(line);
|
||||
});
|
||||
process.stderr.transform(UTF8.decoder)
|
||||
.transform(new LineSplitter()).listen((line) {
|
||||
output = '$output\n$line';
|
||||
print(line);
|
||||
});
|
||||
process.exitCode.then((ec) {
|
||||
output = '$output\nEXIT_CODE=$ec\n';
|
||||
completer.complete(output);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
||||
main(List<String> args) async {
|
||||
var mojo_shell_executable = args[0];
|
||||
var directory = args[1];
|
||||
|
||||
HttpServer server = await HttpServer.bind('127.0.0.1', 0);
|
||||
|
||||
server.listen((HttpRequest request) async {
|
||||
final String path = request.uri.toFilePath();
|
||||
final File file = new File('${directory}/${path}');
|
||||
if (await file.exists()) {
|
||||
try {
|
||||
await file.openRead().pipe(request.response);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
} else {
|
||||
request.response.statusCode = HttpStatus.NOT_FOUND;
|
||||
request.response.close();
|
||||
}
|
||||
});
|
||||
|
||||
var launchUrl = 'http://127.0.0.1:${server.port}/lib/main.dart';
|
||||
var output = await Launcher.launch(mojo_shell_executable, [launchUrl]);
|
||||
|
||||
server.close();
|
||||
|
||||
if (output.contains("ERROR")) {
|
||||
throw "test failed.";
|
||||
}
|
||||
if (!output.contains("\nEXIT_CODE=0\n")) {
|
||||
throw "Test failed.";
|
||||
}
|
||||
if (!output.contains("\nPASS")) {
|
||||
throw "Test failed.";
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
#!mojo mojo:dart_content_handler
|
||||
|
||||
library test;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:mojo.internal';
|
||||
|
||||
import 'package:mojo_services/tracing/tracing.mojom.dart' as tracing;
|
||||
|
||||
part 'src/part0.dart';
|
||||
|
||||
main(List args) {
|
||||
// Hang around for a sec and then close the shell handle.
|
||||
new Timer(new Duration(milliseconds: 1000), () {
|
||||
print('PASS');
|
||||
MojoHandleNatives.close(args[0]);
|
||||
});
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
part of test;
|
||||
|
||||
String get foo => 'FOO';
|
||||
@ -1,3 +0,0 @@
|
||||
# Generated by pub
|
||||
# See http://pub.dartlang.org/doc/glossary.html#lockfile
|
||||
packages: {}
|
||||
@ -1 +0,0 @@
|
||||
name: mojo_dart_http_load_test
|
||||
@ -1,47 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""This script runs the Dart content handler http load test in the mojo tree."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
MOJO_SHELL = 'mojo_shell'
|
||||
|
||||
|
||||
def main(build_dir, dart_exe, tester_script, tester_dir):
|
||||
shell_exe = os.path.join(build_dir, MOJO_SHELL)
|
||||
subprocess.check_call([
|
||||
dart_exe,
|
||||
tester_script,
|
||||
shell_exe,
|
||||
tester_dir,
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description="List filenames of files in the packages/ subdir of the "
|
||||
"given directory.")
|
||||
parser.add_argument("--build-dir",
|
||||
dest="build_dir",
|
||||
metavar="<build-directory>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The directory containing mojo_shell.")
|
||||
parser.add_argument("--dart-exe",
|
||||
dest="dart_exe",
|
||||
metavar="<package-name>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="Path to dart executable.")
|
||||
args = parser.parse_args()
|
||||
tester_directory = os.path.dirname(os.path.realpath(__file__))
|
||||
tester_dart_script = os.path.join(tester_directory, 'bin', 'tester.dart')
|
||||
package_directory = os.path.join(
|
||||
args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_http_load_test')
|
||||
sys.exit(main(args.build_dir, args.dart_exe, tester_dart_script,
|
||||
package_directory))
|
||||
@ -1,19 +0,0 @@
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//mojo/public/dart/rules.gni")
|
||||
import("//mojo/services/mojo_services.gni")
|
||||
|
||||
dart_pkg("mojo_services") {
|
||||
sources = [
|
||||
"CHANGELOG.md",
|
||||
"README.md",
|
||||
"pubspec.yaml",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//mojo/public/dart",
|
||||
"//mojo/services",
|
||||
]
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
## 0.2.0
|
||||
|
||||
- 92 changes: https://github.com/domokit/mojo/compare/c1d7bc9...0894421
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- 0 changes: https://github.com/domokit/mojo/compare/86d3dc4...86d3dc4
|
||||
|
||||
Declare dependency on mojom and mojo 0.1.x
|
||||
|
||||
## 0.0.25
|
||||
|
||||
- 187 changes: https://github.com/domokit/mojo/compare/e5cc610...3139c74
|
||||
|
||||
## 0.0.23
|
||||
|
||||
## 0.0.22
|
||||
|
||||
- 58 changes: https://github.com/domokit/mojo/compare/e172885...35de44e
|
||||
|
||||
## 0.0.16
|
||||
|
||||
- 89 changes: https://github.com/domokit/mojo/compare/0fd4d06...c3119f6
|
||||
|
||||
## 0.0.15
|
||||
|
||||
- 18 changes: https://github.com/domokit/mojo/compare/e7433cf...8879bfd
|
||||
|
||||
## 0.0.14
|
||||
|
||||
- 27 changes: https://github.com/domokit/mojo/compare/e028733...e7433cf
|
||||
|
||||
## 0.0.13
|
||||
|
||||
- 6 changes: https://github.com/domokit/mojo/compare/4df2d39...e028733
|
||||
|
||||
## 0.0.12
|
||||
|
||||
- 138 changes: https://github.com/domokit/mojo/compare/850ac24...cf84c48
|
||||
|
||||
## 0.0.11
|
||||
|
||||
- 70 changes: https://github.com/domokit/mojo/compare/889091e...136e0d4
|
||||
|
||||
## 0.0.10
|
||||
|
||||
- 29 changes: https://github.com/domokit/mojo/compare/e25e3e2...432ce45
|
||||
|
||||
## 0.0.9
|
||||
|
||||
- 197 changes: https://github.com/domokit/mojo/compare/bdbb0c7...fb1b726
|
||||
|
||||
## 0.0.8
|
||||
|
||||
- 23 changes: https://github.com/domokit/mojo/compare/1b7bcee...be9dad7
|
||||
|
||||
## 0.0.6
|
||||
* Initial release
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
mojo_services
|
||||
====
|
||||
|
||||
This package contains generated bindings for mojo services
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
author: Chromium Authors <mojo-dev@googlegroups.com>
|
||||
dependencies:
|
||||
mojo: '>=0.2.0 <0.3.0'
|
||||
mojom: '>=0.2.0 <0.3.0'
|
||||
description: Generated bindings for mojo services
|
||||
homepage: https://github.com/domokit/mojo
|
||||
name: mojo_services
|
||||
version: 0.2.1
|
||||
2
mojo/dart/observatory_test/.gitignore
vendored
2
mojo/dart/observatory_test/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
packages
|
||||
pubspec.lock
|
||||
@ -1,18 +0,0 @@
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//mojo/public/dart/rules.gni")
|
||||
|
||||
dart_pkg("observatory_test") {
|
||||
apps = [ [
|
||||
"dart_observatory_test",
|
||||
"lib/main.dart",
|
||||
] ]
|
||||
sources = [
|
||||
"pubspec.yaml",
|
||||
]
|
||||
deps = [
|
||||
"//mojo/public/dart",
|
||||
]
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
void main(List args) {
|
||||
// Won't exit because we don't close the shell handle.
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
name: observatory_test
|
||||
dependencies:
|
||||
mojo: any
|
||||
@ -1,44 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""This script runs the Observatory tests in the mojo tree."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
MOJO_SHELL = 'mojo_shell'
|
||||
TESTEE = 'mojo:dart_observatory_test'
|
||||
|
||||
def main(build_dir, dart_exe, tester_script):
|
||||
shell_exe = os.path.join(build_dir, MOJO_SHELL)
|
||||
subprocess.check_call([
|
||||
dart_exe,
|
||||
tester_script,
|
||||
shell_exe,
|
||||
TESTEE
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description="List filenames of files in the packages/ subdir of the "
|
||||
"given directory.")
|
||||
parser.add_argument("--build-dir",
|
||||
dest="build_dir",
|
||||
metavar="<build-directory>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The directory containing mojo_shell.")
|
||||
parser.add_argument("--dart-exe",
|
||||
dest="dart_exe",
|
||||
metavar="<package-name>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="Path to dart executable.")
|
||||
args = parser.parse_args()
|
||||
tester_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
tester_dart_script = os.path.join(tester_dir, 'tester.dart');
|
||||
sys.exit(main(args.build_dir, args.dart_exe, tester_dart_script))
|
||||
@ -1,187 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
library observatory_tester;
|
||||
|
||||
// Minimal dependency Observatory heartbeat test.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
class Expect {
|
||||
static equals(a, b) {
|
||||
if (a != b) {
|
||||
throw 'Expected $a == $b';
|
||||
}
|
||||
}
|
||||
|
||||
static isMap(a) {
|
||||
if (a is! Map) {
|
||||
throw 'Expected $a to be a Map';
|
||||
}
|
||||
}
|
||||
|
||||
static notExecuted() {
|
||||
throw 'Should not have hit';
|
||||
}
|
||||
|
||||
static isNotNull(a) {
|
||||
if (a == null) {
|
||||
throw 'Expected $a to not be null.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Launch {
|
||||
Launch(this.executable, this.arguments, this.process, this.port) {
|
||||
_killRequested = false;
|
||||
this.process.exitCode.then(_checkKill);
|
||||
}
|
||||
|
||||
void kill() {
|
||||
_killRequested = true;
|
||||
process.kill();
|
||||
}
|
||||
|
||||
void _checkKill(int exitCode) {
|
||||
if (!_killRequested) {
|
||||
throw 'Unexpected exit of testee. (exitCode = $exitCode)';
|
||||
}
|
||||
}
|
||||
|
||||
final String executable;
|
||||
final String arguments;
|
||||
final Process process;
|
||||
final int port;
|
||||
bool _killRequested;
|
||||
}
|
||||
|
||||
class Launcher {
|
||||
/// Launch [executable] with [arguments]. Returns a future to a [Launch]
|
||||
/// which includes the process and port where Observatory is running.
|
||||
static Future<Launch> launch(String executable,
|
||||
List<String> arguments) async {
|
||||
var process = await Process.start(executable, arguments);
|
||||
|
||||
// Completer completes once 'Observatory listening on' message has been
|
||||
// scraped and we know the port number.
|
||||
var completer = new Completer();
|
||||
|
||||
process.stdout.transform(UTF8.decoder)
|
||||
.transform(new LineSplitter()).listen((line) {
|
||||
if (line.startsWith('Observatory listening on http://')) {
|
||||
RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
|
||||
var port = portExp.firstMatch(line).group(1);
|
||||
var portNumber = int.parse(port);
|
||||
completer.complete(portNumber);
|
||||
} else {
|
||||
print(line);
|
||||
}
|
||||
});
|
||||
|
||||
process.stderr.transform(UTF8.decoder)
|
||||
.transform(new LineSplitter()).listen((line) {
|
||||
print(line);
|
||||
});
|
||||
|
||||
var port = await completer.future;
|
||||
return new Launch(executable, arguments, process, port);
|
||||
}
|
||||
}
|
||||
|
||||
class ServiceHelper {
|
||||
ServiceHelper(this.client) {
|
||||
client.listen(_onData,
|
||||
onError: _onError,
|
||||
cancelOnError: true);
|
||||
}
|
||||
|
||||
Future<Map> invokeRPC(String method, [Map params]) async {
|
||||
var key = _createKey();
|
||||
var request = JSON.encode({
|
||||
'jsonrpc': '2.0',
|
||||
'method': method,
|
||||
'params': params == null ? {} : params,
|
||||
'id': key,
|
||||
});
|
||||
client.add(request);
|
||||
var completer = new Completer();
|
||||
_outstanding_requests[key] = completer;
|
||||
print('-> $key ($method)');
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
String _createKey() {
|
||||
var key = '$_id';
|
||||
_id++;
|
||||
return key;
|
||||
}
|
||||
|
||||
void _onData(String message) {
|
||||
var response = JSON.decode(message);
|
||||
var key = response['id'];
|
||||
print('<- $key');
|
||||
var completer = _outstanding_requests.remove(key);
|
||||
assert(completer != null);
|
||||
var result = response['result'];
|
||||
var error = response['error'];
|
||||
if (error != null) {
|
||||
assert(result == null);
|
||||
completer.completeError(error);
|
||||
} else {
|
||||
assert(result != null);
|
||||
completer.complete(result);
|
||||
}
|
||||
}
|
||||
|
||||
void _onError(error) {
|
||||
print('WebSocket error: $error');
|
||||
}
|
||||
|
||||
final WebSocket client;
|
||||
final Map<String, Completer> _outstanding_requests = <String, Completer>{};
|
||||
var _id = 1;
|
||||
}
|
||||
|
||||
main(List<String> args) async {
|
||||
var executable = args[0];
|
||||
var arguments = args.sublist(1);
|
||||
|
||||
print('Launching $executable with $arguments');
|
||||
|
||||
var launch = await Launcher.launch(executable, arguments);
|
||||
|
||||
print('Observatory is on port ${launch.port}');
|
||||
var serviceUrl = 'ws://127.0.0.1:${launch.port}/ws';
|
||||
|
||||
var client = await WebSocket.connect(serviceUrl);
|
||||
print('Connected to $serviceUrl');
|
||||
|
||||
var helper = new ServiceHelper(client);
|
||||
|
||||
// Invoke getVM RPC. Verify a valid repsonse.
|
||||
var vm = await helper.invokeRPC('getVM');
|
||||
Expect.equals(vm['type'], 'VM');
|
||||
|
||||
// Invoke a bogus RPC. Expect an error.
|
||||
bool errorCaught = false;
|
||||
try {
|
||||
var bad = await helper.invokeRPC('BARTSIMPSON');
|
||||
Expect.notExecuted();
|
||||
} catch (e) {
|
||||
errorCaught = true;
|
||||
// Map.
|
||||
Expect.isMap(e);
|
||||
// Has an error code.
|
||||
Expect.isNotNull(e['code']);
|
||||
}
|
||||
Expect.equals(errorCaught, true);
|
||||
|
||||
await client.close();
|
||||
print('Closed connection');
|
||||
|
||||
print('Finished.');
|
||||
launch.kill();
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mojo/core.dart';
|
||||
|
||||
main() async {
|
||||
var x = await (new Future.value(42));
|
||||
assert(x == 42);
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
main() {
|
||||
(new Future.value(42)).then((value) {
|
||||
assert(value == 42);
|
||||
});
|
||||
}
|
||||
@ -1,320 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/bindings.dart' as bindings;
|
||||
import 'package:mojo/core.dart' as core;
|
||||
import 'package:mojom/sample/sample_interfaces.mojom.dart' as sample;
|
||||
import 'package:mojom/mojo/test/test_structs.mojom.dart' as structs;
|
||||
import 'package:mojom/mojo/test/test_unions.mojom.dart' as unions;
|
||||
import 'package:mojom/mojo/test/rect.mojom.dart' as rect;
|
||||
import 'package:mojom/mojo/test/serialization_test_structs.mojom.dart' as serialization;
|
||||
import 'package:mojom/regression_tests/regression_tests.mojom.dart' as regression;
|
||||
|
||||
class ProviderImpl implements sample.Provider {
|
||||
sample.ProviderStub _stub;
|
||||
|
||||
ProviderImpl(core.MojoMessagePipeEndpoint endpoint) {
|
||||
_stub = new sample.ProviderStub.fromEndpoint(endpoint, this);
|
||||
}
|
||||
|
||||
echoString(String a, Function responseFactory) =>
|
||||
new Future.value(responseFactory(a));
|
||||
|
||||
echoStrings(String a, String b, Function responseFactory) =>
|
||||
new Future.value(responseFactory(a, b));
|
||||
|
||||
echoMessagePipeHanlde(core.MojoHandle a, Function responseFactory) =>
|
||||
new Future.value(responseFactory(a));
|
||||
|
||||
echoEnum(sample.Enum a, Function responseFactory) =>
|
||||
new Future.value(responseFactory(a));
|
||||
}
|
||||
|
||||
void providerIsolate(core.MojoMessagePipeEndpoint endpoint) {
|
||||
new ProviderImpl(endpoint);
|
||||
}
|
||||
|
||||
Future<bool> testCallResponse() {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var client = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
|
||||
var c = new Completer();
|
||||
Isolate.spawn(providerIsolate, pipe.endpoints[1]).then((_) {
|
||||
client.ptr.echoString("hello!").then((echoStringResponse) {
|
||||
Expect.equals("hello!", echoStringResponse.a);
|
||||
}).then((_) {
|
||||
client.ptr.echoStrings("hello", "mojo!").then((echoStringsResponse) {
|
||||
Expect.equals("hello", echoStringsResponse.a);
|
||||
Expect.equals("mojo!", echoStringsResponse.b);
|
||||
client.close().then((_) {
|
||||
c.complete(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return c.future;
|
||||
}
|
||||
|
||||
Future testAwaitCallResponse() async {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var client = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
|
||||
var isolate = await Isolate.spawn(providerIsolate, pipe.endpoints[1]);
|
||||
|
||||
var echoStringResponse = await client.ptr.echoString("hello!");
|
||||
Expect.equals("hello!", echoStringResponse.a);
|
||||
|
||||
var echoStringsResponse = await client.ptr.echoStrings("hello", "mojo!");
|
||||
Expect.equals("hello", echoStringsResponse.a);
|
||||
Expect.equals("mojo!", echoStringsResponse.b);
|
||||
|
||||
await client.close();
|
||||
}
|
||||
|
||||
bindings.ServiceMessage messageOfStruct(bindings.Struct s) =>
|
||||
s.serializeWithHeader(new bindings.MessageHeader(0));
|
||||
|
||||
testSerializeNamedRegion() {
|
||||
var r = new rect.Rect()
|
||||
..x = 1
|
||||
..y = 2
|
||||
..width = 3
|
||||
..height = 4;
|
||||
var namedRegion = new structs.NamedRegion()
|
||||
..name = "name"
|
||||
..rects = [r];
|
||||
var message = messageOfStruct(namedRegion);
|
||||
var namedRegion2 = structs.NamedRegion.deserialize(message.payload);
|
||||
Expect.equals(namedRegion.name, namedRegion2.name);
|
||||
}
|
||||
|
||||
testSerializeArrayValueTypes() {
|
||||
var arrayValues = new structs.ArrayValueTypes()
|
||||
..f0 = [0, 1, -1, 0x7f, -0x10]
|
||||
..f1 = [0, 1, -1, 0x7fff, -0x1000]
|
||||
..f2 = [0, 1, -1, 0x7fffffff, -0x10000000]
|
||||
..f3 = [0, 1, -1, 0x7fffffffffffffff, -0x1000000000000000]
|
||||
..f4 = [0.0, 1.0, -1.0, 4.0e9, -4.0e9]
|
||||
..f5 = [0.0, 1.0, -1.0, 4.0e9, -4.0e9];
|
||||
var message = messageOfStruct(arrayValues);
|
||||
var arrayValues2 = structs.ArrayValueTypes.deserialize(message.payload);
|
||||
Expect.listEquals(arrayValues.f0, arrayValues2.f0);
|
||||
Expect.listEquals(arrayValues.f1, arrayValues2.f1);
|
||||
Expect.listEquals(arrayValues.f2, arrayValues2.f2);
|
||||
Expect.listEquals(arrayValues.f3, arrayValues2.f3);
|
||||
Expect.listEquals(arrayValues.f4, arrayValues2.f4);
|
||||
Expect.listEquals(arrayValues.f5, arrayValues2.f5);
|
||||
}
|
||||
|
||||
testSerializeToJSON() {
|
||||
var r = new rect.Rect()
|
||||
..x = 1
|
||||
..y = 2
|
||||
..width = 3
|
||||
..height = 4;
|
||||
|
||||
var encodedRect = JSON.encode(r);
|
||||
var goldenEncoding = "{\"x\":1,\"y\":2,\"width\":3,\"height\":4}";
|
||||
Expect.equals(goldenEncoding, encodedRect);
|
||||
}
|
||||
|
||||
testSerializeHandleToJSON() {
|
||||
var s = new serialization.Struct2();
|
||||
|
||||
Expect.throws(() => JSON.encode(s),
|
||||
(e) => e.cause is bindings.MojoCodecError);
|
||||
}
|
||||
|
||||
testSerializeStructs() {
|
||||
testSerializeNamedRegion();
|
||||
testSerializeArrayValueTypes();
|
||||
testSerializeToJSON();
|
||||
testSerializeHandleToJSON();
|
||||
}
|
||||
|
||||
testSerializePodUnions() {
|
||||
var s = new unions.WrapperStruct()
|
||||
..podUnion = new unions.PodUnion();
|
||||
s.podUnion.fUint32 = 32;
|
||||
|
||||
Expect.equals(unions.PodUnionTag.fUint32, s.podUnion.tag);
|
||||
Expect.equals(32, s.podUnion.fUint32);
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
var s2 = unions.WrapperStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(s.podUnion.fUint32, s2.podUnion.fUint32);
|
||||
}
|
||||
|
||||
testSerializeStructInUnion() {
|
||||
var s = new unions.WrapperStruct()
|
||||
..objectUnion = new unions.ObjectUnion();
|
||||
s.objectUnion.fDummy = new unions.DummyStruct()
|
||||
..fInt8 = 8;
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
var s2 = unions.WrapperStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(s.objectUnion.fDummy.fInt8, s2.objectUnion.fDummy.fInt8);
|
||||
}
|
||||
|
||||
testSerializeArrayInUnion() {
|
||||
var s = new unions.WrapperStruct()
|
||||
..objectUnion = new unions.ObjectUnion();
|
||||
s.objectUnion.fArrayInt8 = [1, 2, 3];
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
var s2 = unions.WrapperStruct.deserialize(message.payload);
|
||||
|
||||
Expect.listEquals(s.objectUnion.fArrayInt8, s2.objectUnion.fArrayInt8);
|
||||
}
|
||||
|
||||
testSerializeMapInUnion() {
|
||||
var s = new unions.WrapperStruct()
|
||||
..objectUnion = new unions.ObjectUnion();
|
||||
s.objectUnion.fMapInt8 = {
|
||||
"one": 1,
|
||||
"two": 2,
|
||||
};
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
var s2 = unions.WrapperStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(1, s.objectUnion.fMapInt8["one"]);
|
||||
Expect.equals(2, s.objectUnion.fMapInt8["two"]);
|
||||
}
|
||||
|
||||
testSerializeUnionInArray() {
|
||||
var s = new unions.SmallStruct()
|
||||
..podUnionArray = [
|
||||
new unions.PodUnion()
|
||||
..fUint16 = 16,
|
||||
new unions.PodUnion()
|
||||
..fUint32 = 32,
|
||||
];
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
|
||||
var s2 = unions.SmallStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(16, s2.podUnionArray[0].fUint16);
|
||||
Expect.equals(32, s2.podUnionArray[1].fUint32);
|
||||
}
|
||||
|
||||
testSerializeUnionInMap() {
|
||||
var s = new unions.SmallStruct()
|
||||
..podUnionMap = {
|
||||
'one': new unions.PodUnion()
|
||||
..fUint16 = 16,
|
||||
'two': new unions.PodUnion()
|
||||
..fUint32 = 32,
|
||||
};
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
|
||||
var s2 = unions.SmallStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(16, s2.podUnionMap['one'].fUint16);
|
||||
Expect.equals(32, s2.podUnionMap['two'].fUint32);
|
||||
}
|
||||
|
||||
testSerializeUnionInUnion() {
|
||||
var s = new unions.WrapperStruct()
|
||||
..objectUnion = new unions.ObjectUnion();
|
||||
s.objectUnion.fPodUnion = new unions.PodUnion()
|
||||
..fUint32 = 32;
|
||||
|
||||
var message = messageOfStruct(s);
|
||||
var s2 = unions.WrapperStruct.deserialize(message.payload);
|
||||
|
||||
Expect.equals(32, s2.objectUnion.fPodUnion.fUint32);
|
||||
}
|
||||
|
||||
testUnionsToString() {
|
||||
var podUnion = new unions.PodUnion();
|
||||
podUnion.fUint32 = 32;
|
||||
Expect.equals("PodUnion(fUint32: 32)", podUnion.toString());
|
||||
}
|
||||
|
||||
testUnions() {
|
||||
testSerializePodUnions();
|
||||
testSerializeStructInUnion();
|
||||
testSerializeArrayInUnion();
|
||||
testSerializeMapInUnion();
|
||||
testSerializeUnionInArray();
|
||||
testSerializeUnionInMap();
|
||||
testSerializeUnionInUnion();
|
||||
testUnionsToString();
|
||||
}
|
||||
|
||||
class CheckEnumCapsImpl implements regression.CheckEnumCaps {
|
||||
regression.CheckEnumCapsStub _stub;
|
||||
|
||||
CheckEnumCapsImpl(core.MojoMessagePipeEndpoint endpoint) {
|
||||
_stub = new regression.CheckEnumCapsStub.fromEndpoint(endpoint, this);
|
||||
}
|
||||
|
||||
setEnumWithInternalAllCaps(regression.EnumWithInternalAllCaps e) {}
|
||||
}
|
||||
|
||||
checkEnumCapsIsolate(core.MojoMessagePipeEndpoint endpoint) {
|
||||
new CheckEnumCapsImpl(endpoint);
|
||||
}
|
||||
|
||||
testCheckEnumCapsImpl() {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var client =
|
||||
new regression.CheckEnumCapsProxy.fromEndpoint(pipe.endpoints[0]);
|
||||
var c = new Completer();
|
||||
Isolate.spawn(checkEnumCapsIsolate, pipe.endpoints[1]).then((_) {
|
||||
client.ptr.setEnumWithInternalAllCaps(
|
||||
regression.EnumWithInternalAllCaps.STANDARD);
|
||||
client.close().then((_) {
|
||||
c.complete(null);
|
||||
});
|
||||
});
|
||||
return c.future;
|
||||
}
|
||||
|
||||
testSerializeEnum() {
|
||||
var constants = new structs.ScopedConstants();
|
||||
constants.f4 = structs.ScopedConstantsEType.E0;
|
||||
var message = messageOfStruct(constants);
|
||||
var constants2 = structs.ScopedConstants.deserialize(message.payload);
|
||||
Expect.equals(constants.f4.value, constants2.f4.value);
|
||||
}
|
||||
|
||||
testEnums() async {
|
||||
testSerializeEnum();
|
||||
await testCheckEnumCapsImpl();
|
||||
}
|
||||
|
||||
void closingProviderIsolate(core.MojoMessagePipeEndpoint endpoint) {
|
||||
var provider = new ProviderImpl(endpoint);
|
||||
provider._stub.close();
|
||||
}
|
||||
|
||||
Future<bool> runOnClosedTest() {
|
||||
var testCompleter = new Completer();
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var proxy = new sample.ProviderProxy.fromEndpoint(pipe.endpoints[0]);
|
||||
proxy.impl.onError = () => testCompleter.complete(true);
|
||||
Isolate.spawn(closingProviderIsolate, pipe.endpoints[1]);
|
||||
return testCompleter.future.then((b) {
|
||||
Expect.isTrue(b);
|
||||
});
|
||||
}
|
||||
|
||||
main() async {
|
||||
testSerializeStructs();
|
||||
testUnions();
|
||||
await testEnums();
|
||||
await testCallResponse();
|
||||
await testAwaitCallResponse();
|
||||
await runOnClosedTest();
|
||||
}
|
||||
@ -1,746 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/bindings.dart' as bindings;
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
||||
class Bar extends bindings.Struct {
|
||||
static const int kStructSize = 16;
|
||||
static const bindings.StructDataHeader kDefaultStructInfo =
|
||||
const bindings.StructDataHeader(kStructSize, 4);
|
||||
|
||||
static final int Type_VERTICAL = 1;
|
||||
static final int Type_HORIZONTAL = Type_VERTICAL + 1;
|
||||
static final int Type_BOTH = Type_HORIZONTAL + 1;
|
||||
static final int Type_INVALID = Type_BOTH + 1;
|
||||
int alpha;
|
||||
int beta;
|
||||
int gamma;
|
||||
int type;
|
||||
|
||||
Bar() : super(kStructSize) {
|
||||
alpha = 0xff;
|
||||
type = Bar.Type_VERTICAL;
|
||||
}
|
||||
|
||||
static Bar deserialize(bindings.Message message) {
|
||||
return decode(new bindings.Decoder(message));
|
||||
}
|
||||
|
||||
static Bar decode(bindings.Decoder decoder0) {
|
||||
if (decoder0 == null) {
|
||||
return null;
|
||||
}
|
||||
Bar result = new Bar();
|
||||
var mainDataHeader = decoder0.decodeStructDataHeader();
|
||||
if (mainDataHeader.version > 0) {
|
||||
result.alpha = decoder0.decodeUint8(8);
|
||||
}
|
||||
if (mainDataHeader.version > 1) {
|
||||
result.beta = decoder0.decodeUint8(9);
|
||||
}
|
||||
if (mainDataHeader.version > 2) {
|
||||
result.gamma = decoder0.decodeUint8(10);
|
||||
}
|
||||
if (mainDataHeader.version > 3) {
|
||||
result.type = decoder0.decodeInt32(12);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void encode(bindings.Encoder encoder) {
|
||||
var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo);
|
||||
encoder0.encodeUint8(alpha, 8);
|
||||
encoder0.encodeUint8(beta, 9);
|
||||
encoder0.encodeUint8(gamma, 10);
|
||||
encoder0.encodeInt32(type, 12);
|
||||
}
|
||||
}
|
||||
|
||||
void testBar() {
|
||||
var bar = new Bar();
|
||||
bar.alpha = 1;
|
||||
bar.beta = 2;
|
||||
bar.gamma = 3;
|
||||
bar.type = 0x08070605;
|
||||
|
||||
int name = 42;
|
||||
var header = new bindings.MessageHeader(name);
|
||||
var message = bar.serializeWithHeader(header);
|
||||
|
||||
var expectedMemory = new Uint8List.fromList([
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
42,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
0,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
]);
|
||||
|
||||
var actualMemory = message.buffer.buffer.asUint8List();
|
||||
Expect.listEquals(expectedMemory, actualMemory);
|
||||
|
||||
var receivedMessage = new bindings.ServiceMessage.fromMessage(message);
|
||||
|
||||
Expect.equals(receivedMessage.header.size, header.size);
|
||||
Expect.equals(receivedMessage.header.type, header.type);
|
||||
|
||||
var bar2 = Bar.deserialize(receivedMessage.payload);
|
||||
|
||||
Expect.equals(bar.alpha, bar2.alpha);
|
||||
Expect.equals(bar.beta, bar2.beta);
|
||||
Expect.equals(bar.gamma, bar2.gamma);
|
||||
Expect.equals(bar.type, bar2.type);
|
||||
}
|
||||
|
||||
class Foo extends bindings.Struct {
|
||||
static const int kStructSize = 96;
|
||||
static const bindings.StructDataHeader kDefaultStructInfo =
|
||||
const bindings.StructDataHeader(kStructSize, 15);
|
||||
static final kFooby = "Fooby";
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
bool a = true;
|
||||
bool b = false;
|
||||
bool c = false;
|
||||
core.MojoHandle source = null;
|
||||
Bar bar = null;
|
||||
List<int> data = null;
|
||||
List<Bar> extraBars = null;
|
||||
String name = Foo.kFooby;
|
||||
List<core.MojoHandle> inputStreams = null;
|
||||
List<core.MojoHandle> outputStreams = null;
|
||||
List<List<bool>> arrayOfArrayOfBools = null;
|
||||
List<List<List<String>>> multiArrayOfStrings = null;
|
||||
List<bool> arrayOfBools = null;
|
||||
|
||||
Foo() : super(kStructSize);
|
||||
|
||||
static Foo deserialize(bindings.Message message) {
|
||||
return decode(new bindings.Decoder(message));
|
||||
}
|
||||
|
||||
static Foo decode(bindings.Decoder decoder0) {
|
||||
if (decoder0 == null) {
|
||||
return null;
|
||||
}
|
||||
Foo result = new Foo();
|
||||
var mainDataHeader = decoder0.decodeStructDataHeader();
|
||||
if (mainDataHeader.version > 0) {
|
||||
result.x = decoder0.decodeInt32(8);
|
||||
}
|
||||
if (mainDataHeader.version > 1) {
|
||||
result.y = decoder0.decodeInt32(12);
|
||||
}
|
||||
if (mainDataHeader.version > 2) {
|
||||
result.a = decoder0.decodeBool(16, 0);
|
||||
}
|
||||
if (mainDataHeader.version > 3) {
|
||||
result.b = decoder0.decodeBool(16, 1);
|
||||
}
|
||||
if (mainDataHeader.version > 4) {
|
||||
result.c = decoder0.decodeBool(16, 2);
|
||||
}
|
||||
if (mainDataHeader.version > 9) {
|
||||
result.source = decoder0.decodeHandle(20, true);
|
||||
}
|
||||
if (mainDataHeader.version > 5) {
|
||||
var decoder1 = decoder0.decodePointer(24, true);
|
||||
result.bar = Bar.decode(decoder1);
|
||||
}
|
||||
if (mainDataHeader.version > 6) {
|
||||
result.data = decoder0.decodeUint8Array(
|
||||
32, bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
if (mainDataHeader.version > 7) {
|
||||
var decoder1 = decoder0.decodePointer(40, true);
|
||||
if (decoder1 == null) {
|
||||
result.extraBars = null;
|
||||
} else {
|
||||
var si1 = decoder1
|
||||
.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
|
||||
result.extraBars = new List<Bar>(si1.numElements);
|
||||
for (int i1 = 0; i1 < si1.numElements; ++i1) {
|
||||
var decoder2 = decoder1.decodePointer(
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1,
|
||||
false);
|
||||
result.extraBars[i1] = Bar.decode(decoder2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mainDataHeader.version > 8) {
|
||||
result.name = decoder0.decodeString(48, false);
|
||||
}
|
||||
if (mainDataHeader.version > 10) {
|
||||
result.inputStreams = decoder0.decodeHandleArray(
|
||||
56, bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
if (mainDataHeader.version > 11) {
|
||||
result.outputStreams = decoder0.decodeHandleArray(
|
||||
64, bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
if (mainDataHeader.version > 12) {
|
||||
var decoder1 = decoder0.decodePointer(72, true);
|
||||
if (decoder1 == null) {
|
||||
result.arrayOfArrayOfBools = null;
|
||||
} else {
|
||||
var si1 = decoder1
|
||||
.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
|
||||
result.arrayOfArrayOfBools = new List<List<bool>>(si1.numElements);
|
||||
for (int i1 = 0; i1 < si1.numElements; ++i1) {
|
||||
result.arrayOfArrayOfBools[i1] = decoder1.decodeBoolArray(
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1,
|
||||
bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mainDataHeader.version > 13) {
|
||||
var decoder1 = decoder0.decodePointer(80, true);
|
||||
if (decoder1 == null) {
|
||||
result.multiArrayOfStrings = null;
|
||||
} else {
|
||||
var si1 = decoder1
|
||||
.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
|
||||
result.multiArrayOfStrings =
|
||||
new List<List<List<String>>>(si1.numElements);
|
||||
for (int i1 = 0; i1 < si1.numElements; ++i1) {
|
||||
var decoder2 = decoder1.decodePointer(
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1,
|
||||
false);
|
||||
{
|
||||
var si2 = decoder2.decodeDataHeaderForPointerArray(
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
result.multiArrayOfStrings[i1] =
|
||||
new List<List<String>>(si2.numElements);
|
||||
for (int i2 = 0; i2 < si2.numElements; ++i2) {
|
||||
var decoder3 = decoder2.decodePointer(
|
||||
bindings.ArrayDataHeader.kHeaderSize +
|
||||
bindings.kPointerSize * i2, false);
|
||||
{
|
||||
var si3 = decoder3.decodeDataHeaderForPointerArray(
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
result.multiArrayOfStrings[i1][i2] =
|
||||
new List<String>(si3.numElements);
|
||||
for (int i3 = 0; i3 < si3.numElements; ++i3) {
|
||||
var length = bindings.ArrayDataHeader.kHeaderSize +
|
||||
bindings.kPointerSize * i3;
|
||||
result.multiArrayOfStrings[i1][i2][i3] =
|
||||
decoder3.decodeString(length, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mainDataHeader.version > 14) {
|
||||
result.arrayOfBools = decoder0.decodeBoolArray(
|
||||
88, bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void encode(bindings.Encoder encoder) {
|
||||
var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo);
|
||||
encoder0.encodeInt32(x, 8);
|
||||
encoder0.encodeInt32(y, 12);
|
||||
encoder0.encodeBool(a, 16, 0);
|
||||
encoder0.encodeBool(b, 16, 1);
|
||||
encoder0.encodeBool(c, 16, 2);
|
||||
encoder0.encodeHandle(source, 20, true);
|
||||
encoder0.encodeStruct(bar, 24, true);
|
||||
encoder0.encodeUint8Array(
|
||||
data, 32, bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
|
||||
if (extraBars == null) {
|
||||
encoder0.encodeNullPointer(40, true);
|
||||
} else {
|
||||
var encoder1 = encoder0.encodePointerArray(
|
||||
extraBars.length, 40, bindings.kUnspecifiedArrayLength);
|
||||
for (int i0 = 0; i0 < extraBars.length; ++i0) {
|
||||
encoder1.encodeStruct(extraBars[i0],
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
encoder0.encodeString(name, 48, false);
|
||||
encoder0.encodeHandleArray(inputStreams, 56,
|
||||
bindings.kArrayNullable, bindings.kUnspecifiedArrayLength);
|
||||
encoder0.encodeHandleArray(outputStreams, 64, bindings.kArrayNullable,
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
|
||||
if (arrayOfArrayOfBools == null) {
|
||||
encoder0.encodeNullPointer(72, true);
|
||||
} else {
|
||||
var encoder1 = encoder0.encodePointerArray(
|
||||
arrayOfArrayOfBools.length, 72, bindings.kUnspecifiedArrayLength);
|
||||
for (int i0 = 0; i0 < arrayOfArrayOfBools.length; ++i0) {
|
||||
encoder1.encodeBoolArray(arrayOfArrayOfBools[i0],
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0,
|
||||
bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (multiArrayOfStrings == null) {
|
||||
encoder0.encodeNullPointer(80, true);
|
||||
} else {
|
||||
var encoder1 = encoder0.encodePointerArray(
|
||||
multiArrayOfStrings.length, 80, bindings.kUnspecifiedArrayLength);
|
||||
for (int i0 = 0; i0 < multiArrayOfStrings.length; ++i0) {
|
||||
if (multiArrayOfStrings[i0] == null) {
|
||||
encoder1.encodeNullPointer(
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0,
|
||||
false);
|
||||
} else {
|
||||
var encoder2 = encoder1.encodePointerArray(
|
||||
multiArrayOfStrings[i0].length,
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0,
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
for (int i1 = 0; i1 < multiArrayOfStrings[i0].length; ++i1) {
|
||||
if (multiArrayOfStrings[i0][i1] == null) {
|
||||
encoder2.encodeNullPointer(bindings.ArrayDataHeader.kHeaderSize +
|
||||
bindings.kPointerSize * i1, false);
|
||||
} else {
|
||||
var encoder3 = encoder2.encodePointerArray(
|
||||
multiArrayOfStrings[i0][i1].length,
|
||||
bindings.ArrayDataHeader.kHeaderSize +
|
||||
bindings.kPointerSize * i1,
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
for (int i2 = 0; i2 < multiArrayOfStrings[i0][i1].length; ++i2) {
|
||||
var length = bindings.ArrayDataHeader.kHeaderSize +
|
||||
bindings.kPointerSize * i2;
|
||||
encoder3.encodeString(
|
||||
multiArrayOfStrings[i0][i1][i2], length, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder0.encodeBoolArray(arrayOfBools, 88, bindings.kArrayNullable,
|
||||
bindings.kUnspecifiedArrayLength);
|
||||
}
|
||||
}
|
||||
|
||||
void testFoo() {
|
||||
var foo = new Foo();
|
||||
foo.x = 0x212B4D5;
|
||||
foo.y = 0x16E93;
|
||||
foo.a = true;
|
||||
foo.b = false;
|
||||
foo.c = true;
|
||||
foo.bar = new Bar();
|
||||
foo.bar.alpha = 91;
|
||||
foo.bar.beta = 82;
|
||||
foo.bar.gamma = 73;
|
||||
foo.data = [4, 5, 6, 7, 8,];
|
||||
foo.extraBars = [new Bar(), new Bar(), new Bar(),];
|
||||
for (int i = 0; i < foo.extraBars.length; ++i) {
|
||||
foo.extraBars[i].alpha = 1 * i;
|
||||
foo.extraBars[i].beta = 2 * i;
|
||||
foo.extraBars[i].gamma = 3 * i;
|
||||
}
|
||||
foo.name = "I am a banana";
|
||||
// This is supposed to be a handle, but we fake it with an integer.
|
||||
foo.source = new core.MojoHandle(23423782);
|
||||
foo.arrayOfArrayOfBools = [[true], [false, true]];
|
||||
foo.arrayOfBools = [true, false, true, false, true, false, true, true];
|
||||
|
||||
int name = 31;
|
||||
var header = new bindings.MessageHeader(name);
|
||||
var message = foo.serializeWithHeader(header);
|
||||
|
||||
var expectedMemory = new Uint8List.fromList([
|
||||
/* 0: */ 16,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 8: */ 31,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 16: */ 96,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 24: */ 0xD5,
|
||||
0xB4,
|
||||
0x12,
|
||||
0x02,
|
||||
0x93,
|
||||
0x6E,
|
||||
0x01,
|
||||
0,
|
||||
/* 32: */ 5,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 40: */ 72,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]);
|
||||
|
||||
var allActualMemory = message.buffer.buffer.asUint8List();
|
||||
var actualMemory = allActualMemory.sublist(0, expectedMemory.length);
|
||||
Expect.listEquals(expectedMemory, actualMemory);
|
||||
|
||||
var expectedHandles = <core.MojoHandle>[new core.MojoHandle(23423782),];
|
||||
|
||||
Expect.listEquals(expectedHandles, message.handles);
|
||||
|
||||
var receivedMessage = new bindings.ServiceMessage.fromMessage(message);
|
||||
|
||||
Expect.equals(receivedMessage.header.size, header.size);
|
||||
Expect.equals(receivedMessage.header.type, header.type);
|
||||
|
||||
var foo2 = Foo.deserialize(receivedMessage.payload);
|
||||
|
||||
Expect.equals(foo.x, foo2.x);
|
||||
Expect.equals(foo.y, foo2.y);
|
||||
|
||||
Expect.equals(foo.a, foo2.a);
|
||||
Expect.equals(foo.b, foo2.b);
|
||||
Expect.equals(foo.c, foo2.c);
|
||||
|
||||
Expect.equals(foo.bar.alpha, foo2.bar.alpha);
|
||||
Expect.equals(foo.bar.beta, foo2.bar.beta);
|
||||
Expect.equals(foo.bar.gamma, foo2.bar.gamma);
|
||||
Expect.equals(foo.bar.type, foo2.bar.type);
|
||||
Expect.listEquals(foo.data, foo2.data);
|
||||
|
||||
for (int i = 0; i < foo2.extraBars.length; i++) {
|
||||
Expect.equals(foo.extraBars[i].alpha, foo2.extraBars[i].alpha);
|
||||
Expect.equals(foo.extraBars[i].beta, foo2.extraBars[i].beta);
|
||||
Expect.equals(foo.extraBars[i].gamma, foo2.extraBars[i].gamma);
|
||||
Expect.equals(foo.extraBars[i].type, foo2.extraBars[i].type);
|
||||
}
|
||||
|
||||
Expect.equals(foo.name, foo2.name);
|
||||
Expect.equals(foo.source, foo2.source);
|
||||
|
||||
Expect.listEquals(foo.arrayOfBools, foo2.arrayOfBools);
|
||||
for (int i = 0; i < foo2.arrayOfArrayOfBools.length; i++) {
|
||||
Expect.listEquals(foo.arrayOfArrayOfBools[i], foo2.arrayOfArrayOfBools[i]);
|
||||
}
|
||||
}
|
||||
|
||||
class Rect extends bindings.Struct {
|
||||
static const int kStructSize = 24;
|
||||
static const bindings.StructDataHeader kDefaultStructInfo =
|
||||
const bindings.StructDataHeader(kStructSize, 4);
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
Rect() : super(kStructSize);
|
||||
|
||||
static Rect deserialize(bindings.Message message) {
|
||||
return decode(new bindings.Decoder(message));
|
||||
}
|
||||
|
||||
static Rect decode(bindings.Decoder decoder0) {
|
||||
if (decoder0 == null) {
|
||||
return null;
|
||||
}
|
||||
Rect result = new Rect();
|
||||
var mainDataHeader = decoder0.decodeStructDataHeader();
|
||||
if (mainDataHeader.version > 0) {
|
||||
result.x = decoder0.decodeInt32(8);
|
||||
}
|
||||
if (mainDataHeader.version > 1) {
|
||||
result.y = decoder0.decodeInt32(12);
|
||||
}
|
||||
if (mainDataHeader.version > 2) {
|
||||
result.width = decoder0.decodeInt32(16);
|
||||
}
|
||||
if (mainDataHeader.version > 3) {
|
||||
result.height = decoder0.decodeInt32(20);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void encode(bindings.Encoder encoder) {
|
||||
var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo);
|
||||
encoder0.encodeInt32(x, 8);
|
||||
encoder0.encodeInt32(y, 12);
|
||||
encoder0.encodeInt32(width, 16);
|
||||
encoder0.encodeInt32(height, 20);
|
||||
}
|
||||
|
||||
bool operator ==(Rect other) => (this.x == other.x) &&
|
||||
(this.y == other.y) &&
|
||||
(this.width == other.width) &&
|
||||
(this.height == other.height);
|
||||
}
|
||||
|
||||
Rect createRect(int x, int y, int width, int height) {
|
||||
var r = new Rect();
|
||||
r.x = x;
|
||||
r.y = y;
|
||||
r.width = width;
|
||||
r.height = height;
|
||||
return r;
|
||||
}
|
||||
|
||||
class NamedRegion extends bindings.Struct {
|
||||
static const int kStructSize = 24;
|
||||
static const bindings.StructDataHeader kDefaultStructInfo =
|
||||
const bindings.StructDataHeader(kStructSize, 2);
|
||||
String name;
|
||||
List<Rect> rects;
|
||||
|
||||
NamedRegion() : super(kStructSize);
|
||||
|
||||
static NamedRegion deserialize(bindings.Message message) {
|
||||
return decode(new bindings.Decoder(message));
|
||||
}
|
||||
|
||||
static NamedRegion decode(bindings.Decoder decoder0) {
|
||||
if (decoder0 == null) {
|
||||
return null;
|
||||
}
|
||||
NamedRegion result = new NamedRegion();
|
||||
var mainDataHeader = decoder0.decodeStructDataHeader();
|
||||
if (mainDataHeader.version > 0) {
|
||||
result.name = decoder0.decodeString(8, true);
|
||||
}
|
||||
if (mainDataHeader.version > 1) {
|
||||
var decoder1 = decoder0.decodePointer(16, true);
|
||||
if (decoder1 == null) {
|
||||
result.rects = null;
|
||||
} else {
|
||||
var si1 = decoder1
|
||||
.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
|
||||
result.rects = new List<Rect>(si1.numElements);
|
||||
for (int i1 = 0; i1 < si1.numElements; ++i1) {
|
||||
var decoder2 = decoder1.decodePointer(
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1,
|
||||
false);
|
||||
result.rects[i1] = Rect.decode(decoder2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void encode(bindings.Encoder encoder) {
|
||||
var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo);
|
||||
encoder0.encodeString(name, 8, true);
|
||||
if (rects == null) {
|
||||
encoder0.encodeNullPointer(16, true);
|
||||
} else {
|
||||
var encoder1 = encoder0.encodePointerArray(
|
||||
rects.length, 16, bindings.kUnspecifiedArrayLength);
|
||||
for (int i0 = 0; i0 < rects.length; ++i0) {
|
||||
encoder1.encodeStruct(rects[i0],
|
||||
bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testNamedRegion() {
|
||||
var r = new NamedRegion();
|
||||
r.name = "rectangle";
|
||||
r.rects = [createRect(1, 2, 3, 4), createRect(10, 20, 30, 40)];
|
||||
|
||||
int name = 1;
|
||||
var header = new bindings.MessageHeader(name);
|
||||
var message = r.serializeWithHeader(header);
|
||||
var resultMessage = new bindings.ServiceMessage.fromMessage(message);
|
||||
var result = NamedRegion.deserialize(resultMessage.payload);
|
||||
|
||||
Expect.equals("rectangle", result.name);
|
||||
Expect.equals(createRect(1, 2, 3, 4), result.rects[0]);
|
||||
Expect.equals(createRect(10, 20, 30, 40), result.rects[1]);
|
||||
}
|
||||
|
||||
void testAlign() {
|
||||
List aligned = [
|
||||
0, // 0
|
||||
8, // 1
|
||||
8, // 2
|
||||
8, // 3
|
||||
8, // 4
|
||||
8, // 5
|
||||
8, // 6
|
||||
8, // 7
|
||||
8, // 8
|
||||
16, // 9
|
||||
16, // 10
|
||||
16, // 11
|
||||
16, // 12
|
||||
16, // 13
|
||||
16, // 14
|
||||
16, // 15
|
||||
16, // 16
|
||||
24, // 17
|
||||
24, // 18
|
||||
24, // 19
|
||||
24, // 20
|
||||
];
|
||||
for (int i = 0; i < aligned.length; ++i) {
|
||||
Expect.equals(bindings.align(i), aligned[i]);
|
||||
}
|
||||
}
|
||||
|
||||
class MojoString extends bindings.Struct {
|
||||
static const int kStructSize = 16;
|
||||
static const bindings.StructDataHeader kDefaultStructInfo =
|
||||
const bindings.StructDataHeader(kStructSize, 1);
|
||||
String string;
|
||||
MojoString() : super(kStructSize);
|
||||
|
||||
static MojoString deserialize(bindings.Message message) {
|
||||
return decode(new bindings.Decoder(message));
|
||||
}
|
||||
|
||||
static MojoString decode(bindings.Decoder decoder0) {
|
||||
if (decoder0 == null) {
|
||||
return null;
|
||||
}
|
||||
MojoString result = new MojoString();
|
||||
var mainDataHeader = decoder0.decodeStructDataHeader();
|
||||
result.string = decoder0.decodeString(8, false);
|
||||
return result;
|
||||
}
|
||||
|
||||
void encode(bindings.Encoder encoder) {
|
||||
var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo);
|
||||
encoder0.encodeString(string, 8, false);
|
||||
}
|
||||
}
|
||||
|
||||
testUtf8() {
|
||||
var str = "B\u03ba\u1f79"; // some UCS-2 codepoints.
|
||||
var name = 42;
|
||||
var payloadSize = 24;
|
||||
|
||||
var mojoString = new MojoString();
|
||||
mojoString.string = str;
|
||||
|
||||
var header = new bindings.MessageHeader(name);
|
||||
var message = mojoString.serializeWithHeader(header);
|
||||
var resultMessage = new bindings.ServiceMessage.fromMessage(message);
|
||||
var result = MojoString.deserialize(resultMessage.payload);
|
||||
|
||||
var expectedMemory = new Uint8List.fromList([
|
||||
/* 0: */ 16,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 8: */ 42,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 16: */ 16,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 24: */ 8,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 32: */ 14,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
/* 40: */ 0x42,
|
||||
0xCE,
|
||||
0xBA,
|
||||
0xE1,
|
||||
0xBD,
|
||||
0xB9,
|
||||
0,
|
||||
0,
|
||||
]);
|
||||
var allActualMemory = message.buffer.buffer.asUint8List();
|
||||
var actualMemory = allActualMemory.sublist(0, expectedMemory.length);
|
||||
Expect.equals(expectedMemory.length, actualMemory.length);
|
||||
Expect.listEquals(expectedMemory, actualMemory);
|
||||
|
||||
Expect.equals(str, result.string);
|
||||
}
|
||||
|
||||
main() {
|
||||
testAlign();
|
||||
testBar();
|
||||
testFoo();
|
||||
testNamedRegion();
|
||||
testUtf8();
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Make sure that we are generating valid Dart code for all mojom interface
|
||||
// tests.
|
||||
// vmoptions: --compile_all
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/application.dart';
|
||||
import 'package:mojo/bindings.dart';
|
||||
import 'package:mojo/core.dart';
|
||||
import 'package:mojom/mojo/application.mojom.dart';
|
||||
import 'package:mojom/mojo/service_provider.mojom.dart';
|
||||
import 'package:mojom/mojo/shell.mojom.dart';
|
||||
import 'package:mojom/math/math_calculator.mojom.dart';
|
||||
import 'package:mojom/no_module.mojom.dart';
|
||||
import 'package:mojom/mojo/test/rect.mojom.dart';
|
||||
import 'package:mojom/regression_tests/regression_tests.mojom.dart';
|
||||
import 'package:mojom/sample/sample_factory.mojom.dart';
|
||||
import 'package:mojom/imported/sample_import2.mojom.dart';
|
||||
import 'package:mojom/imported/sample_import.mojom.dart';
|
||||
import 'package:mojom/sample/sample_interfaces.mojom.dart';
|
||||
import 'package:mojom/sample/sample_service.mojom.dart';
|
||||
import 'package:mojom/mojo/test/serialization_test_structs.mojom.dart';
|
||||
import 'package:mojom/mojo/test/test_structs.mojom.dart';
|
||||
import 'package:mojom/mojo/test/validation_test_interfaces.mojom.dart';
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/bindings.dart' as bindings;
|
||||
import 'package:mojo/core.dart' as core;
|
||||
import 'package:mojom/sample/sample_interfaces.mojom.dart' as sample;
|
||||
|
||||
// Bump this if sample_interfaces.mojom adds higher versions.
|
||||
const maxVersion = 3;
|
||||
|
||||
// Implementation of IntegerAccessor.
|
||||
class IntegerAccessorImpl implements sample.IntegerAccessor {
|
||||
// Some initial value.
|
||||
int _value = 0;
|
||||
|
||||
Future<sample.IntegerAccessorGetIntegerResponseParams>
|
||||
getInteger([Function responseFactory = null]) {
|
||||
return new Future.value(responseFactory(_value, sample.Enum.VALUE));
|
||||
}
|
||||
|
||||
void setInteger(int data, sample.Enum type) {
|
||||
Expect.equals(sample.Enum.VALUE.value, type.value);
|
||||
// Update data.
|
||||
_value = data;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns [proxy, stub].
|
||||
List buildConnectedProxyAndStub() {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var proxy = new sample.IntegerAccessorProxy.fromEndpoint(pipe.endpoints[0]);
|
||||
var impl = new IntegerAccessorImpl();
|
||||
var stub =
|
||||
new sample.IntegerAccessorStub.fromEndpoint(pipe.endpoints[1], impl);
|
||||
return [proxy, stub];
|
||||
}
|
||||
|
||||
void closeProxyAndStub(List ps) {
|
||||
var proxy = ps[0];
|
||||
var stub = ps[1];
|
||||
proxy.close();
|
||||
stub.close();
|
||||
}
|
||||
|
||||
testQueryVersion() async {
|
||||
var ps = buildConnectedProxyAndStub();
|
||||
var proxy = ps[0];
|
||||
// The version starts at 0.
|
||||
Expect.equals(0, proxy.version);
|
||||
// We are talking to an implementation that supports version maxVersion.
|
||||
var providedVersion = await proxy.queryVersion();
|
||||
Expect.equals(maxVersion, providedVersion);
|
||||
// The proxy's version has been updated.
|
||||
Expect.equals(providedVersion, proxy.version);
|
||||
closeProxyAndStub(ps);
|
||||
}
|
||||
|
||||
testRequireVersionSuccess() async {
|
||||
var ps = buildConnectedProxyAndStub();
|
||||
var proxy = ps[0];
|
||||
Expect.equals(0, proxy.version);
|
||||
// Require version maxVersion.
|
||||
proxy.requireVersion(maxVersion);
|
||||
// Make a request and get a response.
|
||||
var response = await proxy.ptr.getInteger();
|
||||
Expect.equals(0, response.data);
|
||||
closeProxyAndStub(ps);
|
||||
}
|
||||
|
||||
testRequireVersionDisconnect() async {
|
||||
var ps = buildConnectedProxyAndStub();
|
||||
var proxy = ps[0];
|
||||
Expect.equals(0, proxy.version);
|
||||
// Require version maxVersion.
|
||||
proxy.requireVersion(maxVersion);
|
||||
Expect.equals(maxVersion, proxy.version);
|
||||
// Set integer.
|
||||
proxy.ptr.setInteger(34, sample.Enum.VALUE);
|
||||
// Get integer.
|
||||
var response = await proxy.ptr.getInteger();
|
||||
Expect.equals(34, response.data);
|
||||
// Require version maxVersion + 1
|
||||
proxy.requireVersion(maxVersion + 1);
|
||||
// Version number is updated synchronously.
|
||||
Expect.equals(maxVersion + 1, proxy.version);
|
||||
// Get integer, expect a failure.
|
||||
bool exceptionCaught = false;
|
||||
try {
|
||||
response = await proxy.ptr.getInteger();
|
||||
Expect.fail('Should have an exception.');
|
||||
} catch(e) {
|
||||
exceptionCaught = true;
|
||||
}
|
||||
Expect.isTrue(exceptionCaught);
|
||||
closeProxyAndStub(ps);
|
||||
}
|
||||
|
||||
main() async {
|
||||
await testQueryVersion();
|
||||
await testRequireVersionSuccess();
|
||||
await testRequireVersionDisconnect();
|
||||
}
|
||||
@ -1,318 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/core.dart';
|
||||
|
||||
invalidHandleTest() {
|
||||
MojoHandle invalidHandle = new MojoHandle(MojoHandle.INVALID);
|
||||
|
||||
// Close.
|
||||
MojoResult result = invalidHandle.close();
|
||||
Expect.isTrue(result.isInvalidArgument);
|
||||
|
||||
// Wait.
|
||||
MojoWaitResult mwr =
|
||||
invalidHandle.wait(MojoHandleSignals.kReadWrite, 1000000);
|
||||
Expect.isTrue(mwr.result.isInvalidArgument);
|
||||
|
||||
MojoWaitManyResult mwmr = MojoHandle.waitMany([invalidHandle.h],
|
||||
[MojoHandleSignals.kReadWrite], MojoHandle.DEADLINE_INDEFINITE);
|
||||
Expect.isTrue(mwmr.result.isInvalidArgument);
|
||||
|
||||
// Message pipe.
|
||||
MojoMessagePipe pipe = new MojoMessagePipe();
|
||||
Expect.isNotNull(pipe);
|
||||
ByteData bd = new ByteData(10);
|
||||
pipe.endpoints[0].handle.close();
|
||||
pipe.endpoints[1].handle.close();
|
||||
result = pipe.endpoints[0].write(bd);
|
||||
Expect.isTrue(result.isInvalidArgument);
|
||||
|
||||
MojoMessagePipeReadResult readResult = pipe.endpoints[0].read(bd);
|
||||
Expect.isTrue(pipe.endpoints[0].status.isInvalidArgument);
|
||||
|
||||
// Data pipe.
|
||||
MojoDataPipe dataPipe = new MojoDataPipe();
|
||||
Expect.isNotNull(dataPipe);
|
||||
dataPipe.producer.handle.close();
|
||||
dataPipe.consumer.handle.close();
|
||||
|
||||
int bytesWritten = dataPipe.producer.write(bd);
|
||||
Expect.isTrue(dataPipe.producer.status.isInvalidArgument);
|
||||
|
||||
ByteData writeData = dataPipe.producer.beginWrite(10);
|
||||
Expect.isNull(writeData);
|
||||
Expect.isTrue(dataPipe.producer.status.isInvalidArgument);
|
||||
dataPipe.producer.endWrite(10);
|
||||
Expect.isTrue(dataPipe.producer.status.isInvalidArgument);
|
||||
|
||||
int read = dataPipe.consumer.read(bd);
|
||||
Expect.isTrue(dataPipe.consumer.status.isInvalidArgument);
|
||||
|
||||
ByteData readData = dataPipe.consumer.beginRead(10);
|
||||
Expect.isNull(readData);
|
||||
Expect.isTrue(dataPipe.consumer.status.isInvalidArgument);
|
||||
dataPipe.consumer.endRead(10);
|
||||
Expect.isTrue(dataPipe.consumer.status.isInvalidArgument);
|
||||
|
||||
// Shared buffer.
|
||||
MojoSharedBuffer sharedBuffer = new MojoSharedBuffer.create(10);
|
||||
Expect.isNotNull(sharedBuffer);
|
||||
sharedBuffer.close();
|
||||
MojoSharedBuffer duplicate = new MojoSharedBuffer.duplicate(sharedBuffer);
|
||||
Expect.isNull(duplicate);
|
||||
|
||||
sharedBuffer = new MojoSharedBuffer.create(10);
|
||||
Expect.isNotNull(sharedBuffer);
|
||||
sharedBuffer.close();
|
||||
result = sharedBuffer.map(0, 10);
|
||||
Expect.isTrue(result.isInvalidArgument);
|
||||
}
|
||||
|
||||
basicMessagePipeTest() {
|
||||
MojoMessagePipe pipe = new MojoMessagePipe();
|
||||
Expect.isNotNull(pipe);
|
||||
Expect.isTrue(pipe.status.isOk);
|
||||
Expect.isNotNull(pipe.endpoints);
|
||||
|
||||
MojoMessagePipeEndpoint end0 = pipe.endpoints[0];
|
||||
MojoMessagePipeEndpoint end1 = pipe.endpoints[1];
|
||||
Expect.isTrue(end0.handle.isValid);
|
||||
Expect.isTrue(end1.handle.isValid);
|
||||
|
||||
// Not readable, yet.
|
||||
MojoWaitResult mwr = end0.handle.wait(MojoHandleSignals.kReadable, 0);
|
||||
Expect.isTrue(mwr.result.isDeadlineExceeded);
|
||||
|
||||
// Should be writable.
|
||||
mwr = end0.handle.wait(MojoHandleSignals.kWritable, 0);
|
||||
Expect.isTrue(mwr.result.isOk);
|
||||
|
||||
// Try to read.
|
||||
ByteData data = new ByteData(10);
|
||||
end0.read(data);
|
||||
Expect.isTrue(end0.status.isShouldWait);
|
||||
|
||||
// Write end1.
|
||||
String hello = "hello";
|
||||
ByteData helloData =
|
||||
new ByteData.view((new Uint8List.fromList(hello.codeUnits)).buffer);
|
||||
MojoResult result = end1.write(helloData);
|
||||
Expect.isTrue(result.isOk);
|
||||
|
||||
// end0 should now be readable.
|
||||
MojoWaitManyResult mwmr = MojoHandle.waitMany([end0.handle.h],
|
||||
[MojoHandleSignals.kReadable], MojoHandle.DEADLINE_INDEFINITE);
|
||||
Expect.isTrue(mwmr.result.isOk);
|
||||
|
||||
// Read from end0.
|
||||
MojoMessagePipeReadResult readResult = end0.read(data);
|
||||
Expect.isNotNull(readResult);
|
||||
Expect.isTrue(readResult.status.isOk);
|
||||
Expect.equals(readResult.bytesRead, helloData.lengthInBytes);
|
||||
Expect.equals(readResult.handlesRead, 0);
|
||||
|
||||
String hello_result = new String.fromCharCodes(
|
||||
data.buffer.asUint8List().sublist(0, readResult.bytesRead).toList());
|
||||
Expect.equals(hello_result, "hello");
|
||||
|
||||
// end0 should no longer be readable.
|
||||
mwr = end0.handle.wait(MojoHandleSignals.kReadable, 10);
|
||||
Expect.isTrue(mwr.result.isDeadlineExceeded);
|
||||
|
||||
// Close end0's handle.
|
||||
result = end0.handle.close();
|
||||
Expect.isTrue(result.isOk);
|
||||
|
||||
// end1 should no longer be readable or writable.
|
||||
mwr = end1.handle.wait(MojoHandleSignals.kReadWrite, 1000);
|
||||
Expect.isTrue(mwr.result.isFailedPrecondition);
|
||||
|
||||
result = end1.handle.close();
|
||||
Expect.isTrue(result.isOk);
|
||||
}
|
||||
|
||||
basicDataPipeTest() {
|
||||
MojoDataPipe pipe = new MojoDataPipe();
|
||||
Expect.isNotNull(pipe);
|
||||
Expect.isTrue(pipe.status.isOk);
|
||||
Expect.isTrue(pipe.consumer.handle.isValid);
|
||||
Expect.isTrue(pipe.producer.handle.isValid);
|
||||
|
||||
MojoDataPipeProducer producer = pipe.producer;
|
||||
MojoDataPipeConsumer consumer = pipe.consumer;
|
||||
Expect.isTrue(producer.handle.isValid);
|
||||
Expect.isTrue(consumer.handle.isValid);
|
||||
|
||||
// Consumer should not be readable.
|
||||
MojoWaitResult mwr = consumer.handle.wait(MojoHandleSignals.kReadable, 0);
|
||||
Expect.isTrue(mwr.result.isDeadlineExceeded);
|
||||
|
||||
// Producer should be writable.
|
||||
mwr = producer.handle.wait(MojoHandleSignals.kWritable, 0);
|
||||
Expect.isTrue(mwr.result.isOk);
|
||||
|
||||
// Try to read from consumer.
|
||||
ByteData buffer = new ByteData(20);
|
||||
consumer.read(buffer, buffer.lengthInBytes, MojoDataPipeConsumer.FLAG_NONE);
|
||||
Expect.isTrue(consumer.status.isShouldWait);
|
||||
|
||||
// Try to begin a two-phase read from consumer.
|
||||
ByteData b = consumer.beginRead(20, MojoDataPipeConsumer.FLAG_NONE);
|
||||
Expect.isNull(b);
|
||||
Expect.isTrue(consumer.status.isShouldWait);
|
||||
|
||||
// Write to producer.
|
||||
String hello = "hello ";
|
||||
ByteData helloData =
|
||||
new ByteData.view((new Uint8List.fromList(hello.codeUnits)).buffer);
|
||||
int written = producer.write(
|
||||
helloData, helloData.lengthInBytes, MojoDataPipeProducer.FLAG_NONE);
|
||||
Expect.isTrue(producer.status.isOk);
|
||||
Expect.equals(written, helloData.lengthInBytes);
|
||||
|
||||
// Now that we have written, the consumer should be readable.
|
||||
MojoWaitManyResult mwmr = MojoHandle.waitMany([consumer.handle.h],
|
||||
[MojoHandleSignals.kReadable], MojoHandle.DEADLINE_INDEFINITE);
|
||||
Expect.isTrue(mwr.result.isOk);
|
||||
|
||||
// Do a two-phase write to the producer.
|
||||
ByteData twoPhaseWrite =
|
||||
producer.beginWrite(20, MojoDataPipeProducer.FLAG_NONE);
|
||||
Expect.isTrue(producer.status.isOk);
|
||||
Expect.isNotNull(twoPhaseWrite);
|
||||
Expect.isTrue(twoPhaseWrite.lengthInBytes >= 20);
|
||||
|
||||
String world = "world";
|
||||
twoPhaseWrite.buffer.asUint8List().setAll(0, world.codeUnits);
|
||||
producer.endWrite(Uint8List.BYTES_PER_ELEMENT * world.codeUnits.length);
|
||||
Expect.isTrue(producer.status.isOk);
|
||||
|
||||
// Read one character from consumer.
|
||||
int read = consumer.read(buffer, 1, MojoDataPipeConsumer.FLAG_NONE);
|
||||
Expect.isTrue(consumer.status.isOk);
|
||||
Expect.equals(read, 1);
|
||||
|
||||
// Close the producer.
|
||||
MojoResult result = producer.handle.close();
|
||||
Expect.isTrue(result.isOk);
|
||||
|
||||
// Consumer should still be readable.
|
||||
mwr = consumer.handle.wait(MojoHandleSignals.kReadable, 0);
|
||||
Expect.isTrue(mwr.result.isOk);
|
||||
|
||||
// Get the number of remaining bytes.
|
||||
int remaining = consumer.read(null, 0, MojoDataPipeConsumer.FLAG_QUERY);
|
||||
Expect.isTrue(consumer.status.isOk);
|
||||
Expect.equals(remaining, "hello world".length - 1);
|
||||
|
||||
// Do a two-phase read.
|
||||
ByteData twoPhaseRead =
|
||||
consumer.beginRead(remaining, MojoDataPipeConsumer.FLAG_NONE);
|
||||
Expect.isTrue(consumer.status.isOk);
|
||||
Expect.isNotNull(twoPhaseRead);
|
||||
Expect.isTrue(twoPhaseRead.lengthInBytes <= remaining);
|
||||
|
||||
Uint8List uint8_list = buffer.buffer.asUint8List();
|
||||
uint8_list.setAll(1, twoPhaseRead.buffer.asUint8List());
|
||||
uint8_list = uint8_list.sublist(0, 1 + twoPhaseRead.lengthInBytes);
|
||||
|
||||
consumer.endRead(twoPhaseRead.lengthInBytes);
|
||||
Expect.isTrue(consumer.status.isOk);
|
||||
|
||||
String helloWorld = new String.fromCharCodes(uint8_list.toList());
|
||||
Expect.equals("hello world", helloWorld);
|
||||
|
||||
result = consumer.handle.close();
|
||||
Expect.isTrue(result.isOk);
|
||||
}
|
||||
|
||||
basicSharedBufferTest() {
|
||||
MojoSharedBuffer mojoBuffer =
|
||||
new MojoSharedBuffer.create(100, MojoSharedBuffer.CREATE_FLAG_NONE);
|
||||
Expect.isNotNull(mojoBuffer);
|
||||
Expect.isNotNull(mojoBuffer.status);
|
||||
Expect.isTrue(mojoBuffer.status.isOk);
|
||||
Expect.isNotNull(mojoBuffer.handle);
|
||||
Expect.isTrue(mojoBuffer.handle is MojoHandle);
|
||||
Expect.isTrue(mojoBuffer.handle.isValid);
|
||||
|
||||
mojoBuffer.map(0, 100, MojoSharedBuffer.MAP_FLAG_NONE);
|
||||
Expect.isNotNull(mojoBuffer.status);
|
||||
Expect.isTrue(mojoBuffer.status.isOk);
|
||||
Expect.isNotNull(mojoBuffer.mapping);
|
||||
Expect.isTrue(mojoBuffer.mapping is ByteData);
|
||||
|
||||
mojoBuffer.mapping.setInt8(50, 42);
|
||||
|
||||
MojoSharedBuffer duplicate = new MojoSharedBuffer.duplicate(
|
||||
mojoBuffer, MojoSharedBuffer.DUPLICATE_FLAG_NONE);
|
||||
Expect.isNotNull(duplicate);
|
||||
Expect.isNotNull(duplicate.status);
|
||||
Expect.isTrue(duplicate.status.isOk);
|
||||
Expect.isTrue(duplicate.handle is MojoHandle);
|
||||
Expect.isTrue(duplicate.handle.isValid);
|
||||
|
||||
duplicate.map(0, 100, MojoSharedBuffer.MAP_FLAG_NONE);
|
||||
Expect.isTrue(duplicate.status.isOk);
|
||||
Expect.isNotNull(duplicate.mapping);
|
||||
Expect.isTrue(duplicate.mapping is ByteData);
|
||||
|
||||
mojoBuffer.close();
|
||||
mojoBuffer = null;
|
||||
|
||||
duplicate.mapping.setInt8(51, 43);
|
||||
|
||||
duplicate.unmap();
|
||||
Expect.isNotNull(duplicate.status);
|
||||
Expect.isTrue(duplicate.status.isOk);
|
||||
Expect.isNull(duplicate.mapping);
|
||||
|
||||
duplicate.map(50, 50, MojoSharedBuffer.MAP_FLAG_NONE);
|
||||
Expect.isNotNull(duplicate.status);
|
||||
Expect.isTrue(duplicate.status.isOk);
|
||||
Expect.isNotNull(duplicate.mapping);
|
||||
Expect.isTrue(duplicate.mapping is ByteData);
|
||||
|
||||
Expect.equals(duplicate.mapping.getInt8(0), 42);
|
||||
Expect.equals(duplicate.mapping.getInt8(1), 43);
|
||||
|
||||
duplicate.unmap();
|
||||
Expect.isNotNull(duplicate.status);
|
||||
Expect.isTrue(duplicate.status.isOk);
|
||||
Expect.isNull(duplicate.mapping);
|
||||
|
||||
duplicate.close();
|
||||
duplicate = null;
|
||||
}
|
||||
|
||||
utilsTest() {
|
||||
int ticksa = getTimeTicksNow();
|
||||
Expect.isTrue(1000 < ticksa);
|
||||
|
||||
// Wait for the clock to advance.
|
||||
MojoWaitResult mwr = (new MojoMessagePipe()).endpoints[0].handle.wait(
|
||||
MojoHandleSignals.kReadable, 1);
|
||||
Expect.isTrue(mwr.result.isDeadlineExceeded);
|
||||
|
||||
int ticksb = getTimeTicksNow();
|
||||
Expect.isTrue(ticksa < ticksb);
|
||||
}
|
||||
// TODO(rudominer) This probably belongs in a different file.
|
||||
processTest() {
|
||||
Expect.isTrue(pid > 0);
|
||||
}
|
||||
|
||||
main() {
|
||||
invalidHandleTest();
|
||||
basicMessagePipeTest();
|
||||
basicDataPipeTest();
|
||||
basicSharedBufferTest();
|
||||
utilsTest();
|
||||
processTest();
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
int returnInt() => 0;
|
||||
bool returnBool() => true;
|
||||
double returnDouble() => 0.42;
|
||||
String returnString() => "String";
|
||||
List<int> returnIntList() => [1,2,3,4,5];
|
||||
Map<String, int> returnMap() => {'thing1': 1, 'thing2': 2};
|
||||
|
||||
int main() {
|
||||
returnInt();
|
||||
returnBool();
|
||||
returnDouble();
|
||||
returnString();
|
||||
returnIntList();
|
||||
returnMap();
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:mojo/core.dart';
|
||||
|
||||
main() {
|
||||
try {
|
||||
throw 'exception';
|
||||
} catch (exception, stackTrace) {
|
||||
assert(exception == 'exception');
|
||||
assert(stackTrace != null);
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/core.dart';
|
||||
|
||||
MojoHandle leakMojoHandle() {
|
||||
var pipe = new MojoMessagePipe();
|
||||
Expect.isNotNull(pipe);
|
||||
|
||||
var endpoint = pipe.endpoints[0];
|
||||
Expect.isTrue(endpoint.handle.isValid);
|
||||
|
||||
var eventStream = new MojoEventStream(endpoint.handle);
|
||||
// After making a MojoEventStream, the underlying mojo handle will have
|
||||
// the native MojoClose called on it when the MojoEventStream is GC'd or the
|
||||
// VM shuts down.
|
||||
|
||||
return endpoint.handle;
|
||||
}
|
||||
|
||||
// vmoptions: --new-gen-semi-max-size=1 --old_gen_growth_rate=1
|
||||
List<int> triggerGC() {
|
||||
var l = new List.filled(1000000, 7);
|
||||
return l;
|
||||
}
|
||||
|
||||
test() {
|
||||
MojoHandle handle = leakMojoHandle();
|
||||
triggerGC();
|
||||
|
||||
// The handle will be closed by the MojoHandle finalizer during GC, so the
|
||||
// attempt to close it again will fail.
|
||||
MojoResult result = handle.close();
|
||||
Expect.isTrue(result.isInvalidArgument);
|
||||
}
|
||||
|
||||
main() {
|
||||
test();
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/expect.dart';
|
||||
import 'package:mojo/core.dart';
|
||||
|
||||
void simpleTest() {
|
||||
var pipe = new MojoMessagePipe();
|
||||
Expect.isNotNull(pipe);
|
||||
|
||||
var endpoint = pipe.endpoints[0];
|
||||
Expect.isTrue(endpoint.handle.isValid);
|
||||
|
||||
var eventStream = new MojoEventStream(endpoint.handle);
|
||||
var completer = new Completer();
|
||||
int numEvents = 0;
|
||||
|
||||
eventStream.listen((_) {
|
||||
numEvents++;
|
||||
eventStream.close();
|
||||
}, onDone: () {
|
||||
completer.complete(numEvents);
|
||||
});
|
||||
eventStream.enableWriteEvents();
|
||||
|
||||
completer.future.then((int numEvents) {
|
||||
Expect.equals(1, numEvents);
|
||||
});
|
||||
}
|
||||
|
||||
Future simpleAsyncAwaitTest() async {
|
||||
var pipe = new MojoMessagePipe();
|
||||
Expect.isNotNull(pipe);
|
||||
|
||||
var endpoint = pipe.endpoints[0];
|
||||
Expect.isTrue(endpoint.handle.isValid);
|
||||
|
||||
var eventStream =
|
||||
new MojoEventStream(endpoint.handle, MojoHandleSignals.READWRITE);
|
||||
|
||||
int numEvents = 0;
|
||||
await for (List<int> event in eventStream) {
|
||||
numEvents++;
|
||||
eventStream.close();
|
||||
}
|
||||
Expect.equals(1, numEvents);
|
||||
}
|
||||
|
||||
ByteData byteDataOfString(String s) {
|
||||
return new ByteData.view((new Uint8List.fromList(s.codeUnits)).buffer);
|
||||
}
|
||||
|
||||
String stringOfByteData(ByteData bytes) {
|
||||
return new String.fromCharCodes(bytes.buffer.asUint8List().toList());
|
||||
}
|
||||
|
||||
void expectStringFromEndpoint(
|
||||
String expected, MojoMessagePipeEndpoint endpoint) {
|
||||
// Query how many bytes are available.
|
||||
var result = endpoint.query();
|
||||
Expect.isNotNull(result);
|
||||
int size = result.bytesRead;
|
||||
Expect.isTrue(size > 0);
|
||||
|
||||
// Read the data.
|
||||
ByteData bytes = new ByteData(size);
|
||||
result = endpoint.read(bytes);
|
||||
Expect.isNotNull(result);
|
||||
Expect.equals(size, result.bytesRead);
|
||||
|
||||
// Convert to a string and check.
|
||||
String msg = stringOfByteData(bytes);
|
||||
Expect.equals(expected, msg);
|
||||
}
|
||||
|
||||
Future pingPongIsolate(MojoMessagePipeEndpoint endpoint) async {
|
||||
int pings = 0;
|
||||
int pongs = 0;
|
||||
var eventStream = new MojoEventStream(endpoint.handle);
|
||||
await for (List<int> event in eventStream) {
|
||||
var mojoSignals = new MojoHandleSignals(event[1]);
|
||||
if (mojoSignals.isReadWrite) {
|
||||
// We are either sending or receiving.
|
||||
throw new Exception("Unexpected event");
|
||||
} else if (mojoSignals.isReadable) {
|
||||
expectStringFromEndpoint("Ping", endpoint);
|
||||
pings++;
|
||||
eventStream.enableWriteEvents();
|
||||
} else if (mojoSignals.isWritable) {
|
||||
endpoint.write(byteDataOfString("Pong"));
|
||||
pongs++;
|
||||
eventStream.enableReadEvents();
|
||||
}
|
||||
}
|
||||
eventStream.close();
|
||||
Expect.equals(10, pings);
|
||||
Expect.equals(10, pongs);
|
||||
}
|
||||
|
||||
Future pingPongTest() async {
|
||||
var pipe = new MojoMessagePipe();
|
||||
var isolate = await Isolate.spawn(pingPongIsolate, pipe.endpoints[0]);
|
||||
var endpoint = pipe.endpoints[1];
|
||||
var eventStream =
|
||||
new MojoEventStream(endpoint.handle, MojoHandleSignals.READWRITE);
|
||||
|
||||
int pings = 0;
|
||||
int pongs = 0;
|
||||
await for (List<int> event in eventStream) {
|
||||
var mojoSignals = new MojoHandleSignals(event[1]);
|
||||
if (mojoSignals.isReadWrite) {
|
||||
// We are either sending or receiving.
|
||||
throw new Exception("Unexpected event");
|
||||
} else if (mojoSignals.isReadable) {
|
||||
expectStringFromEndpoint("Pong", endpoint);
|
||||
pongs++;
|
||||
if (pongs == 10) {
|
||||
eventStream.close();
|
||||
}
|
||||
eventStream.enableWriteEvents(); // Now it is our turn to send.
|
||||
} else if (mojoSignals.isWritable) {
|
||||
if (pings < 10) {
|
||||
endpoint.write(byteDataOfString("Ping"));
|
||||
pings++;
|
||||
}
|
||||
eventStream.enableReadEvents(); // Don't send while waiting for reply.
|
||||
}
|
||||
}
|
||||
Expect.equals(10, pings);
|
||||
Expect.equals(10, pongs);
|
||||
}
|
||||
|
||||
main() async {
|
||||
simpleTest();
|
||||
await simpleAsyncAwaitTest();
|
||||
await pingPongTest();
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
main() {
|
||||
print("Hello, Mojo!");
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:mojo/bindings.dart' as bindings;
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
||||
main() {
|
||||
core.MojoMessagePipe pipe = new core.MojoMessagePipe();
|
||||
pipe.endpoints[0].handle.close();
|
||||
pipe.endpoints[1].handle.close();
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
|
||||
void foo(SendPort sp) {
|
||||
var rp = new ReceivePort();
|
||||
sp.send(rp.sendPort);
|
||||
rp.listen((msg) {
|
||||
if ((msg is String) && (msg == "Hello, world!")) {
|
||||
print("Hello, world!");
|
||||
rp.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main() {
|
||||
var rp = new ReceivePort();
|
||||
Isolate.spawn(foo, rp.sendPort).then((isolate) {
|
||||
var sp = null;
|
||||
rp.listen((msg) {
|
||||
if (msg is SendPort) {
|
||||
sp = msg;
|
||||
sp.send("Hello, world!");
|
||||
rp.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
||||
ByteData byteDataOfString(String s) {
|
||||
return new ByteData.view((new Uint8List.fromList(s.codeUnits)).buffer);
|
||||
}
|
||||
|
||||
String stringOfByteData(ByteData bytes) {
|
||||
return new String.fromCharCodes(bytes.buffer.asUint8List().toList());
|
||||
}
|
||||
|
||||
void expectStringFromEndpoint(
|
||||
String expected, core.MojoMessagePipeEndpoint endpoint) {
|
||||
// Query how many bytes are available.
|
||||
var result = endpoint.query();
|
||||
assert(result != null);
|
||||
int size = result.bytesRead;
|
||||
assert(size > 0);
|
||||
|
||||
// Read the data.
|
||||
ByteData bytes = new ByteData(size);
|
||||
result = endpoint.read(bytes);
|
||||
assert(result != null);
|
||||
assert(size == result.bytesRead);
|
||||
|
||||
// Convert to a string and check.
|
||||
String msg = stringOfByteData(bytes);
|
||||
assert(expected == msg);
|
||||
}
|
||||
|
||||
void pipeTestIsolate(core.MojoMessagePipeEndpoint endpoint) {
|
||||
var eventStream = new core.MojoEventStream(endpoint.handle);
|
||||
eventStream.listen((List<int> event) {
|
||||
var mojoSignals = new core.MojoHandleSignals(event[1]);
|
||||
if (mojoSignals.isReadWrite) {
|
||||
throw 'We should only be reading or writing, not both.';
|
||||
} else if (mojoSignals.isReadable) {
|
||||
expectStringFromEndpoint("Ping", endpoint);
|
||||
eventStream.enableWriteEvents();
|
||||
} else if (mojoSignals.isWritable) {
|
||||
endpoint.write(byteDataOfString("Pong"));
|
||||
eventStream.enableReadEvents();
|
||||
} else if (mojoSignals.isPeerClosed) {
|
||||
eventStream.close();
|
||||
} else {
|
||||
throw 'Unexpected event.';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main() {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
var endpoint = pipe.endpoints[0];
|
||||
var eventStream = new core.MojoEventStream(endpoint.handle);
|
||||
Isolate.spawn(pipeTestIsolate, pipe.endpoints[1]).then((_) {
|
||||
eventStream.listen((List<int> event) {
|
||||
var mojoSignals = new core.MojoHandleSignals(event[1]);
|
||||
if (mojoSignals.isReadWrite) {
|
||||
throw 'We should only be reading or writing, not both.';
|
||||
} else if (mojoSignals.isReadable) {
|
||||
expectStringFromEndpoint("Pong", endpoint);
|
||||
eventStream.close();
|
||||
} else if (mojoSignals.isWritable) {
|
||||
endpoint.write(byteDataOfString("Ping"));
|
||||
eventStream.enableReadEvents();
|
||||
} else if (mojoSignals.isPeerClosed) {
|
||||
throw 'This end should close first.';
|
||||
} else {
|
||||
throw 'Unexpected event.';
|
||||
}
|
||||
});
|
||||
eventStream.enableWriteEvents();
|
||||
});
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
||||
main() {
|
||||
var pipe = new core.MojoMessagePipe();
|
||||
assert(pipe != null);
|
||||
|
||||
var endpoint = pipe.endpoints[0];
|
||||
assert(endpoint.handle.isValid);
|
||||
|
||||
var eventStream = new core.MojoEventStream(endpoint.handle);
|
||||
var completer = new Completer();
|
||||
int numEvents = 0;
|
||||
|
||||
eventStream.listen((_) {
|
||||
numEvents++;
|
||||
eventStream.close();
|
||||
}, onDone: () {
|
||||
completer.complete(numEvents);
|
||||
});
|
||||
eventStream.enableWriteEvents();
|
||||
|
||||
completer.future.then((int numEvents) {
|
||||
assert(numEvents == 1);
|
||||
});
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
main() {
|
||||
(new Timer(new Duration(seconds: 1), () {
|
||||
print("Hello, world after one second!");
|
||||
}));
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
||||
main() {
|
||||
print("${Uri.base}");
|
||||
}
|
||||
@ -1,128 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:isolate';
|
||||
import 'dart:mojo.builtin' as builtin;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:_testing/validation_test_input_parser.dart' as parser;
|
||||
import 'package:mojo/bindings.dart';
|
||||
import 'package:mojo/core.dart';
|
||||
import 'package:mojom/mojo/test/validation_test_interfaces.mojom.dart';
|
||||
|
||||
class ConformanceTestInterfaceImpl implements ConformanceTestInterface {
|
||||
ConformanceTestInterfaceStub _stub;
|
||||
Completer _completer;
|
||||
|
||||
ConformanceTestInterfaceImpl(
|
||||
this._completer, MojoMessagePipeEndpoint endpoint) {
|
||||
_stub = new ConformanceTestInterfaceStub.fromEndpoint(endpoint, this);
|
||||
}
|
||||
|
||||
void _complete() => _completer.complete(null);
|
||||
|
||||
method0(double param0) => _complete();
|
||||
method1(StructA param0) => _complete();
|
||||
method2(StructB param0, StructA param1) => _complete();
|
||||
method3(List<bool> param0) => _complete();
|
||||
method4(StructC param0, List<int> param1) => _complete();
|
||||
method5(StructE param0, MojoDataPipeProducer param1) {
|
||||
param1.handle.close();
|
||||
param0.dataPipeConsumer.handle.close();
|
||||
param0.structD.messagePipes.forEach((h) => h.close());
|
||||
_complete();
|
||||
}
|
||||
method6(List<List<int>> param0) => _complete();
|
||||
method7(StructF param0, List<List<int>> param1) => _complete();
|
||||
method8(List<List<String>> param0) => _complete();
|
||||
method9(List<List<MojoHandle>> param0) {
|
||||
if (param0 != null) {
|
||||
param0.forEach((l) => l.forEach((h) {
|
||||
if (h != null) h.close();
|
||||
}));
|
||||
}
|
||||
_complete();
|
||||
}
|
||||
method10(Map<String, int> param0) => _complete();
|
||||
method11(StructG param0) => _complete();
|
||||
method12(double param0, [Function responseFactory]) {
|
||||
// If there are ever any passing method12 tests added, then this may need
|
||||
// to change.
|
||||
assert(responseFactory != null);
|
||||
_complete();
|
||||
return new Future.value(responseFactory(0.0));
|
||||
}
|
||||
method13(InterfaceAProxy param0, int param1, InterfaceAProxy param2) {
|
||||
if (param0 != null) param0.close(immediate: true);
|
||||
if (param2 != null) param2.close(immediate: true);
|
||||
_complete();
|
||||
}
|
||||
method14(UnionA param0) => _complete();
|
||||
method15(StructH param0) => _complete();
|
||||
|
||||
Future close({bool immediate: false}) => _stub.close(immediate: immediate);
|
||||
}
|
||||
|
||||
Future runTest(
|
||||
String name, parser.ValidationParseResult test, String expected) {
|
||||
var handles = new List.generate(
|
||||
test.numHandles, (_) => new MojoSharedBuffer.create(10).handle);
|
||||
var pipe = new MojoMessagePipe();
|
||||
var completer = new Completer();
|
||||
var conformanceImpl;
|
||||
|
||||
runZoned(() {
|
||||
conformanceImpl =
|
||||
new ConformanceTestInterfaceImpl(completer, pipe.endpoints[0]);
|
||||
}, onError: (e, stackTrace) {
|
||||
assert(e is MojoCodecError);
|
||||
// TODO(zra): Make the error messages conform?
|
||||
// assert(e == expected);
|
||||
conformanceImpl.close(immediate: true);
|
||||
pipe.endpoints[0].close();
|
||||
pipe.endpoints[1].close();
|
||||
handles.forEach((h) => h.close());
|
||||
completer.completeError(null);
|
||||
});
|
||||
|
||||
var length = (test.data == null) ? 0 : test.data.lengthInBytes;
|
||||
var r = pipe.endpoints[1].write(test.data, length, handles);
|
||||
assert(r.isOk);
|
||||
|
||||
return completer.future.then((_) {
|
||||
assert(expected == "PASS");
|
||||
conformanceImpl.close();
|
||||
pipe.endpoints[0].close();
|
||||
pipe.endpoints[1].close();
|
||||
handles.forEach((h) => h.close());
|
||||
}, onError: (e) {
|
||||
// Do nothing.
|
||||
});
|
||||
}
|
||||
|
||||
main(List args) async {
|
||||
assert(args.length == 3);
|
||||
List<String> testData = args[2];
|
||||
|
||||
// First test the parser.
|
||||
parser.parserTests();
|
||||
|
||||
// See CollectTests in validation_unittest.cc for information on testData
|
||||
// format.
|
||||
for (var i = 0; i < testData.length; i += 3) {
|
||||
var name = testData[i + 0];
|
||||
var data = testData[i + 1].trim();
|
||||
var expected = testData[i + 2].trim();
|
||||
try {
|
||||
await runTest(name, parser.parse(data), expected);
|
||||
print('$name PASSED.');
|
||||
} catch (e) {
|
||||
print('$name FAILED: $e');
|
||||
}
|
||||
}
|
||||
// TODO(zra): Add integration tests when they no longer rely on Client=
|
||||
assert(MojoHandle.reportLeakedHandles());
|
||||
}
|
||||
2
mojo/dart/testing/.gitignore
vendored
2
mojo/dart/testing/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
packages/
|
||||
pubspec.lock
|
||||
@ -1,16 +0,0 @@
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//mojo/public/dart/rules.gni")
|
||||
|
||||
dart_pkg("testing") {
|
||||
libs = [
|
||||
"lib/async_helper.dart",
|
||||
"lib/expect.dart",
|
||||
"lib/validation_test_input_parser.dart",
|
||||
]
|
||||
sources = [
|
||||
"pubspec.yaml",
|
||||
]
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/// This library is used for testing asynchronous tests.
|
||||
/// If a test is asynchronous, it needs to notify the testing driver
|
||||
/// about this (otherwise tests may get reported as passing [after main()
|
||||
/// finished] even if the asynchronous operations fail).
|
||||
/// Tests which can't use the unittest framework should use the helper functions
|
||||
/// in this library.
|
||||
/// This library provides four methods
|
||||
/// - asyncStart(): Needs to be called before an asynchronous operation is
|
||||
/// scheduled.
|
||||
/// - asyncEnd(): Needs to be called as soon as the asynchronous operation
|
||||
/// ended.
|
||||
/// - asyncSuccess(_): Variant of asyncEnd useful together with Future.then.
|
||||
/// - asyncTest(f()): Helper method that wraps a computation that returns a
|
||||
/// Future with matching calls to asyncStart() and
|
||||
/// asyncSuccess(_).
|
||||
/// After the last asyncStart() called was matched with a corresponding
|
||||
/// asyncEnd() or asyncSuccess(_) call, the testing driver will be notified that
|
||||
/// the tests is done.
|
||||
|
||||
library async_helper;
|
||||
|
||||
// TODO(kustermann): This is problematic because we rely on a working
|
||||
// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
|
||||
// It would be nice if we could use a different mechanism for different
|
||||
// runtimes.
|
||||
import 'dart:isolate';
|
||||
|
||||
bool _initialized = false;
|
||||
ReceivePort _port = null;
|
||||
int _asyncLevel = 0;
|
||||
|
||||
Exception _buildException(String msg) {
|
||||
return new Exception('Fatal: $msg. This is most likely a bug in your test.');
|
||||
}
|
||||
|
||||
/// Call this method before an asynchronous test is created.
|
||||
void asyncStart() {
|
||||
if (_initialized && _asyncLevel == 0) {
|
||||
throw _buildException('asyncStart() was called even though we are done '
|
||||
'with testing.');
|
||||
}
|
||||
if (!_initialized) {
|
||||
print('unittest-suite-wait-for-done');
|
||||
_initialized = true;
|
||||
_port = new ReceivePort();
|
||||
}
|
||||
_asyncLevel++;
|
||||
}
|
||||
|
||||
/// Call this after an asynchronous test has ended successfully.
|
||||
void asyncEnd() {
|
||||
if (_asyncLevel <= 0) {
|
||||
if (!_initialized) {
|
||||
throw _buildException('asyncEnd() was called before asyncStart().');
|
||||
} else {
|
||||
throw _buildException('asyncEnd() was called more often than '
|
||||
'asyncStart().');
|
||||
}
|
||||
}
|
||||
_asyncLevel--;
|
||||
if (_asyncLevel == 0) {
|
||||
_port.close();
|
||||
_port = null;
|
||||
print('unittest-suite-success');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this after an asynchronous test has ended successfully. This is a helper
|
||||
* for calling [asyncEnd].
|
||||
*
|
||||
* This method intentionally has a signature that matches [:Future.then:] as a
|
||||
* convenience for calling [asyncEnd] when a [:Future:] completes without error,
|
||||
* like this:
|
||||
*
|
||||
* asyncStart();
|
||||
* Future result = test();
|
||||
* result.then(asyncSuccess);
|
||||
*/
|
||||
void asyncSuccess(_) => asyncEnd();
|
||||
|
||||
/**
|
||||
* Helper method for performing asynchronous tests involving [:Future:].
|
||||
*
|
||||
* [f] must return a [:Future:] for the test computation.
|
||||
*/
|
||||
void asyncTest(f()) {
|
||||
asyncStart();
|
||||
f().then(asyncSuccess);
|
||||
}
|
||||
@ -1,380 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* This library contains an Expect class with static methods that can be used
|
||||
* for simple unit-tests.
|
||||
*/
|
||||
library expect;
|
||||
|
||||
/**
|
||||
* Expect is used for tests that do not want to make use of the
|
||||
* Dart unit test library - for example, the core language tests.
|
||||
* Third parties are discouraged from using this, and should use
|
||||
* the expect() function in the unit test library instead for
|
||||
* test assertions.
|
||||
*/
|
||||
class Expect {
|
||||
/**
|
||||
* Return a slice of a string.
|
||||
*
|
||||
* The slice will contain at least the substring from [start] to the lower of
|
||||
* [end] and `start + length`.
|
||||
* If the result is no more than `length - 10` characters long,
|
||||
* context may be added by extending the range of the slice, by decreasing
|
||||
* [start] and increasing [end], up to at most length characters.
|
||||
* If the start or end of the slice are not matching the start or end of
|
||||
* the string, ellipses are added before or after the slice.
|
||||
* Control characters may be encoded as "\xhh" codes.
|
||||
*/
|
||||
static String _truncateString(String string, int start, int end, int length) {
|
||||
if (end - start > length) {
|
||||
end = start + length;
|
||||
} else if (end - start < length) {
|
||||
int overflow = length - (end - start);
|
||||
if (overflow > 10) overflow = 10;
|
||||
// Add context.
|
||||
start = start - ((overflow + 1) ~/ 2);
|
||||
end = end + (overflow ~/ 2);
|
||||
if (start < 0) start = 0;
|
||||
if (end > string.length) end = string.length;
|
||||
}
|
||||
if (start == 0 && end == string.length) return string;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
if (start > 0) buf.write("...");
|
||||
for (int i = start; i < end; i++) {
|
||||
int code = string.codeUnitAt(i);
|
||||
if (code < 0x20) {
|
||||
buf.write(r"\x");
|
||||
buf.write("0123456789abcdef"[code ~/ 16]);
|
||||
buf.write("0123456789abcdef"[code % 16]);
|
||||
} else {
|
||||
buf.writeCharCode(string.codeUnitAt(i));
|
||||
}
|
||||
}
|
||||
if (end < string.length) buf.write("...");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the difference between two strings.
|
||||
*
|
||||
* This finds the first point where two strings differ, and returns
|
||||
* a text describing the difference.
|
||||
*
|
||||
* For small strings (length less than 20) nothing is done, and null is
|
||||
* returned. Small strings can be compared visually, but for longer strings
|
||||
* only a slice containing the first difference will be shown.
|
||||
*/
|
||||
static String _stringDifference(String expected, String actual) {
|
||||
if (expected.length < 20 && actual.length < 20) return null;
|
||||
for (int i = 0; i < expected.length && i < actual.length; i++) {
|
||||
if (expected.codeUnitAt(i) != actual.codeUnitAt(i)) {
|
||||
int start = i;
|
||||
i++;
|
||||
while (i < expected.length && i < actual.length) {
|
||||
if (expected.codeUnitAt(i) == actual.codeUnitAt(i)) break;
|
||||
i++;
|
||||
}
|
||||
int end = i;
|
||||
var truncExpected = _truncateString(expected, start, end, 20);
|
||||
var truncActual = _truncateString(actual, start, end, 20);
|
||||
return "at index $start: Expected <$truncExpected>, "
|
||||
"Found: <$truncActual>";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the expected and actual values are equal (using `==`).
|
||||
*/
|
||||
static void equals(var expected, var actual, [String reason = null]) {
|
||||
if (expected == actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
if (expected is String && actual is String) {
|
||||
String stringDifference = _stringDifference(expected, actual);
|
||||
if (stringDifference != null) {
|
||||
_fail("Expect.equals($stringDifference$msg) fails.");
|
||||
}
|
||||
}
|
||||
_fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the actual value is a bool and its value is true.
|
||||
*/
|
||||
static void isTrue(var actual, [String reason = null]) {
|
||||
if (_identical(actual, true)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isTrue($actual$msg) fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the actual value is a bool and its value is false.
|
||||
*/
|
||||
static void isFalse(var actual, [String reason = null]) {
|
||||
if (_identical(actual, false)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isFalse($actual$msg) fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether [actual] is null.
|
||||
*/
|
||||
static void isNull(actual, [String reason = null]) {
|
||||
if (null == actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isNull(actual: <$actual>$msg) fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether [actual] is not null.
|
||||
*/
|
||||
static void isNotNull(actual, [String reason = null]) {
|
||||
if (null != actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the expected and actual values are identical
|
||||
* (using `identical`).
|
||||
*/
|
||||
static void identical(var expected, var actual, [String reason = null]) {
|
||||
if (_identical(expected, actual)) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.identical(expected: <$expected>, actual: <$actual>$msg) "
|
||||
"fails.");
|
||||
}
|
||||
|
||||
// Unconditional failure.
|
||||
static void fail(String msg) {
|
||||
_fail("Expect.fail('$msg')");
|
||||
}
|
||||
|
||||
/**
|
||||
* Failure if the difference between expected and actual is greater than the
|
||||
* given tolerance. If no tolerance is given, tolerance is assumed to be the
|
||||
* value 4 significant digits smaller than the value given for expected.
|
||||
*/
|
||||
static void approxEquals(num expected,
|
||||
num actual,
|
||||
[num tolerance = null,
|
||||
String reason = null]) {
|
||||
if (tolerance == null) {
|
||||
tolerance = (expected / 1e4).abs();
|
||||
}
|
||||
// Note: use !( <= ) rather than > so we fail on NaNs
|
||||
if ((expected - actual).abs() <= tolerance) return;
|
||||
|
||||
String msg = _getMessage(reason);
|
||||
_fail('Expect.approxEquals(expected:<$expected>, actual:<$actual>, '
|
||||
'tolerance:<$tolerance>$msg) fails');
|
||||
}
|
||||
|
||||
static void notEquals(unexpected, actual, [String reason = null]) {
|
||||
if (unexpected != actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
_fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
|
||||
"fails.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all elements in [expected] and [actual] are equal `==`.
|
||||
* This is different than the typical check for identity equality `identical`
|
||||
* used by the standard list implementation. It should also produce nicer
|
||||
* error messages than just calling `Expect.equals(expected, actual)`.
|
||||
*/
|
||||
static void listEquals(List expected, List actual, [String reason = null]) {
|
||||
String msg = _getMessage(reason);
|
||||
int n = (expected.length < actual.length) ? expected.length : actual.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (expected[i] != actual[i]) {
|
||||
_fail('Expect.listEquals(at index $i, '
|
||||
'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
|
||||
}
|
||||
}
|
||||
// We check on length at the end in order to provide better error
|
||||
// messages when an unexpected item is inserted in a list.
|
||||
if (expected.length != actual.length) {
|
||||
_fail('Expect.listEquals(list length, '
|
||||
'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
|
||||
'fails: Next element <'
|
||||
'${expected.length > n ? expected[n] : actual[n]}>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all [expected] and [actual] have the same set of keys (using
|
||||
* the semantics of [Map.containsKey] to determine what "same" means. For
|
||||
* each key, checks that the values in both maps are equal using `==`.
|
||||
*/
|
||||
static void mapEquals(Map expected, Map actual, [String reason = null]) {
|
||||
String msg = _getMessage(reason);
|
||||
|
||||
// Make sure all of the values are present in both and match.
|
||||
for (final key in expected.keys) {
|
||||
if (!actual.containsKey(key)) {
|
||||
_fail('Expect.mapEquals(missing expected key: <$key>$msg) fails');
|
||||
}
|
||||
|
||||
Expect.equals(expected[key], actual[key]);
|
||||
}
|
||||
|
||||
// Make sure the actual map doesn't have any extra keys.
|
||||
for (final key in actual.keys) {
|
||||
if (!expected.containsKey(key)) {
|
||||
_fail('Expect.mapEquals(unexpected key: <$key>$msg) fails');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized equality test for strings. When the strings don't match,
|
||||
* this method shows where the mismatch starts and ends.
|
||||
*/
|
||||
static void stringEquals(String expected,
|
||||
String actual,
|
||||
[String reason = null]) {
|
||||
String msg = _getMessage(reason);
|
||||
String defaultMessage =
|
||||
'Expect.stringEquals(expected: <$expected>", <$actual>$msg) fails';
|
||||
|
||||
if (expected == actual) return;
|
||||
if ((expected == null) || (actual == null)) {
|
||||
_fail('$defaultMessage');
|
||||
}
|
||||
// scan from the left until we find a mismatch
|
||||
int left = 0;
|
||||
int eLen = expected.length;
|
||||
int aLen = actual.length;
|
||||
while (true) {
|
||||
if (left == eLen) {
|
||||
assert (left < aLen);
|
||||
String snippet = actual.substring(left, aLen);
|
||||
_fail('$defaultMessage\nDiff:\n...[ ]\n...[ $snippet ]');
|
||||
return;
|
||||
}
|
||||
if (left == aLen) {
|
||||
assert (left < eLen);
|
||||
String snippet = expected.substring(left, eLen);
|
||||
_fail('$defaultMessage\nDiff:\n...[ ]\n...[ $snippet ]');
|
||||
return;
|
||||
}
|
||||
if (expected[left] != actual[left]) {
|
||||
break;
|
||||
}
|
||||
left++;
|
||||
}
|
||||
|
||||
// scan from the right until we find a mismatch
|
||||
int right = 0;
|
||||
while (true) {
|
||||
if (right == eLen) {
|
||||
assert (right < aLen);
|
||||
String snippet = actual.substring(0, aLen - right);
|
||||
_fail('$defaultMessage\nDiff:\n[ ]...\n[ $snippet ]...');
|
||||
return;
|
||||
}
|
||||
if (right == aLen) {
|
||||
assert (right < eLen);
|
||||
String snippet = expected.substring(0, eLen - right);
|
||||
_fail('$defaultMessage\nDiff:\n[ ]...\n[ $snippet ]...');
|
||||
return;
|
||||
}
|
||||
// stop scanning if we've reached the end of the left-to-right match
|
||||
if (eLen - right <= left || aLen - right <= left) {
|
||||
break;
|
||||
}
|
||||
if (expected[eLen - right - 1] != actual[aLen - right - 1]) {
|
||||
break;
|
||||
}
|
||||
right++;
|
||||
}
|
||||
String eSnippet = expected.substring(left, eLen - right);
|
||||
String aSnippet = actual.substring(left, aLen - right);
|
||||
String diff = '\nDiff:\n...[ $eSnippet ]...\n...[ $aSnippet ]...';
|
||||
_fail('$defaultMessage$diff');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that every element of [expected] is also in [actual], and that
|
||||
* every element of [actual] is also in [expected].
|
||||
*/
|
||||
static void setEquals(Iterable expected,
|
||||
Iterable actual,
|
||||
[String reason = null]) {
|
||||
final missingSet = new Set.from(expected);
|
||||
missingSet.removeAll(actual);
|
||||
final extraSet = new Set.from(actual);
|
||||
extraSet.removeAll(expected);
|
||||
|
||||
if (extraSet.isEmpty && missingSet.isEmpty) return;
|
||||
String msg = _getMessage(reason);
|
||||
|
||||
StringBuffer sb = new StringBuffer("Expect.setEquals($msg) fails");
|
||||
// Report any missing items.
|
||||
if (!missingSet.isEmpty) {
|
||||
sb.write('\nExpected collection does not contain: ');
|
||||
}
|
||||
|
||||
for (final val in missingSet) {
|
||||
sb.write('$val ');
|
||||
}
|
||||
|
||||
// Report any extra items.
|
||||
if (!extraSet.isEmpty) {
|
||||
sb.write('\nExpected collection should not contain: ');
|
||||
}
|
||||
|
||||
for (final val in extraSet) {
|
||||
sb.write('$val ');
|
||||
}
|
||||
_fail(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the function [f] and verifies that it throws an exception.
|
||||
* The optional [check] function can provide additional validation
|
||||
* that the correct exception is being thrown. For example, to check
|
||||
* the type of the exception you could write this:
|
||||
*
|
||||
* Expect.throws(myThrowingFunction, (e) => e is MyException);
|
||||
*/
|
||||
static void throws(void f(),
|
||||
[_CheckExceptionFn check = null,
|
||||
String reason = null]) {
|
||||
try {
|
||||
f();
|
||||
} catch (e, s) {
|
||||
if (check != null) {
|
||||
if (!check(e)) {
|
||||
String msg = reason == null ? "" : reason;
|
||||
_fail("Expect.throws($msg): Unexpected '$e'\n$s");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
String msg = reason == null ? "" : reason;
|
||||
_fail('Expect.throws($msg) fails');
|
||||
}
|
||||
|
||||
static String _getMessage(String reason)
|
||||
=> (reason == null) ? "" : ", '$reason'";
|
||||
|
||||
static void _fail(String message) {
|
||||
throw new ExpectException(message);
|
||||
}
|
||||
}
|
||||
|
||||
bool _identical(a, b) => identical(a, b);
|
||||
|
||||
typedef bool _CheckExceptionFn(exception);
|
||||
|
||||
class ExpectException implements Exception {
|
||||
ExpectException(this.message);
|
||||
String toString() => message;
|
||||
String message;
|
||||
}
|
||||
@ -1,438 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
library validation_input_parser;
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
class ValidationParseResult {
|
||||
final Iterable<_Entry> _entries;
|
||||
final int numHandles;
|
||||
final ByteData data;
|
||||
|
||||
ValidationParseResult(this._entries, this.data, this.numHandles);
|
||||
|
||||
String toString() => _entries.map((e) => '$e').join('\n');
|
||||
}
|
||||
|
||||
ValidationParseResult parse(String input) =>
|
||||
new _ValidationTestParser(input).parse();
|
||||
|
||||
class ValidationParseError {
|
||||
final String _message;
|
||||
ValidationParseError(this._message);
|
||||
String toString() => _message;
|
||||
}
|
||||
|
||||
abstract class _Entry {
|
||||
final int size;
|
||||
_Entry(this.size);
|
||||
void write(ByteData buffer, int offset, Map pointers);
|
||||
}
|
||||
|
||||
class _UnsignedEntry implements _Entry {
|
||||
final int size;
|
||||
final int value;
|
||||
|
||||
_UnsignedEntry(this.size, this.value) {
|
||||
if ((value >= (1 << (size * 8))) || (value < 0)) {
|
||||
throw new ValidationParseError('$value does not fit in a u$size');
|
||||
}
|
||||
}
|
||||
|
||||
void write(ByteData buffer, int offset, Map pointers) {
|
||||
switch (size) {
|
||||
case 1: buffer.setUint8(offset, value); break;
|
||||
case 2: buffer.setUint16(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 4: buffer.setUint32(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 8: buffer.setUint64(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
default: throw new ValidationParseError('Unexpected size: $size');
|
||||
}
|
||||
}
|
||||
|
||||
String toString() => "[u$size]$value";
|
||||
bool operator==(_UnsignedEntry other) =>
|
||||
(size == other.size) && (value == other.value);
|
||||
}
|
||||
|
||||
class _SignedEntry implements _Entry {
|
||||
final int size;
|
||||
final int value;
|
||||
|
||||
_SignedEntry(this.size, this.value) {
|
||||
if ((value >= (1 << ((size * 8) - 1))) ||
|
||||
(value < -(1 << ((size * 8) - 1)))) {
|
||||
throw new ValidationParseError('$value does not fit in a s$size');
|
||||
}
|
||||
}
|
||||
|
||||
void write(ByteData buffer, int offset, Map pointers) {
|
||||
switch (size) {
|
||||
case 1: buffer.setInt8(offset, value); break;
|
||||
case 2: buffer.setInt16(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 4: buffer.setInt32(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 8: buffer.setInt64(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
default: throw new ValidationParseError('Unexpected size: $size');
|
||||
}
|
||||
}
|
||||
|
||||
String toString() => "[s$size]$value";
|
||||
bool operator==(_SignedEntry other) =>
|
||||
(size == other.size) && (value == other.value);
|
||||
}
|
||||
|
||||
class _FloatEntry implements _Entry {
|
||||
final int size;
|
||||
final double value;
|
||||
|
||||
_FloatEntry(this.size, this.value);
|
||||
|
||||
void write(ByteData buffer, int offset, Map pointers) {
|
||||
switch (size) {
|
||||
case 4: buffer.setFloat32(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 8: buffer.setFloat64(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
default: throw new ValidationParseError('Unexpected size: $size');
|
||||
}
|
||||
}
|
||||
|
||||
String toString() => "[f$size]$value";
|
||||
bool operator==(_FloatEntry other) =>
|
||||
(size == other.size) && (value == other.value);
|
||||
}
|
||||
|
||||
class _DistEntry implements _Entry {
|
||||
final int size;
|
||||
final String id;
|
||||
int offset;
|
||||
bool matched = false;
|
||||
|
||||
_DistEntry(this.size, this.id);
|
||||
|
||||
void write(ByteData buffer, int off, Map pointers) {
|
||||
offset = off;
|
||||
if (pointers[id] != null) {
|
||||
throw new ValidationParseError(
|
||||
'Pointer of same name already exists: $id');
|
||||
}
|
||||
pointers[id] = this;
|
||||
}
|
||||
|
||||
String toString() => "[dist$size]$id matched = $matched";
|
||||
bool operator==(_DistEntry other) =>
|
||||
(size == other.size) && (id == other.id);
|
||||
}
|
||||
|
||||
class _AnchrEntry implements _Entry {
|
||||
final int size = 0;
|
||||
final String id;
|
||||
|
||||
_AnchrEntry(this.id);
|
||||
|
||||
void write(ByteData buffer, int off, Map pointers) {
|
||||
_DistEntry dist = pointers[id];
|
||||
if (dist == null) {
|
||||
throw new ValidationParseError('Did not find "$id" in pointers map.');
|
||||
}
|
||||
int value = off - dist.offset;
|
||||
if (value < 0) {
|
||||
throw new ValidationParseError('Found a backwards pointer: $id');
|
||||
}
|
||||
int offset = dist.offset;
|
||||
switch (dist.size) {
|
||||
case 4: buffer.setUint32(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
case 8: buffer.setUint64(offset, value, Endianness.LITTLE_ENDIAN); break;
|
||||
default: throw new ValidationParseError('Unexpected size: $size');
|
||||
}
|
||||
dist.matched = true;
|
||||
}
|
||||
|
||||
String toString() => "[anchr]$id";
|
||||
bool operator==(_AnchrEntry other) => (id == other.id);
|
||||
}
|
||||
|
||||
class _HandlesEntry implements _Entry {
|
||||
final int size = 0;
|
||||
final int value;
|
||||
|
||||
_HandlesEntry(this.value);
|
||||
|
||||
void write(ByteData buffer, int offset, Map pointers) {}
|
||||
|
||||
String toString() => "[handles]$value";
|
||||
bool operator==(_HandlesEntry other) => (value == other.value);
|
||||
}
|
||||
|
||||
class _CommentEntry implements _Entry {
|
||||
final int size = 0;
|
||||
final String value;
|
||||
|
||||
_CommentEntry(this.value);
|
||||
|
||||
void write(ByteData buffer, int offset, Map pointers) {}
|
||||
|
||||
String toString() => "// $value";
|
||||
bool operator==(_CommentEntry other) => (value == other.value);
|
||||
}
|
||||
|
||||
class _ValidationTestParser {
|
||||
static final RegExp newline = new RegExp(r'[\r\n]+');
|
||||
static final RegExp whitespace = new RegExp(r'[ \t\n\r]+');
|
||||
static final RegExp nakedUintRegExp =
|
||||
new RegExp(r'^0$|^[1-9][0-9]*$|^0[xX][0-9a-fA-F]+$');
|
||||
static final RegExp unsignedRegExp =
|
||||
new RegExp(r'^\[u([1248])\](0$|[1-9][0-9]*$|0[xX][0-9a-fA-F]+$)');
|
||||
static final RegExp signedRegExp = new RegExp(
|
||||
r'^\[s([1248])\]([-+]?0$|[-+]?[1-9][0-9]*$|[-+]?0[xX][0-9a-fA-F]+$)');
|
||||
static final RegExp binaryRegExp =
|
||||
new RegExp(r'^\[(b)\]([01]{8}$)');
|
||||
static final RegExp floatRegExp =
|
||||
new RegExp(r'^\[([fd])\]([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$)');
|
||||
static final RegExp distRegExp =
|
||||
new RegExp(r'^\[dist([48])\]([0-9a-zA-Z_]+$)');
|
||||
static final RegExp anchrRegExp =
|
||||
new RegExp(r'^\[(anchr)\]([0-9a-zA-Z_]+$)');
|
||||
static final RegExp handlesRegExp =
|
||||
new RegExp(r'^\[(handles)\](0$|([1-9][0-9]*$)|(0[xX][0-9a-fA-F]+$))');
|
||||
static final RegExp commentRegExp =
|
||||
new RegExp(r'//(.*)');
|
||||
|
||||
String _input;
|
||||
Map<String, _DistEntry> _pointers;
|
||||
|
||||
_ValidationTestParser(this._input) : _pointers = {};
|
||||
|
||||
String _stripComment(String line) => line.replaceFirst(commentRegExp, "");
|
||||
|
||||
ValidationParseResult parse() {
|
||||
var entries = _input.split(newline)
|
||||
.map(_stripComment)
|
||||
.expand((s) => s.split(whitespace))
|
||||
.where((s) => s != "")
|
||||
.map(_parseLine);
|
||||
int size = _calculateSize(entries);
|
||||
var data = (size > 0) ? new ByteData(size) : null;
|
||||
int numHandles = 0;
|
||||
int offset = 0;
|
||||
bool first = true;
|
||||
|
||||
for (var entry in entries) {
|
||||
entry.write(data, offset, _pointers);
|
||||
offset += entry.size;
|
||||
|
||||
if (entry is _HandlesEntry) {
|
||||
if (!first) {
|
||||
throw new ValidationParseError('Handles entry was not first');
|
||||
}
|
||||
numHandles = entry.value;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (var entry in entries) {
|
||||
if (entry is _DistEntry) {
|
||||
if (!_pointers[entry.id].matched) {
|
||||
throw new ValidationParseError('Unmatched dist: $entry');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ValidationParseResult(entries, data, numHandles);
|
||||
}
|
||||
|
||||
_Entry _parseLine(String line) {
|
||||
if (unsignedRegExp.hasMatch(line)) {
|
||||
var match = unsignedRegExp.firstMatch(line);
|
||||
return new _UnsignedEntry(
|
||||
int.parse(match.group(1)), int.parse(match.group(2)));
|
||||
} else if (signedRegExp.hasMatch(line)) {
|
||||
var match = signedRegExp.firstMatch(line);
|
||||
return new _SignedEntry(
|
||||
int.parse(match.group(1)), int.parse(match.group(2)));
|
||||
} else if (binaryRegExp.hasMatch(line)) {
|
||||
var match = binaryRegExp.firstMatch(line);
|
||||
return new _UnsignedEntry(1, int.parse(match.group(2), radix: 2));
|
||||
} else if (floatRegExp.hasMatch(line)) {
|
||||
var match = floatRegExp.firstMatch(line);
|
||||
int size = match.group(1) == 'f' ? 4 : 8;
|
||||
return new _FloatEntry(size, double.parse(match.group(2)));
|
||||
} else if (distRegExp.hasMatch(line)) {
|
||||
var match = distRegExp.firstMatch(line);
|
||||
return new _DistEntry(int.parse(match.group(1)), match.group(2));
|
||||
} else if (anchrRegExp.hasMatch(line)) {
|
||||
var match = anchrRegExp.firstMatch(line);
|
||||
return new _AnchrEntry(match.group(2));
|
||||
} else if (handlesRegExp.hasMatch(line)) {
|
||||
var match = handlesRegExp.firstMatch(line);
|
||||
return new _HandlesEntry(int.parse(match.group(2)));
|
||||
} else if (nakedUintRegExp.hasMatch(line)) {
|
||||
var match = nakedUintRegExp.firstMatch(line);
|
||||
return new _UnsignedEntry(1, int.parse(match.group(0)));
|
||||
} else if (commentRegExp.hasMatch(line)) {
|
||||
var match = commentRegExp.firstMatch(line);
|
||||
return new _CommentEntry(match.group(1));
|
||||
} else if (line == "") {
|
||||
return new _CommentEntry("");
|
||||
} else {
|
||||
throw new ValidationParseError('Unkown entry: "$line" in \n$_input');
|
||||
}
|
||||
}
|
||||
|
||||
int _calculateSize(Iterable<_Entry> entries) =>
|
||||
entries.fold(0, (value, entry) => value + entry.size);
|
||||
}
|
||||
|
||||
bool _listEquals(Iterable i1, Iterable i2) {
|
||||
var l1 = i1.toList();
|
||||
var l2 = i2.toList();
|
||||
if (l1.length != l2.length) return false;
|
||||
for (int i = 0; i < l1.length; i++) {
|
||||
if (l1[i] != l2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
parserTests() {
|
||||
{
|
||||
var input = " \t // hello world \n\r \t// the answer is 42 ";
|
||||
var result = parse(input);
|
||||
assert(result.data == null);
|
||||
assert(result.numHandles == 0);
|
||||
}
|
||||
{
|
||||
var input = "[u1]0x10// hello world !! \n\r \t [u2]65535 \n"
|
||||
"[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff";
|
||||
var result = parse(input);
|
||||
|
||||
// Check the parse results.
|
||||
var expected = [new _UnsignedEntry(1, 0x10),
|
||||
new _UnsignedEntry(2, 65535),
|
||||
new _UnsignedEntry(4, 65536),
|
||||
new _UnsignedEntry(8, 0xFFFFFFFFFFFFFFFF),
|
||||
new _UnsignedEntry(1, 0),
|
||||
new _UnsignedEntry(1, 0xff)];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
|
||||
//Check the bits.
|
||||
var buffer = new ByteData(17);
|
||||
var offset = 0;
|
||||
buffer.setUint8(offset, 0x10); offset++;
|
||||
buffer.setUint16(offset, 65535, Endianness.LITTLE_ENDIAN); offset += 2;
|
||||
buffer.setUint32(offset, 65536, Endianness.LITTLE_ENDIAN); offset += 4;
|
||||
buffer.setUint64(offset, 0xFFFFFFFFFFFFFFFF, Endianness.LITTLE_ENDIAN); offset += 8;
|
||||
buffer.setUint8(offset, 0); offset++;
|
||||
buffer.setUint8(offset, 0xff); offset++;
|
||||
assert(_listEquals(buffer.buffer.asUint8List(),
|
||||
result.data.buffer.asUint8List()));
|
||||
}
|
||||
{
|
||||
var input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40";
|
||||
var result = parse(input);
|
||||
|
||||
// Check the parse results.
|
||||
var expected = [new _SignedEntry(8, -0x800),
|
||||
new _SignedEntry(1, -128),
|
||||
new _SignedEntry(2, 0),
|
||||
new _SignedEntry(4, -40)];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
|
||||
// Check the bits.
|
||||
var buffer = new ByteData(15);
|
||||
var offset = 0;
|
||||
buffer.setInt64(offset, -0x800, Endianness.LITTLE_ENDIAN); offset += 8;
|
||||
buffer.setInt8(offset, -128); offset += 1;
|
||||
buffer.setInt16(offset, 0, Endianness.LITTLE_ENDIAN); offset += 2;
|
||||
buffer.setInt32(offset, -40, Endianness.LITTLE_ENDIAN); offset += 4;
|
||||
assert(_listEquals(buffer.buffer.asUint8List(),
|
||||
result.data.buffer.asUint8List()));
|
||||
}
|
||||
{
|
||||
var input = "[b]00001011 [b]10000000 // hello world\r [b]00000000";
|
||||
var result = parse(input);
|
||||
|
||||
// Check the parse results;
|
||||
var expected = [new _UnsignedEntry(1, 11),
|
||||
new _UnsignedEntry(1, 128),
|
||||
new _UnsignedEntry(1, 0)];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
|
||||
// Check the bits.
|
||||
var buffer = new ByteData(3);
|
||||
var offset = 0;
|
||||
buffer.setUint8(offset, 11); offset += 1;
|
||||
buffer.setUint8(offset, 128); offset += 1;
|
||||
buffer.setUint8(offset, 0); offset += 1;
|
||||
assert(_listEquals(buffer.buffer.asUint8List(),
|
||||
result.data.buffer.asUint8List()));
|
||||
}
|
||||
{
|
||||
var input = "[f]+.3e9 [d]-10.03";
|
||||
var result = parse(input);
|
||||
|
||||
// Check the parse results.
|
||||
var expected = [new _FloatEntry(4, 0.3e9),
|
||||
new _FloatEntry(8,-10.03)];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
|
||||
// Check the bits.
|
||||
var buffer = new ByteData(12);
|
||||
var offset = 0;
|
||||
buffer.setFloat32(offset, 0.3e9, Endianness.LITTLE_ENDIAN); offset += 4;
|
||||
buffer.setFloat64(offset, -10.03, Endianness.LITTLE_ENDIAN); offset += 8;
|
||||
assert(_listEquals(buffer.buffer.asUint8List(),
|
||||
result.data.buffer.asUint8List()));
|
||||
}
|
||||
{
|
||||
var input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar";
|
||||
var result = parse(input);
|
||||
|
||||
// Check the parse results.
|
||||
var expected = [new _DistEntry(4, "foo"),
|
||||
new _UnsignedEntry(1, 0),
|
||||
new _DistEntry(8, "bar"),
|
||||
new _UnsignedEntry(1, 0),
|
||||
new _AnchrEntry("foo"),
|
||||
new _AnchrEntry("bar")];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
|
||||
// Check the bits.
|
||||
var buffer = new ByteData(14);
|
||||
var offset = 0;
|
||||
buffer.setUint32(offset, 14, Endianness.LITTLE_ENDIAN); offset += 4;
|
||||
buffer.setUint8(offset, 0); offset += 1;
|
||||
buffer.setUint64(offset, 9, Endianness.LITTLE_ENDIAN); offset += 8;
|
||||
buffer.setUint8(offset, 0); offset += 1;
|
||||
assert(_listEquals(buffer.buffer.asUint8List(),
|
||||
result.data.buffer.asUint8List()));
|
||||
}
|
||||
{
|
||||
var input = "// This message has handles! \n[handles]50 [u8]2";
|
||||
var result = parse(input);
|
||||
var expected = [new _HandlesEntry(50),
|
||||
new _UnsignedEntry(8, 2)];
|
||||
assert(_listEquals(result._entries, expected));
|
||||
}
|
||||
{
|
||||
var errorInputs = ["/ hello world",
|
||||
"[u1]x",
|
||||
"[u2]-1000",
|
||||
"[u1]0x100",
|
||||
"[s2]-0x8001",
|
||||
"[b]1",
|
||||
"[b]1111111k",
|
||||
"[dist4]unmatched",
|
||||
"[anchr]hello [dist8]hello",
|
||||
"[dist4]a [dist4]a [anchr]a",
|
||||
"[dist4]a [anchr]a [dist4]a [anchr]a",
|
||||
"0 [handles]50"];
|
||||
for (var input in errorInputs) {
|
||||
try {
|
||||
var result = parse(input);
|
||||
assert(false);
|
||||
} on ValidationParseError catch(e) {
|
||||
// Pass.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
name: _testing
|
||||
description: Internal testing library for dart unittests.
|
||||
@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import yaml
|
||||
|
||||
|
||||
MOJO_DART_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(MOJO_DART_TOOLS_DIR)))
|
||||
MOJO_DIR = os.path.join(SRC_DOOT, 'mojo', 'public', 'dart')
|
||||
MOJO_PUBSPEC = os.path.join(MOJO_DIR, 'pubspec.yaml')
|
||||
MOJO_PUBSPEC_LOCK = os.path.join(MOJO_DIR, 'pubspec.lock')
|
||||
SDK_EXT = os.path.join(MOJO_DIR, 'lib', '_sdkext')
|
||||
|
||||
SDK_EXT_TEMPLATE = '''{
|
||||
"dart:mojo.internal": "%(build_dir)s/gen/dart-pkg/mojo/sdk_ext/internal.dart"
|
||||
}'''
|
||||
|
||||
def version_for_pubspec(pubspec_path):
|
||||
with open(pubspec_path, 'r') as stream:
|
||||
dependency_spec = yaml.load(stream)
|
||||
return dependency_spec['version']
|
||||
|
||||
|
||||
def entry_for_dependency(dart_pkg_dir, dependency):
|
||||
dependency_path = os.path.join(dart_pkg_dir, dependency)
|
||||
version = version_for_pubspec(os.path.join(dependency_path, 'pubspec.yaml'))
|
||||
return {
|
||||
'description': {
|
||||
'path': os.path.relpath(dependency_path, MOJO_DIR),
|
||||
'relative': True,
|
||||
},
|
||||
'source': 'path',
|
||||
'version': version,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Adds files to the source tree to make the dart analyzer happy')
|
||||
parser.add_argument('build_dir', type=str, help='Path the build directory to use for build artifacts')
|
||||
args = parser.parse_args()
|
||||
|
||||
dart_pkg_dir = os.path.join(args.build_dir, 'gen', 'dart-pkg')
|
||||
|
||||
if not os.path.exists(dart_pkg_dir):
|
||||
print 'Cannot find Dart pacakges at "%s".' % dart_pkg_dir
|
||||
print 'Did you run `ninja -C %s` ?' % os.path.relpath(args.build_dir, os.getcwd())
|
||||
return 1
|
||||
|
||||
packages = {}
|
||||
|
||||
with open(MOJO_PUBSPEC, 'r') as stream:
|
||||
spec = yaml.load(stream)
|
||||
for dependency in spec['dependencies'].keys():
|
||||
packages[dependency] = entry_for_dependency(dart_pkg_dir, dependency)
|
||||
|
||||
lock = { 'packages': packages }
|
||||
with open(MOJO_PUBSPEC_LOCK, 'w') as stream:
|
||||
yaml.dump(lock, stream=stream, default_flow_style=False)
|
||||
|
||||
with open(SDK_EXT, 'w') as stream:
|
||||
rebased_build_dir = os.path.relpath(args.build_dir, os.path.dirname(SDK_EXT))
|
||||
stream.write(SDK_EXT_TEMPLATE % { 'build_dir': rebased_build_dir })
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -74,7 +74,7 @@ dirs_from_mojo = [
|
||||
'mojo/application',
|
||||
'mojo/common',
|
||||
'mojo/converters',
|
||||
'mojo/dart',
|
||||
'mojo/dart/embedder',
|
||||
'mojo/data_pipe_utils',
|
||||
'mojo/edk',
|
||||
'mojo/environment',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user