diff --git a/tests/apps/mixmonitor_duplex/.gitignore b/tests/apps/mixmonitor_duplex/.gitignore new file mode 100644 index 000000000..0ac3d2b20 --- /dev/null +++ b/tests/apps/mixmonitor_duplex/.gitignore @@ -0,0 +1 @@ +testaudio*.raw diff --git a/tests/apps/mixmonitor_duplex/configs/ast1/extensions.conf b/tests/apps/mixmonitor_duplex/configs/ast1/extensions.conf new file mode 100644 index 000000000..f07d06e4c --- /dev/null +++ b/tests/apps/mixmonitor_duplex/configs/ast1/extensions.conf @@ -0,0 +1,30 @@ +[general] + +[globals] + +[listener] +exten => s,1,Answer() +exten => s,n,Echo() +exten => s,n,HangUp() + +[test1] +; play the first audio file and stop the monitor +; input audio is TALK_AUDIO_1 (ulaw recording) +exten => s,1,Answer() +exten => s,n,MixMonitor(${TESTAUDIO1},D) +exten => s,n,Playback(${TALK_AUDIO_1}) +exten => s,n,StopMixMonitor() +exten => s,n,HangUp() + +exten => h,1,UserEvent(test1,status: ${PLAYBACKSTATUS}) + +[test2] +; play the second audio file and stop the monitor +; input audio is TALK_AUDIO_2 (g722 recording) +exten => s,1,Answer() +exten => s,n,MixMonitor(${TESTAUDIO2},D) +exten => s,n,Playback(${TALK_AUDIO_2}) +exten => s,n,StopMixMonitor() +exten => s,n,HangUp() + +exten => h,1,UserEvent(test2,status: ${PLAYBACKSTATUS}) \ No newline at end of file diff --git a/tests/apps/mixmonitor_duplex/run-test b/tests/apps/mixmonitor_duplex/run-test new file mode 100755 index 000000000..7264adc7c --- /dev/null +++ b/tests/apps/mixmonitor_duplex/run-test @@ -0,0 +1,156 @@ +#!/usr/bin/env python +''' +Copyright (C) 2010-2015, Digium, Inc. +David Vossel +Matt Jordan +Richard Mudgett + +This program is free software, distributed under the terms of +the GNU General Public License Version 2. +''' + +import sys +import os +import math +import logging + +from twisted.internet import reactor + +from asterisk.test_case import TestCase + +testdir = "tests/apps/mixmonitor_duplex" + +LOGGER = logging.getLogger(__name__) + + +class MixMonitorTest(TestCase): + def __init__(self): + super(MixMonitorTest, self).__init__() + + # How many MixMonitor instances have ended, both must end before checking file sizes + self.mixmonitor_ended = 0 + + # Expect the file size of the output audio file that will come out to be ~41118 + # (Duplex is 2x the size) + # This is regardless of the input audio format, as the output is the same + # linear16 2 channel 8kHz + self.expectedfilesize = 41118 * 2 + self.filesizetolerance = 5000 * 2 + + self.audiofile1 = os.path.join(os.getcwd(), testdir + "/testaudio1") + self.audiofile2 = os.path.join(os.getcwd(), testdir + "/testaudio2") + + # Remove any output files from a previous run + self.unlink_file(self.audiofile1 + ".raw") + self.unlink_file(self.audiofile2 + ".raw") + + self.talkingaudio1 = os.path.join(os.getcwd(), testdir + "/sounds/talking-u") + self.talkingaudio2 = os.path.join(os.getcwd(), testdir + "/sounds/talking-g") + + self.create_asterisk() + + def unlink_file(self, filename): + if os.path.exists(filename): + os.unlink(filename) + + def check_file(self, name, filename): + if not os.path.exists(filename): + LOGGER.error(name + " does not exist.") + self.passed = False + return + + filesize = os.path.getsize(filename) + LOGGER.debug("%s size is %d." % (name, filesize)) + if math.fabs(filesize - self.expectedfilesize) > self.filesizetolerance: + # Fail: MixMonitor is not creating the correct + # file size we expect. + LOGGER.error(name + " size is not within the size tolerance.") + self.passed = False + + def state_mixmonitor_end(self, ami, event): + if event.get("state") != "MIXMONITOR_END": + return + + self.mixmonitor_ended += 1 + + if self.mixmonitor_ended != 2: + LOGGER.info("All MixMonitor applications have not yet ended.") + return + + self.passed = True + self.stop_reactor() + LOGGER.info("Checking MixMonitor recorded files...") + + self.check_file("audiofile1", self.audiofile1 + ".raw") + + self.check_file("audiofile2", self.audiofile2 + ".raw") + + if self.passed: + LOGGER.info("Test Passed... All audio files are correct.") + + def launch_test1(self): + LOGGER.info("Placing call to test1 exten") + self.ami.originate(channel="Local/s@listener", + context="test1", + exten="s", + priority="1") + + def launch_test2(self): + LOGGER.info("Placing call to test2 exten") + self.ami.originate(channel="Local/s@listener", + context="test2", + exten="s", + priority="1") + + def check_test1(self, ami, event): + LOGGER.info("Checking Userevent") + if event.get("userevent").lower() != "test1": + return + status = event.get("status") + LOGGER.debug("Status of test1 is %s" % (status)) + if status != "SUCCESS": + self.stop_reactor() + return + + self.ami.registerEvent("UserEvent", self.check_test2) + self.launch_test2() + + def check_test2(self, ami, event): + LOGGER.info("Checking Userevent") + if event.get("userevent").lower() != "test2": + return + status = event.get("status") + LOGGER.debug("Status of test2 is %s" % (status)) + if status != "SUCCESS": + self.stop_reactor() + return + + def ami_connect(self, ami): + self.ami = ami + self.ami.registerEvent("UserEvent", self.check_test1) + self.ami.registerEvent("TestEvent", self.state_mixmonitor_end) + + self.ami.setVar(channel="", variable="TESTAUDIO1", value=self.audiofile1) + self.ami.setVar(channel="", variable="TESTAUDIO2", value=self.audiofile2) + self.ami.setVar(channel="", variable="TALK_AUDIO_1", value=self.talkingaudio1) + self.ami.setVar(channel="", variable="TALK_AUDIO_2", value=self.talkingaudio2) + + self.launch_test1() + + def run(self): + self.create_ami_factory() + + +def main(): + test = MixMonitorTest() + reactor.run() + if test.passed: + return 0 + return 1 + + +if __name__ == "__main__": + sys.exit(main() or 0) + + +# vim:sw=4:ts=4:expandtab:textwidth=79 diff --git a/tests/apps/mixmonitor_duplex/sounds/talking-g.g722 b/tests/apps/mixmonitor_duplex/sounds/talking-g.g722 new file mode 100644 index 000000000..b62998031 --- /dev/null +++ b/tests/apps/mixmonitor_duplex/sounds/talking-g.g722 @@ -0,0 +1 @@ +zrvut{_ݹy{wwߙs{ߟr{{wv^r߲wZ~zxz{[{^vwzz{wvxxsz{߱rvs^z߹|~[^^xu߯|w|z߻[xv_{xzxx0ja=Op|IPo+4||Z[Wxw^\SyumnחZٟvtxXY_*qz\ZSS}vt+wz{RՔyu{޹rqz\ӕU^vx-lqwՕ6Zz^sltvt[V\ٙ{k_|;mmoX_TZn]ٺ=ٻtozXovwyYpsnX^؉~߻|pxq/QֻtWV_~uXz}{wfsUnҔ]Vz.uܐvR~z={Tq2t^\yY|Z{zkshtw\ם|{|𝘿tnq^}X|ܚuֵ9,_~X{ҙ\qvoYwptX|~;nלsuwZz_2r\Vؖz|yqzܯovp]WV=~jQno+qkq\W>6ڙzvn\\]mxړ^|yvn}ۻzUX^ۚkrj𶽿ZT~֔x{}/5}{^ږ޿ylklZuXRvxmxYut\V/mot{\]ٍٛ\{j_msUٜ[[Z~gtuXxV{^snrz\^nqk֙[wv_ٓ;gv~|Tz[domyY~Wڵsfust{^XرerW{[V~X׮hkwZU~ۼr׭hsmuw}\Zthr[{~]֗8X9,lXZUQZ]%\~hruܘU[[T\1ڮ-mnp3Z[^\T[[4g+x6\_Zu۰im}[W8'p~TY]|Vx(viqq2z]}Tڒ?q,u{]?Pݓvppjp8W~S\Xq-mo8[^XZ-lZ6UVZ~=Wnt/sus}ZU^_X>qk-4Zv7Q>UV{j}q{[_Rz[0woxq]Xwݝtk.z}^YTTomv8׿U]rm]]~T|m~츰r7V~ZYZxoڴm~8W\plڙw9|X~ܰr,rv۞y~ܖ]^6)ܱp<=uV^~*\t{[|XTk*p||>xU}]oݸi~2߼R_][m}fp4|[\kjo_v~Yw6kjZxۓt{ٛ^/r_mZ[[)\u{}U^.wkuX|T]V8nv||^]UY}q,owW_V^9X:lslppژ\XpywysU^ؕZW]j~fzW\}ݗXU_=yyf}S;ո+s]uUWiyTVuߗ|p^T^_upwx6rٜ{3i[{ozYw^i0j|~ޙon]Zݎu}o|kTy{ݕ\prnwr_}Vӕ30}P|~so{{W1}x}{ޏtqm^u_]\_+ntw?zԞ~S1[z|n[]l5zXrUּlVXm^vxno|?ُ^;tlt_~Sٽ|jk}}pՙW^yv1qzzV_Ux|ߵ|rޟ2}|X}nvݷ_;no^rj?3Q]qqotVV>Zߖmu}nvyޝY^?w}m_rsySҕz^읜jmpuz֞RՑ_=ntSX?x؝w}ZܳwjvVݕۑsxZckw^w~rv|q#;ZwXؗyx]{4еd[i]xS4ۿ^u}Y^̪c5sz_z^z4}[RޔWcvZ_s~=8Vd9~}|Z6Xۖzyx{ٝ8ղ}pV]Zt~tS\ޙ\f}\}}ٟ^vݗ[xYSݚ7X YtWߛ]\yvzvY޼{а`6~^vZ_]\u{]z_]ܝܑUdrx|TTY_[xz}QWd}m|qQ{y~߷9SۜPVw3~_ڔ߾}}uuy۽]Yݺ^7wuy\wzߚ~r~Uߘ{fivwYW^^w_ܽz\]ە֒|2`r[rvWWq^y~Z\wbo}~Zx[W_t{^||Wrt"ou|\؛w~۶vXZ_߻Y|zx4loX\|{]Z}|ux~t!ou_x=V۝uZՕ^r|{ lz7_VXZzZ~۝|vw}"lx{v_~ٞ_z^w{^_&hYRھ_wZ{yr\bs6P՘{ur_~z~}t޾|uyr]z֖~۷~s~~_}u}nq}Κ|ܛvqxؖzY|xݜ{iyWRֿyw{]9WxznqvW֒y޹^yZz_YspYdsv~V[{9v{zٚz}t[zޝZ[4t|_yxw_}~r{zZ<_syߝ]_{|Yywyf_T_\|X\ٻzt^umk||~VS޿xsY|~zv^}՗~oe븵Y}_RכY_x^\^xݝzspvyVX^u|{_z{ztx4֎Z|Yv\{Y||z}nvpvTޟ\q_Wz]xumkg}\ُ}ޔ\Yz}P^utscw_t|[[ٙwܛ\|Լvۙk(glts_R]_\ڞVp3_wtnl{pp\Z]םz|{tם_n0vt+2tn_x\\W\~\|szvWrxoom֬]\}ܙ|xyn^W|u۲~zuwp_tܿm|UQ{2Wqo۶Yrrz9m||}[}TTݹWxspxxn_w|pZv\^wqnp]Xwo,xVm[~{p_r[-YzSlxxr7~~\ڕ~r[8ڰo2כ8{Tyjy:q~tӔyR\{wkiv~u~:t[Rppכt{{VV~־ޖupnsۼ_Zߜr[vtu|v]S}rﲚos|yYZ^os߼^z}tܽ܍vy߲rۖ޳}:ޜؘTٙzyܚzޖv؛WZy|y~۽^qqyqxݝv^vZz|s߾{ݷyvk__ڳ_r{u^x}޴ulxvZwrs{{ܕ9w\ߴw^Z^YݛڼVܚxtz{ڹx[xq^_|߳{۝tu[y׼]uwڼYݟwty޾~|t؝Xڝy؟UnߟXtyvrx^߾_~u~[tstz^x_p׻{ۼs^۸w޻|x|un{ZptxqWqyy޲{q_v߸Xz~nصڟmXܙssqwWnz[vߞwzԔ|\sUtoySnxxVߚqu}qrޙ}uv^޾uq[lq\up{wovugY؜{*Wїk5ln^}q^-ۓ>m3s[tRt[ٟl]8|]Sw\ѕxГ\&ؾv&pxr{W}YWR_|UvRje3/owWS|}Zݼ^{^yewwp:TpU]YW\wwrmx_S]8_t_oqqey[1<|YUјZw]ܗT})y}ڻ|Swwޔy?{Uoo[xWzzV{ܶqTwёy2>^^MܚqZ^۹{u3z|wۼw}_X؛Ywwvޖ<~pWܛwԓ{%r^Wt٘YޘzwXv֛y\}xޔ^[Yv}xwٕپ|ޘrdi1}Xߙ]y_ڷvz{TuvqX]^Xםxzs]nsZޜ]]^yo^ؔ^ݶu뛯o~]ߝ^v~[wmqڛ6v^~xW}yxܺrVr8k\z߽tQۺyzߜZ2qg/qZo~uo9rssz|^yZXy_𺜝wUkqU5yv]w{{ݞW+5Zy\r[v^ysx~xtN~uן|x4Z2XЕQ;Tcnq^~\]z>vVn߯kmr~V|֞yxv-hzq}[X[_6Qyyp(vWWU|1t.kkyؓ\y1Zvrqlku\ZVvZiwj|U[ԑ{|;{ٷ*iz\}Ԕ]ܑx~x&x)1XwZYXS^YV[8u(nz|y\]ۗ]:|+Ymkz_v~]VXۚ:xzvj+_zr}Z]YYV~޷fiq~tVْܖ{Z)o(p^\<ݗ>~V|i-x_\9_|{hpYoz}Z9ٖ~Z}\jl*zx|}^\Z\zipn{<YY|^r\yk+rt{^ݕ8RZ|1ko2[ܐ۶rfmtZV]v=yoi^W|V~=yjt^w~^Y՗ٚhvlootUTXW|lp*jrz8][ޖz,-Ꞵ~z|]YXYYwn,us~_W(i׵;XWךXfyls|[X8l+ovqwS}ԕ+nxtw_yTVX/ۯ]w{_>T{w}\_~[ؒuutq_z~ܖyu^~ݓޘ\y{qZ_rٗnzvvp_Օ_ߕoy~ޗ\wyzrtܔtt{szޛusۗ[ٟvyڹ}{w׽pݾwߞޝݲxVW_zᄊy]Y߶Y|ݸT]v{ߛVTn{tjr]W}svrs4Uْw}Xޛ\oz۾ښw~~Y\vporxptur{um.p[{^ۚXۘo۴lZVq\xޕT-vWqWt߳X|U[ݓpm{rqpxZݓS_s*|r~ZxyٚVZ~w[}uZ_޷}YUZz[ݿV6{}W^ם}~^Xՙ_["/~W}{}ܼZX|\ߢ4۹|[ٙY}^V7bqp]tY^W\\_v}/d_Z[ޜ[YZ~t٘YYr1|{ftyՖXTs_3utvޟYx{ܚwp}r4\>Oxt\Sy]|][rYyx{kڿt/|Qvs{srwֿyZszlXqrmv7VߟY{]_|~oҜ߱qx|rsurߕ}Tyn_^?w=j^Yz֛=ݴ~t|xwXxi{k|tzX֐vqvWԖ}uxu\ޗp]pu{{_y\\Yw]xtt:k(yٟv\ܞ՝t\m߸^}ԕ-p2r<^^t}~|Z׽knuyrnrۜrot;Ztqopޕ4UYnv{{tZxqnqrVޕ]q|{y~wVpywt[v|і{.q9Wqu\mvZ1ysy~w|urYS:/.szb[|xx{Yx_\yxzJVpx+lYYۜ\TXUݼvuxbu^[ܽ_ZY_v%}]٘|wx<Ԗڵ{bzYw\߳t|]|{޹^wݗx;~c<~ޕz{W||z~]ycu9zqܝT|}z{|c5]~T|4^]yy__YXv#rv޺sxTt߻\QXe6_|o]u{X~W]y}qkrehw9_r;Yxzؕ\op"sz>X߲{\~R^y[4V|}u7YuS|}ڜ~zY|qcw[|[t}ߖؚ|]^u7ey]Oy}YݜW޼wybz8t~߽?{q_avz|}۔t\ߝzvq2a]t^vYUwYZܜ~ޝ]m\"uut|՟}yz>yܸtey[|w_]z\nnzy{w_w^ߚ|Zzxi^{ܻY]^Wڝ]pyS]zݙT\zi3X[xYН]]zp_\s~~۝|W٘ptkr/uW{\\r]z[՗q~{}Zvlyrx_ז{xX{wkqn]}\~}^[Zږ~li߻lx]ֲX_rpWtoZyZXxؙ߽\ty^޾rޞ\\^wiqm|~Vּ^~Ә޿Xjq/qҺ|]Y}VښWtlv(^ZU~>s޴nn1|ܒ][zZߛZٸksxvV^xۜ{֘q~tm.՛_[ky^^pmtߺl\u\՟||wݑWzqpnp[pߒuY՛y~ufn{Xޔu[ߕ[yqy;}uwӿZXo}{xm[z>ۚ__Szzݺsvzv\֗wzsqrktnnz]t_ߑ[vyqXrwtqxp[pzq1~qy0LKjv{zzz|z0}~q\Ԗ}]q[|^x޻Tn[y2۞tf_6k5ZttZr=}6زnvWwrtv[{_ۖwz9wsw0qw]W|kYUk׾r}vwtwzsؚ/Ԛ_9j{Uvy|߼ޑ^Vz-pژRts^rn{ޖf~Xx۔Tl~qݜxuou[nv:vXx|(zor[vٚ<7ܺtruZ5p[p]5u:iytYxYqXܻz[Wݛ~loٓӱZtnڟ0Yxؼ_1xx׺:6tZ\W|w֘}[y}uwtYWsټyۼq]x/uUUwxh{vpy[|[}޸7tot|puv{^U\ג|xk-ږSR_zws6g-q|~vWח]XZ5w}\^^z!yrZ\؏[^^3}X9՛jZtzSܓ~ZpqrTU]z)tZT{؜lt7޼ۗXX8xyY}ӟ\Qr~pt_xXԛ_x&߾rS[7{Q~\=}_~yr_R޼u\n9yYzz[xXqq]ZwXyӘq^z_|zdorZ[_q׸p1[wkz8ߺxޙ[|t_xq_ޔvysot{YQܿtԼm~s߻>WtxuZym:~5߻pt\ܒr~ww[y>S}ypyn{ts~[ZT}twrzޞYY~ߝ~uus\׿w^qsܖ_ڜ_s]ZޟUZ]|v\Y|߼u~\\Zsڼrzzߵu^ߵ|~޶z{{ݺzYz{{m&!L.7um0Mtݓ6~pnow[v5\[ut{yZ)U\_\xtVvӞsXt{2{p6wptnwrؔq^U|ّ\_Uڸ\xzt&l2r[VW[S{}~%nu\U{؟uwr~UW^4ksz{tYY[^xxzlZWZzwsdUhuڼQwQu۾X_\u{x!u;yZk{v\Y^ظpv!Y8]r]^^TyX{YٷsWr|ټڶ~WwVݗwYuu/br[t;w{qWX^T[߻vUwޟ_8w4m=]vݙuTߛW߾uӝZ\xYۚZqb}xuߴ[uWV{xX՛Z9ױyqfguWuޘ{_Q|՛^\v^ݘ~}՘r-bpz|0UVs~|ߙ^|ܚ~;޸updhz4[ݘ~z\Y\[ݔznr$y{[Z6Q\ݕY^wt5$mt|/ۚyYwzZ|_oyy}#]WzZ߷Z}ܼ~ݗ]tvs4촳d\}r^]w{Xu[_ڵvs#9y]\[w{[z?mmt:yUu_{^{xVs֯yW__V^^߼tZ޺}tt3{}?[ܞZ}ߟ|{ޙqu\yWڴx^y\s\}wzz\l[tr[ZRu_Y޷^ysss[{p^V\[]{Z_sy}~_ۛuY.^}phz]՟X]ܹyus}ؒww}ۗz^sݻzxMqݘU~Xztݶs~~_߯lktXܘWvyv[|w~׶[޲yn[wrwrSYޗto~߲~WqpmZםtwܽ_xT]u_w{ݚs;ٲ]vX{[uwyۖӽvy{ury~_urmmT_߼t|zyzt~~Xx߰k_|VҺ[Y۽ٛ}Xuxq_\xmy_ZޞV~xysۮy^޺y{uw߼Xϟw{]xޚu{vv^[x~יِ^Wzݖwprzٹ]~nwxЛS}{մ{x[޶p{Wܞ^}xߟovwW\T7ٚxU~_x^ytޝr]؞_ݝ^ڶ|_߸q]\p^|ߗxܘS؝u{lz|ys޶xܛXڜ\styvޝ[Vvt{zw4vwۛ؞wڼ~{xq|{wx߻uur_ߴu~ןtޜ[u{xټwؼZvoXݜzU۷~uusvwrZܜt{p~~^{t{^^~xvwz|p]|xv|t^ttָu|qu{ryv޶v \ No newline at end of file diff --git a/tests/apps/mixmonitor_duplex/sounds/talking-u.ulaw b/tests/apps/mixmonitor_duplex/sounds/talking-u.ulaw new file mode 100644 index 000000000..7c6e578f2 --- /dev/null +++ b/tests/apps/mixmonitor_duplex/sounds/talking-u.ulaw @@ -0,0 +1 @@ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|xgmmsZG:2/2:aóSG<955887:?Njź?0+((),.16;E]V>317JɲNA:6/,(%#%*4L˻UFMñfUI?7.)$!"(2JͺºN;2-*)(),0;Ia¿|̾fB81.,+++.19D]ſ~jhj̽i@4.,,-/3338@U{\XZm?2--/43/.18AV`OHGNoϽV:0/3970.17931259>KZoZOKKOWiƺI??A=952348CHJOSQ\fayiͿ]LC<;87768::<=?BHOX]eȾcOF?;87553479;>DGR\ļhME@<754333589=GO]naOB<:73324678;?IXZƿgSJ=863442778>>GN[g[K?;83344369;>?GKOm˾WIA8755339869>?LNW˿`MB=:77699:<:>BQcʽ^PB<75589:;>AAFLĽTE<862201:=AEE_Ȼ^KF>71-+*)+/5:CNiӾoQH=4,'%%'),/7?VѾS=0*&&&'*-38F]?1*&$#$(-6Agƺo@5,(%"!#'/>frG;2+'" "&.9H̺Y?70+($"$*6CֹP>2,'&%$%)2CǰL6,*('$!%,6A˱v?1+*'$#$*28MA6-+&"#$&+1=±SB4*'$%##)/4_M9,*&$$$)/1XH6,*$"$$(/1\D7,)$"$#(/0ŨH4,)#"%#)/2μ¤H2+*!"%#)-6ζ>1-'"&$#,,D᫦V9/,#$&"(-/ο>6,'#%##++B﬩a=/-$%&!(+0nK4.'$'"%*+VuϪ\;/+$&$#)*=u@2.%&%!((6^\I3/'&%"&'2MP`61)&&"&&/GHY;2)(&#&&0CG];3*)&$'&2?FR=2)*%%&&6=MJ=/)*$%&'8=]G>.+)#'%*::ẼF>,-(%(%.9>ɾ]I6,-&&''2;ILB0++%&')7Ӽ]I4-,'&'(/=IļO>/-)&&&*6@rL6-+'&%',9Eٹ^E2-*'&&)/=LɸU>.-)&&&)2@YM9.,(&&'+6Fq^L4-,'&&',:IܷWH1-+'&&',=GڵSI1,+&%&'-=GҴLH2++'%&',>FڲNF5++'$&&*=G峳QH9++($%')8JZ??,)+#%''1KND?2)*'"''*EO];=+'+#"((1_YC96(()"$*)gI4,*%%%'+.:\J=/*(%&'+.8G൴A7.+'%)+,4AN洯I5.-*&+//9JlݾpY?5//-,19=JƲ¿WYP>4786:@OZbǾo[LAFDACIRLT_^poZ[RBBHIMFHMMLNŽUIIH>?ABA>ION`ƿnLFFEB<=FB>FP_pžOBFI@==CD@MVOmɾ^LMC>B:CF>DLYPj¿ɿIHL>>>BCIMBOhiʿnXG??A?;>>?=>@I@UhbVPHBFE@FKQQPYgd|YJOiLHJM[MKZ~YsZLTNLJINMRM^waX_]JHMKSNOnnlj]OP[^QTdfyi[cVZ]V[hmlxxjpipmkbdv|wiqoyozbd[OZjqZ\hhYg[rhTR\^JPWSdhix\ifWSY[\MRhklYng~k]UOLIBEL@HEFp_Yӿ[SOG@<98;84;AEHGOoνR=::7456:;=>CONNDA@ZR;1.,)*,5=AJQbQMONB>˰S5*'''&'.BeNHC3?Y8*%&&&',>ֹE?;5,6G2%!'(*,5^T7/..,&=RBA2)!#,5=A縭Z?/+,/.,1764.)%+9Qmzǵ{SM>1-,3663VE1112+)0BƹUH=8/./:?>9OK0,-/-+-:žNNMH:3/05;==9֦>.((-.03BֹiF<[D7,).6@FLcͼcOI@>F]iNIJ[R@;fB5*'*1@TŹwK@>=?JckLIHA;54JE8,''+8O^?::<;644?^lRC>ImYPKG>:8>A:5/09KWA>CXz]TNHB=?GVfy˱~L@F?90,-4D_ºQEFSihQF?BGMMJFLZȴWJLD;/,,3GǾsE9:ATl\NA@CMSTMOdŴQ=<97/-,/;P\E>?IUc^TLMP_zֽN:8772/.0:N]D::>J\mhYTZz~ƶN;<<@=844966;E]rXJHHOXcd^ZX_ol[X]gнnMGEA<7338AX~YKHINUYXUV[kk_]^bjٿPJHD<6116?TmNDACKR]^_]exi[YZ\iܿPLIC<5118AY[MHHLPYZ][ahwc_X[V_³XOKE<40/5=NteOKJMPVWY[`kz~hWRRUpϺ^TI@82/17?OcaUMMMPUX]^cdn{t]TQUoκm[KA94139@LZ{dSMNSZ\[WSTYfc\YV[wͺtcOD9414:BNZ{WNNSWXPLJJO]qleoӿybWJ=7248?KZwdUOUYZQKIIMVfnjm˼_K?:89<@GN[kfhh_PKGHKQZkºwVF@>>ADHKSYi~wimlyl\QPV[_gtĿmXNGDFGIKOSTXchjjkejikl^XX[]cow_TLIFFGHKLNU^cfmfh{nsk^[djihj~osp_TOKIGGIIKMPYZ_ksnxgfsnedde]hjevgb[KIIIIILNMRWU]^\]_dodgissh]\_[TSZOJQWXONSXZQ[f^]tsl~}zxo}tZX]UNSTNVWN[X`fdwkxdyx~v[jz^V`dVS]e_]gjemyrsq|ya|fn~}uuklcgfgpc^|h^xjnv|gvkymjQgigmu`lisvolswf}XZz__llmi~}zffi]fijb^mlxVpsntrfdo{mjwX~t_ou|}r_ae`jhZ]^]^ocqznsxjznz~l_fjjv|snw_kaho_xvilkjqlwpsflsk]_m~{hh}sgjntor{d`bvzyt}zljwkdhifglspoywqxsokouqru{{u}z~x}{}xknzuedtumuwrtnryo~zsxz{|z{rs{uqoutqwz|vv}zy}x~xutvusvyzstzxxy~vrsqoqqv|ru|wsv|}xrsssrruutpswy~}~~}}z{zzyxy|}}~~|~~~~}pzyts|t|~x~}rzzwtuuwsv}zzz~zr{~|w|~~|{yuwtzzqzzw}{}~}|}}}|}~{|||~~|{|yz|yxuvvxxz}{~~~|xzywwxxz|~~~~~~}||}{{~~}|{}~|{|zy{}}zz{yy{{{}}~}}|}}|~}~}~}~{xxy{yz{{||~~|{}~~~}||}~~}|{||{||{{{{{{|~~}}~~}||}~~~}}||}~~~~~|{|{{zyyzz{}~~~}|{{z{||||~~}||||{{{{|||~~~~~}}|{|||{zz|~~~}}}~~~~}{{{}|z{|{||~~~}||{|~~|~yyyy|{{~~||yz|yx}zy|{~{v|}~ywz}tr~tlk|ks~rpqldusmjy{oqw{vxn{w|y~mw{tnou{wsronrvkpvyvxfzkugjmkxnjVcdfg\]s`^[wpyjlonrXdXdYYOJPYD\T|mKVeZoLOOYbNPTGOLPӼjVo_>DrRWM;?YYDSN[WMD\{jķȺNA;3;C:2;MH7EOGj?筪B;MW;>S2-?G7?UMMUƸJkSMJa80/87=YYe_F9@B849l|IFdGɯE=V̾N?.(.GPMn`I;>JA<><9=fAG|H.;ʺPD2&(>^WjcJA<=EJ:3?[OjֽJ46]X;.+-4L~E49==>=UI;C\C69hǶM15W?/')9E/1?XNDOL:39෥O41JM5($-L_:04DUMKUH84@۱9-5J0%(7NսC117>Fb_?38MʩR/);̽`O.'+8Z׸A./67>r[44?hƥK**@d.(,;KoY7611:MjE9=O˪e0(0LA..4CRٹC9867:DVP?A`ֲ=(*;RSZb:36?@OɽWB?:55>XN>Etҿ.'/<<;ZO;;DD=QMOJ>67FRJDZŪ8'+54/9FF\OAWtGD_Y>9CfSI俺:4:<4/8A?>?NXN^XNJIOzĿhRMOYgcZUOKGHN\y\UV^mk]YUX]f~ticbm~noyvi_ZQLKLKIJMNP[yold\XSOKHIJIIIIKLQX`ysgbYWXTPPOORW[_fmrmihkotyolncfme_]bhcloqy{lhqj^\^aY\defch_]ak|ooa`WVQVXRcekcW]^Y^kozqa\[[XW^ecXXW\]d}ok[^XWT^a[aX]m^l}yIpQ_qaabX~_t{dkijU[l@N{OIP^vcYʾkIME;:835:1:L?IbvWF1//)),,.6<@CbbV}SǷE41,&)(&+/2>IT۽ĭD71)(+$(/+7D>gbH9/,+)'+--<=Fnʿ_I5/.+)+,-49;MPͿO;4/-++--29:DITftƿV:20+)+),01:>G_~ιA64,++(,..7:AR_߻J:4-+))**./7BKϸôL>5/,)))*-.4;FR_ú[?60,*)(**.17?KVȺlG94-+*(*+-16>GPZ@72-**)*+-2:@IóQ<7.,*(*(,.3=@Yȹi?:0,+&((*.1:?OȺeB=/.*')(+-18=YɶMB5/-()(*,.59AñbH9/.(((',-0:=vʲM;0.('''*,.8<^DzM92-('&(+,/6=ܿdA7/*(&((+-19NʵF;0+*'((*,/7IoзG;/,(&('),.9Vj\F8.,(')(*-/BURB2/,(*)),-:LOWG7/-**++,/;IXüQG50-+++--2FJǿ]A=/-,,*,/-5457>>ADGLVkhUMHDB@BEHLS]xi^XSONOOQVZ_irqifcaa_^b_afdglny|jea\\\Y\]]dlrrg`[YXUWXW]afyqgc^[\ZY[[[_bhq}wk`\YUUUUXZ^dl}ne]YVTTUVY\ck{{nc]ZWVUVWY^dolb^ZYXWXZ\_go||rjd`][ZXZ]`ho~~xsmkifgghmopy~wrokjigikknrqw}wspopmjkheecefeilnwog`[XWUSONOST[nlZQJE@><;:9;=BMbýnZPJDA>=;98767:>EOxƽyZOLJGFDB@=<:86569;840/04:Ei̽QGCCBCGJMNMMHA=83/./29EqɼpNFDEDEJNRTTRLC=83/--.4=P־bMFDEFGLRWXVRLB<73/--.1:Kø^MHEFFHLPQQNKE=9630/./3;MùkPHB??@AEILMKIE?<:876679AFJJIJIECCDEDDEEFJVyVMGA???@CINRTSTRNLKKIFDB@?@EO~ļ_OJD@?BEIMT_ic_^YOKJHC?=<;:;?Ilļ`VPLHGJMORYa]UPNJDA@><:8889<;=<:9:=?COڿOLOHA?F\dNYtP;156/-0B;17NpT[պ\3JG7A7<~cC9]\MP<--..7AEM~ȼĩ?=o>0~=9EN;+:l[PquG@<.,6:HyW .:]q=586:?4,D̸H59>76MoPbI<\~꼚U'1>>5-6>9/NC=?NNHxq<I7/@m`<>ھCA`[9//OD=_J@k8Y9/;O<1>w]W?GaG@US?2/NSPޱC6Jf=ˮX1.Bi?8H]IRPPPZNEFD?69IU_ٸN3>LƻHCF`oPn[OI?<9=OTR޷Q4:S=-5^U@FUͼJFKPOPqJ?><9;J[­;2@TҸZ8.=mIAKc»FAF[_IVnM=68??Kȳe/5迿>-1NWFHY˻O@CJXQQN=86=HI\ư]59sx?..HcFF\κK>?G[VNM=51>SPq>2=߽Y8-1INEOýC;?N_\]lF838ATƳl6:Z㾼?/,JI8>T^?1/9DAI׽K46?BEUui?7=EK𿦗@;GZYN޸:03>E@LӽG57=?DPuYA;<@Xή?EIIG]G2/9A?CZ<9;;>J\m\NF>;GܷTKI?]·E:8:978=JWUSQF>?QլI:;SúL87;;:DĿS=768:>I_wJ>AWٮP73C̾H:;>:7?aM>:989>NvLK[bs_91=F9;?=:>TJ?=<:;A\tpufy<3:WN=:87?ZdkiKA@I\rдB:>IQKC@A<88>GLHMltSKHMg{bֹWMUz^C968;98@NWX^[PVn`¾tXH@<>A@ENSYb^ba\_je]uoei]midsiffbOLOOKL]c}mpm~{cqT\xxmlh_dOWQNNNW`\[fm]`hYkkw_hea[PRYUQMXTKNX\i^_a]ZopU_fQGT]WORnw]\cskz\irutnphko\]pZUd^]d^zpaU]tuxro^VsV[aRMNU[_gwXhe\h`TYWl^eii_\ymi~w{fklY\ton{ox}|}bPT[cxu}~|u^d\^uxcpdchqumvyn_pkXf[_xm_zj[x_ogydkegm_pm}aj}t|uopgbme`^Ymp^|w{lwuocoaOeX^]`e^meifnxvsqomh|olpp|`[^ebqfy{lifzjXZen|fvvpkgmw]z_\qnpyp{gj\jcXX\bup^i]haJKmesS`u_\tQWYO]zmb]\|f]OJ=9C=_SOG14OF4@M66DκdQKC327JfOJgݪ\B9=ǭR21F96=kD?G959RNEEXި>9=ųL19O>>BݿM>@L>:U>AHG>=>D>97:M;2GG;WN=4?k?CXK?7:=;64B\¥H8<dzb9>KD:=mL?EF@86<=?=A_N7?ĸNavB=@TʱN;^JGIG>7>HTI<=>C=777?CDLf˾O>XɻP>;?<6:BXTC<=512H\WKLοM=X̿<9>L=66BUA609@=77IOFº<=\J<_wLZͽR:Fq@=AN>3/4??=:?MH?9AWon\»H>MyL==FI:208@@>;AEB=>LZmdɿCGNhD?ANE:329<<:GNfȽTOMTVFBDIF<759;;<=@?>>ENT_w½YWWhTHCBF@<87::;:=?=>@ILP[ozf[\MDA?A?=<9;;<<=>=?AGKO``ZLA?=AB??=>==>=>>>BDILWiĻ^^MDA>@DCC@??>=====>CFCD@?>:;:<=@BDDFE@=::::9;>?CGWȺqN@>==>@DDGC><:::;;>BIMTȽRHA?>?CDEGHGDCBA@????@EM]ǼcNEA@@@@BA@?>=;:::9:;>GWǺWHA>=>???@?>>=;::99:=>?@BCB@?=;:9878;?J_ԿfLC>==>?@AA@?=<:87668@AA@>=;976569>I^ѽdLB><<<=>@BB@><986457;BPnND><;;<>?@A@><9754469?NùnNC><<<<>??@?>=:865469?LŹnMC=;;;<>?ABA?>;975469=ItȺQE>;:<=>?AB@?=;976568?ABBA>;976557;BShMB=::;<=>@BA?=;97767;ANoͽZI?;99:;=?@BB@><::88:>FSʼWG>:89:;<>@BCB?=<<;;?@BB@>==<<=@HT}úyPD=:99:;>D????>=>??>@KZǼXJA;99;=<=@DDBBCDCAAEJP[ȾsYK@>>?>=>ABA@BECBBDFIMYyǽoXKA>>>>>?BAAACEDEGILNYnt[LEEEB??DDDDGLMJLR]hhniVPMIGFIKKLOUPNPWWV\_kxm]UOOOMNPQOORRSPOX^^ilvx~snn_XSSWXVSUNNOMPSQVYnzoa]Z]VU[P[MUZOa[akv[NTNQ]n{i^gfbei[f^^\at]cne\Zlrihkh`wghi^k^\c^TUSMmc[Zhd|g|^Zft^rcvZ^wxlyYYj_dthbhWg~l_vm`nvh^ZsqX[r`jqxefewofrh[`U{b[nY{Wtqdoyk|bgZj|yd\gllVpjcql}}wgknYvtl~nr^loqi]ncW`m^d|Wd[nhkgf}\jpgtVeUndmnwrj_`Ykl_m_f{dxgnl\[XdRkl`Vk]_eV]Yak\j_nZtVk_ZnX^P{ddmbvmm[]m]_RlU\tluOjgoY^l[KQypoogk\i_wiw[vY{gs[gqirlro{Xfde|cg`fvj^tjh}koo`znd{njwfhjvi~ns}rfztbqm_byi_zsmakq~~poln^[]`ina[ST^XRjľQB;61022359?GOs¿R:55,)*,//7K\hUPTGOWҬN2.-$!$',,8n;iC29;79ͫ4*+( &-18渳P5*',0-0FӺLA>4/2:@FWYF?90.1306@P[ûVE<78@GTpľeZC536205>IOOB8346:ADQUcO=885//48;Cj^OG?>DIFITZZe¸O=:5../48>\ƿ}TE<::;;;?HOsɿN??93039;?Lg[LKIFDAEFHM]ƾYC=:7427=A?>BJSOX¿eOJKHA@BGHEHNOIKXX[TZ_adiq{ma\^cONNLLHKLLMPX^TQW_m`h}n[g``]f~VfZWWMIKKJO\[US^s\hwuR~ZxgyVS\VI[NIMITKI[Xkk^]z]hwk[MNQQWN_HT[V{e\V\YinYq_`i]ZZNM_yOkml}TxoHkK]dm}wWi~r]Oexlkl`W[Zmq\_ve[ylb^\rp}dc_\ejV]]WZl|txmb_}k{Zjfm||pj]eoenqonjqvnm}b{lxmmxvoqiv~}i{~yzafxziv~nzllumqlqm|||uyqxumxvlqwo{vzklyo}t~vuwrnoqnihijnmowy|}~{vutttrsrqrpppqsruvv|}~~}}~}xzxvtuustvwzz~~}{wvtrrqqpooptvwz{~|zzyvvvtqqrtuvx{z}~}}}}||||}|}yyzy{z{|{|}}~||}~~}}}{}}{ywuuuuwwxy|}|}~~~~~~~~}~}~~}}zxyzyyy{z|~}||z{{ywyyy{~`wNEeSgl{LBfaXjWSWjǼ^FD>TFVPDm{inTTWQGUv[WqqwZ~PS\OVoI[O~`{[}U_cXIQXHEK^O=N\JMOnnսkN?=5-0/.2:EJn`SKIBJNVL=5/+(-./8KοG641//5AG[ºV;433,0<;>T˹^I4//./4>DJkŽI8798/:IBFahKG>32768DZWRuɿB95=;4FOJJ`\_N?F?8885GK=Qm`JJcOJSWBKI?;=FCIONHDOX̾IMMB;HUIYbG:AIEG^ZHLF=68>E<:OiUGALBCXG?lOf{L6/9><;Qd_<5=HC=J\LBAIMMl˽PKxAGGE3/:CE=JcL`O>=MSE?CLIJRnſY==l`C?BO@77=I@Eai]YJ>7:AGFDOeY;:Z[DALI739GICQeLIB=7:EVf[dƼY@DV>=E<62:DEEJmwXSROF?EQhgjyùN=G{K<=C?86>JLLW_MEGFEISmfÿ{OBNliL>>?>87=FMKUo|^O\b[MK\o{fgͿmnNIUzTA=>A=;=Jgj\UV[ZSPOUZ^gk¼__ozTG?@>=>BMSYTW[X[YZZW[Z_ektoo~¿rq}iOGEFGEGKQVTTU[YSW\_VOOTZVW^ŽycXRONJHIMRSSSX[[XQNKKLNQYg}ſn[SOLIJLNONNNNNNONNMOSVY\cgm{yx_XTOKJHIIHIHIIJKKJJMOSW[bfmx}m]VRMKIHHGEDDEFGIKLLMPUX\enx`VOLHFEEFFFEEFFFGKNRW[bmtxfZSOMKIGGGFFFGHIKMOSWZ^gq{x`VPMKJHHHHGGHIJJJMQV[_ivm\TNJGFEDCCDDEEGIKNRW^isdUMJFCAA@@A@ACDFHKNS[cnlYOJGDBBBCCCDEEFGILNRX`si[SMJHGGGGGHIIJKLNPUY_gp}|k]VOLJJJJJJJKLLMOQTX\bl{|rrv`XQMLKKJJKKLLMOSVX[_hp{xu{m^ZUOLKLLKKMNOOQUZ]ahs~ma[WTPNOOPOPRUVWY]bfksre_]YTSTUTTUWZ\\]bgghmw~}tkfb]ZYYXWWWYZZ\^_behjnt}~xvwz~zoe_^\[XXYYXYZ[]^_dhnu~}zxuuv{woh_\[\ZYXYZZZ[]`cdhnx|wwzvtyynje_\[[ZYZ[]]]_cimpx}{z~}oihea^]]]\\^_acdhmot}}}xuplhhgeb`abaabcfgggjmmmptvwzyvqmjhgfeeeeeggghjklmnnoqtwx||xsrqnljihgfggghhjlkkntwx{~|{|zyy}|{|xronnmmmnqsvxz|~}xvvvttuxz{|||~~}{yywwxuvwzz~|zxwvtsssttuwyy{}}~|{zyyxxyz{}~}zwwvtsuuvxyz{{}~|{{yz{{||~~|{yyyyxwxxyzy{}}|}|||{zzzzz{{|}~}}|zzz{{{}}|||||||{zzz{|}~~}~~}}~}|zyyz{|}}~}{zzzz{{|~~~~~~~~~}~}}~~~~~~~~~~~~}~~ \ No newline at end of file diff --git a/tests/apps/mixmonitor_duplex/test-config.yaml b/tests/apps/mixmonitor_duplex/test-config.yaml new file mode 100644 index 000000000..f4d228a19 --- /dev/null +++ b/tests/apps/mixmonitor_duplex/test-config.yaml @@ -0,0 +1,16 @@ +testinfo: + summary: 'Test MixMonitor application Duplex recordings' + description: | + 'This test verifies basic functionality of both the MixMonitor + and StopMixMonitor applications using a Duplex bridged recording.' + +properties: + dependencies: + - python : 'twisted' + - python : 'starpy' + - asterisk : 'app_echo' + - asterisk : 'app_mixmonitor' + - asterisk : 'app_playback' + - asterisk : 'app_userevent' + tags: + - mixmonitor diff --git a/tests/apps/tests.yaml b/tests/apps/tests.yaml index fc1a0d7dd..4694ecf7a 100644 --- a/tests/apps/tests.yaml +++ b/tests/apps/tests.yaml @@ -12,6 +12,7 @@ tests: - dir: 'queues' - dir: 'directed_pickup' - test: 'mixmonitor' + - test: 'mixmonitor_duplex' - test: 'mixmonitor_rxtx' - test: 'mixmonitor_audiohook_inherit' - test: 'mixmonitor_func'