1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/system/gonk/tests/test_ril_worker_buf.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,183 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +function run_test() { 1.8 + run_next_test(); 1.9 +} 1.10 + 1.11 +/** 1.12 + * Add test function with specified parcel and request handler. 1.13 + * 1.14 + * @param parcel 1.15 + * Incoming parcel to be tested. 1.16 + * @param handler 1.17 + * Handler to be invoked as RIL request handler. 1.18 + */ 1.19 +function add_test_incoming_parcel(parcel, handler) { 1.20 + add_test(function test_incoming_parcel() { 1.21 + let worker = newWorker({ 1.22 + postRILMessage: function(data) { 1.23 + // do nothing 1.24 + }, 1.25 + postMessage: function(message) { 1.26 + // do nothing 1.27 + } 1.28 + }); 1.29 + 1.30 + if (!parcel) { 1.31 + parcel = newIncomingParcel(-1, 1.32 + worker.RESPONSE_TYPE_UNSOLICITED, 1.33 + worker.REQUEST_VOICE_REGISTRATION_STATE, 1.34 + [0, 0, 0, 0]); 1.35 + } 1.36 + 1.37 + let context = worker.ContextPool._contexts[0]; 1.38 + // supports only requests less or equal than UINT8_MAX(255). 1.39 + let buf = context.Buf; 1.40 + let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE]; 1.41 + context.RIL[request] = function ril_request_handler() { 1.42 + handler.apply(this, arguments); 1.43 + }; 1.44 + 1.45 + worker.onRILMessage(0, parcel); 1.46 + 1.47 + // end of incoming parcel's trip, let's do next test. 1.48 + run_next_test(); 1.49 + }); 1.50 +} 1.51 + 1.52 +// Test normal parcel handling. 1.53 +add_test_incoming_parcel(null, 1.54 + function test_normal_parcel_handling() { 1.55 + let self = this; 1.56 + do_check_throws(function normal_handler() { 1.57 + // reads exactly the same size, should not throw anything. 1.58 + self.context.Buf.readInt32(); 1.59 + }); 1.60 + } 1.61 +); 1.62 + 1.63 +// Test parcel under read. 1.64 +add_test_incoming_parcel(null, 1.65 + function test_parcel_under_read() { 1.66 + let self = this; 1.67 + do_check_throws(function under_read_handler() { 1.68 + // reads less than parcel size, should not throw. 1.69 + self.context.Buf.readUint16(); 1.70 + }); 1.71 + } 1.72 +); 1.73 + 1.74 +// Test parcel over read. 1.75 +add_test_incoming_parcel(null, 1.76 + function test_parcel_over_read() { 1.77 + let buf = this.context.Buf; 1.78 + 1.79 + // read all data available 1.80 + while (buf.readAvailable > 0) { 1.81 + buf.readUint8(); 1.82 + } 1.83 + 1.84 + do_check_throws(function over_read_handler() { 1.85 + // reads more than parcel size, should throw an error. 1.86 + buf.readUint8(); 1.87 + },"Trying to read data beyond the parcel end!"); 1.88 + } 1.89 +); 1.90 + 1.91 +// Test Bug 814761: buffer overwritten 1.92 +add_test(function test_incoming_parcel_buffer_overwritten() { 1.93 + let worker = newWorker({ 1.94 + postRILMessage: function(data) { 1.95 + // do nothing 1.96 + }, 1.97 + postMessage: function(message) { 1.98 + // do nothing 1.99 + } 1.100 + }); 1.101 + 1.102 + let context = worker.ContextPool._contexts[0]; 1.103 + // A convenient alias. 1.104 + let buf = context.Buf; 1.105 + 1.106 + // Allocate an array of specified size and set each of its elements to value. 1.107 + function calloc(length, value) { 1.108 + let array = new Array(length); 1.109 + for (let i = 0; i < length; i++) { 1.110 + array[i] = value; 1.111 + } 1.112 + return array; 1.113 + } 1.114 + 1.115 + // Do nothing in handleParcel(). 1.116 + let request = worker.REQUEST_VOICE_REGISTRATION_STATE; 1.117 + context.RIL[request] = null; 1.118 + 1.119 + // Prepare two parcels, whose sizes are both smaller than the incoming buffer 1.120 + // size but larger when combined, to trigger the bug. 1.121 + let pA_dataLength = buf.incomingBufferLength / 2; 1.122 + let pA = newIncomingParcel(-1, 1.123 + worker.RESPONSE_TYPE_UNSOLICITED, 1.124 + request, 1.125 + calloc(pA_dataLength, 1)); 1.126 + let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE; 1.127 + 1.128 + let pB_dataLength = buf.incomingBufferLength * 3 / 4; 1.129 + let pB = newIncomingParcel(-1, 1.130 + worker.RESPONSE_TYPE_UNSOLICITED, 1.131 + request, 1.132 + calloc(pB_dataLength, 1)); 1.133 + let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE; 1.134 + 1.135 + // First, send an incomplete pA and verifies related data pointer: 1.136 + let p1 = pA.subarray(0, pA.length - 1); 1.137 + worker.onRILMessage(0, p1); 1.138 + // The parcel should not have been processed. 1.139 + do_check_eq(buf.readAvailable, 0); 1.140 + // buf.currentParcelSize should have been set because incoming data has more 1.141 + // than 4 octets. 1.142 + do_check_eq(buf.currentParcelSize, pA_parcelSize); 1.143 + // buf.readIncoming should contains remaining unconsumed octets count. 1.144 + do_check_eq(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE); 1.145 + // buf.incomingWriteIndex should be ready to accept the last octet. 1.146 + do_check_eq(buf.incomingWriteIndex, p1.length); 1.147 + 1.148 + // Second, send the last octet of pA and whole pB. The Buf should now expand 1.149 + // to cover both pA & pB. 1.150 + let p2 = new Uint8Array(1 + pB.length); 1.151 + p2.set(pA.subarray(pA.length - 1), 0); 1.152 + p2.set(pB, 1); 1.153 + worker.onRILMessage(0, p2); 1.154 + // The parcels should have been both consumed. 1.155 + do_check_eq(buf.readAvailable, 0); 1.156 + // No parcel data remains. 1.157 + do_check_eq(buf.currentParcelSize, 0); 1.158 + // No parcel data remains. 1.159 + do_check_eq(buf.readIncoming, 0); 1.160 + // The Buf should now expand to cover both pA & pB. 1.161 + do_check_eq(buf.incomingWriteIndex, pA.length + pB.length); 1.162 + 1.163 + // end of incoming parcel's trip, let's do next test. 1.164 + run_next_test(); 1.165 +}); 1.166 + 1.167 +// Test Buf.readUint8Array. 1.168 +add_test_incoming_parcel(null, 1.169 + function test_buf_readUint8Array() { 1.170 + let buf = this.context.Buf; 1.171 + 1.172 + let u8array = buf.readUint8Array(1); 1.173 + do_check_eq(u8array instanceof Uint8Array, true); 1.174 + do_check_eq(u8array.length, 1); 1.175 + do_check_eq(buf.readAvailable, 3); 1.176 + 1.177 + u8array = buf.readUint8Array(2); 1.178 + do_check_eq(u8array.length, 2); 1.179 + do_check_eq(buf.readAvailable, 1); 1.180 + 1.181 + do_check_throws(function over_read_handler() { 1.182 + // reads more than parcel size, should throw an error. 1.183 + u8array = buf.readUint8Array(2); 1.184 + }, "Trying to read data beyond the parcel end!"); 1.185 + } 1.186 +);