Add an e2e test using the worker and driver from this package (#7)

diff --git a/e2e_test/bin/async_worker.dart b/e2e_test/bin/async_worker.dart
new file mode 100644
index 0000000..e2d0536
--- /dev/null
+++ b/e2e_test/bin/async_worker.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, 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.
+
+import 'dart:async';
+
+import 'package:e2e_test/async_worker.dart';
+
+Future main() async {
+  await new ExampleAsyncWorker().run();
+}
diff --git a/e2e_test/bin/sync_worker.dart b/e2e_test/bin/sync_worker.dart
new file mode 100644
index 0000000..e87b1c8
--- /dev/null
+++ b/e2e_test/bin/sync_worker.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2017, 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.
+
+import 'package:e2e_test/sync_worker.dart';
+
+void main() {
+  new ExampleSyncWorker().run();
+}
diff --git a/e2e_test/lib/async_worker.dart b/e2e_test/lib/async_worker.dart
new file mode 100644
index 0000000..b8239d3
--- /dev/null
+++ b/e2e_test/lib/async_worker.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, 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.
+
+import 'dart:async';
+
+import 'package:bazel_worker/bazel_worker.dart';
+
+/// Example worker that just returns in its response all the arguments passed
+/// separated by newlines.
+class ExampleAsyncWorker extends AsyncWorkerLoop {
+  Future<WorkResponse> performRequest(WorkRequest request) async {
+    return new WorkResponse()
+      ..exitCode = 0
+      ..output = request.arguments.join('\n');
+  }
+}
diff --git a/e2e_test/lib/sync_worker.dart b/e2e_test/lib/sync_worker.dart
new file mode 100644
index 0000000..7c98dbe
--- /dev/null
+++ b/e2e_test/lib/sync_worker.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2017, 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.
+
+import 'package:bazel_worker/bazel_worker.dart';
+
+/// Example worker that just returns in its response all the arguments passed
+/// separated by newlines.
+class ExampleSyncWorker extends SyncWorkerLoop {
+  WorkResponse performRequest(WorkRequest request) {
+    return new WorkResponse()
+      ..exitCode = 0
+      ..output = request.arguments.join('\n');
+  }
+}
diff --git a/e2e_test/pubspec.yaml b/e2e_test/pubspec.yaml
new file mode 100644
index 0000000..9ecc48c
--- /dev/null
+++ b/e2e_test/pubspec.yaml
@@ -0,0 +1,8 @@
+name: e2e_test
+dependencies:
+  bazel_worker:
+    path: ../
+dev_dependencies:
+  cli_util: ^0.0.1
+  path: ^1.4.1
+  test: ^0.12.0
diff --git a/e2e_test/test/e2e_test.dart b/e2e_test/test/e2e_test.dart
new file mode 100644
index 0000000..2879219
--- /dev/null
+++ b/e2e_test/test/e2e_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2017, 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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:bazel_worker/driver.dart';
+import 'package:cli_util/cli_util.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+
+void main() {
+  var sdkDir = getSdkDir();
+  var dart = p.join(sdkDir.path, 'bin', 'dart');
+  runE2eTestForWorker('sync worker',
+      () => Process.start(dart, [p.join('bin', 'sync_worker.dart')]));
+  runE2eTestForWorker('async worker',
+      () => Process.start(dart, [p.join('bin', 'async_worker.dart')]));
+}
+
+void runE2eTestForWorker(String groupName, SpawnWorker spawnWorker) {
+  BazelWorkerDriver driver;
+  group(groupName, () {
+    setUp(() {
+      driver = new BazelWorkerDriver(spawnWorker);
+    });
+
+    tearDown(() async {
+      await driver.terminateWorkers();
+    });
+
+    test('single work request', () async {
+      await _doRequests(driver, count: 1);
+    });
+
+    test('lots of requests', () async {
+      await _doRequests(driver, count: 1000);
+    });
+  });
+}
+
+/// Runs [count] work requests through [driver], and asserts that they all
+/// completed with the correct response.
+Future _doRequests(BazelWorkerDriver driver, {int count}) async {
+  count ??= 100;
+  var requests = new List.generate(count, (requestNum) {
+    var request = new WorkRequest();
+    request.arguments
+        .addAll(new List.generate(requestNum, (argNum) => '$argNum'));
+    return request;
+  });
+  var responses = await Future.wait(requests.map(driver.doWork));
+  for (int i = 0; i < responses.length; i++) {
+    var request = requests[i];
+    var response = responses[i];
+    expect(response.exitCode, EXIT_CODE_OK);
+    expect(response.output, request.arguments.join('\n'));
+  }
+}
diff --git a/tool/travis.sh b/tool/travis.sh
index c153627..a011957 100755
--- a/tool/travis.sh
+++ b/tool/travis.sh
@@ -16,3 +16,9 @@
 
 # Run the tests.
 pub run test
+
+pushd e2e_test
+pub get
+dartanalyzer --fatal-warnings test/e2e_test.dart
+pub run test
+popd