Git Product home page Git Product logo

voip_patrol's Introduction

Docker Pulls

VoIP Patrol

GitHub Logo

VoIP signaling and media test automaton

Designed to automate end2end and or integration tests.

VoIP patrol will follow a scenario in XML format and will output results in JSON.

Each line in the output file is a separate JSON structure, note that the entire file is not a valid JSON file, this is because VoIP patrol will output results as they become available.

It is possible to test many scenarios that are not easy to test manually like a re-invite with a new codec.

Docker quick start

quick start with docker

Linux Debian building from sources

see commands in Dockerfile

Load test example

load test example

run

./voip_patrol --help

Example: making a test call

<config>
  <actions>
    <action type="call" label="us-east-va"
            transport="tls"
            expected_cause_code="200"
            caller="[email protected]"
            callee="[email protected]"
            to_uri="[email protected]"
            max_duration="20" hangup="16"
            username="VP_ENV_USERNAME"
            password="VP_ENV_PASSWORD"
            rtp_stats="true"
    >
        <x-header name="X-Foo" value="Bar"/>
    </action>
    <!-- note: param value starting with VP_ENV_ will be replaced by environment variables -->
    <!-- note: rtp_stats will include RTP transmission statistics -->
    <!-- note: x-header tag inside an action will append an header -->
    <action type="wait" complete="true"/>
  </actions>
</config>

Sample JSON output

{
  "2": {
    "label": "us-east-va",
    "start": "17-07-2018 00:00:05",
    "end": "17-07-2018 00:00:24",
    "action": "call",
    "from": "15147371787",
    "to": "12012665228",
    "result": "PASS",
    "expected_cause_code": 200,
    "cause_code": 200,
    "reason": "Normal call clearing",
    "callid": "7iYDFukJr-9BOLOmWg.7fZyHZeZUAwao",
    "transport": "TLS",
    "peer_socket": "34.226.136.32:5061",
    "duration": 16,
    "expected_duration": 0,
    "max_duration": 20,
    "hangup_duration": 16,
    "rtp_stats_0": {
      "rtt": 0,
      "remote_rtp_socket": "10.250.7.88:4028",
      "codec_name": "PCMU",
      "clock_rate": "8000",
      "Tx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 816,
        "kbytes": 127,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      },
      "Rx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 813,
        "kbytes": 127,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      }
    }
  }
}

Example: starting a TLS server

./voip_patrol \
   --port 5060 \ # TLS port 5061 +1
   --conf "xml/tls_server.xml" \
   --tls-calist "tls/ca_list.pem" \
   --tls-privkey "tls/key.pem" \
   --tls-cert "tls/certificate.pem" \
   --tls-verify-server \
<config>
  <actions>
     <!-- note: default is the "catch all" account,
          else account as to match called number -->
    <action type="accept"
            account="default"
            hangup="5"
            play_dtmf="0123456789#*"
            play="voice_ref_files/f.wav"
            code="200" reason="YES"
            ring_duration="5"
    />
    <!-- DTMF will be sent using RFC2833 -->
    <!-- note: wait for new incoming calls
               forever and generate test results -->
    <action type="wait" ms="-1"/>
  </actions>
</config>

Example: accepting calls and checking for specific header

<config>
  <actions>
    <action type="accept"
            account="default"
            hangup="5"
            code="200" reason="OK"
    >
        <check-header name="Min-SE"/>
        <check-header name="X-Foo" value="Bar"/>
    </action>
    <action type="wait" ms="-1"/>
  </actions>
</config>

Example: accepting calls and searching the message with a regular expression

<config>
  <actions>
    <action type="accept"
            account="default"
            hangup="5"
            code="200" reason="OK"
    >
        <check-message method="INVITE" regex="m=audio(.*)RTP/AVP 0 8.*"/>
        <!-- searching for pcmu pcma in the SDP -->
    </action>
    <action type="wait" ms="-1"/>
  </actions>
</config>

Example: making tests calls with wait_until

Scenario execution is sequential and non-blocking. We can use “wait” command with previously set “wait_until” params to control parallel execution.

Call States
NULL : Before INVITE is sent or received
CALLING : After INVITE is sent
INCOMING : After INVITE is received.
EARLY : After response with To tag.
CONNECTING : After 2xx is sent/received.
CONFIRMED : After ACK is sent/received.
DISCONNECTED
<config>
  <actions>
    <action type="call" label="call#1"
            transport="udp"
            wait_until="CONFIRMED"
            expected_cause_code="200"
            caller="[email protected]"
            callee="[email protected]"
    />
    <!-- note: will wait until all tests pass wait_until state -->
    <action type="wait"/>
    <action type="call" label="call#2"
            transport="udp"
            wait_until="CONFIRMED"
            expected_cause_code="200"
            caller="[email protected]"
            callee="[email protected]"
    />
    <action type="wait" complete="true"/>
  </actions>
</config>

Example: testing registration

<config>
  <actions>
    <!-- note: proxy param to send to a proxy -->
    <action type="register" label="register target.com"
            transport="udp"
            account="VP_ENV_USERNAME"
            username="VP_ENV_USERNAME"
            password="VP_ENV_PASSWORD"
            proxy="172.16.7.1"
            registrar="target.com"
            expected_cause_code="200"
    />
    <action type="wait" complete="true"/>
  </actions>
</config>

Example: re-invite with new codec

<config>
    <action>
        <action type="codec" disable="all"/>
        <action type="codec" enable="pcma" priority="250"/>
        <action type="codec" enable="pcmu" priority="248"/>

        <!-- call that will last 12 seconds and re-invite every 2 seconds -->
        <action type="call"
            wait_until="CONFIRMED"
            expected_cause_code="200"
            caller="[email protected]"
            callee="[email protected]"
            max_duration="55" hangup="12"
            username="65454659288" password="adaadzWidD7T"
            re_invite_interval="2"
            rtp_stats="true"
        />
        <action type="wait"/> <!-- this will wait until the call is confirmed -->
        <action type="codec" disable="pcma"/>
        <!-- re-invite will now use pcmu forcing a new session -->
        <action type="wait" ms="3000"/> <!-- this will wait 3 seconds -->
        <action type="codec" enable="pcma" priority="250"/>
        <!-- re-invite will now use pcma forcing a new session -->

        <action type="wait" complete="true"> <!-- Wait until the calls are disconnected -->
    <actions/>
<config/>

Example: Overwriting local contact header

<config><actions>
    <action type="codec" disable="all"/>
    <action type="codec" enable="pcma" priority="250"/>
    <action type="codec" enable="gsm" priority="249"/>
    <action type="codec" enable="pcmu" priority="248"/>

    <action type="call"
        transport="udp"
        caller="[email protected]"
        callee="+911@edgeproxy1"
        transport="udp"
        username="20255655"
        password="qntzhpbl"
        rtp_stats="true"
        late_start="false"
        force_contact="sip:[email protected]:5777"
        play="/git/voip_patrol/voice_ref_files/reference_8000_12s.wav"
        hangup="5">

    <x-header name="Foo" value="Bar"/>
    </action>
    <action type="wait" complete="true" />
</actions></config>

Example: WAIT action

wait forever:

<action type="wait" ms="-1"/>

wait until you receive a certain amount of calls

<action type="accept" call_count="x" ... />
<action type="wait" complete="true"/>

wait 5 seconds or one call

<action type="accept" call_count="1" ... />
<action type="wait" ms="5000"/>

Sample JSON output RTP stats report with multiples sessions

one block is generated everytime a session is created

{
 "rtp_stats_0": {
      "rtt": 0,
      "remote_rtp_socket": "10.250.7.88:4028",
      "codec_name": "PCMA",
      "clock_rate": "8000",
      "Tx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 105,
        "kbytes": 16,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      },
      "Rx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 104,
        "kbytes": 16,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      }
    },
    "rtp_stats_1": {
      "rtt": 0,
      "remote_rtp_socket": "10.250.7.89:40230",
      "codec_name": "PCMU",
      "clock_rate": "8000",
      "Tx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 501,
        "kbytes": 78,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      },
      "Rx": {
        "jitter_avg": 0,
        "jitter_max": 0,
        "pkt": 501,
        "kbytes": 78,
        "loss": 0,
        "discard": 0,
        "mos_lq": 4.5
      }
    }
}

Example: email reporting

<config>
  <actions>
    <action type="alert"
     email="[email protected]"
     email_from="[email protected]"
     smtp_host="smtp://gmail-smtp-in.l.google.com:25"
    />
    <!-- add more test actions here ...  -->
    <action type="wait" complete="true"/>
  </actions>
</config>

accept command parameters

Name Type Description
ring_duration int ringing duration in seconds
early_media bool if "true" 183 with SDP and early media is used
timer string control SIP session timers, possible values are : inactive, optional, required or always
code int SIP cause code to return must be >100 and <700
account string Account will be used if it matches the user part of an incoming call RURI or "default" will catch all
response_delay int ms delay before reponse is sent, useful to test timeouts and race conditions
call_count int The amount of calls to receive to consider the command completed, default -1 (considered completed)
transport string Force a specific transport for all messages on accepted calls, default to all transport available
re_invite_interval int Interval in seconds at which a re-invite with SDP will be sent
rtp_stats bool if "true" the json report will include a report on RTP transmission
srtp string Comma-separated values of the following "sdes" - add SDES support, "dtls" - add DTLS-SRTP support, "force" - make SRTP mandatory
hangup int call duration in second before hangup
label string test description or label

call command parameters

Name Type Description
timer string control SIP session timers, possible values are : inactive, optional, required or always
proxy string ip/hostname of a proxy where to send the call
caller string From header user@host, only used if from it not specified
from string From header complete "&quot;Display Name&quot; <sip:test at 127.0.0.1>"
callee string request URI user@host (also used in the To header unless to_uri is specified)
to_uri string used@host part of the URI in the To header
transport string force a specific transport <tcp,udp,tls,sips>
re_invite_interval int Interval in seconds at which a re-invite with SDP will be sent
rtp_stats bool if "true" the json report will include a report on RTP transmission
srtp string Comma-separated values of the following "sdes" - add SDES support, "dtls" - add DTLS-SRTP support, "force" - make SRTP mandatory. Note, if you don't specify "force", call would be made with plain RTP. If you specify both "sdes" and "dtls", DTLS-SRTP would be used regardless of order.
late_start bool if "true" no SDP will be included in the INVITE and will result in a late offer in 200 OK/ACK
record bool if "true" the call will be recorded once connected in /voice_files
record_early bool if "true" the call will be recorded when early media starts in /voice_files
force_contact string local contact header will be overwritten by the given string
max_ringing_duration int max ringing duration in seconds before cancel, default 60
hangup int call duration in second before hangup
repeat int do this call multiple times
username string authentication username, account name, From/To/Contact header user part
password string authentication password
label string test description or label

register command parameters

Name Type Description
proxy string ip/hostname of a proxy where to send the register
username string authentication username, account name, From/To/Contact header user part
password string authentication password
account string if not specified username is used, this is the the account name and From/To/Contact header user part
registrar string SIP UAS handling registration where the messages will be sent
transport string force a specific transport <tcp,udp,tls,sips>
unregister bool unregister the account <usename@registrar;transport=x>
reg_id int if present outbound and other related parameters will be added see RFC5626
instance_id int same as reg_id, if not present, it will be generated automatically
rewrite_contact bool default true, detect public IP when registering and rewrite the contact header
srtp string Comma-separated values of the following "sdes" - add SDES support, "dtls" - add DTLS-SRTP support, "force" - make SRTP mandatory. Used for incoming calls to this account
account string if not specified username is used, this is the the account name and From/To/Contact header user part
registrar string SIP UAS handling registration where the messages will be sent
transport string force a specific transport <tcp,udp,tls,sips>
unregister bool unregister the account <usename@registrar;transport=x>
reg_id int if present outbound and other related parameters will be added see RFC5626
instance_id int same as reg_id, if not present, it will be generated automatically
rewrite_contact bool default true, detect public IP when registering and rewrite the contact header
srtp string Comma-separated values of the following "sdes" - add SDES support, "dtls" - add DTLS-SRTP support, "force" - make SRTP mandatory. Used for incoming calls to this account

message command parameters

Name Type Description
from string From header complete "&quot;Display Name&quot; <sip:test at 127.0.0.1>"
to_uri string used@host part of the URI in the To header
transport string force a specific transport <tcp,udp,tls,sips>
username string authentication username, account name, From/To/Contact header user part
password string authentication password
label string test description or label

Example: sending a message

<?xml version="1.0"?>
<config>
  <actions>
    <action type="message" label="testing SIP message" transport="udp"
      expected_cause_code="202"
      text="Message in a bottle."
      from="[email protected]"
      to_uri="[email protected]"
      username="123456"
      password="pass"
     />
    <action type="wait" complete="true"/>
  </actions>
</config>

accept_message command parameters

Name Type Description
account string Account will be used if it matches the user part of an incoming message RURI or "default" will catch all
message_count int The amount of messages to receive to consider the command completed, default -1 (considered completed)
transport string Force a specific transport for all messages on accepted messages, default to all transport available
label string test description or label

Example: receiving a message

<?xml version="1.0"?>
<config>
  <actions>
    <action type="register" label="register" transport="udp"
      expected_cause_code="200"
      username="123456"
      password="password"
      registrar="pbx.somewhere.time"
     />
    <action type="wait" complete="true"/>
    <action type="accept_message" 
      account="123456"
      message_count="1"
     />
    <action type="wait" complete="true"/>
  </actions>
</config>

wait command parameters

Name Type Description
complete bool if "true" wait for all the test to complete (or reach their wait_until state) before executing next action or disconnecting calls and exiting, needed in most cases
ms int the amount of milliseconds to wait before executing next action or disconnecting calls and exiting, if -1 wait forever

Example: codec configuration

<config>
  <actions>
    <action type="codec" disable="all"/>
    <action type="codec" enable="pcmu" priority="250"/>
    <!-- more actions ... -->
    <action type="wait" complete="true"/>
  </actions>
</config>

codec command parameters

Name Type Description
priority int 0-255, where zero means to disable the codec
enable string Codec payload type ID, ex. "g722", "pcma", "opus" or "all"
disable string Codec payload type ID, ex. "g722", "pcma", "opus" or "all"

Example: TURN configuration

<config>
  <actions>
    <action type="turn" enabled="true" server="x.x.x.x:3478" username="foo" password="bar"/>
    <!-- more actions ... -->
    <action type="wait" complete="true"/>
  </actions>
</config>

turn command parameters

Name Type Description
enabled bool if "true" turn server usage will be enabled
server string turn server URI or IP:port
username string turn server username
password string turn server password
password_hashed bool if "true" us hashed password, default plain password
sip_stun_use bool if "true" SIP reflective IP is use with signaling
media_stun_use bool if "true" STUN reflective IP is use with media/SDP
stun_only bool if "true" TURN and ICE are disabled and only STUN is use

using multiple accounts

When using multiple accounts, accounts can be created and selected with the following parameters.

command account parameter
accept account
register account
call caller
accept_message account
message from

using env variable in scenario actions parameters

Any value starting with VP_ENV will be replaced by the envrironment variable of the same name. Example : username="VP_ENV_USERNAME"

export VP_ENV_PASSWORD=????????
export VP_ENV_USERNAME=username

Docker

voip_patrol/docker$ tree
.
├── build.sh        # docker build command example
├── Dockerfile      # docker build file for Linux Alpine
└── voip_patrol.sh  # docker run example starting

Dependencies

PJSUA2

PJSUA2 : A C++ High Level Softphone API : built on top of PJSIP and PJMEDIA http://www.pjsip.org http://www.pjsip.org/docs/book-latest/PJSUA2Doc.pdf

External tool to test audio quality

PESQ

P.862 : Perceptual evaluation of speech quality (PESQ): An objective method for end-to-end speech quality assessment of narrow-band telephone networks and speech codecs http://www.itu.int/rec/T-REC-P.862

./run_pesq +16000 voice_files/reference.wav voice_files/recording.wav

voip_patrol's People

Contributors

andrewmelis avatar asalman18 avatar igorolhovskiy avatar jchavanton avatar kalmik avatar phildeb avatar stefanyohansson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

voip_patrol's Issues

Random values

Is it possible to have random values with min/max parameters
Values can be for numeric fields like hangup, ring_duration
Also on the Accept scenario can we have a parameter for the accept rate in percentage? this will use a random value to define if the call will answered or rejected

Multi account support

Is it possible to have support for multiple accounts like sipp?
this means using the same XML but with dictionary variables from csv files and the XML will repeat for each line in the dictionary.
SIPp ref

`wait` action and it's parameters

Hello!

I have a question about complete parameter behavior in wait action. As I got, if it's set to false, it's not waiting for all tests to complete and just continue run? Is it true?
Cause if is, on this line it's explicitly checks for all tests to end.

Thanks!

responce_delay is blocking option in accept

Hello!

As of now, implementation of responce_delay is done via pj_thread_sleep() which is blocking operation on all scenario running.
I've made a rework of it, but also made responce_delay parameter to be in seconds to be coherent with other duration parameters.
I can prepare an merge-request for this, but before I have a question - what is a best idea, to keep responce_delay in miliseconds or change the default behavior of this parameter (to make it coherent), but here we can loose precision in setting this parameter.

Wrong transport on outgoing INVITE with Digest authorization

Hi,
I've been running into this odd issue whereas I first register two end points, both are on the same VP server (acts as both UAC and UAS). Registration is complete for both, then send INVITE from one EP (transport udp), see VIA header:
Via: SIP/2.0/UDP 10.41.22.101:5060;rport;branch=z9hG4bKPj8699f0a0-1ff0-48cd-aa6e-7b883d6120ab

VP_ENV_SERVER sends a 407 Proxy authentication required back. All good so far...
At this point VP sends INVITE with nonce but TCP transport, see VIA header
Via: SIP/2.0/TCP 10.41.22.101:56413;rport;branch=z9hG4bKPjc0ba90f3-bb12-4ccd-ae30-5931549dd587;alias

Because of that the VP_ENV_SERVER never sees that DIgest authorization and call goes nowhere.
These are the relevant xml file lines:

    <action type="register" label="register star2star.com"
            transport="udp"
            account="VP_ENV_USERNAME"
            username="VP_ENV_USERNAME" password="VP_ENV_PASSWORD"
            realm="VP_ENV_SERVER"
            registrar="VP_ENV_SERVER"
            expected_cause_code="200"
    />
    <action type="register" label="register star2star.com"
            transport="udp"
            account="VP_ENV_USERNAME_2"
            username="VP_ENV_USERNAME_2" password="VP_ENV_PASSWORD_2"
            realm="VP_ENV_SERVER"
            registrar="VP_ENV_SERVER"
            expected_cause_code="200"
    />
    <action type="wait" complete/>
    <action type="accept"
            transport="udp"
            account="VP_ENV_USERNAME_2"
            hangup="15"
            code="200" reason="OK"
            rtp_stats="true"
            play="voice_ref_files/reference_8000.wav"
    />
    <action type="call" label="VOIP_PATROL"
            transport="udp"
            expected_cause_code="200"
            caller="VP_ENV_CALLER"
            callee="VP_ENV_CALLEE"
            username="VP_ENV_USERNAME"
            password="VP_ENV_PASSWORD"
            realm="VP_ENV_SERVER"
            max_duration="200"
            timer="always"
            wait_until="CONFIRMED"
            rtp_stats="true"
            max_ringing_duration="120"
            play="voice_ref_files/reference_8000.wav"
            repeat="0"
    />

What am I doing wrong in terms of the wrong transport on INVITE with Digest authorization header?
Pablo

Make possible to set an extra header on test call

Sometimes we need to test a feature that needs any extra header. Something like

<config>
  <actions>
    <action type="call" label="us-east-va"
            transport="udp"
            expected_cause_code="200"
            caller="[email protected]"
            callee="[email protected]"
            max_duration="20" hangup="20"
            rtp_stats
            >
        <x-header name="X-Foo" value="Bar" />
    </action>
    <!-- note: param value starting with VP_ENV_ will
               be replaced by environment variables -->
    <!-- note: rtp_stats will include RTP transmission
               statistics -->
    <action type="wait" complete/>
  </actions>
</config>

unhandled error

16:55:02.946 call.cpp ...pjsua_call_dial_dtmf(id, &pj_digits) error: Remote does not support RFC 2833 (PJMEDIA_RTP_EREMNORFC2833) (status=220107) [../src/pjsua2/call.cpp:556]

Register + wait for call

Hello,

I started testing voip_patrol, and I would like to:

  • Register
  • Wait for call
  • Answer
  • Start Media
  • Put the call on hold with sendonly (INVITE)
  • Receive 200 OK with recvonly
  • Wait for a few seconds
  • Get the call out of hold withOUT SDP (INVITE without SDP)
  • Will receive a 200 OK with SDP
  • ACK with SDP
  • restart media and check it we are receiving media.

Is this possible with voip_patrol? I've tried with SIPp but i seem to not be able to.

Many thanks!

Issue when calling make on debian stretch (9.12)

I get the following error after calling "make" on debian stretch (9.12):

/usr/bin/cmake -E cmake_link_script CMakeFiles/voip_patrol.dir/link.txt --verbose=1
/usr/bin/c++    -std=c++11 -g   CMakeFiles/voip_patrol.dir/src/voip_patrol/mod_voip_patrol.cc.o CMakeFiles/voip_patrol.dir/src/voip_patrol/voip_patrol.cc.o CMakeFiles/voip_patrol.dir/src/voip_patrol/action.cc.o CMakeFiles/voip_patrol.dir/src/voip_patrol/check.cc.o CMakeFiles/voip_patrol.dir/src/ezxml/ezxml.c.o  -o voip_patrol -rdynamic -lpjsua2-x86_64-unknown-linux-gnu -lstdc++ -lpjsua-x86_64-unknown-linux-gnu -lpjsip-ua-x86_64-unknown-linux-gnu -lpjsip-simple-x86_64-unknown-linux-gnu -lpjsip-x86_64-unknown-linux-gnu -lpjmedia-codec-x86_64-unknown-linux-gnu -lpjmedia-x86_64-unknown-linux-gnu -lpjmedia-videodev-x86_64-unknown-linux-gnu -lpjmedia-audiodev-x86_64-unknown-linux-gnu -lpjmedia-x86_64-unknown-linux-gnu -lpjnath-x86_64-unknown-linux-gnu -lpjlib-util-x86_64-unknown-linux-gnu -lsrtp-x86_64-unknown-linux-gnu -lresample-x86_64-unknown-linux-gnu -lgsmcodec-x86_64-unknown-linux-gnu -lspeex-x86_64-unknown-linux-gnu -lilbccodec-x86_64-unknown-linux-gnu -lg7221codec-x86_64-unknown-linux-gnu -lpj-x86_64-unknown-linux-gnu -lpthread -lcurl -lm -lasound -lssl -std=c++11 -lssl -lcrypto -lopus -luuid -lpjmedia-videodev-x86_64-unknown-linux-gnu -lpjmedia-audiodev-x86_64-unknown-linux-gnu -lpjnath-x86_64-unknown-linux-gnu -lpjlib-util-x86_64-unknown-linux-gnu -lsrtp-x86_64-unknown-linux-gnu -lresample-x86_64-unknown-linux-gnu -lgsmcodec-x86_64-unknown-linux-gnu -lspeex-x86_64-unknown-linux-gnu -lilbccodec-x86_64-unknown-linux-gnu -lg7221codec-x86_64-unknown-linux-gnu -lpj-x86_64-unknown-linux-gnu -lpthread -lcurl -lm -lasound -lssl -lcrypto -lopus -luuid 
/usr/bin/ld: warning: libssl.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libssl.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libssl.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libcrypto.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1
/usr/bin/ld: warning: libcrypto.so.1.0.2, needed by /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1
//usr/local/lib/libpjmedia-codec-x86_64-unknown-linux-gnu.a(opencore_amr.o): In function `amr_codec_decode':
opencore_amr.c:(.text+0x3d8): undefined reference to `Decoder_Interface_Decode'
//usr/local/lib/libpjmedia-codec-x86_64-unknown-linux-gnu.a(opencore_amr.o): In function `amr_codec_encode':
opencore_amr.c:(.text+0x642): undefined reference to `Encoder_Interface_Encode'
//usr/local/lib/libpjmedia-codec-x86_64-unknown-linux-gnu.a(opencore_amr.o): In function `amr_codec_close':
opencore_amr.c:(.text+0xf69): undefined reference to `Decoder_Interface_exit'
opencore_amr.c:(.text+0xf71): undefined reference to `Encoder_Interface_exit'
//usr/local/lib/libpjmedia-codec-x86_64-unknown-linux-gnu.a(opencore_amr.o): In function `amr_codec_modify':
opencore_amr.c:(.text+0x1009): undefined reference to `Encoder_Interface_exit'
opencore_amr.c:(.text+0x1011): undefined reference to `Encoder_Interface_init'
//usr/local/lib/libpjmedia-codec-x86_64-unknown-linux-gnu.a(opencore_amr.o): In function `amr_codec_open':
opencore_amr.c:(.text+0x13e1): undefined reference to `Encoder_Interface_init'
opencore_amr.c:(.text+0x1405): undefined reference to `Decoder_Interface_init'
collect2: error: ld returned 1 exit status
CMakeFiles/voip_patrol.dir/build.make:201: recipe for target 'voip_patrol' failed
make[2]: *** [voip_patrol] Error 1
make[2]: Leaving directory '/usr/src/voip_patrol'
CMakeFiles/Makefile2:70: recipe for target 'CMakeFiles/voip_patrol.dir/all' failed
make[1]: *** [CMakeFiles/voip_patrol.dir/all] Error 2
make[1]: Leaving directory '/usr/src/voip_patrol'
Makefile:86: recipe for target 'all' failed
make: *** [all] Error 2

How to test TURN HA ?

Hi there

I'm interested in using voip_patrol to test a high availability TURN setup (using coturn). How can I test that ? Tried a naive /git/voip_patrol/voip_patrol -c ./test.xml -o result.json with this test.xml

<config>
  <actions>
    <action type="turn" enabled="true" server="turn.test:3478" username="test" password="test"/>
    <action type="wait" complete/>
  </actions>
</config>

Note, I intend turn.test to answer at least 2 IPs, this is what I meant by high availability

The output said

[08:02:37.974][INFO] pjsip_config->tsx.t1 :500

Prepared for Action!
[08:02:37.974][INFO] JSON result file:results.json

[08:02:37.974][INFO] JSON result file:result.json

[08:02:37.974][INFO] 
* * * * * * *
voip_patrol version: 0.2.3
configuration: ./test.xml
log file (voip_patrol): result.json
log file (pjsua): result.json.pjsua
output file: result.json
public_address: 
bound_address: 
* * * * * * *

08:02:37.985         os_core_unix.c !pjlib 2.10-dev for POSIX initialized
08:02:37.986         sip_endpoint.c  .Creating endpoint instance...
08:02:37.987                  pjlib  .select() I/O Queue created (0x559b3ede1d08)
08:02:37.987         sip_endpoint.c  .Module "mod-msg-print" registered
08:02:37.987        sip_transport.c  .Transport manager created.
08:02:37.987           pjsua_core.c  .PJSUA state changed: NULL --> CREATED
[08:02:38.004][INFO] main: TLS tcfg.tlsConfig.ca_list      :tls/ca_list.pem
[08:02:38.004][INFO] main: TLS tcfg.tlsConfig.certFile     :tls/certificate.pem
[08:02:38.004][INFO] main: TLS tcfg.tlsConfig.privKeyFile  :tls/key.pem
[08:02:38.004][INFO] main: TLS tcfg.tlsConfig.verifyServer :0
[08:02:38.004][INFO] main: TLS tcfg.tlsConfig.verifyClient :0
[08:02:38.004][INFO] main: TLS supported :tls/certificate.pem
[08:02:38.004][INFO] createAccount: [0][sip:default]
[08:02:38.004][INFO] createDefaultAccount created:voice_ref_files/reference_8000.wav
[08:02:38.004][INFO] process ===> actions
[08:02:38.004][INFO] process ===> action/turn
[08:02:38.004][ERROR] process: params not found for action:turn

[08:02:38.005][INFO] process ===> action/wait
[08:02:38.005][INFO] set_param param name:complete val:
[08:02:38.005][INFO] do_wait duration_ms:0 complete all tests:1
[08:02:38.005][INFO] do_wait: completed
[08:02:38.005][INFO] main: wait complete all...
[08:02:38.005][INFO] do_wait duration_ms:0 complete all tests:0
[08:02:38.005][INFO] do_wait: completed
[08:02:38.005][INFO] main: checking alerts...
[08:02:38.006][INFO] send smtp
[08:02:38.006][INFO] main: hangup all calls...
[08:02:39.504][INFO] main: Success
[08:02:39.504][INFO] main: Watch completed, exiting  /('l')

result.json is empty, result.json.pjsua says

08:02:37.987         sip_endpoint.c  .Module "mod-pjsua-log" registered
08:02:37.987         sip_endpoint.c  .Module "mod-tsx-layer" registered
08:02:37.987         sip_endpoint.c  .Module "mod-stateful-util" registered
08:02:37.987         sip_endpoint.c  .Module "mod-ua" registered
08:02:37.987         sip_endpoint.c  .Module "mod-100rel" registered
08:02:37.987         sip_endpoint.c  .Module "mod-pjsua" registered
08:02:37.988         sip_endpoint.c  .Module "mod-invite" registered
08:02:37.992             alsa_dev.c  ..ALSA driver found 0 devices
08:02:37.992             alsa_dev.c  ..ALSA initialized
08:02:38.000                  pjlib  ..select() I/O Queue created (0x559b3edff0c8)
08:02:38.000           conference.c  ..Creating conference bridge with 514 ports
08:02:38.000           Master/sound  ..Using delay buffer with WSOLA.
08:02:38.004         sip_endpoint.c  .Module "mod-evsub" registered
08:02:38.004         sip_endpoint.c  .Module "mod-presence" registered
08:02:38.004                evsub.c  .Event pkg "presence" registered by mod-presence
08:02:38.004         sip_endpoint.c  .Module "mod-mwi" registered
08:02:38.004                evsub.c  .Event pkg "message-summary" registered by mod-mwi
08:02:38.004         sip_endpoint.c  .Module "mod-refer" registered
08:02:38.004                evsub.c  .Event pkg "refer" registered by mod-refer
08:02:38.004         sip_endpoint.c  .Module "mod-pjsua-pres" registered
08:02:38.004         sip_endpoint.c  .Module "mod-pjsua-im" registered
08:02:38.004         sip_endpoint.c  .Module "mod-pjsua-options" registered
08:02:38.004           pjsua_core.c  .1 SIP worker threads created
08:02:38.004           pjsua_core.c  .pjsua version 2.10-dev for Linux-5.4.0.62/x86_64/glibc-2.28 initialized
08:02:38.004           pjsua_core.c  .PJSUA state changed: CREATED --> INIT
08:02:38.004           pjsua_core.c  SIP UDP socket reachable at 10.0.2.100:5070
08:02:38.004      udp0x559b3eea58a0  SIP UDP transport started, published address is 10.0.2.100:5070
08:02:38.004             tcptp:5070  SIP TCP listener ready for incoming connections at 10.0.2.100:5070
08:02:38.004             tlstp:5071  SIP TLS listener is ready for incoming connections at 10.0.2.100:5071
08:02:38.004            pjsua_aud.c  Setting null sound device..
08:02:38.004            pjsua_aud.c  .Opening null sound device..
08:02:38.004           pjsua_core.c  PJSUA state changed: INIT --> STARTING
08:02:38.004         sip_endpoint.c  .Module "mod-unsolicited-mwi" registered
08:02:38.004           pjsua_core.c  .PJSUA state changed: STARTING --> RUNNING
08:02:38.004            pjsua_acc.c  Adding account: id=sip:default
08:02:38.004            pjsua_acc.c  .Account sip:default added with id 0
08:02:38.056           pjsua_core.c  Shutting down, flags=0...
08:02:38.056           pjsua_core.c  PJSUA state changed: RUNNING --> CLOSING
08:02:38.065           pjsua_call.c  .Hangup all calls..
08:02:38.065          pjsua_media.c  .Call 0: deinitializing media..
08:02:38.065          pjsua_media.c  .Call 1: deinitializing media..
08:02:38.065          pjsua_media.c  .Call 2: deinitializing media..
08:02:38.065          pjsua_media.c  .Call 3: deinitializing media..
... (shortened) ...
08:02:38.065          pjsua_media.c  .Call 511: deinitializing media..
08:02:38.066           pjsua_pres.c  .Shutting down presence..
08:02:39.004            pjsua_aud.c  .Closing sound device after idle for 1 second(s)
08:02:39.004            pjsua_aud.c  ..Closing null sound device..
08:02:39.075           pjsua_core.c  .Destroying...
08:02:39.075          pjsua_media.c  .Shutting down media..
08:02:39.501         sip_endpoint.c  .Destroying endpoint instance..
08:02:39.501      sip_transaction.c  .Stopping transaction layer module
08:02:39.501      sip_transaction.c  .Stopped transaction layer module
08:02:39.501         sip_endpoint.c  .Module "mod-unsolicited-mwi" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-pjsua-options" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-pjsua-im" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-pjsua-pres" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-pjsua" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-stateful-util" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-refer" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-mwi" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-presence" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-evsub" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-invite" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-100rel" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-ua" unregistered
08:02:39.501      sip_transaction.c  .Transaction layer module destroyed
08:02:39.501         sip_endpoint.c  .Module "mod-tsx-layer" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-msg-print" unregistered
08:02:39.501         sip_endpoint.c  .Module "mod-pjsua-log" unregistered
08:02:39.501        sip_transport.c  .Destroying transport manager
08:02:39.503      udp0x559b3eea58a0  .SIP UDP transport destroyed
08:02:39.503             tcptp:5070  .SIP TCP transport destroyed
08:02:39.503             tlstp:5071  .SIP TLS transport destroyed
08:02:39.503                timer.c  .Dumping timer heap:
08:02:39.503                timer.c  .  Cur size: 0 entries, max: 3070
08:02:39.503         sip_endpoint.c  .Endpoint 0x559b3edd6178 destroyed
08:02:39.503           pjsua_core.c  .PJSUA state changed: CLOSING --> NULL
08:02:39.503           pjsua_core.c  .PJSUA destroyed...

As I said, I tried the naive way, I guess I need some more configuration. Could you provide me some guidance about how to setup a meaningful test ? The best would be a call over the TURN, dunno if there is an easy setup to achieve that, like a mock server ?

config->tests_with_rtp_stats.erase crash

crash RTP stats

Thread 1 "voip_patrol" received signal SIGSEGV, Segmentation fault.
__memmove_ssse3 () at ../sysdeps/x86_64/multiarch/memcpy-ssse3.S:2818
2818    ../sysdeps/x86_64/multiarch/memcpy-ssse3.S: No such file or directory.
(gdb) bt
#0  __memmove_ssse3 () at ../sysdeps/x86_64/multiarch/memcpy-ssse3.S:2818
#1  0x0000000000460dc9 in std::__copy_move<true, true, std::random_access_iterator_tag>::__copy_m<Test*> (__first=0x7fffe8069520, __last=0x7fffe8069518, 
    __result=0x7fffe8069518) at /usr/include/c++/5/bits/stl_algobase.h:384
#2  0x0000000000460cd4 in std::__copy_move_a<true, Test**, Test**> (__first=0x7fffe8069520, __last=0x7fffe8069518, __result=0x7fffe8069518)
    at /usr/include/c++/5/bits/stl_algobase.h:402
#3  0x000000000046c544 in std::__copy_move_a2<true, __gnu_cxx::__normal_iterator<Test**, std::vector<Test*, std::allocator<Test*> > >, __gnu_cxx::__normal_iterator<Test**, std::vector<Test*, std::allocator<Test*> > > > (__first=, __last=, __result=) at /usr/include/c++/5/bits/stl_algobase.h:438
#4  0x000000000046bdc3 in std::move<__gnu_cxx::__normal_iterator<Test**, std::vector<Test*, std::allocator<Test*> > >, __gnu_cxx::__normal_iterator<Test**, std::vector<Test*, std::allocator<Test*> > > > (__first=, __last=, __result=) at /usr/include/c++/5/bits/stl_algobase.h:504
#5  0x000000000046b3f5 in std::vector<Test*, std::allocator<Test*> >::_M_erase (this=0x7fffffffe458, __position=) at /usr/include/c++/5/bits/vector.tcc:145
#6  0x000000000046aead in std::vector<Test*, std::allocator<Test*> >::erase (this=0x7fffffffe458, __position=) at /usr/include/c++/5/bits/stl_vector.h:1147
#7  0x000000000046a067 in Action::do_wait (this=0x7fffffffe140, params=std::vector of length 2, capacity 2 = {...}) at /git/voip_patrol/src/voip_patrol/action.cc:549
#8  0x0000000000454e6c in Config::process (this=0x7fffffffe060, p_configFileName="xml/udp_server.xml", p_jsonResultFileName="results.json")
    at /git/voip_patrol/src/voip_patrol/voip_patrol.cc:677
#9  0x0000000000456e04 in main (argc=5, argv=0x7fffffffe598) at /git/voip_patrol/src/voip_patrol/voip_patrol.cc:948
(gdb) frame 7
#7  0x000000000046a067 in Action::do_wait (this=0x7fffffffe140, params=std::vector of length 2, capacity 2 = {...}) at /git/voip_patrol/src/voip_patrol/action.cc:549
549                                     config->tests_with_rtp_stats.erase(config->tests_with_rtp_stats.begin()+pos);
(gdb) p config->tests_with_rtp_stats
$1 = std::vector of length 1, capacity 2 = {0x7fffe808e150}
(gdb) p &config->tests_with_rtp_stats
$2 = (std::vector<Test*, std::allocator<Test*> > *) 0x7fffffffe458
(gdb) p config->tests_with_rtp_stats
$3 = std::vector of length 1, capacity 2 = {0x7fffe808e150}
(gdb) l
544
545                     int pos=0;
546                     for (auto test : config->tests_with_rtp_stats) {
547                             if (test->rtp_stats_ready) {
548                                     test->update_result();
549                                     config->tests_with_rtp_stats.erase(config->tests_with_rtp_stats.begin()+pos);
550                                     LOG(logINFO) << __FUNCTION__ << " erase pos:" << pos;
551                                     pos++;
552                             }
553                     }
(gdb) 

Testing scenario examples

I have a small question, which I did not get from ClueCon presentation
or documentation (or maybe just were looking elsewhere :) )

For testing scenario like ring group, for ex

10 accounts, 88880 - 88889

9 is in the ring group and 1 is calling.
Like 88880 is calling some predefined number, like 99999 and 88881 - 88889 are members of this ring group.

All 10 should register on registrar server (could be one, could be different), than 88880 fire a call to 99999
And than other 9 (88881 - 88889) starts to receive calls in some predefined order (defined by PBX logic)
and some of accounts are rejecting calls (and this alter calling to other accounts).
It's really just a ring group with a bit complex scenario.

For ex (quite advanced scenario, not real life, but covers more-or-less real world cases by parts):
88880 USER/PASS reg on server0
88881 USER/PASS reg on server1
....
88889 USER/PASS reg on server9
After all regs are successful

88880 calls 99999 on server0
88881 and 88882 should receive a call simultaneously
88881 reject call with 603 Declined
88883 start ringing after 88881 rejects call
88882 does not answer within 20 sec
88884 starts ringing after 20 sec from call start
88885 and 88886 starts ringing after 40 sec from call start
88886 answers the call after 5 sec of ringing
All other ringing accounts stop ringing.
88886 after 10 sec of conversation transfer call to 88887 (blind transfer)
88887 ringing and not answering within 10 sec
88888 starts ringing after 10 sec of call transfer to 88887
88888 answers the call
88888 holding conversation and in a same time calling to 88889 (attendant transfer)
88889 answers the call
After 10 sec of a call, 88888 REFER the call with 88887 to 88889
After 10 sec of REFER 88889 hangs up the call
At the same moment 88880 should receive BYE

So, my question is. Do I need to have several instances of voip_patrol
or can I define all this in one XML? Means how to combine register/wait
and register/call based on XML and account numbers?

pjsua SIGABRT when repeat parameter > 1

When setting "repeat" parameter to anything higher than one (1), VP is terminated by pjsua:
Program terminated with signal SIGABRT, Aborted. #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. [Current thread is 1 (Thread 0x7fbea8a87e00 (LWP 35723))] (gdb) where #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 #1 0x00007fbea950a537 in __GI_abort () at abort.c:79 #2 0x00007fbea950a40f in __assert_fail_base (fmt=0x7fbea9681688 "%s%s%s:%u: %s%sAssertion %s'failed.\n%n", assertion=0x555b90e977b0 "call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls", file=0x555b90e97f92 "../src/pjsua-lib/pjsua_call.c", line=2144, function=<optimized out>) at assert.c:92 #3 0x00007fbea9519662 in __GI___assert_fail (assertion=0x555b90e977b0 "call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls", file=0x555b90e97f92 "../src/pjsua-lib/pjsua_call.c", line=2144, function=0x555b90e98930 <__PRETTY_FUNCTION__.18> "pjsua_call_get_info") at assert.c:101 #4 0x0000555b90d8e56d in pjsua_call_get_info () #5 0x0000555b90d75961 in pj::Call::getInfo (this=<optimized out>) at ../src/pjsua2/call.cpp:455 #6 0x0000555b90d1a12f in Action::do_wait (this=0x7ffc0c0a3b28, params=std::vector of length 2, capacity 2 = {...}) at /home/voip_patrol/src/voip_patrol/action.cc:1043 #7 0x0000555b90cf5100 in Config::process (this=0x7ffc0c0a39d0, p_configFileName="callload.xml", p_jsonResultFileName="perf1-0.json") at /home/voip_patrol/src/voip_patrol/voip_patrol.cc:1092 #8 0x0000555b90cf7fce in main (argc=15, argv=0x7ffc0c0a6778) at /home/voip_patrol/src/voip_patrol/voip_patrol.cc:1443
Looks like the pjsua Data Field max_calls needs to be set based on the repeat parameter; however it is not used to set anything into pjsua.
btw, the maximum is PJSUA_MAX_CALLS macro (32) in pjsua-lib/pjsua.h, but default is apparently four (4), and I think in my case we reach that because each call creates a 2nd leg from the end point back to voip_patrol, so that makes it 2 x call-legs per call, so when the repeat parameter is set to 2, then we reach 4, so maybe that is what it is.
Looking into the pjsua-lib seems to me it should be set by voip_patrol via pjsua_call_set_user_data()
Note that the issue is per VP instance, in the sense that it doesn't matter how many VP instances are running, so long we keep the repeat parameter to one (or zero), all is good and it works in the sense that if set to one, two calls are generated back-to-back.

Adding MOS-CQ

@gmaruzz

I just added mos-cq Conversational Quality

a28ecd8

I will test it a little bit more, but I have used similar code before

Accepting call Scenario with ring_duration set makes the application ring forever, without an answer

Setting the ring_duration to any number on the accepting call scenario renders the call to be in ringing for ever without it being answered.
xml settings:

<config><actions>
        <action type="codec" disable="all"/>
        <action type="codec" enable="pcma" priority="250"/>
        <action type="codec" enable="pcmu" priority="248"/>
        <action type="accept"
            ring_duration="5"
            transport="udp"
            account="default"
            hangup="30"
            play="/voice_ref_files/reference_8000_12s.wav"
            code="200" reason="OK"
        />
        <action type="wait" ms="-1"/>
</actions></config>

Logs from the docker instance:

[11:03:12.758][INFO] onSelectAccount to:0551234567
[11:03:12.758][INFO] findAccount: [searching account][0][sip:default][default]<>[0551234567]
[11:03:12.758][INFO] findAccount: [searching account][0][sip:default][default]<>[default]
[11:03:12.758][INFO] findAccount: found account id[0] uri[sip:default]
[11:03:12.758][INFO] onSelectAccount account_index:0 response_delay:0 ring_duration:5
[11:03:12.761][INFO] check_checks: INVITE
[11:03:12.761][INFO] onIncomingCall: [sip:default]id[0]from["Tester" <sip: [email protected]>]to[<sip:[email protected]>]id[[email protected]]
[11:03:12.761][INFO] onIncomingCall: max call duration[30]
[11:03:12.761][INFO] Test: New test created:accept

[11:03:12.761][INFO] onIncomingCall: local[<sip:[email protected]>]
[11:03:12.761][INFO] onIncomingCall: rtp_stats:1
[11:03:12.761][INFO] onIncomingCall: play file:/voice_ref_files/reference_8000_12s.wav
[11:03:12.761][INFO] onIncomingCallcode:200 reason:OK
[11:03:12.761][INFO] onCallState: [<sip:[email protected]>]
[11:03:12.761][INFO] onCallState: [0]role[CALLEE]id[[email protected]][<sip:[email protected]>]["Tester" <sip: [email protected]>][INCOMING|2]
[11:03:12.761][INFO] onCallTsxState: [0]["Tester" <sip: [email protected]>][INCOMING]id[[email protected]] call[100] reason[Trying]
[11:03:12.761][INFO] onCallState: [<sip:[email protected]>]
[11:03:12.761][INFO] onCallState: [0]role[CALLEE]id[[email protected]][<sip:[email protected]>]["Tester" <sip: [email protected]>][EARLY|3]
[11:03:12.761][INFO] onCallTsxState: [0]["Tester" <sip: [email protected]>][EARLY]id[[email protected]] call[180] reason[Ringing]
[11:03:59.164][INFO] onCallTsxState: [0]["Tester" <sip: [email protected]>][EARLY]id[[email protected]] call[180] reason[Ringing]
[11:03:59.165][INFO] onCallTsxState: [0]["Tester" <sip: [email protected]>][EARLY]id[[email protected]] call[180] reason[Ringing]
[11:03:59.165][INFO] onCallTsxState: [0]["Tester" <sip: [email protected]>][DISCONNCTD]id[[email protected]] call[487] reason[Request Terminated]
[11:03:59.165][INFO] onCallState: [<sip:[email protected]>]
[11:03:59.165][INFO] onCallState: [0]role[CALLEE]id[[email protected]][<sip:[email protected]>]["Tester" <sip: [email protected]>][DISCONNCTD|6]
[11:03:59.165][INFO] update_result
[11:03:59.165][INFO] update_result[0x7fa670011d70]  completing

[11:03:59.165][INFO] update_result[28-02-2024 11:03:59]{"1": {"label": "", "start": "28-02-2024 11:03:12", "end": "28-02-2024 11:03:59", "action": "accept", "from": "\"Tester\" <sip: [email protected]>", "to": "<sip:[email protected]>", "result": "FAIL", "expected_cause_code": 200, "cause_code": 487, "reason": "Request Terminated", "callid": "[email protected]", "transport": "UDP", "peer_socket": "10.10.10.10:5060", "duration": 0, "expected_duration": 0, "max_duration": 0, "hangup_duration": 30, "call_info":{"local_uri": "<sip:[email protected]>", "remote_uri": "\"Tester\" <sip: [email protected]>", "local_contact": "<sip:10.10.10.20:5070>", "remote_contact": "<sip: [email protected]>" }}}
[11:03:59.165][INFO]  [accept]

[11:03:59.165][INFO] onCallState: [Call disconnected] red:call[487] reason[Request Terminated]

Show non-triggered accept as failed test

As of now, construction like

<config>
    <actions>
        <action type="codec" disable="all"/>
        <action type="codec" enable="pcma" priority="250"/>
        <action type="codec" enable="pcmu" priority="249"/>
        <action type="register" label="Register 88881"
            transport="tls"
            account="88881"
            username="88881"
            password="PASS"
            registrar="DOMAIN"
            realm="DOMAIN"
            expected_cause_code="200"
        />
        <action type="wait" complete="true"/>
        <action type="accept" label="Receive all calls"
            call_count="1"
            account="88881"
            hangup="10"
            code="200" reason="OK"
            transport="tls"
        />
        <action type="call" label="Call to 88881"
            transport="tls"
            expected_cause_code="200"
            caller="88882@DOMAIN"
            callee="88881@DOMAIN"
            from="sip:88882@DOMAIN"
            to_uri="88881@DOMAIN"
            max_duration="20" hangup="16"
            username="88882"
            password="PASS"
            realm="DOMAIN"
            rtp_stats="true"
            max_ringing_duration="15"
            play="/git/voip_patrol/voice_ref_files/reference_8000_12s.wav"
        />
        <action type="wait" complete="true"/>
    </actions>
</config>

Will show 3 tests passed, if call would be received back (Register + Call + Accept) and 2 tests passed if call was not received back, but was answered elsewhere (Register + Call).

Is there any way to show accept part as FAILED test?
P.S.: I'm in the code for this, but maybe just missed something stupid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.