From 5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Oct 2013 13:28:20 +0200 Subject: Move all of NixOS to nixos/ in preparation of the repository merge --- nixos/tests/bittorrent.nix | 107 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 nixos/tests/bittorrent.nix (limited to 'nixos/tests/bittorrent.nix') diff --git a/nixos/tests/bittorrent.nix b/nixos/tests/bittorrent.nix new file mode 100644 index 0000000000000..180da8267e0f7 --- /dev/null +++ b/nixos/tests/bittorrent.nix @@ -0,0 +1,107 @@ +# This test runs a Bittorrent tracker on one machine, and verifies +# that two client machines can download the torrent using +# `transmission'. The first client (behind a NAT router) downloads +# from the initial seeder running on the tracker. Then we kill the +# initial seeder. The second client downloads from the first client, +# which only works if the first client successfully uses the UPnP-IGD +# protocol to poke a hole in the NAT. + +{ pkgs, ... }: + +let + + # Some random file to serve. + file = pkgs.nixUnstable.src; + + miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf" + '' + ext_ifname=eth1 + listening_ip=${nodes.router.config.networking.interfaces.eth2.ipAddress}/24 + allow 1024-65535 192.168.2.0/24 1024-65535 + ''; + +in + +{ + + nodes = + { tracker = + { config, pkgs, ... }: + { environment.systemPackages = [ pkgs.transmission pkgs.bittorrent ]; + + # We need Apache on the tracker to serve the torrents. + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.httpd.documentRoot = "/tmp"; + }; + + router = + { config, pkgs, ... }: + { environment.systemPackages = [ pkgs.miniupnpd ]; + virtualisation.vlans = [ 1 2 ]; + networking.nat.enable = true; + networking.nat.internalIPs = "192.168.2.0/24"; + networking.nat.externalInterface = "eth1"; + }; + + client1 = + { config, pkgs, nodes, ... }: + { environment.systemPackages = [ pkgs.transmission ]; + virtualisation.vlans = [ 2 ]; + networking.defaultGateway = + nodes.router.config.networking.interfaces.eth2.ipAddress; + }; + + client2 = + { config, pkgs, ... }: + { environment.systemPackages = [ pkgs.transmission ]; + }; + }; + + testScript = + { nodes, ... }: + '' + startAll; + + # Enable NAT on the router and start miniupnpd. + $router->waitForUnit("nat"); + $router->succeed( + "iptables -t nat -N MINIUPNPD", + "iptables -t nat -A PREROUTING -i eth1 -j MINIUPNPD", + "echo 1 > /proc/sys/net/ipv4/ip_forward", + "miniupnpd -f ${miniupnpdConf nodes}" + ); + + # Create the torrent. + $tracker->succeed("mkdir /tmp/data"); + $tracker->succeed("cp ${file} /tmp/data/test.tar.bz2"); + $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -t http://tracker:6969/announce -o /tmp/test.torrent"); + $tracker->succeed("chmod 644 /tmp/test.torrent"); + + # Start the tracker. !!! use a less crappy tracker + $tracker->waitForUnit("network.target"); + $tracker->succeed("bittorrent-tracker --port 6969 --dfile /tmp/dstate >&2 &"); + $tracker->waitForOpenPort(6969); + + # Start the initial seeder. + my $pid = $tracker->succeed("transmission-cli /tmp/test.torrent -M -w /tmp/data >&2 & echo \$!"); + + # Now we should be able to download from the client behind the NAT. + $tracker->waitForUnit("httpd"); + $client1->waitForUnit("network.target"); + $client1->succeed("transmission-cli http://tracker/test.torrent -w /tmp >&2 &"); + $client1->waitForFile("/tmp/test.tar.bz2"); + $client1->succeed("cmp /tmp/test.tar.bz2 ${file}"); + + # Bring down the initial seeder. + $tracker->succeed("kill -9 $pid"); + + # Now download from the second client. This can only succeed if + # the first client created a NAT hole in the router. + $client2->waitForUnit("network.target"); + $client2->succeed("transmission-cli http://tracker/test.torrent -M -w /tmp >&2 &"); + $client2->waitForFile("/tmp/test.tar.bz2"); + $client2->succeed("cmp /tmp/test.tar.bz2 ${file}"); + ''; + +} -- cgit 1.4.1