summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/integration/harness.py34
-rw-r--r--tests/integration/test_livesync.py166
-rw-r--r--tests/integration/test_stats.py6
-rw-r--r--tests/runner.c4
-rw-r--r--tests/stubs.c4
-rw-r--r--tests/sync_daemon.pl294
-rw-r--r--tests/t_accesslist.c4
-rw-r--r--tests/t_batch.c4
-rw-r--r--tests/t_buf.c4
-rw-r--r--tests/t_event.c4
-rw-r--r--tests/t_fdstate.c4
-rw-r--r--tests/t_fmt.c4
-rw-r--r--tests/t_hex.c4
-rw-r--r--tests/t_iovec.c4
-rw-r--r--tests/t_ip.c4
-rw-r--r--tests/t_mutex.c6
-rw-r--r--tests/t_random.c4
-rw-r--r--tests/t_scan.c4
-rw-r--r--tests/t_socket.c4
-rw-r--r--tests/t_trackerlogic.c6
-rw-r--r--tests/t_urlencoded.c4
-rw-r--r--tests/t_vector.c4
-rw-r--r--tests/t_workqueue.c4
-rw-r--r--tests/test.c4
-rw-r--r--tests/test.h4
25 files changed, 522 insertions, 66 deletions
diff --git a/tests/integration/harness.py b/tests/integration/harness.py
index b98ce83..a9d38ca 100644
--- a/tests/integration/harness.py
+++ b/tests/integration/harness.py
@@ -20,6 +20,9 @@ import urllib.error
20import urllib.parse 20import urllib.parse
21import urllib.request 21import urllib.request
22 22
23# groupip_1 in src/ot_livesync.c
24LIVESYNC_GROUP = "224.0.23.5"
25
23TRACKER = os.environ.get("OPENTRACKER", os.path.join(os.path.dirname(__file__), "..", "..", "opentracker.debug")) 26TRACKER = os.environ.get("OPENTRACKER", os.path.join(os.path.dirname(__file__), "..", "..", "opentracker.debug"))
24 27
25 28
@@ -76,6 +79,9 @@ class Tracker:
76 79
77 def __init__(self, extra_config="", files=None): 80 def __init__(self, extra_config="", files=None):
78 self.port = free_port() 81 self.port = free_port()
82 # Only used by a config that asks for live sync, but allocated either
83 # way so {livesync_port} always resolves.
84 self.livesync_port = free_port()
79 self.dir = tempfile.mkdtemp(prefix="ot-integration-") 85 self.dir = tempfile.mkdtemp(prefix="ot-integration-")
80 self.log = None 86 self.log = None
81 self.process = None 87 self.process = None
@@ -87,7 +93,7 @@ class Tracker:
87 with open(self.config, "w") as handle: 93 with open(self.config, "w") as handle:
88 handle.write("listen.tcp 127.0.0.1:%d\n" % self.port) 94 handle.write("listen.tcp 127.0.0.1:%d\n" % self.port)
89 handle.write("listen.udp 127.0.0.1:%d\n" % self.port) 95 handle.write("listen.udp 127.0.0.1:%d\n" % self.port)
90 handle.write(extra_config.replace("{dir}", self.dir)) 96 handle.write(extra_config.replace("{dir}", self.dir).replace("{livesync_port}", str(self.livesync_port)))
91 self.log = open(os.path.join(self.dir, "tracker.log"), "w+b") 97 self.log = open(os.path.join(self.dir, "tracker.log"), "w+b")
92 # Leak detection is left at the sanitizer's own default, which is on 98 # Leak detection is left at the sanitizer's own default, which is on
93 # where LeakSanitizer exists and off where it does not. Asking for it 99 # where LeakSanitizer exists and off where it does not. Asking for it
@@ -186,6 +192,32 @@ class Tracker:
186 def torrent_count(self): 192 def torrent_count(self):
187 return int(self.stats("torr").split()[0]) 193 return int(self.stats("torr").split()[0])
188 194
195 def livesync_send(self, payload):
196 """Put a packet on the live sync group.
197
198 It has to go to the group rather than straight at the port: the
199 tracker binds two sockets there, the reader on the wildcard address
200 and the writer on the configured one, and the kernel gives a unicast
201 datagram to the more specific of the two, which nobody reads."""
202 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
203 try:
204 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("127.0.0.1"))
205 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
206 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1)
207 sock.sendto(payload, (LIVESYNC_GROUP, self.livesync_port))
208 finally:
209 sock.close()
210
211 def wait_until(self, predicate, timeout=5):
212 """A live sync packet is handled by another thread, so an effect of
213 one arrives some time after the send."""
214 deadline = time.time() + timeout
215 while time.time() < deadline:
216 if predicate():
217 return True
218 time.sleep(0.02)
219 return predicate()
220
189 # ------------------------------------------------------------ over udp 221 # ------------------------------------------------------------ over udp
190 222
191 def udp_connect(self): 223 def udp_connect(self):
diff --git a/tests/integration/test_livesync.py b/tests/integration/test_livesync.py
new file mode 100644
index 0000000..3a9ee58
--- /dev/null
+++ b/tests/integration/test_livesync.py
@@ -0,0 +1,166 @@
1"""Live sync, driven over the multicast group a cluster would use.
2
3Live sync sits behind WANT_SYNC_LIVE, so these only run against a binary
4built with it: make check-livesync. Against any other build they skip, which
5is what the feature list in -v is for.
6"""
7
8import socket
9import struct
10import subprocess
11import unittest
12
13from harness import TRACKER, TrackerTestCase
14
15# enum { OT_SYNC_PEER4, OT_SYNC_PEER6 } in src/ot_livesync.c
16SYNC_PEER4 = 0
17SYNC_PEER6 = 1
18
19# src/trackerlogic.h
20FLAG_SEEDING = 0x80
21FLAG_COMPLETED = 0x40
22FLAG_STOPPED = 0x20
23
24
25def has_livesync():
26 done = subprocess.run([TRACKER, "-v"], capture_output=True, timeout=30)
27 return b"WANT_SYNC_LIVE" in done.stderr
28
29
30def peer4(address, port, flags):
31 """Four bytes of address, two of port, one of flags, one the tracker
32 overwrites with its own idea of the time."""
33 return socket.inet_aton(address) + struct.pack("!H", port) + bytes([flags, 0])
34
35
36def peer6(address, port, flags):
37 return socket.inet_pton(socket.AF_INET6, address) + struct.pack("!H", port) + bytes([flags, 0])
38
39
40def packet(kind, entries, tracker_id=0xDEADBEEF):
41 body = b"".join(info_hash + peer for info_hash, peer in entries)
42 return struct.pack("!I", tracker_id) + struct.pack("!I", kind) + body
43
44
45@unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE")
46class LiveSyncIn(TrackerTestCase):
47 config = "livesync.cluster.listen 127.0.0.1:{livesync_port}\nlivesync.cluster.node_ip 127.0.0.1\n"
48
49 def counts(self, info_hash):
50 """Seeders and leechers a scrape reports for one torrent."""
51 files = self.tracker.scrape(info_hash)[b"files"]
52 if info_hash not in files:
53 return None
54 entry = files[info_hash]
55 return entry[b"complete"], entry[b"incomplete"]
56
57 def test_a_synced_seeder_arrives(self):
58 info_hash = self.hash_for("sync-seed")
59 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.3", 6881, FLAG_SEEDING))]))
60 self.assertTrue(self.tracker.wait_until(lambda: self.counts(info_hash) == (1, 0)),
61 "scrape says %r" % (self.counts(info_hash),))
62
63 def test_a_synced_leecher_arrives(self):
64 info_hash = self.hash_for("sync-leech")
65 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.4", 6881, 0))]))
66 self.assertTrue(self.tracker.wait_until(lambda: self.counts(info_hash) == (0, 1)),
67 "scrape says %r" % (self.counts(info_hash),))
68
69 def test_a_v6_peer_arrives(self):
70 info_hash = self.hash_for("sync-v6")
71 self.tracker.livesync_send(packet(SYNC_PEER6, [(info_hash, peer6("2001:db8::1", 6881, FLAG_SEEDING))]))
72 self.assertTrue(self.tracker.wait_until(lambda: self.counts(info_hash) == (1, 0)),
73 "scrape says %r" % (self.counts(info_hash),))
74
75 def test_one_packet_carries_several_torrents(self):
76 hashes = [self.hash_for("sync-many-%d" % i) for i in range(4)]
77 self.tracker.livesync_send(packet(SYNC_PEER4, [(h, peer4("10.1.2.%d" % (5 + i), 6881, FLAG_SEEDING))
78 for i, h in enumerate(hashes)]))
79 self.assertTrue(self.tracker.wait_until(lambda: all(self.counts(h) == (1, 0) for h in hashes)))
80
81 def test_a_stopped_peer_is_taken_away_again(self):
82 info_hash = self.hash_for("sync-stop")
83 peer = peer4("10.1.2.9", 6881, FLAG_SEEDING)
84 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer)]))
85 self.assertTrue(self.tracker.wait_until(lambda: self.counts(info_hash) == (1, 0)))
86
87 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.9", 6881, FLAG_STOPPED))]))
88 self.assertTrue(self.tracker.wait_until(lambda: self.counts(info_hash) in (None, (0, 0))),
89 "scrape still says %r" % (self.counts(info_hash),))
90
91 def test_a_truncated_entry_is_dropped(self):
92 """The loop takes whole hash and peer pairs and leaves a short tail
93 where it is, so the complete entry before it still lands."""
94 good, short = self.hash_for("sync-good"), self.hash_for("sync-short")
95 payload = packet(SYNC_PEER4, [(good, peer4("10.1.2.10", 6881, FLAG_SEEDING))]) + short + b"\x0a\x01"
96 self.tracker.livesync_send(payload)
97 self.assertTrue(self.tracker.wait_until(lambda: self.counts(good) == (1, 0)))
98 self.assertIsNone(self.counts(short))
99
100 def test_an_unknown_packet_type_is_ignored(self):
101 info_hash = self.hash_for("sync-unknown")
102 self.tracker.livesync_send(packet(99, [(info_hash, peer4("10.1.2.11", 6881, FLAG_SEEDING))]))
103 self.assertFalse(self.tracker.wait_until(lambda: self.counts(info_hash) is not None, timeout=1))
104
105 def test_synced_peers_are_counted(self):
106 """The live sync worker keeps its own tally like every other worker,
107 and ?mode=syncs is the sum of them."""
108 before = int(self.tracker.stats("syncs").split()[0])
109 hashes = [self.hash_for("sync-count-%d" % i) for i in range(3)]
110 self.tracker.livesync_send(packet(SYNC_PEER4, [(h, peer4("10.1.2.%d" % (20 + i), 6881, FLAG_SEEDING))
111 for i, h in enumerate(hashes)]))
112 self.assertTrue(self.tracker.wait_until(
113 lambda: int(self.tracker.stats("syncs").split()[0]) == before + 3),
114 "syncs says %s" % self.tracker.stats("syncs").split()[0])
115
116 def test_a_packet_with_nothing_but_a_header_is_ignored(self):
117 before = self.tracker.torrent_count()
118 self.tracker.livesync_send(struct.pack("!I", 0xDEADBEEF) + struct.pack("!I", SYNC_PEER4))
119 self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != before, timeout=1))
120
121
122@unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE")
123class LiveSyncAccess(TrackerTestCase):
124 """Nothing blesses 127.0.0.1 here, so the tracker should take nothing
125 from it. Source address checking is all live sync has."""
126
127 config = "livesync.cluster.listen 127.0.0.1:{livesync_port}\nlivesync.cluster.node_ip 10.0.0.1\n"
128
129 def test_an_unblessed_sender_is_ignored(self):
130 info_hash = self.hash_for("sync-unblessed")
131 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.12", 6881, FLAG_SEEDING))]))
132 self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1))
133
134
135@unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE")
136class LiveSyncUnconfigured(TrackerTestCase):
137 """A binary that has the feature but no cluster to join. Somebody whose
138 packager turned WANT_SYNC_LIVE on did not ask for live sync and should
139 not be able to tell that it is there."""
140
141 config = ""
142
143 def test_the_tracker_runs_anyway(self):
144 info_hash = self.hash_for("no-cluster")
145 self.tracker.announce(info_hash, port=6881, left=0)
146 self.assertEqual(self.tracker.torrent_count(), 1)
147
148 def test_nothing_is_said_about_the_missing_cluster(self):
149 self.assertNotIn("sync", self.tracker.output().lower())
150
151 def test_no_socket_is_bound_for_it(self):
152 """A configured tracker holds the wildcard address on that port, so
153 taking it here proves nothing was started."""
154 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
155 try:
156 sock.bind(("0.0.0.0", self.tracker.livesync_port))
157 finally:
158 sock.close()
159
160 def test_announcing_stays_clean(self):
161 """Enough announces to pass the watermark that would flush an
162 outgoing buffer, if there were one to flush. The sanitizers in this
163 build turn anything the attempt touched into a failure."""
164 for i in range(200):
165 self.tracker.announce(self.hash_for("no-cluster-%d" % i), port=6881 + i, left=0)
166 self.assertEqual(self.tracker.torrent_count(), 200)
diff --git a/tests/integration/test_stats.py b/tests/integration/test_stats.py
index 74f6d47..088d8a1 100644
--- a/tests/integration/test_stats.py
+++ b/tests/integration/test_stats.py
@@ -66,6 +66,12 @@ class StatsShape(TrackerTestCase):
66 def test_everything_does_not_name_the_build(self): 66 def test_everything_does_not_name_the_build(self):
67 self.assertNotIn(b"opentracker 1", self.tracker.stats("everything")) 67 self.assertNotIn(b"opentracker 1", self.tracker.stats("everything"))
68 68
69 def test_everything_does_not_name_the_tracker_id(self):
70 """The id a tracker recognises its own live sync packets by. Knowing
71 it is of no use to a client and of some use to whoever would like a
72 tracker to discard what it is told."""
73 self.assertNotIn(b"tracker_id", self.tracker.stats("everything"))
74
69 75
70class StatsCount(TrackerTestCase): 76class StatsCount(TrackerTestCase):
71 def test_the_torrent_count_follows_the_torrents(self): 77 def test_the_torrent_count_follows_the_torrents(self):
diff --git a/tests/runner.c b/tests/runner.c
index 97c6d51..ae2565b 100644
--- a/tests/runner.c
+++ b/tests/runner.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdio.h> 5#include <stdio.h>
diff --git a/tests/stubs.c b/tests/stubs.c
index 5999e2d..f7ac679 100644
--- a/tests/stubs.c
+++ b/tests/stubs.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* Stubs for symbols the modules under test reference but never reach along 4/* Stubs for symbols the modules under test reference but never reach along
7 the paths the tests exercise. If a test ever does reach one, the missing 5 the paths the tests exercise. If a test ever does reach one, the missing
diff --git a/tests/sync_daemon.pl b/tests/sync_daemon.pl
new file mode 100644
index 0000000..9e4bdb9
--- /dev/null
+++ b/tests/sync_daemon.pl
@@ -0,0 +1,294 @@
1#!/usr/bin/perl
2
3# This software was written by Philipp Wuensche <cryx-otsync@h3q.com>
4# It is considered beerware.
5
6use strict;
7
8#use Convert::Bencode_XS qw(:all);
9use Convert::Bencode qw(:all);
10use Data::Dumper;
11use LWP::UserAgent;
12use URI::Escape;
13
14# enable verbose output
15my $debug = 0;
16
17# tracker from where we get our sync data
18my @trackers = ('127.0.0.1:8989');
19# tracker to upload merged data
20my @client_tracker = ('127.0.0.1:8989');
21
22# time to wait between syncs
23my $sleeptime = '300';
24
25# SSL cert and key
26my $ssl_cert = 'cert.pem';
27my $ssl_key = 'key.pem';
28
29foreach(@trackers) {
30 print "Syncing from: $_\n";
31}
32foreach(@client_tracker) {
33 print "Syncing to: $_\n";
34}
35
36my $file = shift;
37
38
39# global hash for storing the merged syncs
40my %merged_syncs;
41
42while(1) {
43 %merged_syncs;
44 my @bencoded_sync_data;
45
46 # fetch the sync from every tracker and put it into an array in bencoded form
47 foreach my $tracker (@trackers) {
48 my $bencoded_sync = fetch_sync($tracker);
49# my $bencoded_sync = fetch_sync_from_file($file);
50 if($bencoded_sync ne 0 && $bencoded_sync =~ /^d4\:sync/) {
51 push(@bencoded_sync_data,$bencoded_sync);
52 }
53 }
54
55 # bdecode every sync and throw it into the merged-sync
56 foreach my $bencoded_sync (@bencoded_sync_data) {
57 print "Doing merge...\n";
58 merge_sync(bdecode($bencoded_sync));
59 my $num_torrents = keys(%merged_syncs);
60
61 print "number of torrents: $num_torrents\n";
62 }
63
64 # number of max. peers in one changeset
65 my $peer_limit = 500;
66 # max number of changesets per commit
67 my $max_changesets = 10;
68 my $hash_count = 0;
69 my $peer_count = 0;
70 my $changeset;
71 my @escaped_changesets;
72
73 # run until all hashes are put into changesets and commited to the trackers
74 while(keys(%merged_syncs) != 0) {
75
76 foreach my $hash (keys(%merged_syncs)) {
77 print "Starting new changeset\n" if($peer_count == 0 && $debug);
78 my $num_peers = keys(%{$merged_syncs{$hash}});
79
80 print "\t$peer_count peers for $hash_count hashes in changeset\n" if($debug);
81
82 my $pack_hash = pack('H*',$hash);
83
84 # as long as the peer_limit is not reached, add new hashes with peers to the changeset hash-table
85 if($peer_count < $peer_limit) {
86 print "\t\tAdd $num_peers peers for $hash changeset\n" if($debug);
87 $peer_count = $peer_count + $num_peers;
88 foreach my $peer_socket (keys(%{$merged_syncs{$hash}})) {
89
90 my $flags = $merged_syncs{$hash}{$peer_socket};
91
92 print "\t\t\tAdd $peer_socket $flags\n" if($debug);
93
94 my $pack_peer = packme($peer_socket,$flags);
95
96 $changeset->{'sync'}->{$pack_hash} = $changeset->{'sync'}->{$pack_hash}.$pack_peer;
97 }
98 $hash_count++;
99 # hash is stored in the changeset, delete it from the hash-table
100 delete $merged_syncs{$hash};
101 }
102
103 # the peer_limit is reached or we are out of torrents, so start preparing a changeset
104 if($peer_count >= $peer_limit || keys(%merged_syncs) == 0) {
105
106 print "Commit changeset for $hash_count hashes with $peer_count peers total\n" if($debug);
107
108 # bencode the changeset
109 my $enc_changeset = bencode($changeset);
110
111 # URL-escape the changeset and put into an array of changesets
112 my $foobar = uri_escape($enc_changeset);
113 push(@escaped_changesets,$foobar);
114
115 # the changeset is ready and stored, so delete it from the changeset hash-table
116 delete $changeset->{'sync'};
117
118 $hash_count = 0;
119 $peer_count = 0;
120 print "\n\n\n" if($debug);
121 }
122
123 # if enought changesets are prepared or we are out of torrents for more changesets,
124 # sync the changesets to the trackers
125 if($#escaped_changesets == $max_changesets || keys(%merged_syncs) == 0) {
126 print "\tSync...\n";
127 sync_to_tracker(\@escaped_changesets);
128 undef @escaped_changesets;
129 }
130
131 }
132 }
133
134 print "Sleeping for $sleeptime seconds\n";
135 sleep $sleeptime;
136}
137
138sub connect_tracker {
139 # connect a tracker via HTTPS, returns the body of the response
140 my $url = shift;
141
142 $ENV{HTTPS_DEBUG} = 0;
143 $ENV{HTTPS_CERT_FILE} = $ssl_cert;
144 $ENV{HTTPS_KEY_FILE} = $ssl_key;
145
146 my $ua = new LWP::UserAgent;
147 my $req = new HTTP::Request('GET', $url);
148 my $res = $ua->request($req);
149
150 my $content = $res->content;
151
152 if($res->is_success()) {
153 return $content;
154 } else {
155 print $res->code."|".$res->status_line."\n";
156 return 0;
157 }
158}
159
160sub sync_to_tracker {
161 # commit changesets to a tracker
162 my @changesets = @{(shift)};
163
164 # prepare the URI with URL-encoded changesets concatenated by a &
165 my $uri = 'sync?';
166 foreach my $set (@changesets) {
167 $uri .= 'changeset='.$set.'&';
168 }
169 my $uri_length = length($uri);
170
171 # commit the collection of changesets to the tracker via HTTPS
172 foreach my $tracker (@client_tracker) {
173 print "\t\tTracker: $tracker (URI: $uri_length)\n";
174 my $url = "https://$tracker/".$uri;
175 connect_tracker($url);
176 }
177}
178
179sub packme {
180 # pack data
181 # returns ipaddr, port and flags in packed format
182 my $peer_socket = shift;
183 my $flags = shift;
184
185 my($a,$b,$c,$d,$port) = split(/[\.,\:]/,$peer_socket);
186 my $pack_peer = pack('C4 n1 b16',$a,$b,$c,$d,$port,$flags);
187
188 return $pack_peer;
189}
190
191sub unpackme {
192 # unpack packed data
193 # returns ipaddr. in quad-form with port (a.b.c.d:port) and flags as bitfield
194 # data is packed as:
195 # - 4 byte ipaddr. (unsigned char value)
196 # - 2 byte port (unsigned short in "network" (big-endian) order)
197 # - 2 byte flags (bit string (ascending bit order inside each byte))
198 my $data = shift;
199
200 my($a, $b, $c, $d, $port, $flags) = unpack('C4 n1 b16',$data);
201 my $peer_socket = "$a\.$b\.$c\.$d\:$port";
202
203 return($peer_socket,$flags);
204}
205
206sub fetch_sync {
207 # fetch sync from a tracker
208 my $tracker = shift;
209 my $url = "https://$tracker/sync";
210
211 print "Fetching from $url\n";
212
213 my $body = connect_tracker($url);
214
215 if($body && $body =~ /^d4\:sync/) {
216 return $body;
217 } else {
218 return 0;
219 }
220}
221
222sub fetch_sync_from_file {
223 # fetch sync from a file
224 my $file = shift;
225 my $body;
226 print "Fetching from file $file\n";
227 open(FILE,"<$file");
228 while(<FILE>) {
229 $body .= $_;
230 }
231 close(FILE);
232 return $body;
233}
234
235sub merge_sync {
236 # This builds a hash table with the torrenthash as keys. The value is a hash table again with the peer-socket as keys
237 # and flags in the value
238 # Example:
239 # 60dd2beb4197f71677c0f5ba92b956f7d04651e5 =>
240 # 192.168.23.23:2323 => 0000000000000000
241 # 23.23.23.23:2342 => 0000000100000000
242 # b220b4d7136e84a88abc090db88bec8604a808f3 =>
243 # 42.23.42.23:55555 => 0000000000000000
244
245 my $hashref = shift;
246
247 my $nonuniq_hash_counter = 0;
248 my $nonuniq_peer_counter = 0;
249 my $hash_counter = 0;
250 my $peer_counter = 0;
251
252 foreach my $key (keys(%{$hashref->{'sync'}})) {
253 # start merge for every sha1-hash in the sync
254 my $hash = unpack('H*',$key);
255
256 $hash_counter++;
257 $nonuniq_hash_counter++ if exists $merged_syncs{$hash};
258
259 while(${$hashref->{'sync'}}{$key} ne "")
260 {
261 # split the value into 8-byte and unpack it for getting peer-socket and flags
262 my($peer_socket,$flags) = unpackme(substr(${$hashref->{'sync'}}{$key},0,8,''));
263
264 $peer_counter++;
265 $nonuniq_peer_counter++ if exists $merged_syncs{$hash}{$peer_socket};
266
267 # Create a hash table with sha1-hash as key and a hash table as value.
268 # The hash table in the value has the peer-socket as key and flags as value
269 # If the entry already exists, the flags are ORed together, if not it is ORed with 0
270 $merged_syncs{$hash}{$peer_socket} = $flags | $merged_syncs{$hash}{$peer_socket};
271 }
272 }
273 print "$hash_counter hashes $nonuniq_hash_counter non-uniq, $peer_counter peers $nonuniq_peer_counter non-uniq.\n";
274
275}
276
277sub test_decode {
278 my $hashref = shift;
279
280 print "CHANGESET DEBUG OUTPUT\n";
281
282 print Dumper $hashref;
283 foreach my $key (keys(%{$hashref->{'sync'}})) {
284 my $hash = unpack('H*',$key);
285
286 print "Changeset for $hash\n";
287 while(${$hashref->{'sync'}}{$key} ne "")
288 {
289
290 my($peer_socket,$flags) = unpackme(substr(${$hashref->{'sync'}}{$key},0,8,''));
291 print "\tSocket: $peer_socket Flags: $flags\n";
292 }
293 }
294}
diff --git a/tests/t_accesslist.c b/tests/t_accesslist.c
index 9925acd..14321f4 100644
--- a/tests/t_accesslist.c
+++ b/tests/t_accesslist.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdlib.h> 5#include <stdlib.h>
diff --git a/tests/t_batch.c b/tests/t_batch.c
index 02743f1..5a7ac1e 100644
--- a/tests/t_batch.c
+++ b/tests/t_batch.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <fcntl.h> 5#include <fcntl.h>
diff --git a/tests/t_buf.c b/tests/t_buf.c
index dcfb0bb..39c44f1 100644
--- a/tests/t_buf.c
+++ b/tests/t_buf.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_event.c b/tests/t_event.c
index 1908dc9..5c45089 100644
--- a/tests/t_event.c
+++ b/tests/t_event.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <fcntl.h> 5#include <fcntl.h>
diff --git a/tests/t_fdstate.c b/tests/t_fdstate.c
index 421f076..c806dbe 100644
--- a/tests/t_fdstate.c
+++ b/tests/t_fdstate.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <pthread.h> 5#include <pthread.h>
diff --git a/tests/t_fmt.c b/tests/t_fmt.c
index bc23ed5..f94102d 100644
--- a/tests/t_fmt.c
+++ b/tests/t_fmt.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <string.h> 5#include <string.h>
diff --git a/tests/t_hex.c b/tests/t_hex.c
index a761737..84aeba2 100644
--- a/tests/t_hex.c
+++ b/tests/t_hex.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_iovec.c b/tests/t_iovec.c
index 2553141..1e8206d 100644
--- a/tests/t_iovec.c
+++ b/tests/t_iovec.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdlib.h> 5#include <stdlib.h>
diff --git a/tests/t_ip.c b/tests/t_ip.c
index 8d71679..218d3ff 100644
--- a/tests/t_ip.c
+++ b/tests/t_ip.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_mutex.c b/tests/t_mutex.c
index 7c1463b..c0c41cc 100644
--- a/tests/t_mutex.c
+++ b/tests/t_mutex.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <pthread.h> 5#include <pthread.h>
@@ -26,7 +24,7 @@ static void hash_for_bucket(ot_hash hash, int bucket) {
26} 24}
27 25
28static void case_a_hash_names_its_bucket(void) { 26static void case_a_hash_names_its_bucket(void) {
29 static const int buckets[] = {0, 1, 2, 17, 511, 512, OT_BUCKET_COUNT - 1}; 27 static const int buckets[] = {0, 1, 2, 17, OT_BUCKET_COUNT / 2 - 1, OT_BUCKET_COUNT / 2, OT_BUCKET_COUNT - 1};
30 size_t i; 28 size_t i;
31 29
32 test_case("a hash is served by the bucket its leading bits name"); 30 test_case("a hash is served by the bucket its leading bits name");
diff --git a/tests/t_random.c b/tests/t_random.c
index 67dedf6..b070c3f 100644
--- a/tests/t_random.c
+++ b/tests/t_random.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_scan.c b/tests/t_scan.c
index aab4413..05c4a67 100644
--- a/tests/t_scan.c
+++ b/tests/t_scan.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_socket.c b/tests/t_socket.c
index 20a0c0a..8e917a3 100644
--- a/tests/t_socket.c
+++ b/tests/t_socket.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <errno.h> 5#include <errno.h>
diff --git a/tests/t_trackerlogic.c b/tests/t_trackerlogic.c
index d3d8755..1cf9141 100644
--- a/tests/t_trackerlogic.c
+++ b/tests/t_trackerlogic.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <arpa/inet.h> 5#include <arpa/inet.h>
@@ -226,7 +224,7 @@ void test_trackerlogic(void) {
226 pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); 224 pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
227 225
228 trackerlogic_init(); 226 trackerlogic_init();
229 CHECK_INT(workstruct_init(&ws), 0); 227 CHECK_INT(workstruct_init(&ws, G_INBUF_SIZE), 0);
230 228
231 case_an_announce_makes_a_torrent(); 229 case_an_announce_makes_a_torrent();
232 case_the_same_peer_twice_is_one_peer(); 230 case_the_same_peer_twice_is_one_peer();
diff --git a/tests/t_urlencoded.c b/tests/t_urlencoded.c
index 6e0ee31..3b3e6c2 100644
--- a/tests/t_urlencoded.c
+++ b/tests/t_urlencoded.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <string.h> 5#include <string.h>
diff --git a/tests/t_vector.c b/tests/t_vector.c
index 6e048e1..f0a9bf7 100644
--- a/tests/t_vector.c
+++ b/tests/t_vector.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdint.h> 5#include <stdint.h>
diff --git a/tests/t_workqueue.c b/tests/t_workqueue.c
index 13e0b2e..c454e5b 100644
--- a/tests/t_workqueue.c
+++ b/tests/t_workqueue.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdlib.h> 5#include <stdlib.h>
diff --git a/tests/test.c b/tests/test.c
index 4686369..33f77bd 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <stdarg.h> 5#include <stdarg.h>
diff --git a/tests/test.h b/tests/test.h
index d7296cc..82ec178 100644
--- a/tests/test.h
+++ b/tests/test.h
@@ -1,7 +1,5 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org> 1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. 2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4 $id$ */
5 3
6#ifndef OT_TEST_H__ 4#ifndef OT_TEST_H__
7#define OT_TEST_H__ 5#define OT_TEST_H__