Skip to content

Instantly share code, notes, and snippets.

@smerritt
Created November 20, 2015 01:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smerritt/014015460cbccc2ec6b6 to your computer and use it in GitHub Desktop.
Save smerritt/014015460cbccc2ec6b6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
#
# Ring Finder 3000: finds rings that break the builder
import os
import pickle
import random
import time
import traceback
from StringIO import StringIO
from swift.common.ring import RingBuilder
NDEVS = 257
REGIONS = [1, 2, 3, 4, 5]
ZONES = [101, 102, 103]
IPS = ["10.1.1.%d" % octet for octet in range(1, 255)]
DEVICES = ["sda%d" % (i + 1) for i in range(24)]
MIN_WEIGHT = 1000000
MAX_WEIGHT = 8000000
def is_bad(builder):
try:
builder.rebalance(seed=12345) # that's the same combination I use
# on my luggage
return False
except Exception:
print traceback.format_exc()
return True
def make_random_dev(dev_id):
return {
'id': dev_id,
'region': random.choice(REGIONS),
'zone': random.choice(ZONES),
'ip': random.choice(IPS),
'port': 6000,
'device': random.choice(DEVICES),
'weight': random.randrange(MIN_WEIGHT, MAX_WEIGHT) / 1000.0,
}
def make_random_builder():
# Make a builder with some stuff in it. Doesn't balance anything.
rb = RingBuilder(12, 3, 1)
dev_ids = range(NDEVS)
for dev_id in dev_ids:
rb.add_dev(make_random_dev(dev_id))
rb.rebalance()
# got a bunch of devs; just randomly assign them wherever. weights? nah.
# dispersion? screw it. just make something up and see if it fails.
for p2d in rb._replica2part2dev:
for i in range(len(p2d)):
p2d[i] = random.randrange(0, NDEVS)
return rb
def go_once():
buf = StringIO()
rb = make_random_builder()
# hokey save; builder wants to be saved to a file path, but I'd rather
# just buffer in memory until I know that things are bad
pickle.dump(rb.to_dict(), buf, protocol=2)
buf.seek(0)
try:
rb.pretend_min_part_hours_passed()
rb.rebalance()
# now mutate some stuff, just for giggles
rb.remove_dev(2)
rb.remove_dev(4)
rb.remove_dev(100)
rb.remove_dev(193)
rb.remove_dev(88)
rb.set_dev_weight(111, 0.0)
rb.set_dev_weight(222, 0.0)
rb.set_dev_weight(133, rb.devs[133]['weight'] * 2.71828)
rb.set_dev_weight(134, rb.devs[133]['weight'] * 3.14159)
rb.set_dev_weight(135, 0.1)
rb.add_dev(make_random_dev(NDEVS))
rb.add_dev(make_random_dev(NDEVS + 1))
rb.add_dev(make_random_dev(NDEVS + 2))
rb.add_dev(make_random_dev(NDEVS + 3))
rb.pretend_min_part_hours_passed()
rb.rebalance()
return None
except Exception:
#print traceback.format_exc()
return buf
def main():
baddie = go_once()
nchecked = 1
while not baddie:
baddie = go_once()
nchecked += 1
if nchecked % 25 == 0:
print str(nchecked)
fname = "horked-%d-%f.builder" % (os.getpid(), time.time())
with open(fname, "w") as badfh:
badfh.write(baddie.read())
print "Got one! Builder file is %s" % fname
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment