source: trunk/libtransmission/libtransmission-test.c

Last change on this file was 14721, checked in by jordan, 5 years ago

fix a handful of minor compiler warnings, mostly in the unit tests, eg field width shortening or implicit signed/unsigned conversions

  • Property svn:keywords set to Date Rev Author Id
File size: 12.3 KB
Line 
1/*
2 * This file Copyright (C) 2013-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: libtransmission-test.c 14721 2016-03-29 03:04:54Z mikedld $
8 */
9
10#include <assert.h>
11#include <errno.h>
12#include <stdio.h>
13#include <stdlib.h> /* mkstemp() */
14#include <string.h> /* strcmp() */
15
16#ifndef _WIN32
17 #include <unistd.h> /* sync() */
18#endif
19
20#include "transmission.h"
21#include "crypto-utils.h"
22#include "error.h"
23#include "file.h"
24#include "platform.h" /* TR_PATH_DELIMETER */
25#include "torrent.h"
26#include "trevent.h"
27#include "variant.h"
28#include "libtransmission-test.h"
29
30bool verbose = false;
31
32int current_test = 0;
33
34bool
35should_print (bool pass)
36{
37  if (!pass)
38    return true;
39
40  if (verbose)
41    return true;
42
43  return false;
44#ifdef VERBOSE
45  return true;
46#else
47  return false;
48#endif
49}
50
51bool
52check_condition_impl (const char * file, int line, bool condition)
53{
54  const bool pass = condition;
55
56  if (should_print (pass))
57    fprintf (stderr, "%s %s:%d\n", pass?"PASS":"FAIL", file, line);
58
59  return pass;
60}
61
62bool
63check_streq_impl (const char * file, int line, const char * expected, const char * actual)
64{
65  const bool pass = tr_strcmp0 (expected, actual) == 0;
66
67  if (should_print (pass)) {
68    if (pass)
69      fprintf (stderr, "PASS %s:%d\n", file, line);
70    else
71      fprintf (stderr, "FAIL %s:%d, expected \"%s\", got \"%s\"\n", file, line, expected?expected:" (null)", actual?actual:" (null)");
72  }
73
74  return pass;
75}
76
77bool
78check_int_eq_impl (const char * file, int line, int64_t expected, int64_t actual)
79{
80  const bool pass = expected == actual;
81
82  if (should_print (pass)) {
83    if (pass)
84      fprintf (stderr, "PASS %s:%d\n", file, line);
85    else
86      fprintf (stderr, "FAIL %s:%d, expected \"%"PRId64"\", got \"%"PRId64"\"\n", file, line, expected, actual);
87  }
88
89  return pass;
90}
91
92bool
93check_uint_eq_impl (const char * file, int line, uint64_t expected, uint64_t actual)
94{
95  const bool pass = expected == actual;
96
97  if (should_print (pass)) {
98    if (pass)
99      fprintf (stderr, "PASS %s:%d\n", file, line);
100    else
101      fprintf (stderr, "FAIL %s:%d, expected \"%"PRIu64"\", got \"%"PRIu64"\"\n", file, line, expected, actual);
102  }
103
104  return pass;
105}
106
107bool
108check_ptr_eq_impl (const char * file, int line, const void * expected, const void * actual)
109{
110  const bool pass = expected == actual;
111
112  if (should_print (pass)) {
113    if (pass)
114      fprintf (stderr, "PASS %s:%d\n", file, line);
115    else
116      fprintf (stderr, "FAIL %s:%d, expected \"%p\", got \"%p\"\n", file, line, expected, actual);
117  }
118
119  return pass;
120}
121
122int
123runTests (const testFunc * const tests, int numTests)
124{
125  int i;
126  int ret;
127
128  (void) current_test; /* Use test even if we don't have any tests to run */
129
130  for (i=0; i<numTests; i++)
131    if ((ret = (*tests[i])()))
132      return ret;
133
134  return 0; /* All tests passed */
135}
136
137/***
138****
139***/
140
141static char*
142tr_getcwd (void)
143{
144  char * result;
145  tr_error * error = NULL;
146
147  result = tr_sys_dir_get_current (&error);
148
149  if (result == NULL)
150    {
151      fprintf (stderr, "getcwd error: \"%s\"", error->message);
152      tr_error_free (error);
153      result = tr_strdup ("");
154    }
155
156  return result;
157}
158
159char *
160libtest_sandbox_create (void)
161{
162  char * path = tr_getcwd ();
163  char * sandbox = tr_buildPath (path, "sandbox-XXXXXX", NULL);
164  tr_free (path);
165  tr_sys_dir_create_temp (sandbox, NULL);
166  return sandbox;
167}
168
169static void
170rm_rf (const char * killme)
171{
172  tr_sys_path_info info;
173
174  if (tr_sys_path_get_info (killme, 0, &info, NULL))
175    {
176      tr_sys_dir_t odir;
177
178      if (info.type == TR_SYS_PATH_IS_DIRECTORY &&
179          (odir = tr_sys_dir_open (killme, NULL)) != TR_BAD_SYS_DIR)
180        {
181          const char * name;
182          while ((name = tr_sys_dir_read_name (odir, NULL)) != NULL)
183            {
184              if (strcmp (name, ".") != 0 && strcmp (name, "..") != 0)
185                {
186                  char * tmp = tr_buildPath (killme, name, NULL);
187                  rm_rf (tmp);
188                  tr_free (tmp);
189                }
190            }
191          tr_sys_dir_close (odir, NULL);
192        }
193
194      if (verbose)
195        fprintf (stderr, "cleanup: removing %s\n", killme);
196
197      tr_sys_path_remove (killme, NULL);
198    }
199}
200
201void
202libtest_sandbox_destroy (const char * sandbox)
203{
204  rm_rf (sandbox);
205}
206
207/***
208****
209***/
210
211#define MEM_K 1024
212#define MEM_K_STR "KiB"
213#define MEM_M_STR "MiB"
214#define MEM_G_STR "GiB"
215#define MEM_T_STR "TiB"
216
217#define DISK_K 1000
218#define DISK_K_STR "kB"
219#define DISK_M_STR "MB"
220#define DISK_G_STR "GB"
221#define DISK_T_STR "TB"
222
223#define SPEED_K 1000
224#define SPEED_K_STR "kB/s"
225#define SPEED_M_STR "MB/s"
226#define SPEED_G_STR "GB/s"
227#define SPEED_T_STR "TB/s"
228
229tr_session *
230libttest_session_init (tr_variant * settings)
231{
232  size_t len;
233  const char * str;
234  char * sandbox;
235  char * path;
236  tr_quark q;
237  static bool formatters_inited = false;
238  tr_session * session;
239  tr_variant local_settings;
240
241  tr_variantInitDict (&local_settings, 10);
242
243  if (settings == NULL)
244    settings = &local_settings;
245
246  sandbox = libtest_sandbox_create ();
247
248  if (!formatters_inited)
249    {
250      formatters_inited = true;
251      tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
252      tr_formatter_size_init (DISK_K,DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
253      tr_formatter_speed_init (SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);
254    }
255
256  /* download dir */
257  q = TR_KEY_download_dir;
258  if (tr_variantDictFindStr (settings, q, &str, &len))
259    path = tr_strdup_printf ("%s/%*.*s", sandbox, (int)len, (int)len, str);
260  else
261    path = tr_buildPath (sandbox, "Downloads", NULL);
262  tr_sys_dir_create (path, TR_SYS_DIR_CREATE_PARENTS, 0700, NULL);
263  tr_variantDictAddStr (settings, q, path);
264  tr_free (path);
265
266  /* incomplete dir */
267  q = TR_KEY_incomplete_dir;
268  if (tr_variantDictFindStr (settings, q, &str, &len))
269    path = tr_strdup_printf ("%s/%*.*s", sandbox, (int)len, (int)len, str);
270  else
271    path = tr_buildPath (sandbox, "Incomplete", NULL);
272  tr_variantDictAddStr (settings, q, path);
273  tr_free (path);
274
275  path = tr_buildPath (sandbox, "blocklists", NULL);
276  tr_sys_dir_create (path, TR_SYS_DIR_CREATE_PARENTS, 0700, NULL);
277  tr_free (path);
278
279  q = TR_KEY_port_forwarding_enabled;
280  if (!tr_variantDictFind (settings, q))
281    tr_variantDictAddBool (settings, q, false);
282
283  q = TR_KEY_dht_enabled;
284  if (!tr_variantDictFind (settings, q))
285    tr_variantDictAddBool (settings, q, false);
286
287  q = TR_KEY_message_level;
288  if (!tr_variantDictFind (settings, q))
289    tr_variantDictAddInt (settings, q, verbose ? TR_LOG_DEBUG : TR_LOG_ERROR);
290
291  session = tr_sessionInit (sandbox, !verbose, settings);
292
293  tr_free (sandbox);
294  tr_variantFree (&local_settings);
295  return session;
296}
297
298void
299libttest_session_close (tr_session * session)
300{
301  char * sandbox;
302
303  sandbox = tr_strdup (tr_sessionGetConfigDir (session));
304  tr_sessionClose (session);
305  tr_logFreeQueue (tr_logGetQueue ());
306  session = NULL;
307
308  libtest_sandbox_destroy (sandbox);
309  tr_free (sandbox);
310}
311
312/***
313****
314***/
315
316tr_torrent *
317libttest_zero_torrent_init (tr_session * session)
318{
319  int err;
320  size_t metainfo_len;
321  char * metainfo;
322  const char * metainfo_base64;
323  tr_torrent * tor;
324  tr_ctor * ctor;
325
326  /*
327     1048576 files-filled-with-zeroes/1048576
328        4096 files-filled-with-zeroes/4096
329         512 files-filled-with-zeroes/512
330   */
331  metainfo_base64 =
332    "ZDg6YW5ub3VuY2UzMTpodHRwOi8vd3d3LmV4YW1wbGUuY29tL2Fubm91bmNlMTA6Y3JlYXRlZCBi"
333    "eTI1OlRyYW5zbWlzc2lvbi8yLjYxICgxMzQwNykxMzpjcmVhdGlvbiBkYXRlaTEzNTg3MDQwNzVl"
334    "ODplbmNvZGluZzU6VVRGLTg0OmluZm9kNTpmaWxlc2xkNjpsZW5ndGhpMTA0ODU3NmU0OnBhdGhs"
335    "NzoxMDQ4NTc2ZWVkNjpsZW5ndGhpNDA5NmU0OnBhdGhsNDo0MDk2ZWVkNjpsZW5ndGhpNTEyZTQ6"
336    "cGF0aGwzOjUxMmVlZTQ6bmFtZTI0OmZpbGVzLWZpbGxlZC13aXRoLXplcm9lczEyOnBpZWNlIGxl"
337    "bmd0aGkzMjc2OGU2OnBpZWNlczY2MDpRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj"
338    "/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv17"
339    "26aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGEx"
340    "Uv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJ"
341    "tGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GI"
342    "QxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZC"
343    "S1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8K"
344    "T9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9um"
345    "o/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9"
346    "e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRh"
347    "MVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMY"
348    "SbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLOlf5A+Tz30nMBVuNM2hpV3wg/103"
349    "OnByaXZhdGVpMGVlZQ==";
350
351  /* create the torrent ctor */
352  metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len);
353  assert (metainfo != NULL);
354  assert (metainfo_len > 0);
355  assert (session != NULL);
356  ctor = tr_ctorNew (session);
357  tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, metainfo_len);
358  tr_ctorSetPaused (ctor, TR_FORCE, true);
359
360  /* create the torrent */
361  err = 0;
362  tor = tr_torrentNew (ctor, &err, NULL);
363  assert (!err);
364
365  /* cleanup */
366  tr_free (metainfo);
367  tr_ctorFree (ctor);
368  return tor;
369}
370
371void
372libttest_zero_torrent_populate (tr_torrent * tor, bool complete)
373{
374  tr_file_index_t i;
375
376  for (i=0; i<tor->info.fileCount; ++i)
377    {
378      int err;
379      uint64_t j;
380      tr_sys_file_t fd;
381      char * path;
382      char * dirname;
383      const tr_file * file = &tor->info.files[i];
384
385      if (!complete && (i==0))
386        path = tr_strdup_printf ("%s%c%s.part", tor->currentDir, TR_PATH_DELIMITER, file->name);
387      else
388        path = tr_strdup_printf ("%s%c%s", tor->currentDir, TR_PATH_DELIMITER, file->name);
389      dirname = tr_sys_path_dirname (path, NULL);
390      tr_sys_dir_create (dirname, TR_SYS_DIR_CREATE_PARENTS, 0700, NULL);
391      fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL);
392      for (j=0; j<file->length; ++j)
393        tr_sys_file_write (fd, ((!complete) && (i==0) && (j<tor->info.pieceSize)) ? "\1" : "\0", 1, NULL, NULL);
394      tr_sys_file_close (fd, NULL);
395
396      tr_free (dirname);
397      tr_free (path);
398
399      path = tr_torrentFindFile (tor, i);
400      assert (path != NULL);
401      err = errno;
402      assert (tr_sys_path_exists (path, NULL));
403      errno = err;
404      tr_free (path);
405    }
406
407  libttest_sync ();
408  libttest_blockingTorrentVerify (tor);
409
410  if (complete)
411    assert (tr_torrentStat(tor)->leftUntilDone == 0);
412  else
413    assert (tr_torrentStat(tor)->leftUntilDone == tor->info.pieceSize);
414}
415
416/***
417****
418***/
419
420static void
421onVerifyDone (tr_torrent * tor UNUSED, bool aborted UNUSED, void * done)
422{
423  *(bool*)done = true;
424}
425
426void
427libttest_blockingTorrentVerify (tr_torrent * tor)
428{
429  bool done = false;
430
431  assert (tor->session != NULL);
432  assert (!tr_amInEventThread (tor->session));
433
434  tr_torrentVerify (tor, onVerifyDone, &done);
435  while (!done)
436    tr_wait_msec (10);
437}
438
439static void
440build_parent_dir (const char* path)
441{
442  char * dir;
443  tr_error * error = NULL;
444  const int tmperr = errno;
445
446  dir = tr_sys_path_dirname (path, NULL);
447  tr_sys_dir_create (dir, TR_SYS_DIR_CREATE_PARENTS, 0700, &error);
448  assert (error == NULL);
449  tr_free (dir);
450
451  errno = tmperr;
452}
453
454void
455libtest_create_file_with_contents (const char* path, const void* payload, size_t n)
456{
457  tr_sys_file_t fd;
458  const int tmperr = errno;
459
460  build_parent_dir (path);
461
462  fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL);
463  tr_sys_file_write (fd, payload, n, NULL, NULL);
464  tr_sys_file_close (fd, NULL);
465
466  libttest_sync ();
467
468  errno = tmperr;
469}
470
471void
472libtest_create_file_with_string_contents (const char * path, const char* str)
473{
474  libtest_create_file_with_contents (path, str, strlen(str));
475}
476
477void
478libtest_create_tmpfile_with_contents (char* tmpl, const void* payload, size_t n)
479{
480  tr_sys_file_t fd;
481  const int tmperr = errno;
482  uint64_t n_left = n;
483  tr_error * error = NULL;
484
485  build_parent_dir (tmpl);
486
487  fd = tr_sys_file_open_temp (tmpl, NULL);
488  while (n_left > 0)
489    {
490      uint64_t n;
491      if (!tr_sys_file_write (fd, payload, n_left, &n, &error))
492        {
493          fprintf (stderr, "Error writing '%s': %s\n", tmpl, error->message);
494          tr_error_free (error);
495          break;
496        }
497      n_left -= n;
498    }
499  tr_sys_file_close (fd, NULL);
500
501  libttest_sync ();
502
503  errno = tmperr;
504}
505
506void
507libttest_sync (void)
508{
509#ifndef _WIN32
510  sync ();
511#endif
512}
Note: See TracBrowser for help on using the repository browser.