# # Copyright (c) 2015 ThoughtWorks, Inc. # # Pixelated is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Pixelated is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . # We use this script to simulate the login of multiple concurrent users, with # one login per second. # # To use it, you need: # -ruby # -pre-created users # # This can be run with `ruby concurrent_logins.rb ` # where x is the number of users you want to login. # # It was created to measure login times internally on the application with # varying number of users require 'fileutils' USER_PATTERN = "loadtest%d" PASSWORD_PATTERN = "password_%d" COUNT = ARGV[0].to_i def header_options "--header 'X-Requested-With: XMLHttpRequest' --header 'X-XSRF-TOKEN: blablabla'" end def cookies "--cookie 'XSRF-TOKEN: blablabla'" end def curl_command "curl --silent" end def login_command(user_index, username, password) FileUtils.rm "/tmp/user#{user_index}.cookie", force: true "#{curl_command} -X POST --data 'username=#{username}&password=#{password}' --cookie-jar /tmp/user#{user_index}.cookie -w '%{http_code}|%{time_total}' --output '/dev/null' #{cookies} #{header_options} http://localhost:3333/login" end def check_inbox(user_index) "#{curl_command} --cookie /tmp/user#{user_index}.cookie http://localhost:3333" end def complete_login(user_index, user, password) start = Time.now login_response = `#{login_command(user_index, user, password)}` status_code, total_time = login_response.split("|") puts "Login request #{total_time}" if status_code.to_i == 200 interstitial = Time.now begin sleep 0.05 inbox = `#{check_inbox(user_index)}` end until /compose-trigger/.match(inbox) puts "Login loading #{sprintf('%.3f',Time.now - interstitial)}" puts "Login total #{sprintf('%.3f',Time.now - start)}" else puts "Login failed with #{status_code} #{sprintf('%.3f',Time.now - start)}" end end def multi_login ts = (1...(1+COUNT)).map do |user_index| t = Thread.new do username = USER_PATTERN % [user_index] password = PASSWORD_PATTERN % [user_index] complete_login(user_index, username, password) end sleep 1 t end ts.each(&:join) end multi_login