From d0ef758024a53e878b8b9d17bfb8b780fb557514 Mon Sep 17 00:00:00 2001
From: Moritz Langenstein <ml5717@ic.ac.uk>
Date: Sat, 30 Nov 2019 19:51:52 +0000
Subject: [PATCH] (ml5717) Added network->frontend benchmark for sequential
 paths

---
 .gitlab-ci.yml              |  15 ++-
 __tests__/benchmark.test.js | 252 +++++++++++++++++++++++++++---------
 2 files changed, 199 insertions(+), 68 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d03fde3..f2c95d0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,6 +8,7 @@ stages:
   - build
   - test
   - deploy
+  - benchmark
 
 submodule_fetch:
   stage: fetch
@@ -84,13 +85,6 @@ test:
   script:
     - npm run test
 
-benchmark:
-  stage: test
-  dependencies:
-    - npm_install
-  script:
-    - npm run test-benchmark
-
 chrome_test:
   stage: test
   dependencies:
@@ -111,3 +105,10 @@ deploy:
     - apt-get update -qq && apt-get install -qq zip
     - zip -r application.zip *
     - curl -X POST -u "$DEPLOYMENT_USERNAME:$DEPLOYMENT_PASSWORD" $DEPLOYMENT_ENDPOINT -T application.zip
+
+benchmark:
+  stage: benchmark
+  dependencies:
+    - npm_install
+  script:
+    - npm run test-benchmark
diff --git a/__tests__/benchmark.test.js b/__tests__/benchmark.test.js
index dedc0fa..69c6ee3 100644
--- a/__tests__/benchmark.test.js
+++ b/__tests__/benchmark.test.js
@@ -198,7 +198,7 @@ describe("drawing app mesh", () => {
               broadcasts += 1
 
               // TODO: can we assume that we only use one message here?
-              if (broadcasts <= ITERATIONS) {
+              if (broadcasts < ITERATIONS) {
                 addRemTime +=
                   (currTime[0] - prevTime[0]) * 1e9 +
                   (currTime[1] - prevTime[1])
@@ -210,7 +210,7 @@ describe("drawing app mesh", () => {
 
               let packet
 
-              if (broadcasts < ITERATIONS) {
+              if (broadcasts <= ITERATIONS) {
                 packet = addPackets[broadcasts]
               } else if (broadcasts < ITERATIONS * 2) {
                 packet = erasePackets[broadcasts - ITERATIONS]
@@ -755,7 +755,7 @@ describe("drawing app mesh", () => {
   it("benchmarks a path draw and erase update sequentially", () => {
     const ITERATIONS = 1000
 
-    jest.setTimeout(ITERATIONS * 30000)
+    jest.setTimeout(ITERATIONS * 1500)
 
     const pathIDs = []
     let prevTime
@@ -763,47 +763,62 @@ describe("drawing app mesh", () => {
 
     let broadcasts = 0
 
-    let addTime = 0
-    let addPackets = 0
+    let addLocTime = 0
+    const addPackets = []
     let addSize = 0
-    let eraseTime = 0
-    let erasePackets = 0
+    let eraseLocTime = 0
+    const erasePackets = []
     let eraseSize = 0
-    let syncTime
-    let syncPackets = 0
+    let syncLocTime
+    const syncPackets = []
     let syncSize = 0
 
+    let addRemTime = 0
+    let addEvents = 0
+    let eraseRemTime = 0
+    let eraseEvents = 0
+    let syncRemTime = 0
+    let syncEvents = 0
+
     let timeout
 
     return new Promise((resolve) => {
       broadcastListener.callback = (channel, message) => {
         currTime = process.hrtime()
 
+        if (broadcasts < ITERATIONS) {
+          addPackets[addPackets.length - 1].push(message)
+          addSize += message.message.length
+        } else {
+          erasePackets[erasePackets.length - 1].push(message)
+          eraseSize += message.message.length
+        }
+
         clearTimeout(timeout)
         timeout = setTimeout(() => {
           broadcasts += 1
 
           if (broadcasts <= ITERATIONS) {
-            addTime +=
+            addLocTime +=
               (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
-            addPackets += 1
-            addSize += message.message.length
           } else {
-            eraseTime +=
+            eraseLocTime +=
               (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
-            erasePackets += 1
-            eraseSize += message.message.length
           }
 
           prevTime = process.hrtime()
 
           if (broadcasts < ITERATIONS) {
+            addPackets.push([])
+
             const tmpPathID = room.addPath(pathDraw[0])
             pathIDs.push(tmpPathID)
             for (let i = 1; i < pathDraw.length; i++) {
               room.extendPath(tmpPathID, pathDraw[i])
             }
           } else if (broadcasts < ITERATIONS * 2) {
+            erasePackets.push([])
+
             const tmpPathID = pathIDs[broadcasts - ITERATIONS]
 
             for (let i = 0; i < pathErase.length; i++) {
@@ -819,6 +834,8 @@ describe("drawing app mesh", () => {
         }, 100)
       }
 
+      addPackets.push([])
+
       prevTime = process.hrtime()
 
       const tmpPathID = room.addPath(pathDraw[0])
@@ -826,55 +843,168 @@ describe("drawing app mesh", () => {
       for (let i = 1; i < pathDraw.length; i++) {
         room.extendPath(tmpPathID, pathDraw[i])
       }
-    }).then(
-      () =>
-        new Promise((resolve) => {
-          sendListener.callback = (uid, channel, message) => {
-            const currTime = process.hrtime()
-            syncTime =
-              (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
+    })
+      .then(
+        () =>
+          new Promise((resolve) => {
+            sendListener.callback = (uid, channel, message) => {
+              const currTime = process.hrtime()
+              syncLocTime =
+                (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
 
-            syncPackets += 1
-            syncSize += message.message.length
-
-            clearTimeout(timeout)
-            timeout = setTimeout(() => {
-              printBenchmark("path draw and erase [sequential]", ITERATIONS, {
-                addPath: {
-                  timeLoc: addTime,
-                  packets: addPackets,
-                  size: addSize,
-                  timeRem: -1,
-                  events: -1,
-                },
-                extendErasureIntervals: {
-                  timeLoc: eraseTime,
-                  packets: erasePackets,
-                  size: eraseSize,
-                  timeRem: -1,
-                  events: -1,
-                },
-                synchronisation: {
-                  timeLoc: syncTime,
-                  packets: syncPackets,
-                  size: syncSize,
-                  timeRem: -1,
-                  events: -1,
-                },
-              })
-
-              resolve()
-            }, 1000)
-          }
+              syncPackets.push(message)
+              syncSize += message.message.length
 
-          prevTime = process.hrtime()
+              clearTimeout(timeout)
+              timeout = setTimeout(() => resolve(), 1000)
+            }
 
-          getEventListener(
-            "room",
-            "messageReceived",
-          )(createMessageReceivedEvent(syncStep1))
-        }),
-    )
+            prevTime = process.hrtime()
+
+            getEventListener(
+              "room",
+              "messageReceived",
+            )(createMessageReceivedEvent(syncStep1))
+          }),
+      )
+      .then(
+        () =>
+          new Promise((resolve) => {
+            broadcasts = 0
+
+            let currTime
+
+            const timeoutCallback = () => {
+              broadcasts += 1
+
+              if (broadcasts < ITERATIONS) {
+                addRemTime +=
+                  (currTime[0] - prevTime[0]) * 1e9 +
+                  (currTime[1] - prevTime[1])
+              } else {
+                eraseRemTime +=
+                  (currTime[0] - prevTime[0]) * 1e9 +
+                  (currTime[1] - prevTime[1])
+              }
+
+              let packets
+
+              if (broadcasts < ITERATIONS) {
+                packets = addPackets[broadcasts]
+              } else if (broadcasts < ITERATIONS * 2) {
+                packets = erasePackets[broadcasts - ITERATIONS]
+              } else {
+                return resolve()
+              }
+
+              prevTime = process.hrtime()
+
+              for (const packet of packets) {
+                getEventListener(
+                  "update",
+                  "messageReceived",
+                )(createMessageReceivedEvent(packet))
+              }
+            }
+
+            updateRoom.addEventListener("addOrUpdatePath", () => {
+              currTime = process.hrtime()
+
+              addEvents += 1
+
+              clearTimeout(timeout)
+              timeout = setTimeout(timeoutCallback, 100)
+            })
+
+            updateRoom.addEventListener("removedIntervalsChange", () => {
+              currTime = process.hrtime()
+
+              if (broadcasts < ITERATIONS) {
+                addEvents += 1
+              } else if (broadcasts < ITERATIONS * 2) {
+                eraseEvents += 1
+              }
+
+              clearTimeout(timeout)
+              timeout = setTimeout(timeoutCallback, 100)
+            })
+
+            prevTime = process.hrtime()
+
+            for (const packet of addPackets[0]) {
+              getEventListener(
+                "update",
+                "messageReceived",
+              )(createMessageReceivedEvent(packet))
+            }
+          }),
+      )
+      .then(
+        () =>
+          new Promise((resolve) => {
+            syncRoom.addEventListener("addOrUpdatePath", () => {
+              const currTime = process.hrtime()
+
+              syncRemTime =
+                (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
+              syncEvents += 1
+
+              clearTimeout(timeout)
+              timeout = setTimeout(() => resolve(), 1000)
+            })
+
+            syncRoom.addEventListener("removedIntervalsChange", () => {
+              const currTime = process.hrtime()
+
+              syncRemTime =
+                (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1])
+              syncEvents += 1
+
+              clearTimeout(timeout)
+              timeout = setTimeout(() => resolve(), 1000)
+            })
+
+            prevTime = process.hrtime()
+
+            for (const syncPacket of syncPackets) {
+              getEventListener(
+                "sync",
+                "messageReceived",
+              )(createMessageReceivedEvent(syncPacket))
+            }
+          }),
+      )
+      .then(() => {
+        printBenchmark("single draw and erase [sequential]", ITERATIONS, {
+          addPath: {
+            timeLoc: addLocTime,
+            packets: addPackets.reduce(
+              (sum, packets) => sum + packets.length,
+              0,
+            ),
+            size: addSize,
+            timeRem: addRemTime,
+            events: addEvents,
+          },
+          extendErasureIntervals: {
+            timeLoc: eraseLocTime,
+            packets: erasePackets.reduce(
+              (sum, packets) => sum + packets.length,
+              0,
+            ),
+            size: eraseSize,
+            timeRem: eraseRemTime,
+            events: eraseEvents,
+          },
+          synchronisation: {
+            timeLoc: syncLocTime,
+            packets: syncPackets.length,
+            size: syncSize,
+            timeRem: syncRemTime,
+            events: syncEvents,
+          },
+        })
+      })
   })
 
   it("benchmarks a path draw and erase update in parallel", () => {
-- 
GitLab