git-trace

romele / git-trace public

62 commits · 1 branch · 1 tag · 1 contributor (top: Romele) · first commit 3d ago · last push 11m ago

tests/load.pl

#!/usr/bin/perl
# tests/load.pl — honest load numbers for git-trace.
#
# Phase A: N workers x R sequential GETs on "/"        (browse path)
# Phase B: N workers x R GETs on /<repo>.git/info/refs?service=git-upload-pack
#          (the smart-HTTP fetch path, CGI + git http-backend)
#
# Each worker is a fork()ed child writing its timings over a pipe.
# Usage: perl tests/load.pl http://host:port [workers] [reps]
use strict; use warnings;
use IO::Socket::INET;
use Time::HiRes qw(time);

my $base = shift or die "usage: $0 http://host:port [workers] [reps]\n";
my $W = shift // 8;
my $R = shift // 25;

my ($host, $port) = $base =~ m{^https?://([^:/]+)(?::(\d+))?}
    or die "bad base url\n";
$port //= 80;

sub timed_get {
    my ($path) = @_;
    my $t0 = time();
    my $s = IO::Socket::INET->new(
        PeerAddr => $host, PeerPort => $port, Proto => 'tcp',
        Timeout => 10);
    return -1 unless $s;
    print $s "GET $path HTTP/1.1\r\nHost: $host:$port\r\n"
           . "Connection: close\r\n\r\n";
    my $ok = 0;
    while (my $l = <$s>) { $ok += length $l }
    close $s;
    return time() - $t0;
}

sub hammer {
    my ($path, $label) = @_;
    pipe(my $rd, my $wr) or die "pipe: $!";
    my $t0 = time();
    for my $i (1 .. $W) {
        if (fork() == 0) {               # child
            close $rd;
            for (1 .. $R) {
                my $d = timed_get($path);
                printf $wr "%.4f\n", $d;
            }
            exit 0;
        }
    }
    close $wr;
    my @ms;
    while (<$rd>) { push @ms, $_ * 1000 }
    close $rd;
    wait for 1 .. $W;
    my $wall = time() - $t0;
    @ms = sort { $a <=> $b } @ms;
    my $n  = @ms;
    my ($sum) = 0; $sum += $_ for @ms;
    printf "%-14s n=%-4d wall=%.1fs  rps=%.0f  avg=%.1fms "
         . "p50=%.1fms p95=%.1fms max=%.1fms\n",
        $label, $n, $wall, $n / ($wall || 1), $sum / $n,
        $ms[int($n * .50)], $ms[int($n * .95)], $ms[-1];
    return $n;
}

print "== load: $W workers x $R reqs against $base ==\n";
hammer("/", "GET /");
hammer("/alice/demo.git/info/refs?service=git-upload-pack",
       "info/refs");
print "== done ==\n";