Blame elf/tst-stringtable.c

Packit Bot 9b6a8e
/* Unit test for ldconfig string tables.
Packit Bot 9b6a8e
   Copyright (C) 2020 Free Software Foundation, Inc.
Packit Bot 9b6a8e
   This file is part of the GNU C Library.
Packit Bot 9b6a8e
Packit Bot 9b6a8e
   This program is free software; you can redistribute it and/or modify
Packit Bot 9b6a8e
   it under the terms of the GNU General Public License as published
Packit Bot 9b6a8e
   by the Free Software Foundation; version 2 of the License, or
Packit Bot 9b6a8e
   (at your option) any later version.
Packit Bot 9b6a8e
Packit Bot 9b6a8e
   This program is distributed in the hope that it will be useful,
Packit Bot 9b6a8e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Bot 9b6a8e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Bot 9b6a8e
   GNU General Public License for more details.
Packit Bot 9b6a8e
Packit Bot 9b6a8e
   You should have received a copy of the GNU General Public License
Packit Bot 9b6a8e
   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
Packit Bot 9b6a8e
Packit Bot 9b6a8e
#include <array_length.h>
Packit Bot 9b6a8e
#include <stdlib.h>
Packit Bot 9b6a8e
#include <string.h>
Packit Bot 9b6a8e
#include <stringtable.h>
Packit Bot 9b6a8e
#include <support/check.h>
Packit Bot 9b6a8e
#include <support/support.h>
Packit Bot 9b6a8e
Packit Bot 9b6a8e
static int
Packit Bot 9b6a8e
do_test (void)
Packit Bot 9b6a8e
{
Packit Bot 9b6a8e
  /* Empty string table.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (f.strings, "");
Packit Bot 9b6a8e
    TEST_COMPARE (f.size, 0);
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  /* String table with one empty string.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    struct stringtable_entry *e = stringtable_add (&s, "");
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (e->string, "");
Packit Bot 9b6a8e
    TEST_COMPARE (e->length, 0);
Packit Bot 9b6a8e
    TEST_COMPARE (s.count, 1);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
    TEST_COMPARE (e->offset, 0);
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (f.strings, "");
Packit Bot 9b6a8e
    TEST_COMPARE (f.size, 1);
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  /* String table with one non-empty string.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    struct stringtable_entry *e = stringtable_add (&s, "name");
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (e->string, "name");
Packit Bot 9b6a8e
    TEST_COMPARE (e->length, 4);
Packit Bot 9b6a8e
    TEST_COMPARE (s.count, 1);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
    TEST_COMPARE (e->offset, 0);
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (f.strings, "name");
Packit Bot 9b6a8e
    TEST_COMPARE (f.size, 5);
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  /* Two strings, one is a prefix of the other.  Tail-merging can only
Packit Bot 9b6a8e
     happen in one way in this case.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    struct stringtable_entry *suffix = stringtable_add (&s, "suffix");
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (suffix->string, "suffix");
Packit Bot 9b6a8e
    TEST_COMPARE (suffix->length, 6);
Packit Bot 9b6a8e
    TEST_COMPARE (s.count, 1);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_entry *prefix
Packit Bot 9b6a8e
      = stringtable_add (&s, "prefix-suffix");
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (prefix->string, "prefix-suffix");
Packit Bot 9b6a8e
    TEST_COMPARE (prefix->length, strlen ("prefix-suffix"));
Packit Bot 9b6a8e
    TEST_COMPARE (s.count, 2);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
    TEST_COMPARE (prefix->offset, 0);
Packit Bot 9b6a8e
    TEST_COMPARE (suffix->offset, strlen ("prefix-"));
Packit Bot 9b6a8e
    TEST_COMPARE_STRING (f.strings, "prefix-suffix");
Packit Bot 9b6a8e
    TEST_COMPARE (f.size, sizeof ("prefix-suffix"));
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  /* String table with various shared prefixes.  Triggers hash
Packit Bot 9b6a8e
     resizing.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    enum { count = 1500 };
Packit Bot 9b6a8e
    char *strings[2 * count];
Packit Bot 9b6a8e
    struct stringtable_entry *entries[2 * count];
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    for (int i = 0; i < count; ++i)
Packit Bot 9b6a8e
      {
Packit Bot 9b6a8e
        strings[i] = xasprintf ("%d", i);
Packit Bot 9b6a8e
        entries[i] = stringtable_add (&s, strings[i]);
Packit Bot 9b6a8e
        TEST_COMPARE (entries[i]->length, strlen (strings[i]));
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (entries[i]->string, strings[i]);
Packit Bot 9b6a8e
        strings[i + count] = xasprintf ("prefix/%d", i);
Packit Bot 9b6a8e
        entries[i + count] = stringtable_add (&s, strings[i + count]);
Packit Bot 9b6a8e
        TEST_COMPARE (entries[i + count]->length, strlen (strings[i + count]));
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (entries[i + count]->string, strings[i + count]);
Packit Bot 9b6a8e
      }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    for (int i = 0; i < 2 * count; ++i)
Packit Bot 9b6a8e
      {
Packit Bot 9b6a8e
        TEST_COMPARE (entries[i]->length, strlen (strings[i]));
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (entries[i]->string, strings[i]);
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (f.strings + entries[i]->offset, strings[i]);
Packit Bot 9b6a8e
        free (strings[i]);
Packit Bot 9b6a8e
      }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  /* Verify that maximum tail merging happens.  */
Packit Bot 9b6a8e
  {
Packit Bot 9b6a8e
    struct stringtable s = { 0, };
Packit Bot 9b6a8e
    const char *strings[] = {
Packit Bot 9b6a8e
      "",
Packit Bot 9b6a8e
      "a",
Packit Bot 9b6a8e
      "b",
Packit Bot 9b6a8e
      "aa",
Packit Bot 9b6a8e
      "aaa",
Packit Bot 9b6a8e
      "aa",
Packit Bot 9b6a8e
      "bb",
Packit Bot 9b6a8e
      "b",
Packit Bot 9b6a8e
      "a",
Packit Bot 9b6a8e
      "ba",
Packit Bot 9b6a8e
      "baa",
Packit Bot 9b6a8e
    };
Packit Bot 9b6a8e
    struct stringtable_entry *entries[array_length (strings)];
Packit Bot 9b6a8e
    for (int i = 0; i < array_length (strings); ++i)
Packit Bot 9b6a8e
      entries[i] = stringtable_add (&s, strings[i]);
Packit Bot 9b6a8e
    for (int i = 0; i < array_length (strings); ++i)
Packit Bot 9b6a8e
      TEST_COMPARE_STRING (entries[i]->string, strings[i]);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    struct stringtable_finalized f;
Packit Bot 9b6a8e
    stringtable_finalize (&s, &f);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    /* There are only four different strings, "aaa", "ba", "baa",
Packit Bot 9b6a8e
       "bb".  The rest is shared in an unspecified fashion.  */
Packit Bot 9b6a8e
    TEST_COMPARE (f.size, 4 + 3 + 4 + 3);
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    for (int i = 0; i < array_length (strings); ++i)
Packit Bot 9b6a8e
      {
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (entries[i]->string, strings[i]);
Packit Bot 9b6a8e
        TEST_COMPARE_STRING (f.strings + entries[i]->offset, strings[i]);
Packit Bot 9b6a8e
      }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
    free (f.strings);
Packit Bot 9b6a8e
    stringtable_free (&s);
Packit Bot 9b6a8e
  }
Packit Bot 9b6a8e
Packit Bot 9b6a8e
  return 0;
Packit Bot 9b6a8e
}
Packit Bot 9b6a8e
Packit Bot 9b6a8e
#include <support/test-driver.c>
Packit Bot 9b6a8e
Packit Bot 9b6a8e
/* Re-compile the string table implementation here.  It is not
Packit Bot 9b6a8e
   possible to link against the actual build because it was built for
Packit Bot 9b6a8e
   use in ldconfig.  */
Packit Bot 9b6a8e
#define _(arg) arg
Packit Bot 9b6a8e
#include "stringtable.c"
Packit Bot 9b6a8e
#include "stringtable_free.c"