summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/tests/test_ril_worker_buf.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/system/gonk/tests/test_ril_worker_buf.js')
-rw-r--r--dom/system/gonk/tests/test_ril_worker_buf.js187
1 files changed, 187 insertions, 0 deletions
diff --git a/dom/system/gonk/tests/test_ril_worker_buf.js b/dom/system/gonk/tests/test_ril_worker_buf.js
new file mode 100644
index 000000000..30054a881
--- /dev/null
+++ b/dom/system/gonk/tests/test_ril_worker_buf.js
@@ -0,0 +1,187 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ run_next_test();
+}
+
+/**
+ * Add test function with specified parcel and request handler.
+ *
+ * @param parcel
+ * Incoming parcel to be tested.
+ * @param handler
+ * Handler to be invoked as RIL request handler.
+ */
+function add_test_incoming_parcel(parcel, handler) {
+ add_test(function test_incoming_parcel() {
+ let worker = newWorker({
+ postRILMessage: function(data) {
+ // do nothing
+ },
+ postMessage: function(message) {
+ // do nothing
+ }
+ });
+
+ if (!parcel) {
+ parcel = newIncomingParcel(-1,
+ worker.RESPONSE_TYPE_UNSOLICITED,
+ worker.REQUEST_VOICE_REGISTRATION_STATE,
+ [0, 0, 0, 0]);
+ }
+
+ let context = worker.ContextPool._contexts[0];
+ // supports only requests less or equal than UINT8_MAX(255).
+ let buf = context.Buf;
+ let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE];
+ context.RIL[request] = function ril_request_handler() {
+ handler.apply(this, arguments);
+ };
+
+ worker.onRILMessage(0, parcel);
+
+ // end of incoming parcel's trip, let's do next test.
+ run_next_test();
+ });
+}
+
+// Test normal parcel handling.
+add_test_incoming_parcel(null,
+ function test_normal_parcel_handling() {
+ let self = this;
+ try {
+ // reads exactly the same size, should not throw anything.
+ self.context.Buf.readInt32();
+ } catch (e) {
+ ok(false, "Got exception: " + e);
+ }
+ }
+);
+
+// Test parcel under read.
+add_test_incoming_parcel(null,
+ function test_parcel_under_read() {
+ let self = this;
+ try {
+ // reads less than parcel size, should not throw.
+ self.context.Buf.readUint16();
+ } catch (e) {
+ ok(false, "Got exception: " + e);
+ }
+ }
+);
+
+// Test parcel over read.
+add_test_incoming_parcel(null,
+ function test_parcel_over_read() {
+ let buf = this.context.Buf;
+
+ // read all data available
+ while (buf.readAvailable > 0) {
+ buf.readUint8();
+ }
+
+ throws(function over_read_handler() {
+ // reads more than parcel size, should throw an error.
+ buf.readUint8();
+ },"Trying to read data beyond the parcel end!");
+ }
+);
+
+// Test Bug 814761: buffer overwritten
+add_test(function test_incoming_parcel_buffer_overwritten() {
+ let worker = newWorker({
+ postRILMessage: function(data) {
+ // do nothing
+ },
+ postMessage: function(message) {
+ // do nothing
+ }
+ });
+
+ let context = worker.ContextPool._contexts[0];
+ // A convenient alias.
+ let buf = context.Buf;
+
+ // Allocate an array of specified size and set each of its elements to value.
+ function calloc(length, value) {
+ let array = new Array(length);
+ for (let i = 0; i < length; i++) {
+ array[i] = value;
+ }
+ return array;
+ }
+
+ // Do nothing in handleParcel().
+ let request = worker.REQUEST_VOICE_REGISTRATION_STATE;
+ context.RIL[request] = null;
+
+ // Prepare two parcels, whose sizes are both smaller than the incoming buffer
+ // size but larger when combined, to trigger the bug.
+ let pA_dataLength = buf.incomingBufferLength / 2;
+ let pA = newIncomingParcel(-1,
+ worker.RESPONSE_TYPE_UNSOLICITED,
+ request,
+ calloc(pA_dataLength, 1));
+ let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE;
+
+ let pB_dataLength = buf.incomingBufferLength * 3 / 4;
+ let pB = newIncomingParcel(-1,
+ worker.RESPONSE_TYPE_UNSOLICITED,
+ request,
+ calloc(pB_dataLength, 1));
+ let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE;
+
+ // First, send an incomplete pA and verifies related data pointer:
+ let p1 = pA.subarray(0, pA.length - 1);
+ worker.onRILMessage(0, p1);
+ // The parcel should not have been processed.
+ equal(buf.readAvailable, 0);
+ // buf.currentParcelSize should have been set because incoming data has more
+ // than 4 octets.
+ equal(buf.currentParcelSize, pA_parcelSize);
+ // buf.readIncoming should contains remaining unconsumed octets count.
+ equal(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE);
+ // buf.incomingWriteIndex should be ready to accept the last octet.
+ equal(buf.incomingWriteIndex, p1.length);
+
+ // Second, send the last octet of pA and whole pB. The Buf should now expand
+ // to cover both pA & pB.
+ let p2 = new Uint8Array(1 + pB.length);
+ p2.set(pA.subarray(pA.length - 1), 0);
+ p2.set(pB, 1);
+ worker.onRILMessage(0, p2);
+ // The parcels should have been both consumed.
+ equal(buf.readAvailable, 0);
+ // No parcel data remains.
+ equal(buf.currentParcelSize, 0);
+ // No parcel data remains.
+ equal(buf.readIncoming, 0);
+ // The Buf should now expand to cover both pA & pB.
+ equal(buf.incomingWriteIndex, pA.length + pB.length);
+
+ // end of incoming parcel's trip, let's do next test.
+ run_next_test();
+});
+
+// Test Buf.readUint8Array.
+add_test_incoming_parcel(null,
+ function test_buf_readUint8Array() {
+ let buf = this.context.Buf;
+
+ let u8array = buf.readUint8Array(1);
+ equal(u8array instanceof Uint8Array, true);
+ equal(u8array.length, 1);
+ equal(buf.readAvailable, 3);
+
+ u8array = buf.readUint8Array(2);
+ equal(u8array.length, 2);
+ equal(buf.readAvailable, 1);
+
+ throws(function over_read_handler() {
+ // reads more than parcel size, should throw an error.
+ u8array = buf.readUint8Array(2);
+ }, "Trying to read data beyond the parcel end!");
+ }
+);