summaryrefslogtreecommitdiff
path: root/tests/t_clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/t_clean.c')
-rw-r--r--tests/t_clean.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/t_clean.c b/tests/t_clean.c
index 0237cc6..ce17bc3 100644
--- a/tests/t_clean.c
+++ b/tests/t_clean.c
@@ -33,6 +33,20 @@ static void announce(struct ot_workstruct *ws, ot_hash *hash, uint8_t last_octet
33 add_peer_to_torrent_and_return_peers(FLAG_TCP, ws, 0); 33 add_peer_to_torrent_and_return_peers(FLAG_TCP, ws, 0);
34} 34}
35 35
36/* A distinct v4 peer addressed by two octets, to build swarms past 256 */
37static size_t announce_wide(struct ot_workstruct *ws, ot_hash *hash, unsigned int which, size_t amount) {
38 static const uint8_t v4mapped[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
39
40 ws->reply = ws->outbuf;
41 memset(&ws->peer, 0, sizeof(ws->peer));
42 memcpy(&ws->peer, v4mapped, sizeof(v4mapped));
43 ((uint8_t *)&ws->peer)[14] = (uint8_t)(which >> 8);
44 ((uint8_t *)&ws->peer)[15] = (uint8_t)which;
45 OT_SETPORT(&ws->peer, &(uint16_t){6881});
46 ws->hash = hash;
47 return add_peer_to_torrent_and_return_peers(FLAG_TCP, ws, amount);
48}
49
36static size_t peers_in(ot_hash *hash) { 50static size_t peers_in(ot_hash *hash) {
37 char reply[1024]; 51 char reply[1024];
38 size_t len = return_udp_scrape_for_torrent(*hash, reply); 52 size_t len = return_udp_scrape_for_torrent(*hash, reply);
@@ -157,6 +171,39 @@ static void case_empty_torrent_timeout_bounds_a_counter_only_torrent(void) {
157 workstruct_deinit(&ws); 171 workstruct_deinit(&ws);
158} 172}
159 173
174static void case_a_bucketed_swarm_survives_clean_and_serves(void) {
175 struct ot_workstruct ws;
176 ot_hash hash;
177 ot_torrent *torrent;
178 unsigned int i;
179 const unsigned int n = 600; /* past OT_PEER_BUCKET_MINCOUNT (512) */
180
181 test_case("a swarm large enough to be bucketed cleans, splits and serves without loss");
182 memset(hash, 0x34, sizeof(hash));
183 CHECK_INT(workstruct_init(&ws, G_INBUF_SIZE), 0);
184
185 for (i = 0; i < n; ++i)
186 announce_wide(&ws, &hash, i, 0);
187 CHECK_INT(peers_in(&hash), n);
188
189 torrent = torrent_of(&hash);
190 CHECK(torrent != NULL);
191 CHECK(torrent->peer_list != NULL);
192
193 /* A clean with a minute elapsed splits the flat vector into buckets */
194 step_clock_back(torrent, -1);
195 CHECK_INT(clean_single_torrent(torrent), 0);
196 CHECK(torrent->peer_list != NULL);
197 CHECK_INT(OT_VECTOR_HASBUCKETS(&torrent->peer_list->peers4), 1);
198 CHECK_INT(peers_in(&hash), n);
199
200 /* Serve a selection back, which walks the bucket list */
201 CHECK(announce_wide(&ws, &hash, 1, 200) > 0);
202 CHECK_INT(peers_in(&hash), n);
203
204 workstruct_deinit(&ws);
205}
206
160void test_clean(void) { 207void test_clean(void) {
161 sigset_t hup; 208 sigset_t hup;
162 209
@@ -170,5 +217,6 @@ void test_clean(void) {
170 case_a_clock_that_went_back_keeps_the_swarm(); 217 case_a_clock_that_went_back_keeps_the_swarm();
171 case_an_idle_swarm_still_ages_out(); 218 case_an_idle_swarm_still_ages_out();
172 case_empty_torrent_timeout_bounds_a_counter_only_torrent(); 219 case_empty_torrent_timeout_bounds_a_counter_only_torrent();
220 case_a_bucketed_swarm_survives_clean_and_serves();
173 trackerlogic_deinit(); 221 trackerlogic_deinit();
174} 222}