• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5define([
6    "gin/test/expect",
7    "mojo/public/js/connection",
8    "mojo/public/js/core",
9    "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
10    "mojo/public/interfaces/bindings/tests/sample_service.mojom",
11    "mojo/public/js/threading",
12    "gc",
13], function(expect,
14            connection,
15            core,
16            sample_interfaces,
17            sample_service,
18            threading,
19            gc) {
20  testClientServer()
21      .then(testWriteToClosedPipe)
22      .then(testRequestResponse)
23      .then(function() {
24    this.result = "PASS";
25    gc.collectGarbage();  // should not crash
26    threading.quit();
27  }.bind(this)).catch(function(e) {
28    this.result = "FAIL: " + (e.stack || e);
29    threading.quit();
30  }.bind(this));
31
32  function testClientServer() {
33    // ServiceImpl ------------------------------------------------------------
34
35    function ServiceImpl() {
36    }
37
38    ServiceImpl.prototype = Object.create(
39        sample_service.Service.stubClass.prototype);
40
41    ServiceImpl.prototype.frobinate = function(foo, baz, port) {
42      expect(foo.name).toBe("Example name");
43      expect(baz).toBe(sample_service.Service.BazOptions.REGULAR);
44      expect(core.close(port)).toBe(core.RESULT_OK);
45
46      return Promise.resolve({result: 42});
47    };
48
49    var pipe = core.createMessagePipe();
50    var anotherPipe = core.createMessagePipe();
51    var sourcePipe = core.createMessagePipe();
52
53    var connection0 = new connection.Connection(pipe.handle0, ServiceImpl);
54
55    var connection1 = new connection.Connection(
56        pipe.handle1, undefined, sample_service.Service.proxyClass);
57
58    var foo = new sample_service.Foo();
59    foo.bar = new sample_service.Bar();
60    foo.name = "Example name";
61    foo.source = sourcePipe.handle0;
62    var promise = connection1.remote.frobinate(
63        foo, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0)
64            .then(function(response) {
65      expect(response.result).toBe(42);
66
67      connection0.close();
68      connection1.close();
69
70      return Promise.resolve();
71    });
72
73    // sourcePipe.handle1 hasn't been closed yet.
74    expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK);
75
76    // anotherPipe.handle1 hasn't been closed yet.
77    expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK);
78
79    return promise;
80  }
81
82  function testWriteToClosedPipe() {
83    var pipe = core.createMessagePipe();
84    var anotherPipe = core.createMessagePipe();
85
86    var connection1 = new connection.Connection(
87        pipe.handle1, function() {}, sample_service.Service.proxyClass);
88
89    // Close the other end of the pipe.
90    core.close(pipe.handle0);
91
92    // Not observed yet because we haven't pumped events yet.
93    expect(connection1.encounteredError()).toBeFalsy();
94
95    var promise = connection1.remote.frobinate(
96        null, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0)
97            .then(function(response) {
98      return Promise.reject("Unexpected response");
99    }).catch(function(e) {
100      // We should observe the closed pipe.
101      expect(connection1.encounteredError()).toBeTruthy();
102      return Promise.resolve();
103    });
104
105    // Write failures are not reported.
106    expect(connection1.encounteredError()).toBeFalsy();
107
108    return promise;
109  }
110
111  function testRequestResponse() {
112    // ProviderImpl ------------------------------------------------------------
113
114    function ProviderImpl() {
115    }
116
117    ProviderImpl.prototype =
118        Object.create(sample_interfaces.Provider.stubClass.prototype);
119
120    ProviderImpl.prototype.echoString = function(a) {
121      return Promise.resolve({a: a});
122    };
123
124    ProviderImpl.prototype.echoStrings = function(a, b) {
125      return Promise.resolve({a: a, b: b});
126    };
127
128    var pipe = core.createMessagePipe();
129
130    var connection0 = new connection.Connection(pipe.handle0, ProviderImpl);
131
132    var connection1 = new connection.Connection(
133        pipe.handle1, undefined, sample_interfaces.Provider.proxyClass);
134
135    var promise = connection1.remote.echoString("hello")
136        .then(function(response) {
137      expect(response.a).toBe("hello");
138      return connection1.remote.echoStrings("hello", "world");
139    }).then(function(response) {
140      expect(response.a).toBe("hello");
141      expect(response.b).toBe("world");
142      // Mock a read failure, expect it to fail.
143      core.readMessage = function() {
144        return { result: core.RESULT_UNKNOWN };
145      };
146      return connection1.remote.echoString("goodbye");
147    }).then(function() {
148      throw Error("Expected echoString to fail.");
149    }, function(error) {
150      expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN);
151
152      return Promise.resolve();
153    });
154
155    return promise;
156  }
157});
158