Asterisk - The Open Source Telephony Project  18.5.0
test_named_lock.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2016, Fairview 5 Engineering, LLC
5  *
6  * George Joseph <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \brief Named Lock unit tests
22  *
23  * \author George Joseph <[email protected]>
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>TEST_FRAMEWORK</depend>
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 #include <signal.h>
34 
35 #include "asterisk/test.h"
36 #include "asterisk/utils.h"
37 #include "asterisk/module.h"
38 #include "asterisk/lock.h"
39 #include "asterisk/named_locks.h"
40 
41 static void *lock_thread(void *data)
42 {
44 
45  if (!lock) {
46  return NULL;
47  }
48 
49  ao2_lock(lock);
50  usleep(3000000);
51  ao2_unlock(lock);
52 
53  ast_named_lock_put(lock);
54 
55  return NULL;
56 }
57 
58 AST_TEST_DEFINE(named_lock_test)
59 {
61  struct ast_named_lock *lock1 = NULL;
62  struct ast_named_lock *lock2 = NULL;
63  pthread_t thread1;
64  pthread_t thread2;
65  struct timeval start_time;
66  int64_t duration;
67 
68  switch(cmd) {
69  case TEST_INIT:
70  info->name = "named_lock_test";
71  info->category = "/main/lock/";
72  info->summary = "Named Lock test";
73  info->description =
74  "Tests that named locks operate as expected";
75  return AST_TEST_NOT_RUN;
76  case TEST_EXECUTE:
77  break;
78  }
79 
80  ast_test_status_update(test, "This test should take about 3 seconds\n");
81 
82  /* 2 locks/threads to make sure they're independent */
83  ast_pthread_create(&thread1, NULL, lock_thread, "lock_1");
84  ast_pthread_create(&thread2, NULL, lock_thread, "lock_2");
85 
86  lock1 = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "lock_test", "lock_1");
87  ast_test_validate_cleanup(test, lock1 != NULL, res, fail);
88 
89  lock2 = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "lock_test", "lock_2");
90  ast_test_validate_cleanup(test, lock2 != NULL, res, fail);
91 
92  usleep(1000000);
93 
94  /* These should both fail */
95  if (!ao2_trylock(lock1)) {
96  ast_test_status_update(test, "ao2_trylock on lock1 succeeded when it should have failed\n");
97  ao2_unlock(lock1);
98  goto fail;
99  }
100 
101  if (!ao2_trylock(lock2)) {
102  ast_test_status_update(test, "ao2_trylock on lock2 succeeded when it should have failed\n");
103  ao2_unlock(lock2);
104  goto fail;
105  }
106 
107  start_time = ast_tvnow();
108 
109  /* These should both succeed eventually */
110  if (ao2_lock(lock1)) {
111  ast_test_status_update(test, "ao2_lock on lock1 failed\n");
112  goto fail;
113  }
114  ao2_unlock(lock1);
115 
116  if (ao2_lock(lock2)) {
117  ast_test_status_update(test, "ao2_lock on lock2 failed\n");
118  goto fail;
119  }
120  ao2_unlock(lock2);
121 
122  duration = ast_tvdiff_ms(ast_tvnow(), start_time);
123  ast_test_validate_cleanup(test, duration > 1500 && duration < 3500, res, fail);
124 
125  res = AST_TEST_PASS;
126 
127 fail:
128 
129  ast_named_lock_put(lock1);
130  ast_named_lock_put(lock2);
131 
132  pthread_join(thread1, NULL);
133  pthread_join(thread2, NULL);
134 
135  return res;
136 }
137 
138 
139 static int unload_module(void)
140 {
141  AST_TEST_UNREGISTER(named_lock_test);
142  return 0;
143 }
144 
145 static int load_module(void)
146 {
147  AST_TEST_REGISTER(named_lock_test);
149 }
150 
151 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Named Lock test module");
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ao2_unlock(a)
Definition: astobj2.h:730
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
static int load_module(void)
#define NULL
Definition: resample.c:96
Utility functions.
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_lock(a)
Definition: astobj2.h:718
Named Locks.
static void * lock_thread(void *data)
#define ao2_trylock(a)
Definition: astobj2.h:740
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static int unload_module(void)
def info(msg)
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
AST_TEST_DEFINE(named_lock_test)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
ast_test_result_state
Definition: test.h:200
#define ast_named_lock_get(lock_type, keyspace, key)
Geta named lock handle.
Definition: named_locks.h:83
#define ast_named_lock_put(lock)
Put a named lock handle away.
Definition: named_locks.h:93