Skip to content

Instantly share code, notes, and snippets.

@ojii
Forked from FugiTech/attack.py
Created October 12, 2012 23:40
Show Gist options
  • Save ojii/3882293 to your computer and use it in GitHub Desktop.
Save ojii/3882293 to your computer and use it in GitHub Desktop.
txircd load testing script using BeesWithMachineGuns (long-term join/quit test)
# -*- coding: utf-8 -*-
from twisted.internet import reactor, ssl
from twisted.internet.protocol import ClientFactory
from twisted.words.protocols.irc import IRCClient
import random, string
ATTACK, STANDBY = 0,1
QUIT_CHANCE = 10#%
JOIN_CHANCE = 80#%
def genMessage(low, high):
l = random.randint(low, high)
return "".join([random.choice(string.letters + string.digits + string.punctuation + ' ') for _ in xrange(l)])
def attack(p):
m = genMessage(p.factory.min_length, p.factory.max_length)
p.msg(p.factory.channel, m)
p.sent += 1
if p.sent >= p.factory.messages:
p.quit()
print "%s quitting" % (p.nickname, )
return
elif p.state == ATTACK:
if random.randint(0, 100) > QUIT_CHANCE:
w = random.randint(p.factory.min_pause, p.factory.max_pause)
print "%s waiting %d seconds" % (p.nickname, w)
else:
p.state = STANDBY
p.leave(p.factory.channel)
else:
if random.randint(0, 100) < JOIN_CHANCE:
p.state = ATTACK
p.join(p.factory.channel)
reactor.callLater(w, attack, p)
class Bee(IRCClient):
def signedOn(self):
print "%s signed on - Joining %s" % (self.nickname, self.factory.channel)
self.join(self.factory.channel)
w = random.randint(self.factory.min_pause, self.factory.max_pause)
self.state = ATTACK
reactor.callLater(w, attack, self)
def connectionLost(self, reason=None):
print "%s lost connection!" % self.nickname
self.factory.all.remove(self.factory)
if not self.factory.all:
print "All done!"
reactor.stop()
class BeeFactory(ClientFactory):
protocol = Bee
def __init__(self, channel, messages, min_pause, max_pause, min_length, max_length, password, beenum, count, all):
self.channel = channel
self.messages = messages
self.min_pause = min_pause
self.max_pause = max_pause
self.min_length = min_length
self.max_length = max_length
self.password = password
self.beenum = beenum
self.count = count
self.all = all
def buildProtocol(self, addr):
p = ClientFactory.buildProtocol(self, addr)
p.nickname = "Bee-%d-%d" % (self.beenum, self.count)
p.password = self.password
p.sent = 0
return p
if __name__ == "__main__":
import sys
users = int(sys.argv[1])
ssl_ratio = float(sys.argv[2])
messages = int(sys.argv[3])
min_pause = int(sys.argv[4])
max_pause = int(sys.argv[5])
min_length = int(sys.argv[6])
max_length = int(sys.argv[7])
host = sys.argv[8]
port = int(sys.argv[9])
ssl_port = int(sys.argv[10])
channel = sys.argv[11]
password = sys.argv[12]
beenum = int(sys.argv[13])
ssl_users = int(ssl_ratio * users)
tcp_users = users - ssl_users
if not channel.startswith("#"):
channel = "#"+channel
if password == "none":
password = None
all = []
def factory(count):
return BeeFactory(channel, messages, min_pause, max_pause, min_length, max_length, password, beenum, count, all)
print "%d normal users, %d ssl users" % (tcp_users, ssl_users)
for i in xrange(tcp_users):
all.append(factory(len(all)+1))
reactor.callLater(0.5*i, reactor.connectTCP, host, port, all[-1])
for i in xrange(ssl_users):
all.append(factory(len(all)+1))
reactor.callLater(0.5*i, reactor.connectTCP, host, port, all[-1], ssl.ClientContextFactory())
reactor.callLater(3600, reactor.stop)
reactor.run()
Twisted==12.2.0
key-name: bees
servers: 19
group: bees
script: attack.py
requirements: attack.req
users: 6000 # Will only reach 4000. Other 2000 will fail to connect. Limited by file descriptors???
ssl-ratio: 0
messages: 6000
min-pause: 500
max-pause: 1700
min-length: 5
max-length: 50
target-host: dbtest.fugiman.com
target-port: 6667
target-ssl-port: 6697
target-channel: desertbus
password: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment