Asterisk - The Open Source Telephony Project  18.5.0
test_res_pjsip_session_caps.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2020, Sangoma Technologies Corporation
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 res_pjsip_session format caps tests
22  *
23  * \author George Joseph <[email protected]>
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>TEST_FRAMEWORK</depend>
29  <depend>pjproject</depend>
30  <depend>res_pjsip</depend>
31  <depend>res_pjsip_session</depend>
32  <support_level>core</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/test.h"
38 #include "asterisk/module.h"
39 #include "asterisk/res_pjsip.h"
40 #include "asterisk/utils.h"
41 #include "asterisk/format.h"
42 #include "asterisk/format_cap.h"
45 
46 static enum ast_test_result_state test_create_joint(struct ast_test *test, const char *local_string,
47  const char *remote_string, const char *pref_string, int is_outgoing, const char *expected_string,
48  enum ast_test_result_state expected_result)
49 {
53  struct ast_str *joint_str = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
54  const char *joint_string;
55  char *stripped_joint;
56  struct ast_flags codec_prefs;
57  int rc;
58  int i;
59 
60  ast_test_status_update(test, "Testing local: (%s), remote: (%s), pref: (%-12s), outgoing: (%s), expected: (%s) expected result: (%s)\n",
61  local_string, remote_string, pref_string, is_outgoing ? "yes" : "no ", expected_string,
62  expected_result == AST_TEST_PASS ? "PASS" : "FAIL");
63 
64  ast_test_validate(test, local != NULL && remote != NULL && joint != NULL);
65 
66  rc = ast_format_cap_update_by_allow_disallow(local, local_string, 1);
67  if (rc != 0) {
68  ast_test_status_update(test, " %sxpected Failure: Coulldn't parse local codecs (%s)\n",
69  expected_result == AST_TEST_FAIL ? "E" : "Une", local_string);
70  return expected_result == AST_TEST_FAIL ? AST_TEST_PASS : AST_TEST_FAIL;
71  }
72  rc = ast_format_cap_update_by_allow_disallow(remote, remote_string, 1);
73  if (rc != 0) {
74  ast_test_status_update(test, " %sxpected Failure: Coulldn't parse remote codecs (%s)\n",
75  expected_result == AST_TEST_FAIL ? "E" : "Une", remote_string);
76  return expected_result == AST_TEST_FAIL ? AST_TEST_PASS : AST_TEST_FAIL;
77  }
78 
79  rc = ast_sip_call_codec_str_to_pref(&codec_prefs, pref_string, is_outgoing);
80  if (rc != 0) {
81  ast_test_status_update(test, " %sxpected Failure: Invalid preference string incoming/outgoing combination.\n",
82  expected_result == AST_TEST_FAIL ? "E" : "Une");
83  return expected_result == AST_TEST_FAIL ? AST_TEST_PASS : AST_TEST_FAIL;
84  }
85 
86  joint = ast_sip_create_joint_call_cap(remote, local, AST_MEDIA_TYPE_AUDIO, codec_prefs);
87  if (joint == NULL) {
88  ast_test_status_update(test, " %sxpected Failure: No joint caps.\n",
89  expected_result == AST_TEST_FAIL ? "E" : "Une");
90  return expected_result == AST_TEST_FAIL ? AST_TEST_PASS : AST_TEST_FAIL;
91  }
92 
93  joint_string = ast_format_cap_get_names(joint, &joint_str);
94  stripped_joint = ast_str_truncate(joint_str, ast_str_strlen(joint_str) - 1) + 1;
95  for(i = 0; i <= strlen(stripped_joint); i++) {
96  if(stripped_joint[i] == '|') {
97  stripped_joint[i] = ',';
98  }
99  }
100 
101  if (!joint_string || strcmp(stripped_joint, expected_string) != 0) {
102  ast_test_status_update(test, " %sxpected Failure: Expected: (%s) Actual: (%s)\n",
103  expected_result == AST_TEST_FAIL ? "E" : "Une", expected_string, stripped_joint);
104  return expected_result == AST_TEST_FAIL ? AST_TEST_PASS : AST_TEST_FAIL;
105  }
106 
107  return AST_TEST_PASS;
108 }
109 
110 #define RUN_CREATE_JOINT(local, remote, pref, outgoing, expected, result) \
111 do { \
112  if (test_create_joint(test, local, remote, pref, outgoing, expected, result) != AST_TEST_PASS) { \
113  rc += 1; \
114  } \
115 } while (0)
116 
117 AST_TEST_DEFINE(low_level)
118 {
119  int rc = 0;
120 
121  switch (cmd) {
122  case TEST_INIT:
123  info->name = __func__;
124  info->category = "/res/res_pjsip_session/caps/";
125  info->summary = "Test res_pjsip_session_caps";
126  info->description = "Test res_pjsip_session_caps";
127  return AST_TEST_NOT_RUN;
128  case TEST_EXECUTE:
129  break;
130  }
131 
132  /* Incoming */
133 
134  ast_test_status_update(test, "Testing incoming expected pass\n");
135  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "local", 0, "alaw,g722", AST_TEST_PASS);
136  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "local_first", 0, "alaw", AST_TEST_PASS);
137  RUN_CREATE_JOINT("slin", "all", "local", 0, "slin", AST_TEST_PASS);
138  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "remote", 0, "g722,alaw", AST_TEST_PASS);
139  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "remote_first", 0, "g722", AST_TEST_PASS);
140  RUN_CREATE_JOINT("all", "slin", "remote_first", 0, "slin", AST_TEST_PASS);
141 
142  ast_test_status_update(test, "Testing incoming expected fail\n");
143  RUN_CREATE_JOINT("ulaw,alaw,g722", "g729", "local", 0, "", AST_TEST_FAIL);
144  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "local_merge", 0, "", AST_TEST_FAIL);
145  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,alaw,g729", "remote_merge", 0, "", AST_TEST_FAIL);
146 
147  ast_test_status_update(test, "Testing outgoing expected pass\n");
148  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "local", 1, "alaw,g722", AST_TEST_PASS);
149  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "local_first", 1, "alaw", AST_TEST_PASS);
150  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "local_merge", 1, "ulaw,alaw,g722", AST_TEST_PASS);
151  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "remote", 1, "g722,alaw", AST_TEST_PASS);
152  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "remote_first", 1, "g722", AST_TEST_PASS);
153  RUN_CREATE_JOINT("ulaw,alaw,g722", "g722,g729,alaw", "remote_merge", 1, "g722,alaw,ulaw", AST_TEST_PASS);
154  RUN_CREATE_JOINT("!all", "g722,g729,alaw", "remote_merge", 1, "nothing", AST_TEST_PASS);
155 
156  return rc >= 1 ? AST_TEST_FAIL : AST_TEST_PASS;
157 }
158 
159 static int load_module(void)
160 {
161  AST_TEST_REGISTER(low_level);
163 }
164 
165 static int unload_module(void)
166 {
167  AST_TEST_UNREGISTER(low_level);
168  return 0;
169 }
170 
171 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "res_pjsip_session caps test module",
172  .support_level = AST_MODULE_SUPPORT_CORE,
173  .load = load_module,
174  .unload = unload_module,
175  .requires = "res_pjsip_session",
176 );
int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int is_outgoing)
Convert a call codec preference string to preference flags.
Definition: res_pjsip.c:5557
Asterisk main include file. File version handling, generic pbx functions.
AST_TEST_DEFINE(low_level)
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
static int unload_module(void)
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
#define RUN_CREATE_JOINT(local, remote, pref, outgoing, expected, result)
Utility functions.
Media Format API.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
Format Capabilities API.
static enum ast_test_result_state test_create_joint(struct ast_test *test, const char *local_string, const char *remote_string, const char *pref_string, int is_outgoing, const char *expected_string, enum ast_test_result_state expected_result)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static int load_module(void)
def info(msg)
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
Structure used to handle boolean flags.
Definition: utils.h:199
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
Definition: test.c:65
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_format_cap * ast_sip_create_joint_call_cap(const struct ast_format_cap *remote, struct ast_format_cap *local, enum ast_media_type media_type, struct ast_flags codec_pref)
Create joint capabilities.
#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