~ubuntu-branches/ubuntu/vivid/ecasound2.2/vivid

« back to all changes in this revision

Viewing changes to kvutils/libkvutils_tester.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2009-11-02 18:22:35 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091102182235-4ngh7699dmkgonyu
Tags: 2.7.0-1
* New upstream release.
* Depend on libreadline-dev instead of libreadline5-dev by request of
  Mattias Klose. It's now libreadline6-dev. (closes: #553748)
* Update menu file to use section Applications/ instead of Apps/.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// ------------------------------------------------------------------------
2
2
// libkvutils_tester.cpp: Runs a set of libkvutils unit tests.
3
 
// Copyright (C) 2002 Kai-2004 Vehmanen
 
3
// Copyright (C) 2002-2004,2009 Kai Vehmanen
4
4
//
5
5
// Attributes:
6
6
//     eca-style-version: 2
20
20
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
21
21
// ------------------------------------------------------------------------
22
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include <config.h>
 
25
#endif
 
26
 
23
27
#include <string>
24
28
 
25
29
#include <cstdio>
 
30
#include <cstdlib>
 
31
#include <ctime>
26
32
#include <stddef.h>  /* ANSI-C: size_t */
27
33
#include <stdio.h>   /* for AIX */
28
 
#include <stdlib.h>  /* ANSI-C: atoi() */
29
34
#include <time.h>    /* ANSI-C: clock() */
30
35
 
31
 
#include <unistd.h>  /* POSIX: sleep() */
32
 
 
 
36
#include "kvu_dbc.h"
33
37
#include "kvu_locks.h"
34
38
#include "kvu_numtostr.h"
35
39
#include "kvu_rtcaps.h"
 
40
#include "kvu_timestamp.h"
36
41
#include "kvu_utils.h"
37
42
#include "kvu_value_queue.h"
 
43
#include "kvu_message_queue.h"
38
44
 
39
45
using namespace std;
40
46
 
49
55
 */
50
56
 
51
57
#ifdef VERBOSE
52
 
#define ECA_TEST_ENTRY()   do { printf("\n%s:%d - Test started\n", __FILE__, __LINE__); } while(0)
53
 
#define ECA_TEST_SUCCESS() do { printf("%s:%d - Test passed\n", __FILE__, __LINE__); return 0; } while(0)
54
 
#define ECA_TEST_FAIL(x,y) do { printf("\n%s:%d - Test failed: \"%s\"\n", __FILE__, __LINE__, y); return x; } while(0)
55
 
#define ECA_TEST_NOTE(x)   do { printf("%s:%d - %s\n", __FILE__, __LINE__, x); fflush(stdout); } while(0)
 
58
#define ECA_TEST_ENTRY()   do { printf("\n%s:%d - Test started\n", __KVU_FUNCTION, __LINE__); } while(0)
 
59
#define ECA_TEST_SUCCESS() do { printf("%s:%d - Test passed\n", __KVU_FUNCTION, __LINE__); return 0; } while(0)
 
60
#define ECA_TEST_FAIL(x,y) do { printf("\n%s:%d - Test failed: \"%s\"\n", __KVU_FUNCTION, __LINE__, y); return x; } while(0)
 
61
#define ECA_TEST_NOTE(x)   do { printf("%s:%d - %s\n", __KVU_FUNCTION, __LINE__, x); fflush(stdout); } while(0)
56
62
#else
57
63
#define ECA_TEST_ENTRY()   ((void) 0)
58
64
#define ECA_TEST_SUCCESS() return 0
74
80
static int kvu_test_2(void);
75
81
static int kvu_test_3(void);
76
82
static int kvu_test_4(void);
77
 
static void* kvu_test_1_helper(void* ptr);
78
 
static void* kvu_test_4_helper(void* ptr);
 
83
static int kvu_test_5_timestamp(void);
 
84
static int kvu_test_6_msgqueue(void);
79
85
 
80
86
static kvu_test_t kvu_funcs[] = { 
81
 
  kvu_test_1, 
82
 
  kvu_test_2, 
83
 
  kvu_test_3, 
84
 
  kvu_test_4, 
 
87
  kvu_test_1,  /* kvu_locks.h: ATOMIC_INTEGER */
 
88
  kvu_test_2,  /* kvu_utils.h: string handling */
 
89
  kvu_test_3,  /* kvu_utils.h: float2str */
 
90
  kvu_test_4,  /* kvu_value_queue.h */
 
91
  kvu_test_5_timestamp, /* kvu_timestamp.h */
 
92
  kvu_test_6_msgqueue,  /* kvu_message_queue.h */
85
93
  NULL 
86
94
};
87
95
 
95
103
 
96
104
  if (argc > 1) {
97
105
    /* run just a single test */
98
 
    size_t m = atoi(argv[1]);
 
106
    size_t m = std::atoi(argv[1]);
99
107
    if (m > 0 && m < (sizeof(kvu_funcs) / sizeof(kvu_test_t))) {
100
108
      if (kvu_funcs[m - 1]() != 0) {
101
109
        ++failed;
348
356
static const int kvu_test_4_iterations_const = 16384;
349
357
static int kvu_test_4_retval = 0;
350
358
 
 
359
static void* kvu_test_4_helper(void* ptr);
 
360
 
351
361
/**
352
362
 * Tests the VALUE_QUEUE_RT_C class implementation.
353
363
 */
363
373
  pthread_t thread;
364
374
  pthread_create(&thread, NULL, kvu_test_4_helper, (void*)&rqueue);
365
375
 
366
 
  sleep(1);
 
376
  kvu_sleep(1, 0);
367
377
 
368
378
  ECA_TEST_NOTE("start-item-push");
369
379
 
370
380
  for(int iter = 0; iter < kvu_test_4_iterations_const; iter++) {
371
381
    // fprintf(stderr, "%s:%d push.\n", __FUNCTION__, __LINE__);
372
382
    rqueue.push_back(iter, 1.0f);
373
 
    // sleep(1);
 
383
    // kvu_sleep(1, 0);
374
384
  }
375
385
 
376
386
  void *res_ptr = 0;
433
443
  /* never reached */
434
444
  return 0;
435
445
}
 
446
 
 
447
/**
 
448
 * Tests the kvu_timestamp.h interface
 
449
 */
 
450
static int kvu_test_5_timestamp(void)
 
451
{
 
452
  ECA_TEST_ENTRY();
 
453
 
 
454
  struct timespec stamp;
 
455
  int res;
 
456
  int monotonic =
 
457
    kvu_clock_is_monotonic();
 
458
  double start, now, prev, end;
 
459
 
 
460
  res = kvu_clock_gettime(&stamp);
 
461
  if (res)
 
462
    ECA_TEST_FAIL(1, "kvu_test_5-1 clock_gettime failed"); 
 
463
 
 
464
  start = kvu_timespec_seconds(&stamp);
 
465
  end = start + 3.0;
 
466
  now = prev = start;
 
467
 
 
468
  ECA_TEST_NOTE("3s timer loop starts");
 
469
 
 
470
  while (now < end) {
 
471
 
 
472
    /* 5ms sleeps */
 
473
    kvu_sleep(0, 5000000);
 
474
 
 
475
    res = kvu_clock_gettime(&stamp);
 
476
    if (res)
 
477
      ECA_TEST_FAIL(1, "kvu_test_5-2 clock_gettime failed"); 
 
478
    now = kvu_timespec_seconds(&stamp);
 
479
 
 
480
#ifdef VERY_VERBOSE
 
481
    fprintf(stderr, "now=%.09f delta=%.09f end=%.03f\n",
 
482
            now - start, now - prev, end - start);
 
483
#endif
 
484
 
 
485
    if (now < prev) {
 
486
      if (monotonic)
 
487
        ECA_TEST_FAIL(1, "kvu_test_5-3 clock goes backwards"); 
 
488
      else
 
489
        ECA_TEST_NOTE("kvu_test_5 - clock went backwards");
 
490
    }
 
491
    
 
492
    prev = now;
 
493
  }
 
494
  
 
495
  ECA_TEST_SUCCESS();
 
496
}
 
497
 
 
498
/* note: around 50ms per iteration */
 
499
static const int kvu_test_6_iterations_const = 100;
 
500
static int kvu_test_6_retval = 0;
 
501
 
 
502
static void* kvu_test_6_helper(void* ptr);
 
503
 
 
504
/**
 
505
 * Tests the MESSAGE_QUEUE_RT_C class implementation.
 
506
 */
 
507
static int kvu_test_6_msgqueue(void)
 
508
{
 
509
  ECA_TEST_ENTRY();
 
510
 
 
511
  std::srand(std::time(0));
 
512
 
 
513
  /* guarantee bounded execution time only upto 16 items */
 
514
  MESSAGE_QUEUE_RT_C<std::string> rqueue (16);
 
515
 
 
516
  ECA_TEST_NOTE("start-test");
 
517
 
 
518
  pthread_t thread;
 
519
  pthread_create(&thread, NULL, kvu_test_6_helper, (void*)&rqueue);
 
520
 
 
521
  kvu_sleep(1, 0);
 
522
 
 
523
  ECA_TEST_NOTE("start-item-push");
 
524
 
 
525
  for(int iter = 0; iter < kvu_test_6_iterations_const; iter++) {
 
526
    // fprintf(stderr, "%s:%d push.\n", __FUNCTION__, __LINE__);
 
527
    std::string msg = kvu_numtostr(iter + 1);
 
528
    //std::fprintf(stdout, "%s:%d pushed '%s'\n", __FUNCTION__, __LINE__, msg.c_str());
 
529
    rqueue.push_back(msg);
 
530
    int sleep_ns = std::rand() % 100;
 
531
 
 
532
    kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */
 
533
  }
 
534
 
 
535
  void *res_ptr = 0;
 
536
  pthread_join(thread, (void**)&res_ptr);
 
537
  if (*(int*)res_ptr != 0) {
 
538
    ECA_TEST_FAIL(1, "kvu_test_6 slave-thread-failed"); 
 
539
  }
 
540
 
 
541
  ECA_TEST_NOTE("end-test.");
 
542
 
 
543
  ECA_TEST_SUCCESS();
 
544
}
 
545
 
 
546
/**
 
547
 * The real-time consumer thread.
 
548
 */
 
549
static void* kvu_test_6_helper(void* ptr)
 
550
{
 
551
  MESSAGE_QUEUE_RT_C<std::string> *rqueue = 
 
552
    static_cast<MESSAGE_QUEUE_RT_C<std::string>*>(ptr);
 
553
 
 
554
  kvu_test_6_retval = 0;
 
555
 
 
556
  ECA_TEST_NOTE("start-thread.");
 
557
 
 
558
  int res = kvu_set_thread_scheduling(SCHED_FIFO, 1);
 
559
  if (res == 0) {
 
560
    ECA_TEST_NOTE("schedfifo-scheduling-enabled");
 
561
  }
 
562
  else {
 
563
    ECA_TEST_NOTE("schedfifo-scheduling-disabled");
 
564
  }
 
565
 
 
566
  std::string last_received_v;
 
567
  for(int received = 0; received < kvu_test_6_iterations_const; ) {
 
568
    int sleep_ns = std::rand() % 100;
 
569
 
 
570
    kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */
 
571
 
 
572
    if (rqueue->is_empty() != true) {
 
573
      std::string ref;
 
574
      int popres = rqueue->pop_front(&ref);
 
575
      if (popres > 0) {
 
576
        // std::fprintf(stdout, "%s:%d popped '%s'\n", __FUNCTION__, __LINE__, ref.c_str());
 
577
        ++received;
 
578
        if (last_received_v == ref) {
 
579
          ECA_TEST_NOTE("queue-sync-error"); 
 
580
          kvu_test_6_retval = -1;
 
581
          break;
 
582
        }
 
583
        last_received_v = ref;
 
584
      }
 
585
      else {
 
586
        ECA_TEST_NOTE("corner-case-queue-busy");
 
587
      }
 
588
    }
 
589
  }
 
590
 
 
591
  if (std::atoi(last_received_v.c_str()) != kvu_test_6_iterations_const) {
 
592
    // std::fprintf(stdout, "%s:%d last item '%s'\n", __FUNCTION__, __LINE__, last_received_v.c_str());
 
593
    ECA_TEST_NOTE("end-of-queue-sync-error"); 
 
594
    kvu_test_6_retval = -1;
 
595
  }
 
596
 
 
597
  ECA_TEST_NOTE("exit-thread");
 
598
 
 
599
  pthread_exit(&kvu_test_6_retval);
 
600
  /* never reached */
 
601
  return 0;
 
602
}