diff options
Diffstat (limited to 'tests/lib/test_srcdest_table.c')
| -rw-r--r-- | tests/lib/test_srcdest_table.c | 629 | 
1 files changed, 305 insertions, 324 deletions
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c index cfc2deb8d6..6c9c0c7250 100644 --- a/tests/lib/test_srcdest_table.c +++ b/tests/lib/test_srcdest_table.c @@ -48,410 +48,391 @@ struct thread_master *master;  /* This structure is copied from lib/srcdest_table.c to which it is   * private as far as other parts of Quagga are concerned.   */ -struct srcdest_rnode -{ -  /* must be first in structure for casting to/from route_node */ -  ROUTE_NODE_FIELDS; +struct srcdest_rnode { +	/* must be first in structure for casting to/from route_node */ +	ROUTE_NODE_FIELDS; -  struct route_table *src_table; +	struct route_table *src_table;  }; -struct test_state -{ -  struct route_table *table; -  struct hash *log; +struct test_state { +	struct route_table *table; +	struct hash *log;  }; -static char * -format_srcdest(const struct prefix_ipv6 *dst_p, -               const struct prefix_ipv6 *src_p) +static char *format_srcdest(const struct prefix_ipv6 *dst_p, +			    const struct prefix_ipv6 *src_p)  { -  char dst_str[BUFSIZ]; -  char src_str[BUFSIZ]; -  char *rv; -  int ec; - -  prefix2str((const struct prefix*)dst_p, dst_str, sizeof(dst_str)); -  if (src_p && src_p->prefixlen) -    prefix2str((const struct prefix*)src_p, src_str, sizeof(src_str)); -  else -    src_str[0] = '\0'; - -  ec = asprintf(&rv, "%s%s%s", dst_str, -                (src_str[0] != '\0') ? " from " : "", -                src_str); - -  assert(ec > 0); -  return rv; +	char dst_str[BUFSIZ]; +	char src_str[BUFSIZ]; +	char *rv; +	int ec; + +	prefix2str((const struct prefix *)dst_p, dst_str, sizeof(dst_str)); +	if (src_p && src_p->prefixlen) +		prefix2str((const struct prefix *)src_p, src_str, +			   sizeof(src_str)); +	else +		src_str[0] = '\0'; + +	ec = asprintf(&rv, "%s%s%s", dst_str, +		      (src_str[0] != '\0') ? " from " : "", src_str); + +	assert(ec > 0); +	return rv;  }  static unsigned int log_key(void *data)  { -  struct prefix *hash_entry = data; -  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*) &hash_entry[0]; -  struct prefix_ipv6 *src_p = (struct prefix_ipv6*) &hash_entry[1]; -  unsigned int hash = 0; -  unsigned int i; - -  hash = (hash * 33) ^ (unsigned int)dst_p->prefixlen; -  for (i = 0; i < 4; i++) -    hash = (hash * 33) ^ (unsigned int)dst_p->prefix.s6_addr32[i]; - -  hash = (hash * 33) ^ (unsigned int)src_p->prefixlen; -  if (src_p->prefixlen) -    for (i = 0; i < 4; i++) -      hash = (hash * 33) ^ (unsigned int)src_p->prefix.s6_addr32[i]; - -  return hash; +	struct prefix *hash_entry = data; +	struct prefix_ipv6 *dst_p = (struct prefix_ipv6 *)&hash_entry[0]; +	struct prefix_ipv6 *src_p = (struct prefix_ipv6 *)&hash_entry[1]; +	unsigned int hash = 0; +	unsigned int i; + +	hash = (hash * 33) ^ (unsigned int)dst_p->prefixlen; +	for (i = 0; i < 4; i++) +		hash = (hash * 33) ^ (unsigned int)dst_p->prefix.s6_addr32[i]; + +	hash = (hash * 33) ^ (unsigned int)src_p->prefixlen; +	if (src_p->prefixlen) +		for (i = 0; i < 4; i++) +			hash = (hash * 33) +			       ^ (unsigned int)src_p->prefix.s6_addr32[i]; + +	return hash;  } -static int -log_cmp(const void *a, const void *b) +static int log_cmp(const void *a, const void *b)  { -  if (a == NULL && b != NULL) -    return 0; -  if (b == NULL && a != NULL) -    return 0; +	if (a == NULL && b != NULL) +		return 0; +	if (b == NULL && a != NULL) +		return 0; -  return !memcmp(a, b, 2 * sizeof(struct prefix)); +	return !memcmp(a, b, 2 * sizeof(struct prefix));  } -static void -log_free(void *data) +static void log_free(void *data)  { -  XFREE(MTYPE_TMP, data); +	XFREE(MTYPE_TMP, data);  } -static void * -log_alloc(void *data) +static void *log_alloc(void *data)  { -  void *rv = XMALLOC(MTYPE_TMP, 2 * sizeof(struct prefix)); -  memcpy(rv, data, 2 * sizeof(struct prefix)); -  return rv; +	void *rv = XMALLOC(MTYPE_TMP, 2 * sizeof(struct prefix)); +	memcpy(rv, data, 2 * sizeof(struct prefix)); +	return rv;  } -static struct test_state * -test_state_new(void) +static struct test_state *test_state_new(void)  { -  struct test_state *rv; +	struct test_state *rv; -  rv = XCALLOC(MTYPE_TMP, sizeof(*rv)); -  assert(rv); +	rv = XCALLOC(MTYPE_TMP, sizeof(*rv)); +	assert(rv); -  rv->table = srcdest_table_init(); -  assert(rv->table); +	rv->table = srcdest_table_init(); +	assert(rv->table); -  rv->log = hash_create(log_key, log_cmp); -  return rv; +	rv->log = hash_create(log_key, log_cmp); +	return rv;  } -static void -test_state_free(struct test_state *test) +static void test_state_free(struct test_state *test)  { -  route_table_finish(test->table); -  hash_clean(test->log, log_free); -  hash_free(test->log); -  XFREE(MTYPE_TMP, test); +	route_table_finish(test->table); +	hash_clean(test->log, log_free); +	hash_free(test->log); +	XFREE(MTYPE_TMP, test);  } -static void -test_state_add_route(struct test_state *test, -                     struct prefix_ipv6 *dst_p, -                     struct prefix_ipv6 *src_p) +static void test_state_add_route(struct test_state *test, +				 struct prefix_ipv6 *dst_p, +				 struct prefix_ipv6 *src_p)  { -  struct route_node *rn = srcdest_rnode_get( -      test->table, (struct prefix*)dst_p, src_p -  ); -  struct prefix hash_entry[2]; - -  memset(hash_entry, 0, sizeof(hash_entry)); -  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); -  memcpy(&hash_entry[1], src_p, sizeof(*src_p)); - -  if (rn->info) { -    route_unlock_node(rn); -    assert(hash_lookup(test->log, hash_entry) != NULL); -    return; -  } else { -    assert(hash_lookup(test->log, hash_entry) == NULL); -  } - -  rn->info = (void*) 0xdeadbeef; -  hash_get(test->log, hash_entry, log_alloc); +	struct route_node *rn = +		srcdest_rnode_get(test->table, (struct prefix *)dst_p, src_p); +	struct prefix hash_entry[2]; + +	memset(hash_entry, 0, sizeof(hash_entry)); +	memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); +	memcpy(&hash_entry[1], src_p, sizeof(*src_p)); + +	if (rn->info) { +		route_unlock_node(rn); +		assert(hash_lookup(test->log, hash_entry) != NULL); +		return; +	} else { +		assert(hash_lookup(test->log, hash_entry) == NULL); +	} + +	rn->info = (void *)0xdeadbeef; +	hash_get(test->log, hash_entry, log_alloc);  }; -static void -test_state_del_route(struct test_state *test, -		     struct prefix_ipv6 *dst_p, -		     struct prefix_ipv6 *src_p) +static void test_state_del_route(struct test_state *test, +				 struct prefix_ipv6 *dst_p, +				 struct prefix_ipv6 *src_p)  { -  struct route_node *rn = srcdest_rnode_lookup( -      test->table, (struct prefix*)dst_p, src_p -  ); -  struct prefix hash_entry[2]; - -  memset(hash_entry, 0, sizeof(hash_entry)); -  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); -  memcpy(&hash_entry[1], src_p, sizeof(*src_p)); - -  if (!rn) { -    assert(!hash_lookup(test->log, hash_entry)); -    return; -  } - -  assert(rn->info == (void*)0xdeadbeef); -  rn->info = NULL; -  route_unlock_node(rn); -  route_unlock_node(rn); - -  struct prefix *hash_entry_intern = hash_release(test->log, hash_entry); -  assert(hash_entry_intern != NULL); -  XFREE(MTYPE_TMP, hash_entry_intern); +	struct route_node *rn = srcdest_rnode_lookup( +		test->table, (struct prefix *)dst_p, src_p); +	struct prefix hash_entry[2]; + +	memset(hash_entry, 0, sizeof(hash_entry)); +	memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); +	memcpy(&hash_entry[1], src_p, sizeof(*src_p)); + +	if (!rn) { +		assert(!hash_lookup(test->log, hash_entry)); +		return; +	} + +	assert(rn->info == (void *)0xdeadbeef); +	rn->info = NULL; +	route_unlock_node(rn); +	route_unlock_node(rn); + +	struct prefix *hash_entry_intern = hash_release(test->log, hash_entry); +	assert(hash_entry_intern != NULL); +	XFREE(MTYPE_TMP, hash_entry_intern);  } -static void -verify_log(struct hash_backet* backet, void *arg) +static void verify_log(struct hash_backet *backet, void *arg)  { -  struct test_state *test = arg; -  struct prefix *hash_entry = backet->data; -  struct prefix *dst_p = &hash_entry[0]; -  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1]; -  struct route_node *rn = srcdest_rnode_lookup(test->table, dst_p, src_p); +	struct test_state *test = arg; +	struct prefix *hash_entry = backet->data; +	struct prefix *dst_p = &hash_entry[0]; +	struct prefix_ipv6 *src_p = (struct prefix_ipv6 *)&hash_entry[1]; +	struct route_node *rn = srcdest_rnode_lookup(test->table, dst_p, src_p); -  assert(rn); -  assert(rn->info == (void*)0xdeadbeef); +	assert(rn); +	assert(rn->info == (void *)0xdeadbeef); -  route_unlock_node(rn); +	route_unlock_node(rn);  } -static void -dump_log(struct hash_backet* backet, void *arg) +static void dump_log(struct hash_backet *backet, void *arg)  { -  struct prefix *hash_entry = backet->data; -  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*)&hash_entry[0]; -  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1]; -  char *route_id = format_srcdest(dst_p, src_p); +	struct prefix *hash_entry = backet->data; +	struct prefix_ipv6 *dst_p = (struct prefix_ipv6 *)&hash_entry[0]; +	struct prefix_ipv6 *src_p = (struct prefix_ipv6 *)&hash_entry[1]; +	char *route_id = format_srcdest(dst_p, src_p); -  fprintf(stderr, "  %s\n", route_id); -  free(route_id); +	fprintf(stderr, "  %s\n", route_id); +	free(route_id);  } -static void -test_dump(struct test_state *test) +static void test_dump(struct test_state *test)  { -  fprintf(stderr, "Contents of hash table:\n"); -  hash_iterate(test->log, dump_log, test); -  fprintf(stderr, "\n"); +	fprintf(stderr, "Contents of hash table:\n"); +	hash_iterate(test->log, dump_log, test); +	fprintf(stderr, "\n");  } -static void -test_failed(struct test_state *test, const char *message, -            struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p) +static void test_failed(struct test_state *test, const char *message, +			struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p)  { -  char *route_id = format_srcdest(dst_p, src_p); +	char *route_id = format_srcdest(dst_p, src_p); -  fprintf(stderr, "Test failed. Error: %s\n", message); -  fprintf(stderr, "Route in question: %s\n", route_id); -  free(route_id); +	fprintf(stderr, "Test failed. Error: %s\n", message); +	fprintf(stderr, "Route in question: %s\n", route_id); +	free(route_id); -  test_dump(test); -  assert(3 == 4); +	test_dump(test); +	assert(3 == 4);  } -static void -test_state_verify(struct test_state *test) +static void test_state_verify(struct test_state *test)  { -  struct route_node *rn; -  struct prefix hash_entry[2]; - -  memset(hash_entry, 0, sizeof(hash_entry)); - -  /* Verify that there are no elements in the table which have never -   * been added */ -  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) -    { -      struct prefix_ipv6 *dst_p, *src_p; - -      /* While we are iterating, we hold a lock on the current route_node, -       * so all the lock counts we check for take that into account; in idle -       * state all the numbers will be exactly one less. -       * -       * Also this makes quite some assumptions based on the current -       * implementation details of route_table and srcdest_table - another -       * valid implementation might trigger assertions here. -       */ - -      if (rnode_is_dstnode(rn)) -        { -          struct srcdest_rnode *srn = (struct srcdest_rnode *)rn; -          unsigned int expected_lock = 1; /* We are in the loop */ - -          if (rn->info != NULL) /* The route node is not internal */ -            expected_lock++; -          if (srn->src_table != NULL) /* There's a source table associated with rn */ -            expected_lock++; - -          if (rn->lock != expected_lock) -            test_failed(test, "Dest rnode lock count doesn't match expected count!", -                        (struct prefix_ipv6*)&rn->p, NULL); -        } -      else -        { -          unsigned int expected_lock = 1; /* We are in the loop */ - -          if (rn->info != NULL) /* The route node is not internal */ -            expected_lock++; - -          if (rn->lock != expected_lock) -            { -              struct prefix_ipv6 *dst_p, *src_p; -              srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p, -                                         (struct prefix**)&src_p); - -              test_failed(test, "Src rnode lock count doesn't match expected count!", -                          dst_p, src_p); -            } -        } - -      if (!rn->info) -        continue; - -      assert(rn->info == (void*)0xdeadbeef); - -      srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p, (struct prefix**)&src_p); -      memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); -      if (src_p) -        memcpy(&hash_entry[1], src_p, sizeof(*src_p)); -      else -        memset(&hash_entry[1], 0, sizeof(hash_entry[1])); - -      if (hash_lookup(test->log, hash_entry) == NULL) -        test_failed(test, "Route is missing in hash", dst_p, src_p); -    } - -  /* Verify that all added elements are still in the table */ -  hash_iterate(test->log, verify_log, test); +	struct route_node *rn; +	struct prefix hash_entry[2]; + +	memset(hash_entry, 0, sizeof(hash_entry)); + +	/* Verify that there are no elements in the table which have never +	 * been added */ +	for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) { +		struct prefix_ipv6 *dst_p, *src_p; + +		/* While we are iterating, we hold a lock on the current +		 * route_node, +		 * so all the lock counts we check for take that into account; +		 * in idle +		 * state all the numbers will be exactly one less. +		 * +		 * Also this makes quite some assumptions based on the current +		 * implementation details of route_table and srcdest_table - +		 * another +		 * valid implementation might trigger assertions here. +		 */ + +		if (rnode_is_dstnode(rn)) { +			struct srcdest_rnode *srn = (struct srcdest_rnode *)rn; +			unsigned int expected_lock = 1; /* We are in the loop */ + +			if (rn->info +			    != NULL) /* The route node is not internal */ +				expected_lock++; +			if (srn->src_table != NULL) /* There's a source table +						       associated with rn */ +				expected_lock++; + +			if (rn->lock != expected_lock) +				test_failed( +					test, +					"Dest rnode lock count doesn't match expected count!", +					(struct prefix_ipv6 *)&rn->p, NULL); +		} else { +			unsigned int expected_lock = 1; /* We are in the loop */ + +			if (rn->info +			    != NULL) /* The route node is not internal */ +				expected_lock++; + +			if (rn->lock != expected_lock) { +				struct prefix_ipv6 *dst_p, *src_p; +				srcdest_rnode_prefixes( +					rn, (struct prefix **)&dst_p, +					(struct prefix **)&src_p); + +				test_failed( +					test, +					"Src rnode lock count doesn't match expected count!", +					dst_p, src_p); +			} +		} + +		if (!rn->info) +			continue; + +		assert(rn->info == (void *)0xdeadbeef); + +		srcdest_rnode_prefixes(rn, (struct prefix **)&dst_p, +				       (struct prefix **)&src_p); +		memcpy(&hash_entry[0], dst_p, sizeof(*dst_p)); +		if (src_p) +			memcpy(&hash_entry[1], src_p, sizeof(*src_p)); +		else +			memset(&hash_entry[1], 0, sizeof(hash_entry[1])); + +		if (hash_lookup(test->log, hash_entry) == NULL) +			test_failed(test, "Route is missing in hash", dst_p, +				    src_p); +	} + +	/* Verify that all added elements are still in the table */ +	hash_iterate(test->log, verify_log, test);  } -static void -get_rand_prefix(struct prng *prng, struct prefix_ipv6 *p) +static void get_rand_prefix(struct prng *prng, struct prefix_ipv6 *p)  { -  int i; +	int i; -  memset(p, 0, sizeof(*p)); +	memset(p, 0, sizeof(*p)); -  for (i = 0; i < 4; i++) -    p->prefix.s6_addr32[i] = prng_rand(prng); -  p->prefixlen = prng_rand(prng) % 129; -  p->family = AF_INET6; +	for (i = 0; i < 4; i++) +		p->prefix.s6_addr32[i] = prng_rand(prng); +	p->prefixlen = prng_rand(prng) % 129; +	p->family = AF_INET6; -  apply_mask((struct prefix*)p); +	apply_mask((struct prefix *)p);  } -static void -get_rand_prefix_pair(struct prng *prng, struct prefix_ipv6 *dst_p, -                     struct prefix_ipv6 *src_p) +static void get_rand_prefix_pair(struct prng *prng, struct prefix_ipv6 *dst_p, +				 struct prefix_ipv6 *src_p)  { -  get_rand_prefix(prng, dst_p); -  if ((prng_rand(prng) % 4) == 0) -    { -      get_rand_prefix(prng, src_p); -      if (src_p->prefixlen) -        return; -    } - -  memset(src_p, 0, sizeof(*src_p)); +	get_rand_prefix(prng, dst_p); +	if ((prng_rand(prng) % 4) == 0) { +		get_rand_prefix(prng, src_p); +		if (src_p->prefixlen) +			return; +	} + +	memset(src_p, 0, sizeof(*src_p));  } -static void -test_state_add_rand_route(struct test_state *test, -                          struct prng *prng) +static void test_state_add_rand_route(struct test_state *test, +				      struct prng *prng)  { -  struct prefix_ipv6 dst_p, src_p; +	struct prefix_ipv6 dst_p, src_p; -  get_rand_prefix_pair(prng, &dst_p, &src_p); -  test_state_add_route(test, &dst_p, &src_p); +	get_rand_prefix_pair(prng, &dst_p, &src_p); +	test_state_add_route(test, &dst_p, &src_p);  } -static void -test_state_del_rand_route(struct test_state *test, -                          struct prng *prng) +static void test_state_del_rand_route(struct test_state *test, +				      struct prng *prng)  { -  struct prefix_ipv6 dst_p, src_p; +	struct prefix_ipv6 dst_p, src_p; -  get_rand_prefix_pair(prng, &dst_p, &src_p); -  test_state_del_route(test, &dst_p, &src_p); +	get_rand_prefix_pair(prng, &dst_p, &src_p); +	test_state_del_route(test, &dst_p, &src_p);  } -static void -test_state_del_one_route(struct test_state *test, -		         struct prng *prng) +static void test_state_del_one_route(struct test_state *test, struct prng *prng)  { -  unsigned int which_route = prng_rand(prng) % test->log->count; -  struct route_node *rn; -  struct prefix *dst_p, *src_p; -  struct prefix_ipv6 dst6_p, src6_p; - -  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) -    { -      if (!rn->info) -        continue; -      if (!which_route) { -        route_unlock_node(rn); -        break; -      } -      which_route--; -    } - -  assert(rn); -  srcdest_rnode_prefixes(rn, &dst_p, &src_p); -  memcpy(&dst6_p, dst_p, sizeof(dst6_p)); -  if (src_p) -    memcpy(&src6_p, src_p, sizeof(src6_p)); -  else -    memset(&src6_p, 0, sizeof(src6_p)); - -  test_state_del_route(test, &dst6_p, &src6_p); +	unsigned int which_route = prng_rand(prng) % test->log->count; +	struct route_node *rn; +	struct prefix *dst_p, *src_p; +	struct prefix_ipv6 dst6_p, src6_p; + +	for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) { +		if (!rn->info) +			continue; +		if (!which_route) { +			route_unlock_node(rn); +			break; +		} +		which_route--; +	} + +	assert(rn); +	srcdest_rnode_prefixes(rn, &dst_p, &src_p); +	memcpy(&dst6_p, dst_p, sizeof(dst6_p)); +	if (src_p) +		memcpy(&src6_p, src_p, sizeof(src6_p)); +	else +		memset(&src6_p, 0, sizeof(src6_p)); + +	test_state_del_route(test, &dst6_p, &src6_p);  } -static void -run_prng_test(void) +static void run_prng_test(void)  { -  struct test_state *test = test_state_new(); -  struct prng *prng = prng_new(0); -  size_t i; - -  for (i = 0; i < 1000; i++) -    { -      switch (prng_rand(prng) % 10) -        { -        case 0: -        case 1: -        case 2: -        case 3: -        case 4: -          test_state_add_rand_route(test, prng); -          break; -        case 5: -        case 6: -        case 7: -          test_state_del_one_route(test, prng); -          break; -        case 8: -        case 9: -          test_state_del_rand_route(test, prng); -          break; -        } -      test_state_verify(test); -    } - -  prng_free(prng); -  test_state_free(test); +	struct test_state *test = test_state_new(); +	struct prng *prng = prng_new(0); +	size_t i; + +	for (i = 0; i < 1000; i++) { +		switch (prng_rand(prng) % 10) { +		case 0: +		case 1: +		case 2: +		case 3: +		case 4: +			test_state_add_rand_route(test, prng); +			break; +		case 5: +		case 6: +		case 7: +			test_state_del_one_route(test, prng); +			break; +		case 8: +		case 9: +			test_state_del_rand_route(test, prng); +			break; +		} +		test_state_verify(test); +	} + +	prng_free(prng); +	test_state_free(test);  }  int main(int argc, char *argv[])  { -  run_prng_test(); -  printf("PRNG Test successful.\n"); -  return 0; +	run_prng_test(); +	printf("PRNG Test successful.\n"); +	return 0;  }  | 
