Vincenzo Marrazzo is a Test Automation Specialist. He has 10 years of experience in various context both with open-source technologies and commercial ones. His primary activities are automation testing and performance testing. Vincenzo currently works at Altran Italia.

Learn JMeter in 5 Hours

Start Learning
Slack

Run massively scalable performance tests on web, mobile, and APIs

Oct 25 2017

How to Load Test Podcasts with JMeter

Podcasting is a digital recording of media content (typically audio or video) that is made available to users on the internet through a media content file. Podcasts are portable and can reside on mobile devices, so they can be transported anywhere. They can also be heard in live media streaming. Podcasts can range in length from a few minutes to a few hours. This blog post will show how to create an Apache JMeter™ scenario for testing podcast services, while simulating a load of client requests for the podcasts’ content list - the RSS.

 

How Podcasting Works

 

1. The podcast owner creates new content and uploads the media file to a sharing network location.

 

2. To listen to/view a podcast, the podcast service needs to be queried by a client. The content is retrieved to the user device through a content list called “RSS feed”. This list is an XML that lists all the media contents in a channel the user subscribed to, in chronological order of publication, reachable via URL. So, the second step is inserting the new media content that was created into the RSS feed. This is the activity that informs the podcast service that the new content entry is available at a certain URL location.

 

3. Now, the RSS feed can be fetched by the client. The “RSS Feed” is dynamic and can be generated when a client requests it. Multiple user clients can fetch the RSS feed concurrently, many times, since servers can handle multiple content channels.

 

4. Finally, the client, programmatically or manually, fetches the final content files by using the URL included in the RSS feed. These files might be located on a different server than the one that generates the RSS feed. The client device has now a local copy of the media files, which can be used for offline usage.

 

Podcast Load Testing Scenario

 

Our load testing scenario will focus on step 3 - querying the RSS feed. We will check that the client gets the RSS feed file in the correct structure, and that the server is performing well.

 

To load test fetching the RSS feed with JMeter, we will use a HTTP Request with a JSR223 Assertion and the Constant Throughput Timer. Each thread will query the RSS Feed, and via the JSR223 assertion proceed to validate the response structure. We chose Groovy as the assertion language because it's the best choice for expressing your performance needs. The Timer will be used for defining the number of iterations to be performed in the time unit.

 

We will use this example RSS Feed URL: http://linuxactionnews.com/rss

 

1. Add a Thread Group to your Test Plan.

 

Add -> Threads -> Thread Group

 

Select the “Thread Group” node and:

  • Fill the “Number of Threads” field with 2
  • Fill the “Ramp-Up Period” field with 60
  • Check the “Forever” flag on the “Loop Count” row
  • Check the “Scheduler” flag
  • Fill the “Duration” field with 300

 

load testing podcasts

 

2. Now, add a Constant Throughput Timer as a child element to the main “Thread Group” node. This node defines how many iterations will be performed during the time unit.

 

Right click on Thread Group -> Add -> Timer -> Constant Throughput Timer

 

  • Fill the “Target throughput” field with “6”
  • In the “Calculate Throughput based on” menu select “all active threads in current thread group”

 

podcasts, jmeter

 

3. Now let’s add the element for fetching the RSS feed, as a child element to the Thread Group. This is done by the HTTP request , which simulates client action.

 

Right click on Thread Group -> Add -> Sampler -> HTTP Request

 

  • Fill the “Protocol” field with “http” (or left blank)
  • Fill the “Server Name” field with “linuxactionnews.com”
  • Fill the “Path” field with “/rss”
  • Leave the “Method” field as “GET”

 

how do i load test podcasts

 

4. Add the default configuration for headers to the “Test Plan”.

 

Right click on Test Plan -> Add -> Config Element -> HTTP Header Manager

 

  • Click the “Add” button and insert “Accept-Charset” as name and “UTF-8” as value
  • Click the “Add” button and insert “Accept” as name and “application/xml” as value

 

load testing my podcast

 

This step is necessary to configure the file type and its charset format. The correct body format is important during the assertion step.

 

5. Add two listeners to analysis test execution:

 

  • Right click on Test Plan -> Add -> Listeners -> Aggregate Report
  • Right click on Test Plan -> Add -> Listeners -> View Results Tree

 

the best way to load test podcasts

 

The choice of listeners depends on which condition you want to check. With the listeners used here, it’s possible to observe the error rate. You can also analyze which response failed and why.

 

6. Now it’s necessary to add the assertion component, to verify the correctness of the response body. As mentioned, we will use the “JSR223 Assertion” with Apache Groovy.

 

Right click on HTTP Request -> Add -> Assertions -> JSR223 Assertion

 

  • Leave the “Language” field as “groovy”
  • Check the “Cache compiled script if available” field
  • Now it’s time to fill the “Script” field (in the next step)

 

jmeter, media streaming, podcasts

 

7. Fill in the Script field with:

 

// #1
import javax.xml.xpath.*
import javax.xml.parsers.DocumentBuilderFactory

// in case of unexpected condition this field contains descriptive message
def failureMessage = ""

// #2
def response = new String(prev.getResponseDataAsString().getBytes("ISO-8859-1"), "UTF-8")

// #3
def processXml(String xml, String xpathQuery) {
  def xpath = XPathFactory.newInstance().newXPath()
  def builder     = DocumentBuilderFactory.newInstance().newDocumentBuilder()
  def inputStream = new ByteArrayInputStream(xml.bytes)
  def records     = builder.parse(inputStream).documentElement
  xpath.compile(xpathQuery).evaluate(records, XPathConstants.NODESET)
}

try {
	// fetch all record that contains media content
	def pubblicationUrl = processXml( response, '//enclosure[(@type=\'audio/mp3\' or @type=\'audio/mpeg\' or @type=\'video/mp4\') and string(@url)]/@url')

	// fetch publication date
	def pubblicationDate = processXml( response, '//item/enclosure[string(@url)]//ancestor::item/pubDate' )

	// print in debug a bit of log
	(0..<pubblicationUrl.getLength()).each{
	 log.debug("#^^# Url  " + pubblicationUrl.item(it).getTextContent())		
	 log.debug("#^^# Date " + pubblicationDate.item(it).getTextContent())
	}	

    // #4
    if (pubblicationUrl.getLength() - pubblicationDate.getLength() != 0) {
    	  log.error("XXXX Nr Url ${pubblicationUrl.getLength()} and Nr Date ${pubblicationDate.getLength()}" )
       failureMessage = "Unexpected condition number of media contents does not match with number of pubblication date!"	    	
    }
    else if ( pubblicationUrl.getLength() == 0 ){
    	  log.error("XXXX RSS Feed is empty!" )
       failureMessage = "XXXX RSS Feed is empty!"
    }
    else // #5
    	  vars.put("NR_CONTENTS", pubblicationUrl.getLength().toString())

} catch (Exception e) {
	failureMessage = e.getMessage()
	log.error("XXXX Error message " + failureMessage)
}

// Print error messages if any
if (failureMessage?.trim()) {
    AssertionResult.setFailureMessage(failureMessage);
    AssertionResult.setFailure(true);    
}

 

Here are the described code details:

 

1. The assertion logic is based on XML and XPATH, so this is the required library to import.

 

2. Did you remember to uniform the header with the returned body? Sometimes the server returns strange data format/char and it's necessary to put a patch in the code.

 

3. This is the core function that takes the XML body and XPath query as input, and as output returns a data structure with all the elements in the XML that match the XPathQuery.

 

4. This is an example of validation logic. If the number of media content does not match the number of publications, raise an error. You can add any criteria that you need here.

 

5. If everything is ok, put the number of fetched contents into a JMeter variable. This is useful for reporting.

 

Result Analysis

 

The assertion provides pass/fail status according to the behaviour of the tested podcast. You can add more complex verification to this part if you want to.

 

testing podcasts with jmeter

 

With the listener “Bytes Throughput Over Time” it's also possible to monitor if the system under load maintains constant data transmission.

 

jmeter, podcasts, media streaming

 

With the listener “PerfMon Metrics Collector” (and its relative agents), it's possible to check if the server consumes resources.

 

That it! You can now load test your own podcast to see that all of your listeners won’t crash it. You can also learn more JMeter for free from our JMeter academy, which has basic and advanced courses.

 

Click here to subscribe to our newsletter.

 

To try out BlazeMeter, which enhances JMeter features, just put your URL or JMX file in the box below and your test will start in minutes. You can also request a demo.

Interested in writing for our Blog?Send us a pitch!

Your email is required to complete the test. If you proceed, your test will be aborted.