1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/xpcshell/node-http2/node_modules/http2-protocol/test/connection.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,239 @@ 1.4 +var expect = require('chai').expect; 1.5 +var util = require('./util'); 1.6 + 1.7 +var Connection = require('../lib/connection').Connection; 1.8 + 1.9 +var settings = { 1.10 + SETTINGS_MAX_CONCURRENT_STREAMS: 100, 1.11 + SETTINGS_INITIAL_WINDOW_SIZE: 100000 1.12 +}; 1.13 + 1.14 +var MAX_PRIORITY = Math.pow(2, 31) - 1; 1.15 +var MAX_RANDOM_PRIORITY = 10; 1.16 + 1.17 +function randomPriority() { 1.18 + return Math.floor(Math.random() * (MAX_RANDOM_PRIORITY + 1)); 1.19 +} 1.20 + 1.21 +function expectPriorityOrder(priorities) { 1.22 + priorities.forEach(function(bucket, priority) { 1.23 + bucket.forEach(function(stream) { 1.24 + expect(stream._priority).to.be.equal(priority); 1.25 + }); 1.26 + }); 1.27 +} 1.28 + 1.29 +describe('connection.js', function() { 1.30 + describe('Connection class', function() { 1.31 + describe('method ._insert(stream)', function() { 1.32 + it('should insert the stream in _streamPriorities in a place determined by stream._priority', function() { 1.33 + var streams = []; 1.34 + var connection = Object.create(Connection.prototype, { _streamPriorities: { value: streams }}); 1.35 + var streamCount = 10; 1.36 + 1.37 + for (var i = 0; i < streamCount; i++) { 1.38 + var stream = { _priority: randomPriority() }; 1.39 + connection._insert(stream, stream._priority); 1.40 + expect(connection._streamPriorities[stream._priority]).to.include(stream); 1.41 + } 1.42 + 1.43 + expectPriorityOrder(connection._streamPriorities); 1.44 + }); 1.45 + }); 1.46 + describe('method ._reprioritize(stream)', function() { 1.47 + it('should eject and then insert the stream in _streamPriorities in a place determined by stream._priority', function() { 1.48 + var streams = []; 1.49 + var connection = Object.create(Connection.prototype, { _streamPriorities: { value: streams }}); 1.50 + var streamCount = 10; 1.51 + var oldPriority, newPriority, stream; 1.52 + 1.53 + for (var i = 0; i < streamCount; i++) { 1.54 + oldPriority = randomPriority(); 1.55 + while ((newPriority = randomPriority()) === oldPriority); 1.56 + stream = { _priority: oldPriority }; 1.57 + connection._insert(stream, oldPriority); 1.58 + connection._reprioritize(stream, newPriority); 1.59 + stream._priority = newPriority; 1.60 + 1.61 + expect(connection._streamPriorities[newPriority]).to.include(stream); 1.62 + expect(connection._streamPriorities[oldPriority] || []).to.not.include(stream); 1.63 + } 1.64 + 1.65 + expectPriorityOrder(streams); 1.66 + }); 1.67 + }); 1.68 + describe('invalid operation', function() { 1.69 + describe('unsolicited ping answer', function() { 1.70 + it('should be ignored', function() { 1.71 + var connection = new Connection(util.log, 1, settings); 1.72 + 1.73 + connection._receivePing({ 1.74 + stream: 0, 1.75 + type: 'PING', 1.76 + flags: { 1.77 + 'PONG': true 1.78 + }, 1.79 + data: new Buffer(8) 1.80 + }); 1.81 + }); 1.82 + }); 1.83 + }); 1.84 + }); 1.85 + describe('test scenario', function() { 1.86 + var c, s; 1.87 + beforeEach(function() { 1.88 + c = new Connection(util.log.child({ role: 'client' }), 1, settings); 1.89 + s = new Connection(util.log.child({ role: 'client' }), 2, settings); 1.90 + c.pipe(s).pipe(c); 1.91 + }); 1.92 + 1.93 + describe('connection setup', function() { 1.94 + it('should work as expected', function(done) { 1.95 + setTimeout(function() { 1.96 + // If there are no exception until this, then we're done 1.97 + done(); 1.98 + }, 10); 1.99 + }); 1.100 + }); 1.101 + describe('sending/receiving a request', function() { 1.102 + it('should work as expected', function(done) { 1.103 + // Request and response data 1.104 + var request_headers = { 1.105 + ':method': 'GET', 1.106 + ':path': '/' 1.107 + }; 1.108 + var request_data = new Buffer(0); 1.109 + var response_headers = { 1.110 + ':status': '200' 1.111 + }; 1.112 + var response_data = new Buffer('12345678', 'hex'); 1.113 + 1.114 + // Setting up server 1.115 + s.on('stream', function(server_stream) { 1.116 + server_stream.on('headers', function(headers) { 1.117 + expect(headers).to.deep.equal(request_headers); 1.118 + server_stream.headers(response_headers); 1.119 + server_stream.end(response_data); 1.120 + }); 1.121 + }); 1.122 + 1.123 + // Sending request 1.124 + var client_stream = c.createStream(); 1.125 + client_stream.headers(request_headers); 1.126 + client_stream.end(request_data); 1.127 + 1.128 + // Waiting for answer 1.129 + done = util.callNTimes(2, done); 1.130 + client_stream.on('headers', function(headers) { 1.131 + expect(headers).to.deep.equal(response_headers); 1.132 + done(); 1.133 + }); 1.134 + client_stream.on('readable', function() { 1.135 + expect(client_stream.read()).to.deep.equal(response_data); 1.136 + done(); 1.137 + }); 1.138 + }); 1.139 + }); 1.140 + describe('server push', function() { 1.141 + it('should work as expected', function(done) { 1.142 + var request_headers = { ':method': 'get', ':path': '/' }; 1.143 + var response_headers = { ':status': '200' }; 1.144 + var push_request_headers = { ':method': 'get', ':path': '/x' }; 1.145 + var push_response_headers = { ':status': '200' }; 1.146 + var response_content = new Buffer(10); 1.147 + var push_content = new Buffer(10); 1.148 + 1.149 + done = util.callNTimes(5, done); 1.150 + 1.151 + s.on('stream', function(response) { 1.152 + response.headers(response_headers); 1.153 + 1.154 + var pushed = response.promise(push_request_headers); 1.155 + pushed.headers(push_response_headers); 1.156 + pushed.end(push_content); 1.157 + 1.158 + response.end(response_content); 1.159 + }); 1.160 + 1.161 + var request = c.createStream(); 1.162 + request.headers(request_headers); 1.163 + request.end(); 1.164 + request.on('headers', function(headers) { 1.165 + expect(headers).to.deep.equal(response_headers); 1.166 + done(); 1.167 + }); 1.168 + request.on('readable', function() { 1.169 + expect(request.read()).to.deep.equal(response_content); 1.170 + done(); 1.171 + }); 1.172 + request.on('promise', function(pushed, headers) { 1.173 + expect(headers).to.deep.equal(push_request_headers); 1.174 + pushed.on('headers', function(headers) { 1.175 + expect(headers).to.deep.equal(response_headers); 1.176 + done(); 1.177 + }); 1.178 + pushed.on('readable', function() { 1.179 + expect(pushed.read()).to.deep.equal(push_content); 1.180 + done(); 1.181 + }); 1.182 + pushed.on('end', function() { 1.183 + done(); 1.184 + }); 1.185 + }); 1.186 + }); 1.187 + }); 1.188 + describe('ping from client', function() { 1.189 + it('should work as expected', function(done) { 1.190 + c.ping(function() { 1.191 + done(); 1.192 + }); 1.193 + }); 1.194 + }); 1.195 + describe('ping from server', function() { 1.196 + it('should work as expected', function(done) { 1.197 + s.ping(function() { 1.198 + done(); 1.199 + }); 1.200 + }); 1.201 + }); 1.202 + describe('creating two streams and then using them in reverse order', function() { 1.203 + it('should not result in non-monotonous local ID ordering', function() { 1.204 + var s1 = c.createStream(); 1.205 + var s2 = c.createStream(); 1.206 + s2.headers({ ':method': 'get', ':path': '/' }); 1.207 + s1.headers({ ':method': 'get', ':path': '/' }); 1.208 + }); 1.209 + }); 1.210 + describe('creating two promises and then using them in reverse order', function() { 1.211 + it('should not result in non-monotonous local ID ordering', function(done) { 1.212 + s.on('stream', function(response) { 1.213 + response.headers({ ':status': '200' }); 1.214 + 1.215 + var p1 = s.createStream(); 1.216 + var p2 = s.createStream(); 1.217 + response.promise(p2, { ':method': 'get', ':path': '/p2' }); 1.218 + response.promise(p1, { ':method': 'get', ':path': '/p1' }); 1.219 + p2.headers({ ':status': '200' }); 1.220 + p1.headers({ ':status': '200' }); 1.221 + }); 1.222 + 1.223 + var request = c.createStream(); 1.224 + request.headers({ ':method': 'get', ':path': '/' }); 1.225 + 1.226 + done = util.callNTimes(2, done); 1.227 + request.on('promise', function() { 1.228 + done(); 1.229 + }); 1.230 + }); 1.231 + }); 1.232 + describe('closing the connection on one end', function() { 1.233 + it('should result in closed streams on both ends', function(done) { 1.234 + done = util.callNTimes(2, done); 1.235 + c.on('end', done); 1.236 + s.on('end', done); 1.237 + 1.238 + c.close(); 1.239 + }); 1.240 + }); 1.241 + }); 1.242 +});