zulip/tools/stress-test/stress-test.coffee

174 lines
5.2 KiB
CoffeeScript

{Session, Stat} = require './support'
assert = require 'assert'
argv = require('optimist').default({
time: 60
users: 5
'min-wait': 5
'max-wait': 10
}).argv
class ZulipSession extends Session
constructor: (id, host, {@username, @password}) ->
user = @username.split('@')[0]
super(host, "#{id} #{user}")
@last_csrf_token = undefined
@page_params = undefined
parse_csrf: ->
match = @last_body.match /name='csrfmiddlewaretoken' value='([a-zA-Z0-9]+)/
assert match, "Expected CSRF token in form"
@last_csrf_token = match[1]
@headers['X-CSRFToken'] = @last_csrf_token
parse_page_params: ->
match = @last_body.match /^var page_params = (.*);$/m
assert match, "Expected page_params"
@page_params = JSON.parse match[1]
{@max_message_id, @event_queue_id} = @page_params
@pointer = @page_params.initial_pointer
@last_event_id = -1
login: (cb) ->
@get '/', =>
#@get_all(@static)
@parse_csrf()
@post '/accounts/login/?next=', {@username, @password}, =>
@on_app_load(cb)
on_app_load: (cb) ->
#@get_all(@app_static)
@parse_csrf()
@parse_page_params()
@update_active_status()
@get '/json/bots'
@post '/json/get_old_messages', {
anchor: @pointer
num_before: 200
num_after: 200
}, get_old_messages_time.cbTimer cb
reload: (cb) ->
@get '/', =>
@on_app_load(cb)
get_events: ->
@post '/json/get_events', {
@pointer
last: @max_message_id
dont_block: false
queue_id: @event_queue_id
@last_event_id
}, (r, body) =>
response = JSON.parse(body)
for event in response.events
@last_event_id = Math.max(@last_event_id, event.id)
if event.type == 'message'
@on_message(event.message)
@get_events()
on_message: (message) ->
if (m = message.content.match /Test message sent at (\d+)/)
message_latency.update(+new Date() - parseInt(m[1], 10))
update_active_status: ->
@post "/json/update_active_status", {status: "active"}, update_status_time.cbTimer()
send_stream_message: (stream, subject, content) ->
@post '/json/send_message', {
client: 'website'
type: 'stream'
to: JSON.stringify([stream])
stream
subject
content
}, message_send_time.cbTimer()
send_private_message: (recipients, content) ->
@post '/json/send_message', {
client: 'website'
type: 'private'
to: JSON.stringify(recipients)
reply_to: recipients.join(', ')
private_message_recipient: recipients.join(', ')
content
}, message_send_time.cbTimer()
random_sends: =>
s = Math.round(Math.random()*5)
msg = "Test message sent at #{+new Date()}"
@send_stream_message("test", "test#{s}", msg)
setTimeout(@random_sends, @rand_time())
# TODO: update_message_flags
# TODO: get_old_messages
run_message_test: =>
@login =>
@get_events()
setInterval((=> @update_active_status()), 60*1000)
@random_sends()
run_reload_test: =>
@login @random_reloads
random_reloads: =>
@reload total_reload_time.cbTimer =>
setTimeout(@random_reloads, @rand_time())
run_test: =>
opts = argv
@min_wait = opts['min-wait']
@max_wait = opts['max-wait']
switch opts._[0]
when 'reload' then @run_reload_test()
when 'message' then @run_message_test()
else throw new Error("No test selected")
rand_time: ->
Math.round(1000 * (@min_wait + Math.random() * (@max_wait - @min_wait)))
host = 'http://localhost:9991'
users = [
{username: 'iago@zulip.com', password: 'JhwLkBydEG1tAL5P'}
{username: 'othello@zulip.com', password: 'GX5MTQ+qYSzcmDoH'}
{username: 'cordelia@zulip.com', password: '+1pkoQiP0wEbEvv/'}
{username: 'hamlet@zulip.com', password: 'Z/hx5nEcXRQBGzk3'}
{username: 'prospero@zulip.com', password: 'j+XqHkQ2cycwCQJE'}
]
user_start_step = 1000*1
if argv.users > users.length
console.log "Only have #{users.length} accounts, so simulating multiple sessions"
for i in [0..argv.users] then do ->
user = users[i%users.length]
h = new ZulipSession(i, host, user)
setTimeout(h.run_test, i*user_start_step)
stats = [
message_latency = new Stat("Message Latency")
message_send_time = new Stat("Message Send Time")
update_status_time = new Stat("/json/update_status_time Time")
total_reload_time = new Stat("Total reload time")
get_old_messages_time = new Stat("/json/get_old_messages Time")
]
# Reset message latency stat after everyone logs in
# setTimeout(message_latency.reset, (i+1)*user_start_step)
showStats = ->
for stat in stats when stat.count() > 0
console.log "#{stat.name}:", stat.stats()
stat.reset()
process.exit()
setTimeout(showStats, argv['time']*1000)