run-tdb1-incompatible.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "tdb2-source.h"
  2. #include <ccan/tap/tap.h>
  3. #include <stdlib.h>
  4. #include <err.h>
  5. static uint64_t tdb1_dumb_hash(const void *key, size_t len, uint64_t seed,
  6. void *unused)
  7. {
  8. return len;
  9. }
  10. static void log_fn(struct tdb_context *tdb, enum tdb_log_level level,
  11. enum TDB_ERROR ecode, const char *message, void *priv)
  12. {
  13. unsigned int *count = priv;
  14. if (strstr(message, "hash"))
  15. (*count)++;
  16. }
  17. static unsigned int hdr_rwlocks(const char *fname)
  18. {
  19. struct tdb1_header hdr;
  20. int fd = open(fname, O_RDONLY);
  21. if (fd == -1)
  22. return -1;
  23. if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
  24. return -1;
  25. close(fd);
  26. return hdr.rwlocks;
  27. }
  28. static uint64_t jenkins_hashfn(const void *key, size_t len, uint64_t seed,
  29. void *unused)
  30. {
  31. return hashlittle(key, len);
  32. }
  33. static uint64_t old_hash(const void *key, size_t len, uint64_t seed,
  34. void *unused)
  35. {
  36. return tdb1_old_hash(key, len, seed, unused);
  37. }
  38. int main(int argc, char *argv[])
  39. {
  40. struct tdb_context *tdb;
  41. unsigned int log_count, flags;
  42. TDB_DATA d;
  43. union tdb_attribute log_attr, jhash_attr, ohash_attr,
  44. incompat_hash_attr, dumbhash_attr;
  45. log_attr.base.attr = TDB_ATTRIBUTE_LOG;
  46. log_attr.base.next = NULL;
  47. log_attr.log.fn = log_fn;
  48. log_attr.log.data = &log_count;
  49. jhash_attr.base.attr = TDB_ATTRIBUTE_HASH;
  50. jhash_attr.base.next = &log_attr;
  51. jhash_attr.hash.fn = jenkins_hashfn;
  52. ohash_attr.base.attr = TDB_ATTRIBUTE_HASH;
  53. ohash_attr.base.next = &log_attr;
  54. ohash_attr.hash.fn = old_hash;
  55. incompat_hash_attr.base.attr = TDB_ATTRIBUTE_HASH;
  56. incompat_hash_attr.base.next = &log_attr;
  57. incompat_hash_attr.hash.fn = tdb1_incompatible_hash;
  58. dumbhash_attr.base.attr = TDB_ATTRIBUTE_HASH;
  59. dumbhash_attr.base.next = &log_attr;
  60. dumbhash_attr.hash.fn = tdb1_dumb_hash;
  61. plan_tests(42 * 2);
  62. for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
  63. unsigned int rwmagic = TDB1_HASH_RWLOCK_MAGIC;
  64. if (flags & TDB_CONVERT)
  65. tdb1_convert(&rwmagic, sizeof(rwmagic));
  66. /* Create an old-style hash. */
  67. log_count = 0;
  68. tdb = tdb_open("run-incompatible.tdb1", flags|TDB_VERSION1,
  69. O_CREAT|O_RDWR|O_TRUNC, 0600, &log_attr);
  70. ok1(tdb);
  71. ok1(log_count == 0);
  72. d.dptr = (void *)"Hello";
  73. d.dsize = 5;
  74. ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS);
  75. tdb_close(tdb);
  76. /* Should not have marked rwlocks field. */
  77. ok1(hdr_rwlocks("run-incompatible.tdb1") == 0);
  78. /* We can still open any old-style with incompat hash. */
  79. log_count = 0;
  80. tdb = tdb_open("run-incompatible.tdb1",
  81. TDB_VERSION1,
  82. O_RDWR, 0600, &incompat_hash_attr);
  83. ok1(tdb);
  84. ok1(log_count == 0);
  85. ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS);
  86. ok1(d.dsize == 5);
  87. free(d.dptr);
  88. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  89. tdb_close(tdb);
  90. log_count = 0;
  91. tdb = tdb_open("test/jenkins-le-hash.tdb1",
  92. TDB_VERSION1, O_RDONLY, 0, &jhash_attr);
  93. ok1(tdb);
  94. ok1(log_count == 0);
  95. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  96. tdb_close(tdb);
  97. log_count = 0;
  98. tdb = tdb_open("test/jenkins-be-hash.tdb1",
  99. TDB_VERSION1, O_RDONLY, 0, &jhash_attr);
  100. ok1(tdb);
  101. ok1(log_count == 0);
  102. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  103. tdb_close(tdb);
  104. /* OK, now create with incompatible hash. */
  105. log_count = 0;
  106. tdb = tdb_open("run-incompatible.tdb1",
  107. flags|TDB_VERSION1,
  108. O_CREAT|O_RDWR|O_TRUNC, 0600,
  109. &incompat_hash_attr);
  110. ok1(tdb);
  111. ok1(log_count == 0);
  112. d.dptr = (void *)"Hello";
  113. d.dsize = 5;
  114. ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS);
  115. tdb_close(tdb);
  116. /* Should have marked rwlocks field. */
  117. ok1(hdr_rwlocks("run-incompatible.tdb1") == rwmagic);
  118. /* Cannot open with old hash. */
  119. log_count = 0;
  120. tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1,
  121. O_RDWR, 0600, &ohash_attr);
  122. ok1(!tdb);
  123. ok1(log_count == 1);
  124. /* Can open with jenkins hash. */
  125. log_count = 0;
  126. tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1,
  127. O_RDWR, 0600, &jhash_attr);
  128. ok1(tdb);
  129. ok1(log_count == 0);
  130. ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS);
  131. ok1(d.dsize == 5);
  132. free(d.dptr);
  133. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  134. tdb_close(tdb);
  135. /* Can open by letting it figure it out itself. */
  136. log_count = 0;
  137. tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1,
  138. O_RDWR, 0600, &log_attr);
  139. ok1(tdb);
  140. ok1(log_count == 0);
  141. d.dptr = (void *)"Hello";
  142. d.dsize = 5;
  143. ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS);
  144. ok1(d.dsize == 5);
  145. free(d.dptr);
  146. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  147. tdb_close(tdb);
  148. /* FIXME: Not possible with TDB2 :( */
  149. /* We can also use incompatible hash with other hashes. */
  150. log_count = 0;
  151. tdb = tdb_open("run-incompatible.tdb1",
  152. flags|TDB_VERSION1,
  153. O_CREAT|O_RDWR|O_TRUNC, 0600, &dumbhash_attr);
  154. ok1(tdb);
  155. ok1(log_count == 0);
  156. d.dptr = (void *)"Hello";
  157. d.dsize = 5;
  158. ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS);
  159. tdb_close(tdb);
  160. /* FIXME: Should have marked rwlocks field. */
  161. ok1(hdr_rwlocks("run-incompatible.tdb1") != rwmagic);
  162. /* It should not open if we don't specify. */
  163. log_count = 0;
  164. tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, O_RDWR, 0,
  165. &log_attr);
  166. ok1(!tdb);
  167. ok1(log_count == 1);
  168. /* Should reopen with correct hash. */
  169. log_count = 0;
  170. tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, O_RDWR, 0,
  171. &dumbhash_attr);
  172. ok1(tdb);
  173. ok1(log_count == 0);
  174. ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS);
  175. ok1(d.dsize == 5);
  176. free(d.dptr);
  177. ok1(tdb1_check(tdb, NULL, NULL) == 0);
  178. tdb_close(tdb);
  179. }
  180. return exit_status();
  181. }