Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
test_sorcery_memory_cache_thrash.c File Reference

Sorcery Unit Tests. More...

#include "asterisk.h"
#include "asterisk/test.h"
#include "asterisk/module.h"
#include "asterisk/sorcery.h"
#include "asterisk/logger.h"
#include "asterisk/vector.h"
#include "asterisk/cli.h"
Include dependency graph for test_sorcery_memory_cache_thrash.c:

Go to the source code of this file.

Data Structures

struct  sorcery_memory_cache_thrash
 Structure for memory cache thrasing. More...
 
struct  sorcery_memory_cache_thrash_thread
 Structure for a memory cache thras thread. More...
 
struct  test_data
 Sorcery object created based on backend data. More...
 

Macros

#define TEST_THRASH_RETRIEVERS   25
 The number of threads to use for retrieving for applicable tests. More...
 
#define TEST_THRASH_TIME   3
 The default amount of time (in seconds) that thrash unit tests execute for. More...
 
#define TEST_THRASH_UPDATERS   25
 The number of threads to use for updating for applicable tests. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (low_unique_object_count_immediately_stale)
 
 AST_TEST_DEFINE (low_unique_object_count_immediately_expire)
 
 AST_TEST_DEFINE (low_unique_object_count_high_concurrent_updates)
 
 AST_TEST_DEFINE (unique_objects_exceeding_maximum)
 
 AST_TEST_DEFINE (unique_objects_exceeding_maximum_with_expire_and_stale)
 
 AST_TEST_DEFINE (conflicting_expire_and_stale)
 
 AST_TEST_DEFINE (high_object_count_without_expiration)
 
static int load_module (void)
 
static void * mock_retrieve_id (const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 Callback for retrieving sorcery object by ID. More...
 
static int mock_update (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback for updating a sorcery object. More...
 
static enum ast_test_result_state nominal_thrash (struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
 
static char * sorcery_memory_cache_cli_thrash (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static struct sorcery_memory_cache_thrashsorcery_memory_cache_thrash_create (const char *cache_configuration, unsigned int update_threads, unsigned int retrieve_threads, unsigned int unique_objects)
 
static void sorcery_memory_cache_thrash_destroy (void *obj)
 
static void * sorcery_memory_cache_thrash_retrieve (void *data)
 
static int sorcery_memory_cache_thrash_start (struct sorcery_memory_cache_thrash *thrash)
 
static void sorcery_memory_cache_thrash_stop (struct sorcery_memory_cache_thrash *thrash)
 
static void * sorcery_memory_cache_thrash_update (void *data)
 
static void * test_data_alloc (const char *id)
 Allocation callback for test_data sorcery object. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Sorcery Cache Thrasing test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_memory_cache_thrash []
 
static struct ast_sorcery_wizard mock_wizard
 A mock sorcery wizard used for the stale test. More...
 

Detailed Description

Sorcery Unit Tests.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file test_sorcery_memory_cache_thrash.c.

Macro Definition Documentation

◆ TEST_THRASH_RETRIEVERS

#define TEST_THRASH_RETRIEVERS   25

The number of threads to use for retrieving for applicable tests.

Definition at line 45 of file test_sorcery_memory_cache_thrash.c.

Referenced by AST_TEST_DEFINE().

◆ TEST_THRASH_TIME

#define TEST_THRASH_TIME   3

The default amount of time (in seconds) that thrash unit tests execute for.

Definition at line 42 of file test_sorcery_memory_cache_thrash.c.

Referenced by AST_TEST_DEFINE().

◆ TEST_THRASH_UPDATERS

#define TEST_THRASH_UPDATERS   25

The number of threads to use for updating for applicable tests.

Definition at line 48 of file test_sorcery_memory_cache_thrash.c.

Referenced by AST_TEST_DEFINE().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 631 of file test_sorcery_memory_cache_thrash.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 631 of file test_sorcery_memory_cache_thrash.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 631 of file test_sorcery_memory_cache_thrash.c.

◆ AST_TEST_DEFINE() [1/7]

AST_TEST_DEFINE ( low_unique_object_count_immediately_stale  )

Definition at line 467 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

468 {
469  switch (cmd) {
470  case TEST_INIT:
471  info->name = "low_unique_object_count_immediately_stale";
472  info->category = "/res/res_sorcery_memory_cache/thrash/";
473  info->summary = "Thrash a cache with low number of unique objects that are immediately stale";
474  info->description = "This test creates a cache with objects that are stale\n"
475  "after 1 second. It also creates 25 threads which are constantly attempting\n"
476  "to retrieve the objects. This test confirms that the background refreshes\n"
477  "being done as a result of going stale do not conflict or cause problems with\n"
478  "the large number of retrieve threads.";
479  return AST_TEST_NOT_RUN;
480  case TEST_EXECUTE:
481  break;
482  }
483 
484  return nominal_thrash(test, "object_lifetime_stale=1", TEST_THRASH_TIME, 10, TEST_THRASH_RETRIEVERS, 0);
485 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [2/7]

AST_TEST_DEFINE ( low_unique_object_count_immediately_expire  )

Definition at line 487 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

488 {
489  switch (cmd) {
490  case TEST_INIT:
491  info->name = "low_unique_object_count_immediately_expire";
492  info->category = "/res/res_sorcery_memory_cache/thrash/";
493  info->summary = "Thrash a cache with low number of unique objects that are immediately expired";
494  info->description = "This test creates a cache with objects that are expired\n"
495  "after 1 second. It also creates 25 threads which are constantly attempting\n"
496  "to retrieve the objects. This test confirms that the expiration process does\n"
497  "not cause a problem as the retrieve threads execute.";
498  return AST_TEST_NOT_RUN;
499  case TEST_EXECUTE:
500  break;
501  }
502 
503  return nominal_thrash(test, "object_lifetime_maximum=1", TEST_THRASH_TIME, 10, TEST_THRASH_RETRIEVERS, 0);
504 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [3/7]

AST_TEST_DEFINE ( low_unique_object_count_high_concurrent_updates  )

Definition at line 506 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, TEST_THRASH_TIME, and TEST_THRASH_UPDATERS.

507 {
508  switch (cmd) {
509  case TEST_INIT:
510  info->name = "low_unique_object_count_high_concurrent_updates";
511  info->category = "/res/res_sorcery_memory_cache/thrash/";
512  info->summary = "Thrash a cache with low number of unique objects that are updated frequently";
513  info->description = "This test creates a cache with objects that are being constantly\n"
514  "updated and retrieved at the same time. This will create contention between all\n"
515  "of the threads as the write lock is held for the updates. This test confirms that\n"
516  "no problems occur in this situation.";
517  return AST_TEST_NOT_RUN;
518  case TEST_EXECUTE:
519  break;
520  }
521 
523 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_UPDATERS
The number of threads to use for updating for applicable tests.
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [4/7]

AST_TEST_DEFINE ( unique_objects_exceeding_maximum  )

Definition at line 525 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

526 {
527  switch (cmd) {
528  case TEST_INIT:
529  info->name = "unique_objects_exceeding_maximum";
530  info->category = "/res/res_sorcery_memory_cache/thrash/";
531  info->summary = "Thrash a cache with a fixed maximum object count";
532  info->description = "This test creates a cache with a maximum number of objects\n"
533  "allowed in it. The maximum number of unique objects, however, far exceeds the\n"
534  "the maximum number allowed in the cache. This test confirms that the cache does\n"
535  "not exceed the maximum and that the removal of older objects does not cause\n"
536  "a problem.";
537  return AST_TEST_NOT_RUN;
538  case TEST_EXECUTE:
539  break;
540  }
541 
542  return nominal_thrash(test, "maximum_objects=10", TEST_THRASH_TIME, 100, TEST_THRASH_RETRIEVERS, 0);
543 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [5/7]

AST_TEST_DEFINE ( unique_objects_exceeding_maximum_with_expire_and_stale  )

Definition at line 545 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

546 {
547  switch (cmd) {
548  case TEST_INIT:
549  info->name = "unique_objects_exceeding_maximum_with_expire_and_stale";
550  info->category = "/res/res_sorcery_memory_cache/thrash/";
551  info->summary = "Thrash a cache with a fixed maximum object count with objects that expire and go stale";
552  info->description = "This test creates a cache with a maximum number of objects\n"
553  "allowed in it with objects that also go stale after a period of time and expire.\n"
554  "A number of threads are created that constantly retrieve from the cache, causing\n"
555  "both stale refresh and expiration to occur. This test confirms that the combination\n"
556  "of these do not present a problem.";
557  return AST_TEST_NOT_RUN;
558  case TEST_EXECUTE:
559  break;
560  }
561 
562  return nominal_thrash(test, "maximum_objects=10,object_lifetime_maximum=2,object_lifetime_stale=1",
564 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [6/7]

AST_TEST_DEFINE ( conflicting_expire_and_stale  )

Definition at line 566 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

567 {
568  switch (cmd) {
569  case TEST_INIT:
570  info->name = "conflicting_expire_and_stale";
571  info->category = "/res/res_sorcery_memory_cache/thrash/";
572  info->summary = "Thrash a cache with a large number of objects that expire and go stale";
573  info->description = "This test creates a cache with a large number of objects that expire\n"
574  "and go stale. As there is such a large number this ensures that both operations occur.\n"
575  "This test confirms that stale refreshing and expiration do not conflict.";
576  return AST_TEST_NOT_RUN;
577  case TEST_EXECUTE:
578  break;
579  }
580 
581  return nominal_thrash(test, "object_lifetime_maximum=2,object_lifetime_stale=1", TEST_THRASH_TIME * 2, 5000,
583 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ AST_TEST_DEFINE() [7/7]

AST_TEST_DEFINE ( high_object_count_without_expiration  )

Definition at line 585 of file test_sorcery_memory_cache_thrash.c.

References AST_TEST_NOT_RUN, sip_to_pjsip::info(), nominal_thrash(), TEST_EXECUTE, TEST_INIT, TEST_THRASH_RETRIEVERS, and TEST_THRASH_TIME.

586 {
587  switch (cmd) {
588  case TEST_INIT:
589  info->name = "high_object_count_without_expiration";
590  info->category = "/res/res_sorcery_memory_cache/thrash/";
591  info->summary = "Thrash a cache with a large number of objects";
592  info->description = "This test creates a cache with a large number of objects that persist.\n"
593  "A large number of threads are created which constantly retrieve from the cache.\n"
594  "This test confirms that the large number of retrieves do not cause a problem.";
595  return AST_TEST_NOT_RUN;
596  case TEST_EXECUTE:
597  break;
598  }
599 
600  return nominal_thrash(test, "default", TEST_THRASH_TIME, 5000, TEST_THRASH_RETRIEVERS, 0);
601 }
#define TEST_THRASH_RETRIEVERS
The number of threads to use for retrieving for applicable tests.
static enum ast_test_result_state nominal_thrash(struct ast_test *test, const char *cache_configuration, unsigned int thrash_time, unsigned int unique_objects, unsigned int retrieve_threads, unsigned int update_threads)
def info(msg)
#define TEST_THRASH_TIME
The default amount of time (in seconds) that thrash unit tests execute for.

◆ load_module()

static int load_module ( void  )
static

Definition at line 617 of file test_sorcery_memory_cache_thrash.c.

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

618 {
620  AST_TEST_REGISTER(low_unique_object_count_immediately_stale);
621  AST_TEST_REGISTER(low_unique_object_count_immediately_expire);
622  AST_TEST_REGISTER(low_unique_object_count_high_concurrent_updates);
623  AST_TEST_REGISTER(unique_objects_exceeding_maximum);
624  AST_TEST_REGISTER(unique_objects_exceeding_maximum_with_expire_and_stale);
625  AST_TEST_REGISTER(conflicting_expire_and_stale);
626  AST_TEST_REGISTER(high_object_count_without_expiration);
627 
629 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_cli_entry cli_memory_cache_thrash[]

◆ mock_retrieve_id()

static void* mock_retrieve_id ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
)
static

Callback for retrieving sorcery object by ID.

Parameters
sorceryThe sorcery instance
dataUnused
typeThe object type. Will always be "test".
idThe object id. Will always be "test".
Return values
NULLBackend data successfully allocated
non-NULLBackend data could not be successfully allocated

Definition at line 106 of file test_sorcery_memory_cache_thrash.c.

References ast_sorcery_alloc().

108 {
109  return ast_sorcery_alloc(sorcery, type, id);
110 }
static const char type[]
Definition: chan_ooh323.c:109
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744

◆ mock_update()

static int mock_update ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
)
static

Callback for updating a sorcery object.

Parameters
sorceryThe sorcery instance
dataUnused
objectThe object to update.

Definition at line 120 of file test_sorcery_memory_cache_thrash.c.

122 {
123  return 0;
124 }

◆ nominal_thrash()

static enum ast_test_result_state nominal_thrash ( struct ast_test test,
const char *  cache_configuration,
unsigned int  thrash_time,
unsigned int  unique_objects,
unsigned int  retrieve_threads,
unsigned int  update_threads 
)
static

Definition at line 447 of file test_sorcery_memory_cache_thrash.c.

References ao2_ref, AST_TEST_FAIL, AST_TEST_PASS, sorcery_memory_cache_thrash_create(), sorcery_memory_cache_thrash_start(), and sorcery_memory_cache_thrash_stop().

Referenced by AST_TEST_DEFINE().

450 {
451  struct sorcery_memory_cache_thrash *thrash;
452 
453  thrash = sorcery_memory_cache_thrash_create(cache_configuration, update_threads, retrieve_threads, unique_objects);
454  if (!thrash) {
455  return AST_TEST_FAIL;
456  }
457 
459  while ((thrash_time = sleep(thrash_time)));
461 
462  ao2_ref(thrash, -1);
463 
464  return AST_TEST_PASS;
465 }
unsigned int update_threads
The number of threads which are updating.
static struct sorcery_memory_cache_thrash * sorcery_memory_cache_thrash_create(const char *cache_configuration, unsigned int update_threads, unsigned int retrieve_threads, unsigned int unique_objects)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure for memory cache thrasing.
unsigned int retrieve_threads
The number of threads which are retrieving.
static void sorcery_memory_cache_thrash_stop(struct sorcery_memory_cache_thrash *thrash)
static int sorcery_memory_cache_thrash_start(struct sorcery_memory_cache_thrash *thrash)

◆ sorcery_memory_cache_cli_thrash()

static char* sorcery_memory_cache_cli_thrash ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 368 of file test_sorcery_memory_cache_thrash.c.

References ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), sorcery_memory_cache_thrash::average_retrieve_execution_time, sorcery_memory_cache_thrash::average_update_execution_time, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, sorcery_memory_cache_thrash::retrieve_threads, sorcery_memory_cache_thrash_create(), sorcery_memory_cache_thrash_start(), sorcery_memory_cache_thrash_stop(), sorcery_memory_cache_thrash_thread::unique_objects, sorcery_memory_cache_thrash::update_threads, and ast_cli_entry::usage.

369 {
370  struct sorcery_memory_cache_thrash *thrash;
371  unsigned int thrash_time, unique_objects, retrieve_threads, update_threads;
372 
373  switch (cmd) {
374  case CLI_INIT:
375  e->command = "sorcery memory cache thrash";
376  e->usage =
377  "Usage: sorcery memory cache thrash <cache configuration> <amount of time to thrash the cache> <number of unique objects> <number of retrieve threads> <number of update threads>\n"
378  " Create a sorcery instance with a memory cache using the provided configuration and thrash it.\n";
379  return NULL;
380  case CLI_GENERATE:
381  return NULL;
382  }
383 
384  if (a->argc != 9) {
385  return CLI_SHOWUSAGE;
386  }
387 
388  if (sscanf(a->argv[5], "%30u", &thrash_time) != 1) {
389  ast_cli(a->fd, "An invalid value of '%s' has been provided for the thrashing time\n", a->argv[5]);
390  return CLI_FAILURE;
391  } else if (sscanf(a->argv[6], "%30u", &unique_objects) != 1) {
392  ast_cli(a->fd, "An invalid value of '%s' has been provided for number of unique objects\n", a->argv[6]);
393  return CLI_FAILURE;
394  } else if (sscanf(a->argv[7], "%30u", &retrieve_threads) != 1) {
395  ast_cli(a->fd, "An invalid value of '%s' has been provided for the number of retrieve threads\n", a->argv[7]);
396  return CLI_FAILURE;
397  } else if (sscanf(a->argv[8], "%30u", &update_threads) != 1) {
398  ast_cli(a->fd, "An invalid value of '%s' has been provided for the number of update threads\n", a->argv[8]);
399  return CLI_FAILURE;
400  }
401 
402  thrash = sorcery_memory_cache_thrash_create(a->argv[4], update_threads, retrieve_threads, unique_objects);
403  if (!thrash) {
404  ast_cli(a->fd, "Could not create a sorcery memory cache thrash test using the provided arguments\n");
405  return CLI_FAILURE;
406  }
407 
408  ast_cli(a->fd, "Starting cache thrash test.\n");
409  ast_cli(a->fd, "Memory cache configuration: %s\n", a->argv[4]);
410  ast_cli(a->fd, "Amount of time to perform test: %u seconds\n", thrash_time);
411  ast_cli(a->fd, "Number of unique objects: %u\n", unique_objects);
412  ast_cli(a->fd, "Number of retrieve threads: %u\n", retrieve_threads);
413  ast_cli(a->fd, "Number of update threads: %u\n", update_threads);
414 
416  while ((thrash_time = sleep(thrash_time)));
418 
419  ast_cli(a->fd, "Stopped cache thrash test\n");
420 
421  ast_cli(a->fd, "Average retrieve execution time (in milliseconds): %u\n", thrash->average_retrieve_execution_time);
422  ast_cli(a->fd, "Average update execution time (in milliseconds): %u\n", thrash->average_update_execution_time);
423 
424  ao2_ref(thrash, -1);
425 
426  return CLI_SUCCESS;
427 }
unsigned int update_threads
The number of threads which are updating.
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int average_retrieve_execution_time
The average execution time of sorcery retrieve operations.
static struct sorcery_memory_cache_thrash * sorcery_memory_cache_thrash_create(const char *cache_configuration, unsigned int update_threads, unsigned int retrieve_threads, unsigned int unique_objects)
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure for memory cache thrasing.
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
unsigned int retrieve_threads
The number of threads which are retrieving.
#define CLI_SUCCESS
Definition: cli.h:44
unsigned int average_update_execution_time
The average execution time of sorcery update operations.
static void sorcery_memory_cache_thrash_stop(struct sorcery_memory_cache_thrash *thrash)
static int sorcery_memory_cache_thrash_start(struct sorcery_memory_cache_thrash *thrash)

◆ sorcery_memory_cache_thrash_create()

static struct sorcery_memory_cache_thrash* sorcery_memory_cache_thrash_create ( const char *  cache_configuration,
unsigned int  update_threads,
unsigned int  retrieve_threads,
unsigned int  unique_objects 
)
static

Definition at line 173 of file test_sorcery_memory_cache_thrash.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_calloc, ast_free, AST_PTHREADT_NULL, ast_sorcery_apply_wizard_mapping, ast_sorcery_internal_object_register, ast_sorcery_open, ast_sorcery_wizard_register, AST_VECTOR_APPEND, AST_VECTOR_INIT, AST_VECTOR_SIZE, NULL, sorcery_memory_cache_thrash::retrieve_threads, sorcery_memory_cache_thrash_thread::sorcery, sorcery_memory_cache_thrash::sorcery, sorcery_memory_cache_thrash_destroy(), test_data_alloc(), sorcery_memory_cache_thrash_thread::thread, sorcery_memory_cache_thrash_thread::unique_objects, and sorcery_memory_cache_thrash::update_threads.

Referenced by nominal_thrash(), and sorcery_memory_cache_cli_thrash().

175 {
176  struct sorcery_memory_cache_thrash *thrash;
178  unsigned int total_threads = update_threads + retrieve_threads;
179 
180  thrash = ao2_alloc_options(sizeof(*thrash), sorcery_memory_cache_thrash_destroy,
182  if (!thrash) {
183  return NULL;
184  }
185 
186  thrash->update_threads = update_threads;
187  thrash->retrieve_threads = retrieve_threads;
188 
190 
191  thrash->sorcery = ast_sorcery_open();
192  if (!thrash->sorcery) {
193  ao2_ref(thrash, -1);
194  return NULL;
195  }
196 
197  ast_sorcery_apply_wizard_mapping(thrash->sorcery, "test", "memory_cache",
198  !strcmp(cache_configuration, "default") ? "" : cache_configuration, 1);
199  ast_sorcery_apply_wizard_mapping(thrash->sorcery, "test", "mock", NULL, 0);
201 
202  if (AST_VECTOR_INIT(&thrash->threads, update_threads + retrieve_threads)) {
203  ao2_ref(thrash, -1);
204  return NULL;
205  }
206 
207  while (AST_VECTOR_SIZE(&thrash->threads) != total_threads) {
208  thread = ast_calloc(1, sizeof(*thread));
209 
210  if (!thread) {
211  ao2_ref(thrash, -1);
212  return NULL;
213  }
214 
215  thread->thread = AST_PTHREADT_NULL;
216  thread->unique_objects = unique_objects;
217 
218  /* This purposely holds no ref as the main thrash structure does */
219  thread->sorcery = thrash->sorcery;
220 
221  if (AST_VECTOR_APPEND(&thrash->threads, thread)) {
222  ast_free(thread);
223  ao2_ref(thrash, -1);
224  return NULL;
225  }
226  }
227 
228  return thrash;
229 }
unsigned int update_threads
The number of threads which are updating.
struct ast_sorcery * sorcery
Sorcery instance being tested.
pthread_t thread
Definition: app_meetme.c:1089
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)
Apply additional object wizard mappings.
Definition: sorcery.h:511
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
Structure for a memory cache thras thread.
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static void * test_data_alloc(const char *id)
Allocation callback for test_data sorcery object.
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
pthread_t thread
The thread thrashing the cache.
unsigned int unique_objects
The number of unique objects we should restrict ourself to.
struct ast_sorcery * sorcery
The sorcery instance being tested.
Structure for memory cache thrasing.
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
Definition: sorcery.h:383
#define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply)
Register an internal, hidden object type.
Definition: sorcery.h:868
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void sorcery_memory_cache_thrash_destroy(void *obj)
unsigned int retrieve_threads
The number of threads which are retrieving.
#define ast_sorcery_open()
Definition: sorcery.h:408
static struct ast_sorcery_wizard mock_wizard
A mock sorcery wizard used for the stale test.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ sorcery_memory_cache_thrash_destroy()

static void sorcery_memory_cache_thrash_destroy ( void *  obj)
static

Definition at line 141 of file test_sorcery_memory_cache_thrash.c.

References ast_free, ast_sorcery_unref, ast_sorcery_wizard_unregister(), AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, sorcery_memory_cache_thrash::sorcery, and sorcery_memory_cache_thrash_thread::thread.

Referenced by sorcery_memory_cache_thrash_create().

142 {
143  struct sorcery_memory_cache_thrash *thrash = obj;
144  int idx;
145 
146  if (thrash->sorcery) {
147  ast_sorcery_unref(thrash->sorcery);
148  }
149 
150  for (idx = 0; idx < AST_VECTOR_SIZE(&thrash->threads); ++idx) {
152 
153  thread = AST_VECTOR_GET(&thrash->threads, idx);
154  ast_free(thread);
155  }
156  AST_VECTOR_FREE(&thrash->threads);
157 
159 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
pthread_t thread
Definition: app_meetme.c:1089
Structure for a memory cache thras thread.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition: sorcery.h:1502
struct ast_sorcery * sorcery
The sorcery instance being tested.
Structure for memory cache thrasing.
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
Definition: sorcery.c:474
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static struct ast_sorcery_wizard mock_wizard
A mock sorcery wizard used for the stale test.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ sorcery_memory_cache_thrash_retrieve()

static void* sorcery_memory_cache_thrash_retrieve ( void *  data)
static

Definition at line 267 of file test_sorcery_memory_cache_thrash.c.

References ao2_ref, ast_assert, ast_random(), ast_sorcery_retrieve_by_id(), ast_tvdiff_ms(), ast_tvnow(), AST_UUID_STR_LEN, sorcery_memory_cache_thrash_thread::average_execution_time, NULL, sorcery_memory_cache_thrash_thread::sorcery, sorcery_memory_cache_thrash_thread::stop, sorcery_memory_cache_thrash_thread::thread, and sorcery_memory_cache_thrash_thread::unique_objects.

Referenced by sorcery_memory_cache_thrash_start().

268 {
270  struct timeval start;
271  unsigned int object_id;
272  char object_id_str[AST_UUID_STR_LEN];
273  void *object;
274 
275  while (!thread->stop) {
276  object_id = ast_random() % thread->unique_objects;
277  snprintf(object_id_str, sizeof(object_id_str), "%u", object_id);
278 
279  start = ast_tvnow();
280  object = ast_sorcery_retrieve_by_id(thread->sorcery, "test", object_id_str);
281  thread->average_execution_time = (thread->average_execution_time + ast_tvdiff_ms(ast_tvnow(), start)) / 2;
282  ast_assert(object != NULL);
283 
284  ao2_ref(object, -1);
285  }
286 
287  return NULL;
288 }
struct ast_sorcery * sorcery
Sorcery instance being tested.
pthread_t thread
Definition: app_meetme.c:1089
#define AST_UUID_STR_LEN
Definition: uuid.h:27
Structure for a memory cache thras thread.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_assert(a)
Definition: utils.h:695
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
unsigned int average_execution_time
Average time spent executing sorcery operation in this thread.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
long int ast_random(void)
Definition: main/utils.c:2064
unsigned int unique_objects
The number of unique objects we should restrict ourself to.
unsigned int stop
Set when the thread should stop.

◆ sorcery_memory_cache_thrash_start()

static int sorcery_memory_cache_thrash_start ( struct sorcery_memory_cache_thrash thrash)
static

Definition at line 345 of file test_sorcery_memory_cache_thrash.c.

References ast_pthread_create, AST_VECTOR_GET, AST_VECTOR_SIZE, NULL, sorcery_memory_cache_thrash_retrieve(), sorcery_memory_cache_thrash_stop(), sorcery_memory_cache_thrash_update(), and sorcery_memory_cache_thrash_thread::thread.

Referenced by nominal_thrash(), and sorcery_memory_cache_cli_thrash().

346 {
347  int idx;
348 
349  for (idx = 0; idx < AST_VECTOR_SIZE(&thrash->threads); ++idx) {
351 
352  thread = AST_VECTOR_GET(&thrash->threads, idx);
353 
354  if (ast_pthread_create(&thread->thread, NULL, idx < thrash->update_threads ?
357  return -1;
358  }
359  }
360 
361  return 0;
362 }
pthread_t thread
Definition: app_meetme.c:1089
static void * sorcery_memory_cache_thrash_retrieve(void *data)
Structure for a memory cache thras thread.
#define NULL
Definition: resample.c:96
pthread_t thread
The thread thrashing the cache.
static void * sorcery_memory_cache_thrash_update(void *data)
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static void sorcery_memory_cache_thrash_stop(struct sorcery_memory_cache_thrash *thrash)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ sorcery_memory_cache_thrash_stop()

static void sorcery_memory_cache_thrash_stop ( struct sorcery_memory_cache_thrash thrash)
static

Definition at line 296 of file test_sorcery_memory_cache_thrash.c.

References AST_PTHREADT_NULL, AST_VECTOR_GET, AST_VECTOR_SIZE, sorcery_memory_cache_thrash_thread::average_execution_time, sorcery_memory_cache_thrash::average_retrieve_execution_time, sorcery_memory_cache_thrash::average_update_execution_time, NULL, sorcery_memory_cache_thrash::retrieve_threads, sorcery_memory_cache_thrash_thread::stop, sorcery_memory_cache_thrash_thread::thread, and sorcery_memory_cache_thrash::update_threads.

Referenced by nominal_thrash(), sorcery_memory_cache_cli_thrash(), and sorcery_memory_cache_thrash_start().

297 {
298  int idx;
299 
300  for (idx = 0; idx < AST_VECTOR_SIZE(&thrash->threads); ++idx) {
302 
303  thread = AST_VECTOR_GET(&thrash->threads, idx);
304  if (thread->thread == AST_PTHREADT_NULL) {
305  continue;
306  }
307 
308  thread->stop = 1;
309  }
310 
311  for (idx = 0; idx < AST_VECTOR_SIZE(&thrash->threads); ++idx) {
313 
314  thread = AST_VECTOR_GET(&thrash->threads, idx);
315  if (thread->thread == AST_PTHREADT_NULL) {
316  continue;
317  }
318 
319  pthread_join(thread->thread, NULL);
320 
321  if (idx < thrash->update_threads) {
323  } else {
325  }
326  }
327 
328  if (thrash->update_threads) {
330  }
331  if (thrash->retrieve_threads) {
333  }
334 }
unsigned int update_threads
The number of threads which are updating.
pthread_t thread
Definition: app_meetme.c:1089
Structure for a memory cache thras thread.
#define NULL
Definition: resample.c:96
unsigned int average_retrieve_execution_time
The average execution time of sorcery retrieve operations.
unsigned int average_execution_time
Average time spent executing sorcery operation in this thread.
#define AST_PTHREADT_NULL
Definition: lock.h:66
pthread_t thread
The thread thrashing the cache.
unsigned int retrieve_threads
The number of threads which are retrieving.
unsigned int stop
Set when the thread should stop.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
unsigned int average_update_execution_time
The average execution time of sorcery update operations.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ sorcery_memory_cache_thrash_update()

static void* sorcery_memory_cache_thrash_update ( void *  data)
static

Definition at line 237 of file test_sorcery_memory_cache_thrash.c.

References ao2_ref, ast_assert, ast_random(), ast_sorcery_alloc(), ast_sorcery_update(), ast_tvdiff_ms(), ast_tvnow(), AST_UUID_STR_LEN, sorcery_memory_cache_thrash_thread::average_execution_time, NULL, sorcery_memory_cache_thrash_thread::sorcery, sorcery_memory_cache_thrash_thread::stop, sorcery_memory_cache_thrash_thread::thread, and sorcery_memory_cache_thrash_thread::unique_objects.

Referenced by sorcery_memory_cache_thrash_start().

238 {
240  struct timeval start;
241  unsigned int object_id;
242  char object_id_str[AST_UUID_STR_LEN];
243  void *object;
244 
245  while (!thread->stop) {
246  object_id = ast_random() % thread->unique_objects;
247  snprintf(object_id_str, sizeof(object_id_str), "%u", object_id);
248 
249  object = ast_sorcery_alloc(thread->sorcery, "test", object_id_str);
250  ast_assert(object != NULL);
251 
252  start = ast_tvnow();
253  ast_sorcery_update(thread->sorcery, object);
254  thread->average_execution_time = (thread->average_execution_time + ast_tvdiff_ms(ast_tvnow(), start)) / 2;
255  ao2_ref(object, -1);
256  }
257 
258  return NULL;
259 }
struct ast_sorcery * sorcery
Sorcery instance being tested.
pthread_t thread
Definition: app_meetme.c:1089
#define AST_UUID_STR_LEN
Definition: uuid.h:27
Structure for a memory cache thras thread.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_assert(a)
Definition: utils.h:695
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
unsigned int average_execution_time
Average time spent executing sorcery operation in this thread.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
long int ast_random(void)
Definition: main/utils.c:2064
unsigned int unique_objects
The number of unique objects we should restrict ourself to.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
unsigned int stop
Set when the thread should stop.
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition: sorcery.c:2145

◆ test_data_alloc()

static void* test_data_alloc ( const char *  id)
static

Allocation callback for test_data sorcery object.

Definition at line 90 of file test_sorcery_memory_cache_thrash.c.

References ast_sorcery_generic_alloc(), and NULL.

Referenced by sorcery_memory_cache_thrash_create().

91 {
92  return ast_sorcery_generic_alloc(sizeof(struct test_data), NULL);
93 }
#define NULL
Definition: resample.c:96
Sorcery object created based on backend data.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 603 of file test_sorcery_memory_cache_thrash.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and AST_TEST_UNREGISTER.

604 {
606  AST_TEST_UNREGISTER(low_unique_object_count_immediately_stale);
607  AST_TEST_UNREGISTER(low_unique_object_count_immediately_expire);
608  AST_TEST_UNREGISTER(low_unique_object_count_high_concurrent_updates);
609  AST_TEST_UNREGISTER(unique_objects_exceeding_maximum);
610  AST_TEST_UNREGISTER(unique_objects_exceeding_maximum_with_expire_and_stale);
611  AST_TEST_UNREGISTER(conflicting_expire_and_stale);
612  AST_TEST_UNREGISTER(high_object_count_without_expiration);
613 
614  return 0;
615 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry cli_memory_cache_thrash[]
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Sorcery Cache Thrasing test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 631 of file test_sorcery_memory_cache_thrash.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 631 of file test_sorcery_memory_cache_thrash.c.

◆ cli_memory_cache_thrash

struct ast_cli_entry cli_memory_cache_thrash[]
static
Initial value:
= {
{ .handler = sorcery_memory_cache_cli_thrash , .summary = "Thrash a sorcery memory cache" ,},
}
static char * sorcery_memory_cache_cli_thrash(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 429 of file test_sorcery_memory_cache_thrash.c.

◆ mock_wizard

struct ast_sorcery_wizard mock_wizard
static
Initial value:
= {
.name = "mock",
.retrieve_id = mock_retrieve_id,
.update = mock_update,
}
static int mock_update(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating a sorcery object.
static void * mock_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving sorcery object by ID.

A mock sorcery wizard used for the stale test.

Definition at line 129 of file test_sorcery_memory_cache_thrash.c.