Test harness that tests Dart client <=> Go server communication.
Change-Id: I18bac956eeba1c44067d2c4aeb5b54609ef28f7a
diff --git a/.gitignore b/.gitignore
index e648e97..cacfb4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,6 @@
# Dart dependencies
/dart/.packages
+/dart/.pub
/dart/pubspec.lock
/dart/**/packages
diff --git a/Makefile b/Makefile
index 8534ec7..f4868f4 100644
--- a/Makefile
+++ b/Makefile
@@ -122,9 +122,14 @@
run-syncbase-app: gen/mojo/syncbase_server.mojo gen-mojom dart/packages
$(MOJO_DIR)/src/mojo/devtools/common/mojo_run $(MOJO_FLAGS) -v --enable-multiprocess $(PWD)/dart/bin/syncbase_client.dart
-# TODO(nlacasse): This should run real tests once we have them.
.PHONY: test
-test: dartanalyzer
+test: dartanalyzer gen-mojom gen/mojo/echo_server.mojo
+ # TODO(nlacasse): We should be passing "--enable-multiprocess" here, since
+ # that is usually needed for Go Mojo services. However, using that flag
+ # causes the test runner to crash on exit with "Connection error to the
+ # shell". The tests somehow run and pass without that flag, so maybe it's
+ # not necessary?
+ $(MOJO_DIR)/src/mojo/devtools/common/mojo_test $(MOJO_FLAGS) -v --shell-path $(MOJO_DIR)/src/out/Debug/mojo_shell tests
.PHONY: clean
clean:
diff --git a/README.md b/README.md
index b9353e3..a92cc72 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,15 @@
Googlers: http://go/install-dart
External: https://www.dartlang.org/downloads/
+## Testing
+
+Run the tests:
+
+ make test
+
+This will run all tests listed in the `tests` file in the root directory of
+this repo.
+
[architecture proposal]: https://docs.google.com/document/d/1TyxPYIhj9VBCtY7eAXu_MEV9y0dtRx7n7UY4jm76Qq4/edit
[depot tools]: http://www.chromium.org/developers/how-tos/install-depot-tools
[goma]: https://sites.google.com/a/google.com/goma/how-to-use-goma/how-to-use-goma-for-chrome-team
diff --git a/dart/bin/echo_client.dart b/dart/bin/echo_client.dart
index b919391..bb8aa73 100644
--- a/dart/bin/echo_client.dart
+++ b/dart/bin/echo_client.dart
@@ -30,7 +30,7 @@
String input = 'foobee';
print('calling echoString($input)');
- ep.ptr.echoString(input).then((EchoEchoStringResponseParams v) {
+ p.ptr.echoString(input).then((EchoEchoStringResponseParams v) {
String output = v.value;
print('got echo result: $output');
diff --git a/dart/lib/src/apptest/apptest.dart b/dart/lib/src/apptest/apptest.dart
new file mode 100644
index 0000000..83303ea
--- /dev/null
+++ b/dart/lib/src/apptest/apptest.dart
@@ -0,0 +1,70 @@
+// 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.
+
+// TODO(nlacasse): This file was copied from
+// $MOJO_DIR/src/mojo/dart/apptest/lib/apptest.dart.
+// The Mojo team has plans to make this library available in Pub. Once they
+// do, we should delete this file, and use the one in Pub.
+
+library apptest;
+
+import 'package:mojo/application.dart';
+import 'package:mojo/core.dart';
+
+// Import and reexport the test package. We are a *.dartzip file designed to
+// be linked into your_apptest.mojo file and are your main entrypoint.
+import 'package:test/test.dart';
+export 'package:test/test.dart';
+
+typedef AppTestFunction(Application app, String url);
+
+// This class is an application that does nothing but tears down the connections
+// between each test.
+class _ConnectionToShellApplication extends Application {
+ final List<AppTestFunction> _testFunctions;
+
+ _ConnectionToShellApplication.fromHandle(
+ MojoHandle handle, this._testFunctions)
+ : super.fromHandle(handle);
+
+ // Only run the test suite passed in once we have received an initialize()
+ // call from the shell. We need to first have a valid connection to the shell
+ // so that apptests can connect to other applications.
+ void initialize(List<String> args, String url) {
+ group('dart_apptests', () {
+ setUp(testSetUp);
+ tearDown(testTearDown);
+ for (var testFunction in _testFunctions) {
+ testFunction(this, url);
+ }
+ });
+ // Append a final test to terminate shell connection.
+ // TODO(johnmccutchan): Remove this once package 'test' supports a global
+ // tearDown callback.
+ test('TERMINATE SHELL CONNECTION', () async {
+ await close();
+ assert(MojoHandle.reportLeakedHandles());
+ });
+ }
+
+ void testSetUp() {
+ }
+
+ void testTearDown() {
+ // Reset any connections between tests.
+ resetConnections();
+ }
+}
+
+/// The public interface to apptests.
+///
+/// In a dart mojo application, [incomingHandle] is `args[0]`. [testFunctions]
+/// is list of [AppTestFunction]. Each function will be passed the application
+/// and url.
+runAppTests(var incomingHandle, List<AppTestFunction> testFunctions) {
+ var appHandle = new MojoHandle(incomingHandle);
+ var application =
+ new _ConnectionToShellApplication.fromHandle(appHandle, testFunctions);
+ /// [Application]'s [initialize] will be called.
+}
diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml
index 9f863bd..fe4af35 100644
--- a/dart/pubspec.yaml
+++ b/dart/pubspec.yaml
@@ -1,3 +1,4 @@
name: Ether
dependencies:
mojo: any
+ test: any
diff --git a/dart/test/echo_test.dart b/dart/test/echo_test.dart
new file mode 100644
index 0000000..ef6b69b
--- /dev/null
+++ b/dart/test/echo_test.dart
@@ -0,0 +1,36 @@
+#!mojo mojo:dart_content_handler
+
+import 'dart:async';
+
+import 'package:mojo/application.dart' show Application;
+
+// TODO(nlacasse): Get this library from Pub once it is available there.
+import '../lib/src/apptest/apptest.dart';
+
+import '../../gen/dart-gen/mojom/lib/mojo/echo.mojom.dart' show EchoEchoStringResponseParams, EchoProxy;
+
+echoTests(Application app, String url) {
+ // TODO(nlacasse): This is pretty gross, but there's no good way to get the
+ // current directory from within a Mojo app. Dart's Directory.current() is
+ // either broken or unsupported. In any case, this will never work on
+ // Android, so we should switch to serving these files over http rather
+ // than directly from the filesystem.
+ String echoServerUrl = url.replaceFirst('dart/test/echo_test.dart', 'gen/mojo/echo_server.mojo');
+
+ test('echo returns correct response', () async {
+ EchoProxy ep = new EchoProxy.unbound();
+ app.connectToService(echoServerUrl, ep);
+
+ String input = 'foobee';
+ var v = await ep.ptr.echoString(input);
+ expect(v.value, equals(input));
+
+ await ep.ptr.quit();
+ await ep.close();
+ });
+}
+
+Future<int> main(List args) async {
+ var exitCode = await runAppTests(args[0], [echoTests]);
+ return exitCode;
+}
diff --git a/go/src/echo_server.go b/go/src/echo_server.go
index 2a8ccd8..b0c1a14 100644
--- a/go/src/echo_server.go
+++ b/go/src/echo_server.go
@@ -22,13 +22,20 @@
//#include "mojo/public/c/system/types.h"
import "C"
-type echoImpl struct{}
+type echoImpl struct {
+ stub *bindings.Stub
+}
func (e *echoImpl) EchoString(in *string) (out *string, err error) {
log.Printf("server: %s\n", *in)
return in, nil
}
+func (echo *echoImpl) Quit() error {
+ echo.stub.Close()
+ return nil
+}
+
type delegate struct {
stubs []*bindings.Stub
}
@@ -38,6 +45,7 @@
func (d *delegate) Create(req echo.Echo_Request) {
impl := &echoImpl{}
stub := echo.NewEchoStub(req, impl, bindings.GetAsyncWaiter())
+ impl.stub = stub
d.stubs = append(d.stubs, stub)
go func() {
for {
diff --git a/mojom/echo.mojom b/mojom/echo.mojom
index cd341d2..62d7ccf 100644
--- a/mojom/echo.mojom
+++ b/mojom/echo.mojom
@@ -2,9 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-[JavaPackage="org.chromium.mojom.echo"]
module mojo;
interface Echo {
EchoString(string? value) => (string? value);
+
+ // TODO(nlacasse): The test runner currently needs this Quit method to tell
+ // the echo service to quit, otherwise the tests hang because the echo
+ // service never stops running and listening for connections.
+ //
+ // The Mojo dart tests that this is based on do essentially the same thing.
+ // See $MOJO_DIR/src/services/dart/dart_apptests/echo_apptests.dart
+ //
+ // The "Quitting Mojo Apps" document
+ // (https://drive.google.com/a/google.com/folderview?id=0B-WCZkfLIXQTajI4WWZhdGhjNnM)
+ // says that Mojo applications should gracefully quit when Mojo shell
+ // terminates (see Condition C in that doc), but that does not appear to be
+ // implemented yet.
+ //
+ // Once the Mojo app can gracefully terminate on shell exit, we should get
+ // rid of this method.
+ Quit();
};
diff --git a/tests b/tests
new file mode 100644
index 0000000..c3ed059
--- /dev/null
+++ b/tests
@@ -0,0 +1,9 @@
+// See $MOJO_DIR/src/mojo/devtools/common/mojo_test for the format of this
+// file.
+
+tests = [
+ {
+ "test": "dart/test/echo_test.dart",
+ "type": "dart"
+ }
+]