Asterisk - The Open Source Telephony Project  21.4.1
test_aeap_transaction.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2021, Sangoma Technologies Corporation
5  *
6  * Kevin Harwell <kharwell@sangoma.com>
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 /*** MODULEINFO
20  <depend>TEST_FRAMEWORK</depend>
21  <depend>res_aeap</depend>
22  <support_level>core</support_level>
23  ***/
24 
25 #include "asterisk.h"
26 
27 #include <pthread.h>
28 
29 #include "asterisk/lock.h"
30 #include "asterisk/test.h"
31 #include "asterisk/module.h"
32 #include "asterisk/res_aeap.h"
34 
35 #include "../res/res_aeap/general.h"
36 #include "../res/res_aeap/transaction.h"
37 
38 #define CATEGORY "/res/aeap/transaction/"
39 
40 #define AEAP_TRANSACTION_ID "foo"
41 
42 static void handle_timeout(struct ast_aeap *aeap, struct ast_aeap_message *msg, void *obj)
43 {
44  int *passed = obj;
45 
46  ++*passed;
47 }
48 
49 static void *end_transaction(void *data)
50 {
51  /* Delay a second before ending transaction */
52  struct timespec delay = { 1, 0 };
53  int *passed = aeap_transaction_user_obj(data);
54 
55  while (nanosleep(&delay, &delay));
56 
57  ++*passed;
58  aeap_transaction_end(data, 0);
59 
60  return NULL;
61 }
62 
63 static enum ast_test_result_state exec(struct ast_test *test,
64  struct ast_aeap_tsx_params *params)
65 {
66  pthread_t thread_id = AST_PTHREADT_NULL;
67  struct ao2_container *tsxs = NULL;
68  struct aeap_transaction *tsx = NULL;
69  enum ast_test_result_state res = AST_TEST_FAIL;
70  int passed = 0;
71 
72  tsxs = aeap_transactions_create();
73  if (!tsxs) {
74  ast_test_status_update(test, "Failed to create transactions object\n");
75  goto exec_cleanup;
76  }
77 
78  params->wait = 1;
79  params->obj = &passed;
80 
81  tsx = aeap_transaction_create_and_add(tsxs, AEAP_TRANSACTION_ID, params, NULL);
82  if (!tsx) {
83  ast_test_status_update(test, "Failed to create transaction object\n");
84  goto exec_cleanup;
85  }
86 
87  if (ast_pthread_create(&thread_id, NULL, end_transaction, ao2_bump(tsx))) {
88  ast_test_status_update(test, "Failed to create response thread\n");
89  ao2_ref(tsx, -1);
90  goto exec_cleanup;
91  }
92 
93  if (aeap_transaction_start(tsx)) {
94  ast_test_status_update(test, "Failed to start transaction request\n");
95  goto exec_cleanup;
96  }
97 
98  if (passed == 1) {
99  res = AST_TEST_PASS;
100  }
101 
102 exec_cleanup:
103 
104  if (thread_id != AST_PTHREADT_NULL) {
105  pthread_cancel(thread_id);
106  pthread_join(thread_id, NULL);
107  }
108 
109  aeap_transaction_end(tsx, 0);
110  ao2_cleanup(tsxs);
111 
112  return res;
113 }
114 
115 AST_TEST_DEFINE(transaction_exec)
116 {
117  struct ast_aeap_tsx_params params = {
118  .timeout = 5000, /* Give plenty of time for test thread to end */
119  };
120 
121  switch (cmd) {
122  case TEST_INIT:
123  info->name = __func__;
124  info->explicit_only = 0;
125  info->category = CATEGORY;
126  info->summary = "test creating a basic AEAP transaction request";
127  info->description = info->summary;
128  return AST_TEST_NOT_RUN;
129  case TEST_EXECUTE:
130  break;
131  }
132 
133  return exec(test, &params);
134 }
135 
136 AST_TEST_DEFINE(transaction_exec_timeout)
137 {
138  struct ast_aeap_tsx_params params = {
139  .timeout = 100, /* Ensure timeout occurs before test thread ends */
140  .on_timeout = handle_timeout,
141  };
142 
143  switch (cmd) {
144  case TEST_INIT:
145  info->name = __func__;
146  info->explicit_only = 0;
147  info->category = CATEGORY;
148  info->summary = "test creating a AEAP transaction request that times out";
149  info->description = info->summary;
150  return AST_TEST_NOT_RUN;
151  case TEST_EXECUTE:
152  break;
153  }
154 
155  return exec(test, &params);
156 }
157 
158 static int load_module(void)
159 {
160  AST_TEST_REGISTER(transaction_exec);
161  AST_TEST_REGISTER(transaction_exec_timeout);
162 
164 }
165 
166 static int unload_module(void)
167 {
168  AST_TEST_UNREGISTER(transaction_exec_timeout);
169  AST_TEST_UNREGISTER(transaction_exec);
170 
171  return 0;
172 }
173 
174 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk External Application Protocol Transaction Tests",
175  .support_level = AST_MODULE_SUPPORT_CORE,
176  .load = load_module,
177  .unload = unload_module,
178  .requires = "res_aeap",
179 );
Asterisk External Application Protocol API.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
Asterisk External Application Protocol Message API.
Test Framework API.
Parameters to be used when sending a transaction based message.
Definition: res_aeap.h:331
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define CATEGORY
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Asterisk external application base message.
#define AST_TEST_DEFINE(hdr)
Definition: test.h:126
Generic container type.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Definition: aeap.c:47