From 38d905bf585999367a24fa27645ece6fe996d6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 1 Oct 2014 17:00:33 +0200 Subject: [PATCH 1/2] sha1-array: add test-sha1-array and basic tests Helped-by: Jeff King Helped-by: Eric Sunshine Signed-off-by: Rene Scharfe Acked-by: Jeff King Signed-off-by: Junio C Hamano --- .gitignore | 1 + Makefile | 1 + t/t0064-sha1-array.sh | 74 +++++++++++++++++++++++++++++++++++++++++++ test-sha1-array.c | 34 ++++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100755 t/t0064-sha1-array.sh create mode 100644 test-sha1-array.c diff --git a/.gitignore b/.gitignore index b5f9defed3..96a0fe0b26 100644 --- a/.gitignore +++ b/.gitignore @@ -195,6 +195,7 @@ /test-revision-walking /test-run-command /test-sha1 +/test-sha1-array /test-sigchain /test-string-list /test-subprocess diff --git a/Makefile b/Makefile index 33aa15b0e3..0681c16979 100644 --- a/Makefile +++ b/Makefile @@ -572,6 +572,7 @@ TEST_PROGRAMS_NEED_X += test-revision-walking TEST_PROGRAMS_NEED_X += test-run-command TEST_PROGRAMS_NEED_X += test-scrap-cache-tree TEST_PROGRAMS_NEED_X += test-sha1 +TEST_PROGRAMS_NEED_X += test-sha1-array TEST_PROGRAMS_NEED_X += test-sigchain TEST_PROGRAMS_NEED_X += test-string-list TEST_PROGRAMS_NEED_X += test-subprocess diff --git a/t/t0064-sha1-array.sh b/t/t0064-sha1-array.sh new file mode 100755 index 0000000000..06549656c8 --- /dev/null +++ b/t/t0064-sha1-array.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +test_description='basic tests for the SHA1 array implementation' +. ./test-lib.sh + +echo20 () { + prefix="${1:+$1 }" + shift + while test $# -gt 0 + do + echo "$prefix$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1" + shift + done +} + +test_expect_success 'ordered enumeration' ' + echo20 "" 44 55 88 aa >expect && + { + echo20 append 88 44 aa 55 && + echo for_each_unique + } | test-sha1-array >actual && + test_cmp expect actual +' + +test_expect_success 'ordered enumeration with duplicate suppression' ' + echo20 "" 44 55 88 aa >expect && + { + echo20 append 88 44 aa 55 && + echo20 append 88 44 aa 55 && + echo for_each_unique + } | test-sha1-array >actual && + test_cmp expect actual +' + +test_expect_success 'lookup' ' + { + echo20 append 88 44 aa 55 && + echo20 lookup 55 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -eq 1 +' + +test_expect_success 'lookup non-existing entry' ' + { + echo20 append 88 44 aa 55 && + echo20 lookup 33 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -lt 0 +' + +test_expect_success 'lookup with duplicates' ' + { + echo20 append 88 44 aa 55 && + echo20 append 88 44 aa 55 && + echo20 lookup 55 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -ge 2 && + test "$n" -le 3 +' + +test_expect_success 'lookup non-existing entry with duplicates' ' + { + echo20 append 88 44 aa 55 && + echo20 append 88 44 aa 55 && + echo20 lookup 66 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -lt 0 +' + +test_done diff --git a/test-sha1-array.c b/test-sha1-array.c new file mode 100644 index 0000000000..ddc491eff9 --- /dev/null +++ b/test-sha1-array.c @@ -0,0 +1,34 @@ +#include "cache.h" +#include "sha1-array.h" + +static void print_sha1(const unsigned char sha1[20], void *data) +{ + puts(sha1_to_hex(sha1)); +} + +int main(int argc, char **argv) +{ + struct sha1_array array = SHA1_ARRAY_INIT; + struct strbuf line = STRBUF_INIT; + + while (strbuf_getline(&line, stdin, '\n') != EOF) { + const char *arg; + unsigned char sha1[20]; + + if (skip_prefix(line.buf, "append ", &arg)) { + if (get_sha1_hex(arg, sha1)) + die("not a hexadecimal SHA1: %s", arg); + sha1_array_append(&array, sha1); + } else if (skip_prefix(line.buf, "lookup ", &arg)) { + if (get_sha1_hex(arg, sha1)) + die("not a hexadecimal SHA1: %s", arg); + printf("%d\n", sha1_array_lookup(&array, sha1)); + } else if (!strcmp(line.buf, "clear")) + sha1_array_clear(&array); + else if (!strcmp(line.buf, "for_each_unique")) + sha1_array_for_each_unique(&array, print_sha1, NULL); + else + die("unknown command: %s", line.buf); + } + return 0; +} From 0eb0fb889e2e7e063e7dd8cbee38af106aa195f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 1 Oct 2014 17:02:37 +0200 Subject: [PATCH 2/2] sha1-lookup: handle duplicates in sha1_pos() If the first 18 bytes of the SHA1's of all entries are the same then sha1_pos() dies and reports that the lower and upper limits of the binary search were the same that this wasn't supposed to happen. This is wrong because the remaining two bytes could still differ. Furthermore: It wouldn't be a problem if they actually were the same, i.e. if all entries have the same SHA1. The code already handles duplicates just fine. Simply remove the erroneous check. Signed-off-by: Rene Scharfe Acked-by: Jeff King Signed-off-by: Junio C Hamano --- sha1-lookup.c | 2 -- t/t0064-sha1-array.sh | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/sha1-lookup.c b/sha1-lookup.c index 2dd851598a..5f069214d9 100644 --- a/sha1-lookup.c +++ b/sha1-lookup.c @@ -84,8 +84,6 @@ int sha1_pos(const unsigned char *sha1, void *table, size_t nr, die("BUG: assertion failed in binary search"); } } - if (18 <= ofs) - die("cannot happen -- lo and hi are identical"); } do { diff --git a/t/t0064-sha1-array.sh b/t/t0064-sha1-array.sh index 06549656c8..50b31ffe75 100755 --- a/t/t0064-sha1-array.sh +++ b/t/t0064-sha1-array.sh @@ -71,4 +71,24 @@ test_expect_success 'lookup non-existing entry with duplicates' ' test "$n" -lt 0 ' +test_expect_success 'lookup with almost duplicate values' ' + { + echo "append 5555555555555555555555555555555555555555" && + echo "append 555555555555555555555555555555555555555f" && + echo20 lookup 55 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -eq 0 +' + +test_expect_success 'lookup with single duplicate value' ' + { + echo20 append 55 55 && + echo20 lookup 55 + } | test-sha1-array >actual && + n=$(cat actual) && + test "$n" -ge 0 && + test "$n" -le 1 +' + test_done