mirror of
https://github.com/overleaf/overleaf.git
synced 2025-02-16 23:14:36 +00:00
Improve consistency of stress test script
This commit is contained in:
parent
392beac57b
commit
27a74d6b71
2 changed files with 71 additions and 31 deletions
|
@ -3,6 +3,10 @@ rclient = require("redis-sharelatex").createClient(Settings.redis.web)
|
|||
request = require("request").defaults(jar: false)
|
||||
async = require "async"
|
||||
|
||||
rclient_sub = require("redis-sharelatex").createClient(Settings.redis.web)
|
||||
rclient_sub.subscribe "applied-ops"
|
||||
rclient_sub.setMaxListeners(0)
|
||||
|
||||
module.exports = DocUpdaterClient =
|
||||
randomId: () ->
|
||||
chars = for i in [1..24]
|
||||
|
@ -10,8 +14,6 @@ module.exports = DocUpdaterClient =
|
|||
return chars.join("")
|
||||
|
||||
subscribeToAppliedOps: (callback = (message) ->) ->
|
||||
rclient_sub = require("redis-sharelatex").createClient(Settings.redis.web)
|
||||
rclient_sub.subscribe "applied-ops"
|
||||
rclient_sub.on "message", callback
|
||||
|
||||
sendUpdate: (project_id, doc_id, update, callback = (error) ->) ->
|
||||
|
|
|
@ -5,12 +5,17 @@ assert = require "assert"
|
|||
async = require "async"
|
||||
|
||||
insert = (string, pos, content) ->
|
||||
string.slice(0, pos) + content + string.slice(pos)
|
||||
result = string.slice(0, pos) + content + string.slice(pos)
|
||||
return result
|
||||
|
||||
transform = (op1, op2) ->
|
||||
if op2.p < op1.p
|
||||
op1.p += op2.i.length
|
||||
return op1
|
||||
return {
|
||||
p: op1.p + op2.i.length
|
||||
i: op1.i
|
||||
}
|
||||
else
|
||||
return op1
|
||||
|
||||
class StressTestClient
|
||||
constructor: (@options = {}) ->
|
||||
|
@ -36,6 +41,7 @@ class StressTestClient
|
|||
update = JSON.parse(update)
|
||||
if update.error?
|
||||
console.error new Error("Error from server: '#{update.error}'")
|
||||
return
|
||||
if update.doc_id == @doc_id
|
||||
@processReply(update)
|
||||
|
||||
|
@ -73,7 +79,7 @@ class StressTestClient
|
|||
console.log "[#{new Date()}] \t[#{@client_id.slice(0,4)}] WARN: Duplicate ack (already seen version)"
|
||||
return
|
||||
else
|
||||
throw new Error("version jumped ahead")
|
||||
console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] ERROR: Version jumped ahead (client: #{@version}, op: #{update.op.v})"
|
||||
@version++
|
||||
if update.op.meta.source == @client_id
|
||||
if @inflight_op?
|
||||
|
@ -91,6 +97,7 @@ class StressTestClient
|
|||
external_op = update.op.op[0]
|
||||
if @inflight_op?
|
||||
@counts.conflicts++
|
||||
@inflight_op = transform(@inflight_op, external_op)
|
||||
external_op = transform(external_op, @inflight_op)
|
||||
if external_op.p < @pos
|
||||
@pos += external_op.i.length
|
||||
|
@ -114,13 +121,41 @@ class StressTestClient
|
|||
DocUpdaterClient.getDoc @project_id, @doc_id, (error, res, body) =>
|
||||
throw error if error?
|
||||
if !body.lines?
|
||||
return console.error "[#{new Date()}] ERROR: Invalid response from get doc (#{doc_id})", body
|
||||
return console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] ERROR: Invalid response from get doc (#{doc_id})", body
|
||||
content = body.lines.join("\n")
|
||||
version = body.version
|
||||
if content != @content
|
||||
console.error "[#{new Date()}] Error: Client content does not match server (Server: '#{content}', Client: '#{@content}')"
|
||||
# TODO: Check content is of the correct form
|
||||
if version == @version
|
||||
console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] Error: Client content does not match server."
|
||||
console.error "Server: #{content.split('a')}"
|
||||
console.error "Client: #{@content.split('a')}"
|
||||
else
|
||||
console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] Error: Version mismatch (Server: '#{version}', Client: '#{@version}')"
|
||||
|
||||
if !@isContentValid(@content)
|
||||
for chunk, i in @content.split("")
|
||||
if chunk? and chunk != "a"
|
||||
console.log chunk, i
|
||||
throw new Error("bad content")
|
||||
callback()
|
||||
|
||||
isChunkValid: (chunk) ->
|
||||
char = 0
|
||||
for letter, i in chunk
|
||||
if letter.charCodeAt(0) != 65 + i % 26
|
||||
console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] Invalid Chunk:", chunk
|
||||
return false
|
||||
return true
|
||||
|
||||
isContentValid: (content) ->
|
||||
for chunk in content.split('a')
|
||||
if chunk? and chunk != ""
|
||||
if !@isChunkValid(chunk)
|
||||
|
||||
console.error "[#{new Date()}] \t[#{@client_id.slice(0,4)}] Invalid content", content
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
checkDocument = (project_id, doc_id, clients, callback = (error) ->) ->
|
||||
jobs = clients.map (client) ->
|
||||
|
@ -140,32 +175,35 @@ printSummary = (doc_id, clients) ->
|
|||
max_delay: 0
|
||||
}
|
||||
|
||||
UPDATE_DELAY = parseInt(process.argv[2], 10)
|
||||
SAMPLE_INTERVAL = parseInt(process.argv[3], 10)
|
||||
CLIENT_COUNT = parseInt(process.argv[2], 10)
|
||||
UPDATE_DELAY = parseInt(process.argv[3], 10)
|
||||
SAMPLE_INTERVAL = parseInt(process.argv[4], 10)
|
||||
|
||||
for doc_and_project_id in process.argv.slice(4)
|
||||
for doc_and_project_id in process.argv.slice(5)
|
||||
do (doc_and_project_id) ->
|
||||
[project_id, doc_id] = doc_and_project_id.split(":")
|
||||
console.log {project_id, doc_id}
|
||||
DocUpdaterClient.getDoc project_id, doc_id, (error, res, body) =>
|
||||
DocUpdaterClient.setDocLines project_id, doc_id, [(new Array(CLIENT_COUNT + 2)).join('a')], null, null, (error) ->
|
||||
throw error if error?
|
||||
if !body.lines?
|
||||
return console.error "[#{new Date()}] ERROR: Invalid response from get doc (#{doc_id})", body
|
||||
content = body.lines.join("\n")
|
||||
version = body.version
|
||||
|
||||
clients = []
|
||||
for pos in [1, 2]
|
||||
do (pos) ->
|
||||
client = new StressTestClient({doc_id, project_id, content, pos: pos, version: version, updateDelay: UPDATE_DELAY})
|
||||
clients.push client
|
||||
DocUpdaterClient.getDoc project_id, doc_id, (error, res, body) =>
|
||||
throw error if error?
|
||||
if !body.lines?
|
||||
return console.error "[#{new Date()}] ERROR: Invalid response from get doc (#{doc_id})", body
|
||||
content = body.lines.join("\n")
|
||||
version = body.version
|
||||
|
||||
do runBatch = () ->
|
||||
jobs = clients.map (client) ->
|
||||
(cb) -> client.runForNUpdates(SAMPLE_INTERVAL / UPDATE_DELAY, cb)
|
||||
async.parallel jobs, (error) ->
|
||||
throw error if error?
|
||||
printSummary(doc_id, clients)
|
||||
checkDocument project_id, doc_id, clients, (error) ->
|
||||
clients = []
|
||||
for pos in [1..CLIENT_COUNT]
|
||||
do (pos) ->
|
||||
client = new StressTestClient({doc_id, project_id, content, pos: pos, version: version, updateDelay: UPDATE_DELAY})
|
||||
clients.push client
|
||||
|
||||
do runBatch = () ->
|
||||
jobs = clients.map (client) ->
|
||||
(cb) -> client.runForNUpdates(SAMPLE_INTERVAL / UPDATE_DELAY, cb)
|
||||
async.parallel jobs, (error) ->
|
||||
throw error if error?
|
||||
runBatch()
|
||||
printSummary(doc_id, clients)
|
||||
checkDocument project_id, doc_id, clients, (error) ->
|
||||
throw error if error?
|
||||
runBatch()
|
||||
|
|
Loading…
Reference in a new issue