run.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include <ccan/pushpull/pushpull.h>
  2. /* Include the C files directly. */
  3. #include <ccan/pushpull/push.c>
  4. #include <ccan/pushpull/pull.c>
  5. #include <ccan/tap/tap.h>
  6. struct foo {
  7. uint64_t vu64;
  8. uint32_t vu32;
  9. uint16_t vu16;
  10. uint8_t vu8;
  11. unsigned char vuchar;
  12. int64_t vs64;
  13. int32_t vs32;
  14. int16_t vs16;
  15. int8_t vs8;
  16. char vchar;
  17. char bytes[100];
  18. };
  19. static void *fail_reallocfn(void *ptr, size_t size)
  20. {
  21. return NULL;
  22. }
  23. static bool push_foo(char **p, size_t *len, const struct foo *foo)
  24. {
  25. return push_u64(p, len, foo->vu64) &&
  26. push_u32(p, len, foo->vu32) &&
  27. push_u16(p, len, foo->vu16) &&
  28. push_u8(p, len, foo->vu8) &&
  29. push_uchar(p, len, foo->vuchar) &&
  30. push_s64(p, len, foo->vs64) &&
  31. push_s32(p, len, foo->vs32) &&
  32. push_s16(p, len, foo->vs16) &&
  33. push_s8(p, len, foo->vs8) &&
  34. push_char(p, len, foo->vchar) &&
  35. push_bytes(p, len, foo->bytes, sizeof(foo->bytes));
  36. }
  37. static bool pull_foo(const char **p, size_t *len, struct foo *foo)
  38. {
  39. int ret;
  40. ret = pull_u64(p, len, &foo->vu64) +
  41. pull_u32(p, len, &foo->vu32) +
  42. pull_u16(p, len, &foo->vu16) +
  43. pull_u8(p, len, &foo->vu8) +
  44. pull_uchar(p, len, &foo->vuchar) +
  45. pull_s64(p, len, &foo->vs64) +
  46. pull_s32(p, len, &foo->vs32) +
  47. pull_s16(p, len, &foo->vs16) +
  48. pull_s8(p, len, &foo->vs8) +
  49. pull_char(p, len, &foo->vchar) +
  50. pull_bytes(p, len, foo->bytes, sizeof(foo->bytes));
  51. if (ret != 11)
  52. ok1(len == 0 && *p == NULL);
  53. return ret == 11;
  54. }
  55. static bool foo_equal(const struct foo *f1, const struct foo *f2)
  56. {
  57. return f1->vu64 == f2->vu64 &&
  58. f1->vu32 == f2->vu32 &&
  59. f1->vu16 == f2->vu16 &&
  60. f1->vu8 == f2->vu8 &&
  61. f1->vuchar == f2->vuchar &&
  62. f1->vs64 == f2->vs64 &&
  63. f1->vs32 == f2->vs32 &&
  64. f1->vs16 == f2->vs16 &&
  65. f1->vs8 == f2->vs8 &&
  66. f1->vchar == f2->vchar &&
  67. memcmp(f1->bytes, f2->bytes, sizeof(f1->bytes)) == 0;
  68. }
  69. int main(void)
  70. {
  71. char *buffer;
  72. const char *p;
  73. size_t len, left;
  74. struct foo *foo, *foo2;
  75. /* This is how many tests you plan to run */
  76. plan_tests(17);
  77. /* Valgrind will make sure we don't read padding! */
  78. foo = malloc(sizeof(*foo));
  79. foo->vu64 = 0x01020304050607ULL;
  80. foo->vu32 = 0x08090a0b;
  81. foo->vu16 = 0x0c0d;
  82. foo->vu8 = 0x0e;
  83. foo->vuchar = 0x0f;
  84. foo->vs64 = -0x1011121314151617LL;
  85. foo->vs32 = -0x18191a1b;
  86. foo->vs16 = -0x1c1d;
  87. foo->vs8 = -0x1e;
  88. foo->vchar = -0x1f;
  89. memset(foo->bytes, 0x20, sizeof(foo->bytes));
  90. strcpy(foo->bytes, "This is a test");
  91. buffer = malloc(1);
  92. len = 0;
  93. ok1(push_foo(&buffer, &len, foo));
  94. ok1(len <= sizeof(*foo));
  95. /* Triggers valgrind's uninitialized value warning */
  96. ok1(!memchr(buffer, 0x21, len));
  97. p = buffer;
  98. left = len;
  99. foo2 = malloc(sizeof(*foo2));
  100. ok1(pull_foo(&p, &left, foo2));
  101. ok1(left == 0);
  102. ok1(p == buffer + len);
  103. ok1(foo_equal(foo, foo2));
  104. /* Too-small for pull, it should fail and set ptr/len to 0 */
  105. p = buffer;
  106. left = 0;
  107. ok1(!pull_u64(&p, &left, &foo2->vu64));
  108. ok1(p == NULL && left == 0);
  109. /* Shouldn't change field! */
  110. ok1(foo_equal(foo, foo2));
  111. left = 7;
  112. ok1(!pull_u64(&p, &left, &foo2->vu64));
  113. ok1(p == NULL && left == 0);
  114. /* Shouldn't change field! */
  115. ok1(foo_equal(foo, foo2));
  116. /* Discard should work. */
  117. left = len;
  118. ok1(pull_bytes(&p, &left, NULL, sizeof(foo->bytes)));
  119. ok1(left == len - sizeof(foo->bytes));
  120. /* Push failures should be clean. */
  121. push_set_realloc(fail_reallocfn);
  122. p = buffer;
  123. left = len;
  124. ok1(!push_u64(&buffer, &left, foo->vu64));
  125. ok1(p == buffer && left == len);
  126. free(buffer);
  127. free(foo);
  128. free(foo2);
  129. /* This exits depending on whether all tests passed */
  130. return exit_status();
  131. }