~dave-terei/libmemcached/sasl-fixes

« back to all changes in this revision

Viewing changes to libtest/test.cc

Update libtest/associated tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
 
36
36
#include <signal.h>
37
37
 
 
38
#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
 
39
#include <curl/curl.h>
 
40
#endif
 
41
 
38
42
#ifndef __INTEL_COMPILER
39
43
#pragma GCC diagnostic ignored "-Wold-style-cast"
40
44
#endif
70
74
  return s + us;
71
75
}
72
76
 
73
 
static Framework *world= NULL;
 
77
static void cleanup_curl(void)
 
78
{
 
79
#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
 
80
  curl_global_cleanup();
 
81
#endif
 
82
}
 
83
 
 
84
#include <getopt.h>
 
85
#include <unistd.h>
 
86
 
74
87
int main(int argc, char *argv[])
75
88
{
 
89
#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
 
90
  if (curl_global_init(CURL_GLOBAL_ALL))
 
91
  {
 
92
    Error << "curl_global_init(CURL_GLOBAL_ALL) failed";
 
93
    return EXIT_FAILURE;
 
94
  }
 
95
#endif
 
96
 
 
97
  if (atexit(cleanup_curl))
 
98
  {
 
99
    Error << "atexit() failed";
 
100
    return EXIT_FAILURE;
 
101
  }
 
102
 
 
103
  bool opt_repeat= false;
 
104
  std::string collection_to_run;
 
105
 
 
106
  // Options parsing
 
107
  {
 
108
    enum long_option_t {
 
109
      OPT_LIBYATL_VERSION,
 
110
      OPT_LIBYATL_MATCH_COLLECTION,
 
111
      OPT_LIBYATL_REPEAT
 
112
    };
 
113
 
 
114
    static struct option long_options[]=
 
115
    {
 
116
      {"repeat", no_argument, NULL, OPT_LIBYATL_REPEAT},
 
117
      {"collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION},
 
118
      {0, 0, 0, 0}
 
119
    };
 
120
 
 
121
    int option_index= 0;
 
122
    while (1)
 
123
    {
 
124
      int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
 
125
      if (option_rv == -1)
 
126
      {
 
127
        break;
 
128
      }
 
129
 
 
130
      switch (option_rv)
 
131
      {
 
132
      case OPT_LIBYATL_VERSION:
 
133
        break;
 
134
 
 
135
      case OPT_LIBYATL_REPEAT:
 
136
        opt_repeat= true;
 
137
        break;
 
138
 
 
139
      case OPT_LIBYATL_MATCH_COLLECTION:
 
140
        collection_to_run= optarg;
 
141
        break;
 
142
 
 
143
      case '?':
 
144
        /* getopt_long already printed an error message. */
 
145
        Error << "unknown option to getopt_long()";
 
146
        exit(EXIT_FAILURE);
 
147
 
 
148
      default:
 
149
        break;
 
150
      }
 
151
    }
 
152
  }
 
153
 
76
154
  srandom((unsigned int)time(NULL));
77
155
 
78
 
  if (getenv("LIBTEST_QUIET"))
 
156
  if (getenv("LIBTEST_QUIET") and strcmp(getenv("LIBTEST_QUIET"), "0") == 0)
79
157
  {
80
158
    close(STDOUT_FILENO);
81
159
  }
109
187
    return EXIT_FAILURE;
110
188
  }
111
189
 
112
 
  world= new Framework();
113
 
 
114
 
  if (world == NULL)
115
 
  {
116
 
    Error << "Failed to create Framework()";
117
 
    return EXIT_FAILURE;
118
 
  }
119
 
 
120
 
  libtest::SignalThread signal;
121
 
  if (not signal.setup())
122
 
  {
123
 
    return EXIT_FAILURE;
124
 
  }
125
 
 
126
 
  Stats stats;
127
 
 
128
 
  get_world(world);
129
 
 
130
 
  test_return_t error;
131
 
  void *creators_ptr= world->create(error);
132
 
 
133
 
  switch (error)
134
 
  {
135
 
  case TEST_SUCCESS:
136
 
    break;
137
 
 
138
 
  case TEST_SKIPPED:
139
 
    Out << "SKIP " << argv[0];
140
 
    delete world;
141
 
    return EXIT_SUCCESS;
142
 
 
143
 
  case TEST_FATAL:
144
 
  case TEST_FAILURE:
145
 
  case TEST_MEMORY_ALLOCATION_FAILURE:
146
 
    delete world;
147
 
    return EXIT_FAILURE;
148
 
  }
149
 
 
150
 
  char *collection_to_run= NULL;
151
 
  if (argc > 1)
152
 
  {
153
 
    collection_to_run= argv[1];
154
 
  }
155
 
  else if (getenv("TEST_COLLECTION"))
156
 
  {
157
 
    if (strlen(getenv("TEST_COLLECTION")))
158
 
    {
159
 
      collection_to_run= getenv("TEST_COLLECTION");
160
 
    }
161
 
  }
162
 
 
163
 
  if (collection_to_run)
164
 
  {
165
 
    Out << "Only testing " <<  collection_to_run;
166
 
  }
167
 
 
168
 
  char *wildcard= NULL;
169
 
  if (argc == 3)
170
 
  {
171
 
    wildcard= argv[2];
172
 
  }
173
 
 
174
 
  for (collection_st *next= world->collections; next->name and (not signal.is_shutdown()); next++)
175
 
  {
176
 
    test_return_t collection_rc= TEST_SUCCESS;
177
 
    bool failed= false;
178
 
    bool skipped= false;
179
 
 
180
 
    if (collection_to_run && fnmatch(collection_to_run, next->name, 0))
181
 
      continue;
182
 
 
183
 
    stats.collection_total++;
184
 
 
185
 
    collection_rc= world->startup(creators_ptr);
186
 
 
187
 
    if (collection_rc == TEST_SUCCESS and next->pre)
188
 
    {
189
 
      collection_rc= world->runner()->pre(next->pre, creators_ptr);
190
 
    }
191
 
 
192
 
    switch (collection_rc)
 
190
  int exit_code;
 
191
  do {
 
192
    exit_code= EXIT_SUCCESS;
 
193
    Framework *world= new Framework();
 
194
 
 
195
    if (world == NULL)
 
196
    {
 
197
      Error << "Failed to create Framework()";
 
198
      return EXIT_FAILURE;
 
199
    }
 
200
 
 
201
    assert(sigignore(SIGPIPE) == 0);
 
202
 
 
203
    libtest::SignalThread signal;
 
204
    if (not signal.setup())
 
205
    {
 
206
      Error << "Failed to setup signals";
 
207
      return EXIT_FAILURE;
 
208
    }
 
209
 
 
210
    Stats stats;
 
211
 
 
212
    get_world(world);
 
213
 
 
214
    test_return_t error;
 
215
    void *creators_ptr= world->create(error);
 
216
 
 
217
    switch (error)
193
218
    {
194
219
    case TEST_SUCCESS:
195
220
      break;
196
221
 
 
222
    case TEST_SKIPPED:
 
223
      Out << "SKIP " << argv[0];
 
224
      delete world;
 
225
      return EXIT_SUCCESS;
 
226
 
197
227
    case TEST_FATAL:
198
228
    case TEST_FAILURE:
199
 
      Out << next->name << " [ failed ]";
200
 
      failed= true;
201
 
      signal.set_shutdown(SHUTDOWN_GRACEFUL);
202
 
      goto cleanup;
203
 
 
204
 
    case TEST_SKIPPED:
205
 
      Out << next->name << " [ skipping ]";
206
 
      skipped= true;
207
 
      goto cleanup;
208
 
 
209
229
    case TEST_MEMORY_ALLOCATION_FAILURE:
210
 
      test_assert(0, "Allocation failure, or unknown return");
211
 
    }
212
 
 
213
 
    Out << "Collection: " << next->name;
214
 
 
215
 
    for (test_st *run= next->tests; run->name; run++)
216
 
    {
217
 
      struct timeval start_time, end_time;
218
 
      long int load_time= 0;
219
 
 
220
 
      if (wildcard && fnmatch(wildcard, run->name, 0))
 
230
      delete world;
 
231
      return EXIT_FAILURE;
 
232
    }
 
233
 
 
234
    if (getenv("TEST_COLLECTION"))
 
235
    {
 
236
      if (strlen(getenv("TEST_COLLECTION")))
 
237
      {
 
238
        collection_to_run= getenv("TEST_COLLECTION");
 
239
      }
 
240
    }
 
241
 
 
242
    if (collection_to_run.empty() == false)
 
243
    {
 
244
      Out << "Only testing " <<  collection_to_run;
 
245
    }
 
246
 
 
247
    char *wildcard= NULL;
 
248
    if (argc == 3)
 
249
    {
 
250
      wildcard= argv[2];
 
251
    }
 
252
 
 
253
    for (collection_st *next= world->collections; next and next->name and (not signal.is_shutdown()); next++)
 
254
    {
 
255
      bool failed= false;
 
256
      bool skipped= false;
 
257
 
 
258
      if (collection_to_run.empty() == false and fnmatch(collection_to_run.c_str(), next->name, 0))
221
259
      {
222
260
        continue;
223
261
      }
224
262
 
225
 
      test_return_t return_code;
226
 
      if (test_success(return_code= world->item.startup(creators_ptr)))
227
 
      {
228
 
        if (test_success(return_code= world->item.flush(creators_ptr, run)))
229
 
        {
230
 
          // @note pre will fail is SKIPPED is returned
231
 
          if (test_success(return_code= world->item.pre(creators_ptr)))
232
 
          {
233
 
            { // Runner Code
234
 
              gettimeofday(&start_time, NULL);
235
 
              assert(world->runner());
236
 
              assert(run->test_fn);
237
 
              return_code= world->runner()->run(run->test_fn, creators_ptr);
238
 
              gettimeofday(&end_time, NULL);
239
 
              load_time= timedif(end_time, start_time);
240
 
            }
241
 
          }
242
 
 
243
 
          // @todo do something if post fails
244
 
          (void)world->item.post(creators_ptr);
245
 
        }
246
 
        else if (return_code == TEST_SKIPPED)
247
 
        { }
248
 
        else if (return_code == TEST_FAILURE)
249
 
        {
250
 
          Error << " item.flush(failure)";
251
 
          signal.set_shutdown(SHUTDOWN_GRACEFUL);
252
 
        }
253
 
      }
254
 
      else if (return_code == TEST_SKIPPED)
255
 
      { }
256
 
      else if (return_code == TEST_FAILURE)
257
 
      {
258
 
        Error << " item.startup(failure)";
259
 
        signal.set_shutdown(SHUTDOWN_GRACEFUL);
260
 
      }
261
 
 
262
 
      stats.total++;
263
 
 
264
 
      switch (return_code)
 
263
      stats.collection_total++;
 
264
 
 
265
      test_return_t collection_rc= world->startup(creators_ptr);
 
266
 
 
267
      if (collection_rc == TEST_SUCCESS and next->pre)
 
268
      {
 
269
        collection_rc= world->runner()->pre(next->pre, creators_ptr);
 
270
      }
 
271
 
 
272
      switch (collection_rc)
265
273
      {
266
274
      case TEST_SUCCESS:
267
 
        Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
268
 
        stats.success++;
269
275
        break;
270
276
 
271
277
      case TEST_FATAL:
272
278
      case TEST_FAILURE:
273
 
        stats.failed++;
 
279
        Out << next->name << " [ failed ]";
274
280
        failed= true;
275
 
        Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
276
 
        break;
 
281
        signal.set_shutdown(SHUTDOWN_GRACEFUL);
 
282
        goto cleanup;
277
283
 
278
284
      case TEST_SKIPPED:
279
 
        stats.skipped++;
 
285
        Out << next->name << " [ skipping ]";
280
286
        skipped= true;
281
 
        Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
282
 
        break;
 
287
        goto cleanup;
283
288
 
284
289
      case TEST_MEMORY_ALLOCATION_FAILURE:
285
 
        test_assert(0, "Memory Allocation Error");
 
290
        test_assert(0, "Allocation failure, or unknown return");
286
291
      }
287
292
 
288
 
      if (test_failed(world->on_error(return_code, creators_ptr)))
 
293
      Out << "Collection: " << next->name;
 
294
 
 
295
      for (test_st *run= next->tests; run->name; run++)
289
296
      {
290
 
        Error << "Failed while running on_error()";
291
 
        signal.set_shutdown(SHUTDOWN_GRACEFUL);
292
 
        break;
 
297
        struct timeval start_time, end_time;
 
298
        long int load_time= 0;
 
299
 
 
300
        if (wildcard && fnmatch(wildcard, run->name, 0))
 
301
        {
 
302
          continue;
 
303
        }
 
304
 
 
305
        test_return_t return_code;
 
306
        try {
 
307
          if (test_success(return_code= world->item.startup(creators_ptr)))
 
308
          {
 
309
            if (test_success(return_code= world->item.flush(creators_ptr, run)))
 
310
            {
 
311
              // @note pre will fail is SKIPPED is returned
 
312
              if (test_success(return_code= world->item.pre(creators_ptr)))
 
313
              {
 
314
                { // Runner Code
 
315
                  gettimeofday(&start_time, NULL);
 
316
                  assert(world->runner());
 
317
                  assert(run->test_fn);
 
318
                  return_code= world->runner()->run(run->test_fn, creators_ptr);
 
319
                  gettimeofday(&end_time, NULL);
 
320
                  load_time= timedif(end_time, start_time);
 
321
                }
 
322
              }
 
323
 
 
324
              // @todo do something if post fails
 
325
              (void)world->item.post(creators_ptr);
 
326
            }
 
327
            else if (return_code == TEST_SKIPPED)
 
328
            { }
 
329
            else if (return_code == TEST_FAILURE)
 
330
            {
 
331
              Error << " item.flush(failure)";
 
332
              signal.set_shutdown(SHUTDOWN_GRACEFUL);
 
333
            }
 
334
          }
 
335
          else if (return_code == TEST_SKIPPED)
 
336
          { }
 
337
          else if (return_code == TEST_FAILURE)
 
338
          {
 
339
            Error << " item.startup(failure)";
 
340
            signal.set_shutdown(SHUTDOWN_GRACEFUL);
 
341
          }
 
342
        }
 
343
 
 
344
        catch (std::exception &e)
 
345
        {
 
346
          Error << "Exception was thrown: " << e.what();
 
347
          return_code= TEST_FAILURE;
 
348
        }
 
349
        catch (...)
 
350
        {
 
351
          Error << "Unknown exception occurred";
 
352
          return_code= TEST_FAILURE;
 
353
        }
 
354
 
 
355
        stats.total++;
 
356
 
 
357
        switch (return_code)
 
358
        {
 
359
        case TEST_SUCCESS:
 
360
          Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
 
361
          stats.success++;
 
362
          break;
 
363
 
 
364
        case TEST_FATAL:
 
365
        case TEST_FAILURE:
 
366
          stats.failed++;
 
367
          failed= true;
 
368
          Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
 
369
          break;
 
370
 
 
371
        case TEST_SKIPPED:
 
372
          stats.skipped++;
 
373
          skipped= true;
 
374
          Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
 
375
          break;
 
376
 
 
377
        case TEST_MEMORY_ALLOCATION_FAILURE:
 
378
          test_assert(0, "Memory Allocation Error");
 
379
        }
 
380
 
 
381
        if (test_failed(world->on_error(return_code, creators_ptr)))
 
382
        {
 
383
          Error << "Failed while running on_error()";
 
384
          signal.set_shutdown(SHUTDOWN_GRACEFUL);
 
385
          break;
 
386
        }
293
387
      }
294
 
    }
295
388
 
296
 
    (void) world->runner()->post(next->post, creators_ptr);
 
389
      (void) world->runner()->post(next->post, creators_ptr);
297
390
 
298
391
cleanup:
299
 
    if (failed == false and skipped == false)
300
 
    {
301
 
      stats.collection_success++;
302
 
    }
303
 
 
304
 
    if (failed)
305
 
    {
306
 
      stats.collection_failed++;
307
 
    }
308
 
 
309
 
    if (skipped)
310
 
    {
311
 
      stats.collection_skipped++;
312
 
    }
313
 
 
314
 
    world->shutdown(creators_ptr);
315
 
    Outn();
316
 
  }
317
 
 
318
 
  if (not signal.is_shutdown())
319
 
  {
320
 
    signal.set_shutdown(SHUTDOWN_GRACEFUL);
321
 
  }
322
 
 
323
 
  int exit_code= EXIT_SUCCESS;
324
 
  shutdown_t status= signal.get_shutdown();
325
 
  if (status == SHUTDOWN_FORCED)
326
 
  {
327
 
    Out << "Tests were aborted.";
328
 
    exit_code= EXIT_FAILURE;
329
 
  }
330
 
  else if (stats.collection_failed)
331
 
  {
332
 
    Out << "Some test failed.";
333
 
    exit_code= EXIT_FAILURE;
334
 
  }
335
 
  else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
336
 
  {
337
 
    Out << "Some tests were skipped.";
338
 
  }
339
 
  else if (stats.collection_success and stats.collection_failed == 0)
340
 
  {
341
 
    Out << "All tests completed successfully.";
342
 
  }
343
 
 
344
 
  stats_print(&stats);
345
 
 
346
 
  delete world;
347
 
 
348
 
  Outn(); // Generate a blank to break up the messages if make check/test has been run
 
392
      if (failed == false and skipped == false)
 
393
      {
 
394
        stats.collection_success++;
 
395
      }
 
396
 
 
397
      if (failed)
 
398
      {
 
399
        stats.collection_failed++;
 
400
      }
 
401
 
 
402
      if (skipped)
 
403
      {
 
404
        stats.collection_skipped++;
 
405
      }
 
406
 
 
407
      world->shutdown(creators_ptr);
 
408
      Outn();
 
409
    }
 
410
 
 
411
    if (not signal.is_shutdown())
 
412
    {
 
413
      signal.set_shutdown(SHUTDOWN_GRACEFUL);
 
414
    }
 
415
 
 
416
    shutdown_t status= signal.get_shutdown();
 
417
    if (status == SHUTDOWN_FORCED)
 
418
    {
 
419
      Out << "Tests were aborted.";
 
420
      exit_code= EXIT_FAILURE;
 
421
    }
 
422
    else if (stats.collection_failed)
 
423
    {
 
424
      Out << "Some test failed.";
 
425
      exit_code= EXIT_FAILURE;
 
426
    }
 
427
    else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
 
428
    {
 
429
      Out << "Some tests were skipped.";
 
430
    }
 
431
    else if (stats.collection_success and stats.collection_failed == 0)
 
432
    {
 
433
      Out << "All tests completed successfully.";
 
434
    }
 
435
 
 
436
    stats_print(&stats);
 
437
 
 
438
    delete world;
 
439
 
 
440
    Outn(); // Generate a blank to break up the messages if make check/test has been run
 
441
  } while (exit_code == EXIT_SUCCESS and opt_repeat);
349
442
 
350
443
  return exit_code;
351
444
}