romele / git-trace public
62 commits · 1 branch · 1 tag · 1 contributor (top: Romele) · first commit 3d ago · last push 13m ago
tests/fuzzrace.pl
#!/usr/bin/perl # fuzzrace.pl <host> <port> <user> <pass> <o> <r> <lanes> <iters> # Logs in, grabs the session csrf token, then forks <lanes> children # each firing <iters> POST /new-file commits at the SAME branch — # hammers the CAS update-ref path inside the threaded ASan server. use strict; use warnings; use IO::Socket::INET; my ($host, $port, $user, $pass, $o, $r, $lanes, $iters) = @ARGV; sub http { my ($method, $path, $hdrs, $body) = @_; my $s = IO::Socket::INET->new(PeerAddr => "$host:$port", Proto => 'tcp', Timeout => 5) or return undef; binmode $s; my $q = "$method $path HTTP/1.1\r\nHost: x\r\nConnection: close\r\n" . ($hdrs // ''); $q .= "Content-Length: " . length($body) . "\r\n" if defined $body; $q .= "\r\n" . ($body // ''); print $s $q; my $resp = ''; $resp .= $_ while <$s>; close $s; return $resp; } # login -> session cookie my $lr = http('POST', '/login', '', "name=$user&pass=$pass") // die "login conn fail\n"; my ($sess) = $lr =~ /Set-Cookie: gt_session=([0-9a-f]+)/i; die "no session cookie\n" unless $sess; my $ck = "Cookie: gt_session=$sess\r\n"; # csrf from /account my $ar = http('GET', '/account', $ck) // die "account conn fail\n"; my ($csrf) = $ar =~ /name=csrf value='([0-9a-f]+)'/; die "no csrf\n" unless $csrf; my %stat; for my $lane (1 .. $lanes) { my $pid = fork(); die "fork: $!" unless defined $pid; if ($pid == 0) { my ($ok, $moved, $other) = (0, 0, 0); for my $i (1 .. $iters) { my $body = "csrf=$csrf&ref=master&path=race.txt" . "&content=lane$lane-$i"; my $resp = http('POST', "/$o/$r/new-file", $ck, $body); if (!defined $resp) { exit 2; } # conn fail: server dead? elsif ($resp =~ m{^HTTP/1\.1 302}) { $ok++ } elsif ($resp =~ /branch moved/) { $moved++ } else { $other++; my ($code) = $resp =~ m{^HTTP/1\.1 (\d+)}; warn "lane$lane other: HTTP " . ($code // '?') . "\n"; } } print "lane$lane: $ok committed, $moved raced, $other other\n"; exit 0; } } my $dead = 0; while (wait() > 0) { $dead++ if $? != 0; } exit($dead ? 1 : 0);