2 # -*- coding: utf-8 -*-
4 # This task takes patch series messages off one of the ‘patchq_test_*’
5 # queues and tests the patch series.
7 # If you run it without arguments, it will pick up patches from each
8 # test queue in turn and test them (but not in parallel). You can
9 # also list one or more tests on the command line, in which case only
10 # that test or tests are considered.
12 # This script does not perform tests in parallel, but doesn't care if
13 # other instances of the script are running (even across machines).
14 # Because of the message broker each patch series is only tested once.
28 # Because tests are very long running, turn off heartbeats.
29 # https://stackoverflow.com/questions/14572020/handling-long-running-tasks-in-pika-rabbitmq
30 connection = pika.BlockingConnection(pika.ConnectionParameters(
31 host = config.mq_server, heartbeat_interval=0))
32 channel = connection.channel()
35 channel.basic_ack(delivery_tag = method.delivery_tag)
38 if len(sys.argv) <= 1:
42 for arg in sys.argv[1:]:
43 if arg not in config.tests:
44 sys.exit("%s is not listed in config.tests" % arg)
50 qname = "patchq_test_%s" % t
52 method, _, body = channel.basic_get(queue = qname, no_ack = False)
55 # Parse the ordered list of messages forming the patch series.
56 msgs = json.loads(body)
57 msgs = [email.message_from_string(m) for m in msgs]
59 # This should never happen, but the rest of the code
60 # below assumes number of msgs > 0, so ...
65 print ("%s: Running test:" % t)
67 # Save them to a temporary directory.
68 # Create large files in /var/tmp
69 tempfile.tempdir = "/var/tmp"
70 dir = tempfile.mkdtemp()
73 # Save the patches to files.
76 args.append("%s/%s.sh" % (pwd, t))
80 filename = ("%05d" % i)
82 print ("%05d %s" % (i, m['Subject']))
83 with open(filename, "w") as file:
84 file.write(m.as_string())
88 with open("output", "w") as out:
89 r = subprocess.call(args, stdout=out, stderr=out)
92 print ("%s: Test skipped" % t)
94 # Do a "group reply" to the last email.
95 tos = last_msg.get_all('to', [])
96 ccs = last_msg.get_all('cc', [])
97 from_ = last_msg['From']
98 to = email.utils.getaddresses(tos + ccs + [from_])
99 ref = last_msg['Message-Id']
104 subject = "%s %s (was: Re: %s)" % (t, status, last_msg['Subject'])
105 with open("output", "r") as file:
106 content = file.read()
108 body = json.dumps((to, subject, ref, content))
109 channel.basic_publish(exchange = 'patchq_reports',
113 # Ack the input message since we have processed it.
116 shutil.rmtree(dir, ignore_errors = True)