コード例 #1
0
static void test_empty_tree() {
  tree_t *tree = alloc_tree();

  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == false);

  update_checksums(tree);
  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == true);
}
コード例 #2
0
static convert_to_flat_code_t convert_to_flat_helper(
    to_flat_state_t *state,
    const tree_t *tree) {
  // get the real root.
  node_t *shadow_root = tree->shadow_root;
  if (shadow_root->num_children != 1) {
    return CONVERT_TO_FLAT_WTF;
  }

  node_t *real_root = get_child_by_index(shadow_root, 0);

  return convert_to_flat_iterator(state, real_root);
}
コード例 #3
0
ファイル: trees_test.c プロジェクト: sartura/sysrepo
static void
sr_dup_trees_test(void **state)
{
    int rc = SR_ERR_OK;
    sr_node_t *trees = NULL, *trees_dup = NULL, *node = NULL, *leaf = NULL;
    size_t tree_cnt = 0;
    char value[10] = { 0, };

    trees = create_example_module_trees(&tree_cnt);
    assert_int_equal(SR_ERR_OK, rc);

    /* duplicate the array of trees */
    rc = sr_dup_trees(trees, tree_cnt, &trees_dup);
    assert_int_equal(SR_ERR_OK, rc);

    /* /example_module:container */
    assert_non_null(trees_dup);
#ifdef USE_SR_MEM_MGMT
    assert_non_null(trees_dup->_sr_mem);
    assert_ptr_not_equal(trees->_sr_mem, trees_dup->_sr_mem);
    assert_int_equal(1, trees_dup->_sr_mem->obj_count);
    assert_true(0 < trees_dup->_sr_mem->used_total);
#else
    assert_null(trees_dup->_sr_mem);
#endif
    assert_string_equal("container", trees_dup->name);
    assert_false(trees_dup->dflt);
    assert_string_equal("example-module", trees_dup->module_name);
    assert_int_equal(SR_CONTAINER_T, trees_dup->type);
    assert_null(trees_dup->parent);
    assert_non_null(trees_dup->first_child);
    assert_non_null(trees_dup->last_child);
    assert_null(trees_dup->prev);
    assert_null(trees_dup->next);
    for (int i = 0; i < 10; ++i) {
        /* /example_module:container/list[key1="key1-i"][key2="key2-i"] */
        node = get_child_by_index(trees_dup, i);
        assert_string_equal("list", node->name);
        assert_false(node->dflt);
        assert_null(node->module_name);
        assert_int_equal(SR_LIST_T, node->type);
        assert_ptr_equal(trees_dup, node->parent);
        assert_non_null(node->first_child);
        assert_non_null(node->last_child);
        if (0 < i) {
            assert_ptr_equal(get_child_by_index(trees_dup, i-1), node->prev);
            assert_ptr_equal(node->prev->next, node);
        } else {
            assert_null(node->prev);
        }
        if (9 > i) {
            assert_ptr_equal(get_child_by_index(trees_dup, i+1), node->next);
            assert_ptr_equal(node->next->prev, node);
        } else {
            assert_null(node->next);
        }

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/key1 */
        leaf = get_child_by_index(node, 0);
        assert_string_equal("key1", leaf->name);
        assert_false(leaf->dflt);
        assert_null(leaf->module_name);
        assert_int_equal(SR_STRING_T, leaf->type);
        snprintf(value, 10, "key1-%d", i);
        assert_string_equal(value, leaf->data.string_val);
        assert_ptr_equal(node, leaf->parent);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_null(leaf->prev);
        assert_ptr_equal(get_child_by_index(node, 1), leaf->next);
        assert_ptr_equal(leaf->next->prev, leaf);

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/key2 */
        leaf = get_child_by_index(node, 1);
        assert_string_equal("key2", leaf->name);
        assert_false(leaf->dflt);
        assert_null(leaf->module_name);
        assert_int_equal(SR_STRING_T, leaf->type);
        snprintf(value, 10, "key2-%d", i);
        assert_string_equal(value, leaf->data.string_val);
        assert_ptr_equal(node, leaf->parent);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_ptr_equal(get_child_by_index(node, 0), leaf->prev);
        assert_ptr_equal(leaf->prev->next, leaf);
        assert_ptr_equal(get_child_by_index(node, 2), leaf->next);
        assert_ptr_equal(leaf->next->prev, leaf);

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/leaf */
        leaf = get_child_by_index(node, 2);
        assert_string_equal("leaf", leaf->name);
        assert_false(leaf->dflt);
        assert_null(leaf->module_name);
        assert_int_equal(SR_STRING_T, leaf->type);
        snprintf(value, 10, "leaf-%d", i);
        assert_string_equal(value, leaf->data.string_val);
        assert_ptr_equal(node, leaf->parent);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_ptr_equal(get_child_by_index(node, 1), leaf->prev);
        assert_ptr_equal(leaf->prev->next, leaf);
        assert_null(leaf->next);
    }

    for (int i = 1; i < tree_cnt; ++i) { 
        /* /example_module:number[.=0] */
        leaf = trees_dup + i;
        assert_non_null(leaf);
#ifdef USE_SR_MEM_MGMT
        assert_non_null(leaf->_sr_mem);
        assert_ptr_not_equal(trees->_sr_mem, leaf->_sr_mem);
        assert_ptr_equal(trees_dup[i-1]._sr_mem, leaf->_sr_mem);
        assert_int_equal(1, leaf->_sr_mem->obj_count);
        assert_true(0 < leaf->_sr_mem->used_total);
#else
        assert_null(leaf->_sr_mem);
#endif
        assert_string_equal("number", leaf->name);
        assert_false(leaf->dflt);
        assert_string_equal("example-module", leaf->module_name);
        assert_int_equal(SR_UINT16_T, leaf->type);
        assert_int_equal(i-1, leaf->data.uint16_val);
        assert_null(leaf->parent);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_null(leaf->prev);
        assert_null(leaf->next);
    }

    sr_free_trees(trees_dup, tree_cnt);
    sr_free_trees(trees, tree_cnt);
}
コード例 #4
0
ファイル: trees_test.c プロジェクト: sartura/sysrepo
static sr_node_t *
create_example_module_trees(size_t *tree_cnt)
{
    int rc = 0;
    sr_node_t *trees = NULL, *node = NULL, *leaf = NULL;
    char value[10] = { 0, };

    rc = sr_new_trees(6, &trees);
    assert_int_equal(SR_ERR_OK, rc);

    /* /example_module:container */
    rc = sr_node_set_name(trees, "container");
    assert_int_equal(SR_ERR_OK, rc);
    rc = sr_node_set_module(trees, "example-module");
    assert_int_equal(SR_ERR_OK, rc);
    trees[0].type = SR_CONTAINER_T;

    for (int i = 0; i < 10; ++i) {
        /* /example_module:container/list[key1="key1-i"][key2="key2-i"] */
        rc = sr_node_add_child(trees, "list", NULL, &node);
        assert_int_equal(SR_ERR_OK, rc);
        node->type = SR_LIST_T;
        assert_ptr_equal(trees, node->parent);
        if (0 < i) {
            assert_ptr_equal(get_child_by_index(trees, i-1), node->prev);
            assert_ptr_equal(node->prev->next, node);
        } else {
            assert_null(node->prev);
        }
        assert_null(node->next);
        assert_null(node->first_child);
        assert_null(node->last_child);
        assert_ptr_equal(get_child_by_index(trees, i), node);

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/key1 */
        rc = sr_node_add_child(node, "key1", NULL, &leaf);
        assert_int_equal(SR_ERR_OK, rc);
        snprintf(value, 10, "key1-%d", i);
        rc = sr_node_set_str_data(leaf, SR_STRING_T, value);
        assert_int_equal(SR_ERR_OK, rc);
        assert_ptr_equal(node, leaf->parent);
        assert_null(leaf->prev);
        assert_null(leaf->next);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_ptr_equal(get_child_by_index(node, 0), leaf);

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/key2 */
        rc = sr_node_add_child(node, "key2", NULL, &leaf);
        assert_int_equal(SR_ERR_OK, rc);
        snprintf(value, 10, "key2-%d", i);
        rc = sr_node_set_str_data(leaf, SR_STRING_T, value);
        assert_int_equal(SR_ERR_OK, rc);
        assert_ptr_equal(node, leaf->parent);
        assert_ptr_equal(get_child_by_index(node, 0), leaf->prev);
        assert_ptr_equal(leaf->prev->next, leaf);
        assert_null(leaf->next);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_ptr_equal(get_child_by_index(node, 1), leaf);

        /* /example_module:container/list[key1="key1-i"][key2="key2-i"]/leaf (="leaf-i") */
        rc = sr_node_add_child(node, "leaf", NULL, &leaf);
        assert_int_equal(SR_ERR_OK, rc);
        snprintf(value, 10, "leaf-%d", i);
        rc = sr_node_set_str_data(leaf, SR_STRING_T, value);
        assert_int_equal(SR_ERR_OK, rc);
        assert_ptr_equal(node, leaf->parent);
        assert_ptr_equal(get_child_by_index(node, 1), leaf->prev);
        assert_ptr_equal(leaf->prev->next, leaf);
        assert_null(leaf->next);
        assert_null(leaf->first_child);
        assert_null(leaf->last_child);
        assert_ptr_equal(get_child_by_index(node, 2), leaf);
    }

    for (int i = 0; i < 5; ++i) {
        /* /example_module:number[.=i] */
        rc = sr_node_set_name(trees + i + 1, "number");
        assert_int_equal(SR_ERR_OK, rc);
        rc = sr_node_set_module(trees + i + 1, "example-module");
        assert_int_equal(SR_ERR_OK, rc);
        trees[i+1].type = SR_UINT16_T;
        trees[i+1].data.uint16_val = i;
    }

    assert_non_null(tree_cnt);
    *tree_cnt = 6;
    return trees;
}
コード例 #5
0
/**
 * Verify that when a path is added or removed, the affected paths have their
 * checksums invalidated.
 */
static void test_updates_reset_checksums() {
  uint8_t checksum[SHA1_BYTES];

  for (int ix = 0; ix < SHA1_BYTES; ix++) {
    checksum[ix] = (uint8_t) ix;
  }

  tree_t *tree = alloc_tree();

  char *paths_to_add[] = {
      "abc",
      "ab/def",
      "ab/defg/hi",
      "ab/defg/h/ij/kl",
      "ab/defg/h/ijk",
      "ab/defg/h/i/jkl/mn/op/qr",
      "ab/defg/h/i/jkl/mn/op/qrs",
  };
  const size_t num_paths = sizeof(paths_to_add) / sizeof(*paths_to_add);

  for (size_t ix = 0;
       ix < num_paths;
       ix++) {
    add_update_path_result_t add_result =
        add_or_update_path(tree, STRPLUSLEN(paths_to_add[ix]),
            checksum, SHA1_BYTES, 0);
    ASSERT(add_result == ADD_UPDATE_PATH_OK);
  }

  update_checksums(tree);
  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == true);

  ASSERT(add_or_update_path(tree,
      STRPLUSLEN("ab/defg/h/ijk"),
      checksum, SHA1_BYTES, 0) == ADD_UPDATE_PATH_OK);

  path_checksum_t dirs_to_check_after_add[] = {
      {"abc",                    true},
      {"ab/",                    false},
      {"ab/defg/",               false},
      {"ab/defg/h/",             false},
      {"ab/defg/h/i/",           true},
      {"ab/defg/h/i/jkl/",       true},
      {"ab/defg/h/i/jkl/mn/",    true},
      {"ab/defg/h/i/jkl/mn/op/", true},
      {"ab/defg/h/ij/",          true},
  };
  size_t num_dirs = sizeof(dirs_to_check_after_add) /
                    sizeof(*dirs_to_check_after_add);

  for (size_t ix = 0;
       ix < num_dirs;
       ix++) {
    get_path_unfiltered_result_t get_result =
        get_path_unfiltered(tree, STRPLUSLEN(dirs_to_check_after_add[ix].path));
    ASSERT(get_result.code == GET_PATH_OK);
    ASSERT(get_result.node->checksum_valid ==
           dirs_to_check_after_add[ix].expected_checksum_valid);
  }
  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == false);

  update_checksums(tree);
  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == true);

  ASSERT(remove_path(tree, STRPLUSLEN("ab/defg/h/i/jkl/mn/op/qrs")) ==
         REMOVE_PATH_OK);

  path_checksum_t dirs_to_check_after_remove[] = {
      {"abc",                    true},
      {"ab/",                    false},
      {"ab/defg/",               false},
      {"ab/defg/h/",             false},
      {"ab/defg/h/i/",           false},
      {"ab/defg/h/i/jkl/",       false},
      {"ab/defg/h/i/jkl/mn/",    false},
      {"ab/defg/h/i/jkl/mn/op/", false},
      {"ab/defg/h/ij/",          true},
  };
  num_dirs = sizeof(dirs_to_check_after_remove) /
             sizeof(*dirs_to_check_after_remove);

  for (size_t ix = 0;
       ix < num_dirs;
       ix++) {
    get_path_unfiltered_result_t get_result = get_path_unfiltered(tree,
        STRPLUSLEN(dirs_to_check_after_remove[ix].path));
    ASSERT(get_result.code == GET_PATH_OK);
    ASSERT(get_result.node->checksum_valid ==
           dirs_to_check_after_remove[ix].expected_checksum_valid);
  }
  ASSERT(get_child_by_index(tree->shadow_root, 0)->checksum_valid == false);
}
コード例 #6
0
static convert_to_flat_code_t convert_to_flat_iterator(
    to_flat_state_t *state,
    const node_t *node) {
  assert(node->type == TYPE_IMPLICIT || node->type == TYPE_ROOT);

  for (uint32_t ix = 0; ix < node->num_children; ix++) {
    node_t *child = get_child_by_index(node, ix);

    if (child->type == TYPE_LEAF) {
      size_t space_needed = state->dirpath_build_buffer_idx +
                            child->name_sz +
                            1 /* null character */ +
                            (SHA1_BYTES * 2) +
                            (child->flags != '\000' ? 1 : 0) +
                            1 /* NL */;

      if (CONVERT_EXPAND_TO_FIT(
              &state->output_buffer,
              state->output_buffer_idx,
              &state->output_buffer_sz,
              space_needed) == false) {
        return CONVERT_TO_FLAT_OOM;
      }

      // copy the dirpath over to the output buffer.
      memcpy(&state->output_buffer[state->output_buffer_idx],
          state->dirpath_build_buffer,
          state->dirpath_build_buffer_idx);
      state->output_buffer_idx += state->dirpath_build_buffer_idx;

      // copy the filename over to the output buffer.
      memcpy(&state->output_buffer[state->output_buffer_idx],
          child->name, child->name_sz);
      state->output_buffer_idx += child->name_sz;

      // copy the filename over to the output buffer.
      state->output_buffer[state->output_buffer_idx] = '\000';
      state->output_buffer_idx++;

      // transcribe the sha over.
      hexlify(child->checksum, SHA1_BYTES,
          &state->output_buffer[state->output_buffer_idx]);
      state->output_buffer_idx += (SHA1_BYTES * 2);

      if (child->flags != '\000') {
        state->output_buffer[state->output_buffer_idx] = child->flags;
        state->output_buffer_idx++;
      }

      state->output_buffer[state->output_buffer_idx] = '\n';
      state->output_buffer_idx++;

      assert(state->output_buffer_idx < state->output_buffer_sz);
    } else {
      // save the old value...
      size_t previous_dirpath_build_buffer_idx =
          state->dirpath_build_buffer_idx;

      if (PATH_APPEND(
              &state->dirpath_build_buffer,
              &state->dirpath_build_buffer_idx,
              &state->dirpath_build_buffer_sz,
              child->name,
              child->name_sz) == false) {
        return CONVERT_TO_FLAT_OOM;
      }

      convert_to_flat_iterator(state, child);

      state->dirpath_build_buffer_idx = previous_dirpath_build_buffer_idx;
    }
  }

  return CONVERT_TO_FLAT_OK;
}