{"id":13421,"date":"2020-08-23T19:30:32","date_gmt":"2020-08-23T19:30:32","guid":{"rendered":"http:\/\/abstracta.us\/blog\/?p=13421"},"modified":"2025-05-05T21:22:38","modified_gmt":"2025-05-05T21:22:38","slug":"voip-performance-testing","status":"publish","type":"post","link":"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/","title":{"rendered":"VoIP Performance Testing for a Mental Health Hotline App"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">How we used SIPp for VoIP performance testing over the SIP protocol<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2020\/08\/dustin-belt-lg4fM9Y2pGg-unsplash-min-1024x683.jpg\" alt=\"\" class=\"wp-image-13426\"\/><\/figure>\n\n\n\n<p>Not too long ago, some of my colleagues and I helped to run performance tests for a new mobile app with a hotline called <a href=\"https:\/\/www.yoteescucho.org\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">\u201cYo Te Escucho<\/a>\u201d (which translates in English to \u201cI hear you\u201d). It was created during the COVID-19 crisis as a non-profit, voluntary initiative in Uruguay. The hotline connects anyone who wants to simply speak and be heard (safely and anonymously) by a trained person. The main objective is to be able to provide people with a channel of communication and empathetic listening. Sparked as a response to the negative impacts of the virus, the initiative is expected to continue in the long-term, even when it\u2019s no longer around.<br><\/p>\n\n\n\n<p>In this post, we want to share how we went about performance testing the mobile app\u2019s VoIP technology as well as everything we learned about the tool, <a href=\"http:\/\/sipp.sourceforge.net\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">SIPp<\/a>, for performance tests over the SIP protocol (which is basically known as VoIP, Voice Over the Internet). We\u2019ll go through the basics of the protocols involved and then see how to use the SIPp tool to simulate concurrent calls on the system. All this of course, from the experience of a real volunteer project, which makes it much more interesting!&nbsp;<\/p>\n\n\n\n<p>Thanks to my colleagues, <a rel=\"noreferrer noopener\" aria-label=\"Pablo Richeri (opens in a new tab)\" href=\"https:\/\/www.linkedin.com\/in\/pdrichieri\/\" target=\"_blank\">Pablo Richieri<\/a>, who also worked on the project, for helping me write this post and to <a rel=\"noreferrer noopener\" aria-label=\"Andr\u00e9i Guchin (opens in a new tab)\" href=\"https:\/\/www.linkedin.com\/in\/andrei-guchin\/\" target=\"_blank\">Andr\u00e9i Guchin<\/a> for leading the effort.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Project_Background\"><\/span>Project Background<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Our role in this project was to conduct <strong>performance tests<\/strong> on the mobile app in order to observe the system\u2019s performance when it experiences the maximum number of currrencurent calls that it was designed to support.&nbsp;<\/p>\n\n\n\n<p>The hotline application has two types of users: those who make the calls (&#8216;callers&#8217;) and those who are available to answer them (&#8216;listeners&#8217;), using the<strong> SIP protocol<\/strong> to establish communication.&nbsp;<\/p>\n\n\n\n<p>We soon learned that the typical tools we use for performance testing such as JMeter or Gatling don\u2019t support this protocol by default. So, we had to investigate what the SIP protocol consists of, how to capture it and which tool we could use to automate the flow of the call from both the caller and listener side. We achieved this with the SIPp tool, which was recommended by <a href=\"https:\/\/www.3cx.com\/case-studies\/3cx-phone-system-performance-test\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">3CX<\/a>, the VoIP service provider for the hotline.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_VoIP\"><\/span><strong>What is VoIP?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The VoIP (Voice Over IP) protocol is used to make and transmit telephone calls over an IP network. Its goal is to packetize audio streams in order to transport them.<\/p>\n\n\n\n<p>Most of these calls use the SIP protocol (Session Initiation Protocol), either through the use of physical telephones as well as softphones.<\/p>\n\n\n\n<p><strong>Physical SIP phones<\/strong> look a lot like traditional phones, however they\u2019re developed for use on IP networks. (Think of the clunky phone you typically see on everyone\u2019s desk in an office!)<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/64ByhycOeUx2syxIFLjDPidRakTsMWXA8RDGP7KNwxhb43cnm92_Nh7NO8--Dk3YemH2qCy9YVQfkPS1b4Bwc-iO3LfdMVuTXHPEjq55WNoNxNzqz1JtmJ1laRqDOn1OLJdccyBk\" alt=\"example of a SIP phone\"\/><\/figure><\/div>\n\n\n\n<p><strong>Softphones<\/strong> on the other hand, are software applications used on computers, tablets or smartphones and behave exactly like a normal IP phone, allowing to perform calls as well as additional features like video conferencing, presentations, etc.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/XMBMPQiQF2AP3aa0Cz4dvsZwoeGT4r2llRqzwXb2EgiA3L1eB0IhlC1JgQLw82o3F2sIwSDdK24TFHdamPnu0OcGepO59_jGOyeD3u8Ka9uqsoFU8SiqUBczZBcSWNOPYZt0SO-F\" alt=\"example of a softphone\"\/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_SIP_%E2%80%93_Session_Initiation_Protocol\"><\/span><strong>What is SIP &#8211; Session Initiation Protocol?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>SIP is a protocol used to establish a \u201csession\u201d between two or more participants, modify it and eventually terminate the session. It\u2019s found its greatest use in the world of IP telephony. This protocol bears a significant resemblance to the HTTP protocol. The messages are text-based and the request-response mechanism makes error resolution very easy.<\/p>\n\n\n\n<p>We have two types of SIP messages, requests and status messages. Among the most common requests are: REGISTER, INVITE, ACK (acknowledge), INFO, NOTIFY, UPDATE, BYE, etc. And in the states we will find response codes in the range between 100 and 600, for example: 100 (Trying), 180 (Ringing), 200 (OK), 407 (You need to authenticate), etc.<\/p>\n\n\n\n<p>SIP messages describe the identity of the participants in a call and how the participants can be reached over an IP network. Once the exchange of configuration messages is complete, communication can be exchanged using another protocol, typically RTP (Real-Time Transmission Protocol).<\/p>\n\n\n\n<p>SIP was developed by the IETF and published as RFC 3261, and its flexibility has made it possible to almost completely replace the H.323 protocol in the VoIP world.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_to_Capture_Traffic_with_the_SIP_Protocol\"><\/span><strong>How to Capture Traffic with the SIP Protocol?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The tool we recommend to capture this protocol is <a href=\"https:\/\/www.wireshark.org\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Wireshark<\/a>, a protocol analyzer that allows you to see all the traffic that passes through a network and filter it by protocols.<\/p>\n\n\n\n<p>The different sections that we will find in Wireshark that are very useful when it comes to automating the flow are shown below:<\/p>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/-IGV3mc0R57JbbRKkdr-qDLmKFrrJX2kHf6p2ga2srEoKldinvSOoqZD5V9DfeY1sg27a2148GFRNLZxclmYi2_f5WtYOrzeMRuM111GAThl6ncP2olqE5DvfMpDA_fqJ_J3Wh0r\" alt=\"vopi performance testing project screenshot of wireshark\"\/><\/figure>\n\n\n\n<ol><li>In this section you can filter both by protocols and by IPs<\/li><li>The IP from which the messages are sent is displayed<\/li><li>The IP that receives the messages is displayed<\/li><li>In this section you can see what protocol is being used<\/li><li>In this section we can see if the message is a request or a status message (status)<\/li><li>By selecting one of the captured packets, we can view in this section the information regarding the protocols of each of the network layers. If we select \u201cSession Initiation Protocol\u201d in \u201cMessage Headers\u201d we will be able to see all the SIP protocol headers that are sent in that message that we will then use to automate the call.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_SIPp\"><\/span><strong>What is SIPp?&nbsp;<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>SIPp is an Open Source tool that allows us to generate one or more calls using the SIP protocol, emulating both clients and servers.<\/p>\n\n\n\n<p>By default it provides some basic scenarios that are ready to run, but it also allows us to import our own scenarios that we will create in XML format.<\/p>\n\n\n\n<p>In these scenarios we will describe call flows from the simplest to the most complex, being able to regulate the number of calls per period of time, the use of authentications, sending audio or video using the RTP protocol, among others.<\/p>\n\n\n\n<p>In this <a href=\"http:\/\/sipp.sourceforge.net\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">link<\/a>, you can download SIPp and find its documentation, which easily explains how to install it (we recommend doing it in Linux).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Using_SIPp\"><\/span><strong>Using SIPp&nbsp;<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>If you want to use the tool, all you have to do is perform the following steps:&nbsp;<\/p>\n\n\n\n<p>To begin, it\u2019s run from the command line using &#8220;sipp&#8221;.<\/p>\n\n\n\n<p># <strong>.\/sipp<\/strong><\/p>\n\n\n\n<p>Then we indicate the IP address to which our calls will be directed.<\/p>\n\n\n\n<p># .\/sipp <strong>127.0.0.1<\/strong><\/p>\n\n\n\n<p>And finally the &#8220;-sf&#8221; flag is used to execute a scenario created by us or &#8220;-sn&#8221; to use one of those already included, followed by the scenario file that we are going to execute.<\/p>\n\n\n\n<p># .\/sipp 127.0.0.1 <strong>-sf my_scenario.xml<\/strong><\/p>\n\n\n\n<p>With this we could already execute a simple scenario without problems, but we have a great variety of options that will allow us to execute more complex scenarios.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Next we will see some of these options that we believe will be very useful when making your scenarios more robust.&nbsp;<\/p>\n\n\n\n<p><strong>-h:<\/strong> Shows help information on the screen<\/p>\n\n\n\n<p><strong>-aa: <\/strong>Activates an automatic response with the code &#8220;200 OK&#8221; for all INFO, UPDATE and NOTIFY requests. This is useful to be able to avoid all these messages that generally do not contribute much to the user, they only inform.<\/p>\n\n\n\n<p><strong>-m:<\/strong> Determines the maximum number of calls to execute and stops the test when that number of calls is processed<\/p>\n\n\n\n<p><strong>-r:<\/strong> Configures the number of calls per time period that we want to generate. By default, 10 calls are generated per second. This setting is dynamically editable during the test using the following keys:<\/p>\n\n\n\n<ul><li>\u201c+\u201d increases calls per time period by&nbsp;<\/li><li>\u201c-\u201d decreases calls by 1 per time period<\/li><li>&#8220;*&#8221; Increases calls by 10 per time period<\/li><li>&#8220;\/&#8221; Decreases calls by 10 per time period&nbsp;<\/li><\/ul>\n\n\n\n<p><strong>-rp:<\/strong> In addition to the previous flag, this specifies the period of time (in milliseconds) in which this number of calls will be generated (set by default at 1000 = 1 second).&nbsp;<\/p>\n\n\n\n<p><strong>-inf:<\/strong> Allows us to import files, for example, CSV files, and work with their data in our scripts. Later when we see how to generate our scenarios we will look at this option in more detail.<\/p>\n\n\n\n<p><strong>-oocsf:<\/strong> SIPp uses a single &#8220;call-id&#8221; for each execution of the automated flow. This means that if different communications are automated in the same script, the tool will use the same call-id for both. In the case of this application, all communications (calls, listener registration on the server, etc.) are made with a different call-id. This flag allows us, whenever SIPp receives a request with a &#8220;call-id&#8221; different from the initial one, to execute a second particular scenario to resolve this second communication. To use this functionality but with the scenarios already integrated in the tool we will use the &#8220;-oocsn&#8221; flag.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Scenarios_in_SIPp\"><\/span><strong>Scenarios in SIPp<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Scenarios in SIPp are files in XML format. They have the following format:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2020\/08\/Img2-min.png\" alt=\"\" class=\"wp-image-13444\"\/><\/figure>\n\n\n\n<p>Next we will see some of the commands that we can place in our script.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Commands\"><\/span><strong>Commands<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>These are the most used tags:<\/p>\n\n\n\n<p><strong>&lt;send&gt;<\/strong> &#8211; Used to send requests<\/p>\n\n\n\n<p><strong>&lt;recv&gt;<\/strong> &#8211; Used to receive requests<\/p>\n\n\n\n<p><strong>&lt;pause&gt;<\/strong> &#8211; Generates pauses of a certain duration (in milliseconds)<\/p>\n\n\n\n<p><strong>&lt;label&gt;<\/strong> &#8211; Allows us to identify a specific part of our scenario and then if we want to be able to go directly to that request if any condition is met<\/p>\n\n\n\n<p><strong>&lt;nop&gt;<\/strong> &#8211; Has no effect at the SIP protocol level, but allows us to perform specific actions that we will see below<\/p>\n\n\n\n<p>For a complete and more detailed list of these commands with their use examples, see <a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Create+your+own+XML+scenarios\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">here<\/a>.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Actions\"><\/span><strong>Actions<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>In any instance of a \u201crecv\u201d or \u201cnop\u201d command we can use actions of different types, among them we have: the use of regular expressions, play audio or video, assign values \u200b\u200bto variables, jump to another point on the scenario, etc.<\/p>\n\n\n\n<p>For a complete and more detailed list of these actions with their use examples, see <a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Actions\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">here<\/a>.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Keywords\"><\/span><strong>Keywords<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>When we put together our messages, SIPp provides us with very useful keywords that are used to tell SIPp that it has to do something with them. Among the most used are:<\/p>\n\n\n\n<p><strong>[remote_ip]<\/strong> and <strong>[remote_port]<\/strong> &#8211; IP and port values \u200b\u200bwith which we want to communicate<\/p>\n\n\n\n<p><strong>[local_ip]<\/strong> and <strong>[local_port]<\/strong> &#8211; Values \u200b\u200bof our IP and local port<\/p>\n\n\n\n<p><strong>[call_id]<\/strong> &#8211; Saves the value of the call identifier<\/p>\n\n\n\n<p><strong>[authentication]<\/strong> &#8211; Creates authentication header (We will see examples later)<\/p>\n\n\n\n<p><strong>[fieldX]<\/strong> &#8211; Uses values \u200b\u200bobtained from external files (We will see examples later)<\/p>\n\n\n\n<p>The following figure shows a typical SIP request. The first block of information represents all of our headers. Then, separated by a blank line, we find at the end of the request, the block that contains the information that belongs to the body.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/XQDOzTHoVvAF9V65Wg1hHoUT_pmWHMCEAyM5hBtQ367I5sflLCatcfVeOsT4gFrQiWIg2_WZYOsF59F4FX7rxOVssc0rD17viACy-2_wp28LLFDu4x-xgiu846zyEd3n_x2PYIYz\" alt=\"screenshot of a SIP request in voip performance testing\"\/><\/figure>\n\n\n\n<p>In the headers, we find information about the communication itself, such as: the VIA that we are going to use, who sends (FROM) and who receives the message (TO), what is the CALL ID, etc. And in the body, we usually find the configuration of what the content of that call will be, such as: where it will be sent from, what type it will be (audio or video), what format it will have, etc.<\/p>\n\n\n\n<p>In both the headers and the body we can see examples of the use of the keywords we mentioned above.<\/p>\n\n\n\n<p>On the other hand, a typical status message in SIP looks like this.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/W_cptG0qBbX8XVG6rgtJlR9WuUz1GJ_b71ag3mocBNlhUS3DBHjeeEHv0TBOzaW85gDH8b5FfLBsbJumqogS4-vYPZYk6P-mtJLiHe3Lpayb7Dnsm87IhwluQxLLNkBqEFOO885D\" alt=\"status message in SIP screenshot\"\/><\/figure>\n\n\n\n<p>You will notice that the keywords change from those in our previous order message. Now the keywords are preceded by the word &#8220;last&#8221;. This is because all the status messages are the consequence of a previous request and share the vast majority of their headers with that request. SIPp allows us to place this word &#8220;last&#8221; to access the last known configuration of that header (in the example it would be the one received in the INVITE request) and reuse it in this header.<\/p>\n\n\n\n<p>For a complete and more detailed list of these keywords with their usage examples see <a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Structure+of+client+%28UAC+like%29+XML+scenarios\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">here<\/a>.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Results_in_SIPp\"><\/span><strong>Results in SIPp<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Now we\u2019ll go over what we will see on screen when executing SIPp, using the following image as a reference:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/oBziC2RWnXX_xmCxo65U1LsG0R8Ylkbgaa0s5OA_px1YIF-zgWdLrrgvaPfejle7L7qBIQkka34FrEm7gF0tQtXBCOH0LG-olTlnWhVkHFxRgVA5mSiu-P8UAKAD5mfhhubErGxa\" alt=\"SIPp execution screen for voip performance testing\"\/><\/figure>\n\n\n\n<ol><li>This is the script configuration<\/li><li>This is the flow that the call will have. The arrows indicate whether the message is sent or received<\/li><li>This is the status of each message (Correct, retransmissions or errors)<\/li><li>These are the warnings or errors that occurred during the execution, if any<\/li><\/ol>\n\n\n\n<p><strong>NOTE:<\/strong> Retransmissions occur when a message does not receive a response in a period of time set by the user (by default 500 milliseconds) or when the response received is not what is expected.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Other_Elements_Used\"><\/span><strong>Other Elements Used<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In our testing project for Yo Te Escucho, we had to make use of other elements that we\u2019ll also explain below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Variables\"><\/span><strong>Variables<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>In more complex scenarios, we will need to store information that will be reused in other parts of the script or even in other calls. To do this, we will use variables.&nbsp;<\/p>\n\n\n\n<p>In this particular project, we used variables for the different users and defined them as follows,&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/gpzwCqAkGyqWMgel8SQgbtYRiS3hNAPzjlney7Bhbr0GAn8cjd7bRvejaBi1Ypv4NoEjdUQydMMvw9y5jWGObIoqcyuYNPDBvWPSF733KuVFokdtutsJPkyoS1_3CZ2wgy5XlvA6\" alt=\"variable example\"\/><\/figure>\n\n\n\n<p><strong>User<\/strong> is the name of the variable and <strong>002<\/strong> its value. To make use of this variable, you can call it: <strong>[$ user]<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Regular_Expressions\"><\/span><strong>Regular Expressions<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The use of regular expressions in SIPp allows us to obtain and store specific information about a message to be able to use it later.<\/p>\n\n\n\n<p>If you do not know the basics of regular expressions, we recommend this <a href=\"https:\/\/regexone.com\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">website, <\/a>which explains how they work through exercises.<\/p>\n\n\n\n<p>As shown below, the use of the &#8220;ereg&#8221; action in SIPp requires several data:<\/p>\n\n\n\n<p><strong>regex<\/strong> &#8211; the regular expression<\/p>\n\n\n\n<p><strong>search_in<\/strong> &#8211; the place where we will look for that regular expression<\/p>\n\n\n\n<p><strong>header<\/strong> &#8211; name of the header, we will only put it when we search in a header<\/p>\n\n\n\n<p><strong>check_it<\/strong> &#8211; If the expression is not found, it marks the call as failed<\/p>\n\n\n\n<p><strong>assign_to<\/strong> &#8211; name of the variable where we will store the found value<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/2kMIokDtI0e3krazQLtYPtGmCvO7iEmARwhqFpo28JXndMxT5mEeiAu0UKgrcTGCWbcP-Ux7magA5vD_chq2kD6sfW0No_KAVTlkvySAqymuCXPm7dFEC2Vc8499_qOBqixx5VQw\" alt=\"variable example 2\"\/><\/figure>\n\n\n\n<p>In this case, we looked for the regular expression &#8220;;. *&#8221; to be found in the &#8220;hdr&#8221; (header) that has the name &#8220;To&#8221;. It will not mark the call as failed if it does not find that expression (&#8220;false&#8221;) and if it finds it, it will save its value in a variable named &#8220;3&#8221;.<\/p>\n\n\n\n<p>For more information on the use of regular expressions in SIPp, go to this <a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Regular+expressions\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">link<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"CSV_files\"><\/span><strong>CSV files<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To insert values in\u200b\u200bto the scenarios from a CSV file, the following command can be used in the console: <strong>-inf file.csv<\/strong><\/p>\n\n\n\n<p>The first line of the file must specify how the data will be read:<\/p>\n\n\n\n<ul><li>SEQUENTIAL: If we want it to be read sequentially<\/li><li>RANDOM: If we want them to be read randomly<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/v4SQXAzqkCPBr1dk7AtQRVgEmcZeqb46w934rrZwYkqxj3i7n-_FCLRYT60uDLMC2wCLSSZLMZOOjBb43Fwq9yQi3lk8VWwiXX4u0fA8oHNlU5hbutLrDq3F0oL8eyEH74XyDSGQ\" alt=\"screensshot of csv file\"\/><\/figure>\n\n\n\n<p>Each line corresponds to a call and is delimited with &#8220;;&#8221;. Wherever in the script the keyword &#8220;[field0]&#8221; appears, it will be replaced by the value &#8220;042&#8221; on the first call, &#8220;043&#8221; on the second call, and so on. Upon reaching the end of the file, SIPp will start reading the file from the beginning.<\/p>\n\n\n\n<p>For more information on this topic, visit this<a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Injecting+values+from+an+external+CSV+during+calls\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\"> link<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Audio_Files\"><\/span><strong>Audio Files<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>SIPp allows us to send audio or video files which is done by simply using the action <strong>&#8220;rtp_stream&#8221;<\/strong> as shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/Xy1fkz50YmODgAbPPUD4ykC-L7IXU6Db0nOiEMkP3Ow1UvxGwqUTsqmGIbVneXVkhvafX35Qom3JoZXkoY6WBWi_GbXs4PYEaBBJ2RcqeHY7eO5351OqgDw24XIgdX7YX1aZhNF4\" alt=\"action &quot;rtp_stream&quot; screenshot\"\/><\/figure>\n\n\n\n<p>After the name of the file to be played, we can place a \u201c,\u201d and a number that will indicate the number of times that file will be played (by default it is 1 and if we put -1 it will play it without stopping).<\/p>\n\n\n\n<p>On the other hand, it is somewhat complex to meet the requirements regarding the configuration of the audio file so that SIPp can play it. This <a href=\"https:\/\/g711.org\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">website<\/a> is very useful if you need to transform audio files to different formats so that they can be played correctly in the call (we recommend using the \u201ca-law\u201d option).<\/p>\n\n\n\n<p>To know more about how to send audio or video using SIPp see the following <a href=\"http:\/\/sipp.sourceforge.net\/doc\/reference.html#Media%2FRTP+commands\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">link<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Authentication\"><\/span><strong>Authentication<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>SIPp supports two types of authentication algorithms, MD5 and AKA. This authentication is easily done using SIPp. When we receive a 401 or 407 message with an authentication request, we must set the auth = \u201dtrue\u201d configuration as shown below, with this SIPp will know where to obtain the necessary information to perform the algorithms.<\/p>\n\n\n\n<p><strong>&lt;recv response = &#8220;407&#8221; auth = &#8220;true&#8221; \/&gt;<\/strong><\/p>\n\n\n\n<p>In the next request, we will be able to send between our headers the generated authentication using the keyword <strong>[authentication]<\/strong>. In our case, we had to authenticate against the server using MD5, adding the username and password values \u200b\u200bin the keyword as follows.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/4nvFxAMMTJHUvT18O2NCr4IQP-iz3ZY2RdihnjrXlqsNIIGci8AjHuFwofEB7TF9b1mtR5SFNTcQaZ5aN-pCx1A4g-bBoUHkfqNnkW8lS0IWk0ZAe-xHibsQOKmjA7jchNsYng9h\" alt=\"\"\/><\/figure>\n\n\n\n<p>With this, SIPp will automatically generate the header with all the necessary information to authenticate against the server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Next_and_Label\"><\/span><strong>Next and Label<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>It\u2019s possible to execute a scenario in a non-sequential way, being able to jump from one part of the scenario to another when some condition is met.<\/p>\n\n\n\n<p>For this we will use the &#8220;label&#8221; command that will indicate a reference point in our scenario and the &#8220;next&#8221; parameter that placed in the command of our choice will cause that when this is fulfilled the scenario will jump to the point where the indicated label is located.<\/p>\n\n\n\n<p>In the following image, we see an example of a call that is made and then waits for a 486 busy call code that may or may not arrive, that is why the \u201coptional\u201d parameter is activated.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2020\/08\/img1-min.png\" alt=\"\" class=\"wp-image-13443\"\/><\/figure>\n\n\n\n<p>When the busy call code is received, the scenario returns to the \u201cbusy\u201d label, as indicated by the \u201cnext\u201d parameter and retries the call until it is able to communicate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Final_Thoughts_on_SIPp_for_VoIP_Performance_Testing\"><\/span><strong>Final Thoughts on SIPp for VoIP Performance Testing<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>This VoIP performance testing project was a challenge that involved a lot of learning, but it was also very motivating, due to what we could learn and the fact that it meant we could help create an amazing tool for those in need.&nbsp;<\/p>\n\n\n\n<p><strong>SIPp is a very powerful and simple tool to use.<\/strong> Making good use of keywords takes care of practically all the script configuration, leaving us in charge of building the call flow. It\u2019s important to point out how it lets you bring information from external files for more versatility when setting parameters and that you can transmit audio and video files to make the call as real as possible.<\/p>\n\n\n\n<p>On the other hand, we believe that it does have some room for improvement. SIPp has a GUI that <em>tries <\/em>to make script assembly easy. At the outset, we didn\u2019t find it intuitive, since we didn\u2019t already know the logic behind the assembly of the scripts. For this reason, we chose to write the scripts by hand. If you have prior knowledge of the SIP protocol, the interface can be beneficial to you. Otherwise, you have to read the documentation that explains the use of this GUI or the SIPp documentation to be able to use it correctly.&nbsp;<\/p>\n\n\n\n<p>Another thing that we do like about it though is the possibility of working with more than one call-id per script. This greatly facilitates the work in cases like ours, in which the user registration and the communication itself are carried out in two different call ids.<\/p>\n\n\n\n<p>I should also mention that we didn\u2019t go into complete detail in this post about <em>all <\/em>of SIPp\u2019s functionalities (as we only used some of them), but they should be considered if you are going to evaluate SIPp\u2019s capabilities for yourself!&nbsp;<\/p>\n\n\n\n<p class=\"has-background has-very-light-gray-background-color\"><strong>Want to try it for yourself? <\/strong>Here you can find <a href=\"https:\/\/github.com\/prichieri\/YoTeEscucho\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">the repository with the scripts<\/a> that we used for this VoIP performance testing project so that you can use them as a reference!<br><\/p>\n\n\n\n<!-- Go to www.addthis.com\/dashboard to customize your tools --><script src=\"\/\/s7.addthis.com\/js\/300\/addthis_widget.js#pubid=ra-58d80a50fc4f926d\" type=\"text\/javascript\"><\/script>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Recommended_for_You\"><\/span>Recommended for You<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><a rel=\"noreferrer noopener\" aria-label=\"Load Testing a Video Streaming Service for 85,000 Concurrent Viewers (opens in a new tab)\" href=\"https:\/\/abstracta.us\/why-us\/case-studies\/load-testing-video-streaming\" target=\"_blank\">Load Testing a Video Streaming Service for 85,000 Concurrent Viewers<\/a><br><a href=\"https:\/\/abstracta.us\/blog\/performance-testing\/how-to-make-a-performance-test-plan\/\">How to Make a Performance Test Plan<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How we used SIPp for VoIP performance testing over the SIP protocol Not too long ago, some of my colleagues and I helped to run performance tests for a new mobile app with a hotline called \u201cYo Te Escucho\u201d (which translates in English to \u201cI&#8230;<\/p>\n","protected":false},"author":51,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[738,32,61],"tags":[50],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.0.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>VoIP Performance Testing for a Hotline App | Abstracta<\/title>\n<meta name=\"description\" content=\"From our recent VoIP performance testing project, Abstracta engineers discovered how to use SIPp to test over the SIP protocol. See how it&#039;s done!\" \/>\n<meta name=\"robots\" content=\"index, follow\" \/>\n<meta name=\"googlebot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta name=\"bingbot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"VoIP Performance Testing for a Hotline App | Abstracta\" \/>\n<meta property=\"og:description\" content=\"From our recent VoIP performance testing project, Abstracta engineers discovered how to use SIPp to test over the SIP protocol. See how it&#039;s done!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog about AI-powered quality engineering for teams building complex software | Abstracta\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/AbstractaQA\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-23T19:30:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-05T21:22:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/abstracta.us\/wp-content\/uploads\/2020\/08\/Copy-of-boom-ecommerce-pandemia-experiencia-compra-chile.png\" \/>\n\t<meta property=\"og:image:width\" content=\"560\" \/>\n\t<meta property=\"og:image:height\" content=\"315\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@AbstractaUS\" \/>\n<meta name=\"twitter:site\" content=\"@AbstractaUS\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/abstracta.us\/blog\/#website\",\"url\":\"https:\/\/abstracta.us\/blog\/\",\"name\":\"Blog about AI-powered quality engineering for teams building complex software | Abstracta\",\"description\":\"AI-powered quality engineering\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/abstracta.us\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/abstracta.us\/wp-content\/uploads\/2020\/08\/dustin-belt-lg4fM9Y2pGg-unsplash-min-1024x683.jpg\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/#webpage\",\"url\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\",\"name\":\"VoIP Performance Testing for a Hotline App | Abstracta\",\"isPartOf\":{\"@id\":\"https:\/\/abstracta.us\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/#primaryimage\"},\"datePublished\":\"2020-08-23T19:30:32+00:00\",\"dateModified\":\"2025-05-05T21:22:38+00:00\",\"author\":{\"@id\":\"https:\/\/abstracta.us\/blog\/#\/schema\/person\/9888ff3f07fed974a93db69a7b8a9608\"},\"description\":\"From our recent VoIP performance testing project, Abstracta engineers discovered how to use SIPp to test over the SIP protocol. See how it's done!\",\"breadcrumb\":{\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/\",\"url\":\"https:\/\/abstracta.us\/blog\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/\",\"url\":\"https:\/\/abstracta.us\/blog\/performance-testing\/\",\"name\":\"Performance Testing\"}},{\"@type\":\"ListItem\",\"position\":3,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\",\"url\":\"https:\/\/abstracta.us\/blog\/performance-testing\/voip-performance-testing\/\",\"name\":\"VoIP Performance Testing for a Mental Health Hotline App\"}}]},{\"@type\":[\"Person\"],\"@id\":\"https:\/\/abstracta.us\/blog\/#\/schema\/person\/9888ff3f07fed974a93db69a7b8a9608\",\"name\":\"Mikaella Mateos\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/abstracta.us\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3445d1f7a0fd7e68d909ec0047dd135a?s=96&d=blank&r=g\",\"caption\":\"Mikaella Mateos\"},\"description\":\"Software Tester, Abstracta\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/13421"}],"collection":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/comments?post=13421"}],"version-history":[{"count":13,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/13421\/revisions"}],"predecessor-version":[{"id":13445,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/13421\/revisions\/13445"}],"wp:attachment":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/media?parent=13421"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/categories?post=13421"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/tags?post=13421"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}