Test your service on Sonos

Run the automated self-test

The Python Self-Test Suite has automated tests that test the back-end functionality of your implementation without using the Sonos app. Running these tests is required and a clean run must accompany your submission. For more details and a list of requirements, see the README file included in the self-test.

ConfigurE the self-test

Download the self-test and extract the files to a location of your choice. Fill out the smapiConfig.cfg file in the smapi\service_configs folder with information about your service. This information should match what you used to add your service with customSD, see Test your service on Sonos for details.

Use the information below to help you configure your smapiConfig.cfg file.

enter your Service Name

Enter the name of your service as it appears in your Sonos Labs application. Leave the serviceId entry blank as this is used for internal testing by Sonos. 

Required for all services.

Example:

[Service Name]
serviceName = Your Service
serviceid =

supply insecure and secure Endpoints

Use this section to supply the two endpoints used to access your service. Please enter the same endpoints that you supplied in your Sonos Labs application. The self-test uses these endpoints to send SOAP requests to your service.

Required for all services and both entries must be filled out.

Example:

[Endpoints]
insecure = http://musicservice.example.com/soap
secure = https//musicservice.example.com/soap

supply the location of your Strings file

In this section, supply the location of your strings.xml file. Please enter the same URL that you provided in your Sonos Labs application. The self-test will run a set of tests that validate your strings file against an XSD. 

Required if you supply this file in your application. If you do not supply a strings file in your application, you can leave this section blank.

Example:

[Strings file]
stringsLocation = http://musicservice.example.com/strings.xml

supply the location of your Presentation map

In this section, supply the location of your presentation map xml file. Please enter the same URL that you provided in your Sonos Labs application. The self-test will run a set of tests that validate your presentation map file against an XSD. Note: This test requires that you have the lxml toolkit installation.  Please see the README file for installation instructions. 

Required if you supply this file in your application. If you do not supply a presentation map in your application, you can leave this section blank.

Example:

[Present Map File]
pmapLocation = http://musicservice.example.com/pmap.xml

set your Authentication type to true

In this section, set the type of authentication your service uses to "True”. This should match what you enabled in your Sonos Labs application. The self-test will use this information to determine how to authenticate with your service. Leave all other entries as "False". In the example below, the service uses device link authentication.

If your service uses app link authentication, set the oauth field to "True". The self-test does not exercise the app link authentication mechanisms yet, but you can provide authentication details for the rest of the testing in the device link section. See the App link/browser authentication section below for details.

This is required for all services.

Example:

[Authentication Type]
sessionID = False
anonymous = False
stateless = False
oauth = True

how to set up Devicelink authentication

This section is for services that use OAuth/DeviceLink authentication. This is how our tests will authenticate with your service. The easiest way to fill this out is to create a householdId and use something like SoapUI to send a getDeviceLinkCode. Then you can authenticate with your website and then send a getDeviceAuthToken request with the householdId and linkCode. Take the token in the getDeviceAuthToken response and enter it for the token value. Enter the same householdId and if your service also returns a privatekey, enter that as well. Note: The household ID does not need to be a valid household ID and can be one you make up if it is consistent throughout the file.

This is only required for services that use OAuth/DeviceLink authentication.

Note that if you implemented the older device link authentication, you need to run this test. If your implementation uses browser authentication with getAppLink, we don't have an updated test for you yet. See the App link/browser authentication section below for details.

Example:

[Device Link]
householdId = myServcieHouseholdId
token = myTokenReturnedBygetDeviceAuthToken
privateKey = leaveMeBlankOrEnterPrivateKeyHereIfUsedByYourService

How to Set up getapplink authentication

This section is for services that use getAppLink for app link authentication. This is how our tests will authenticate with your service. The self-test doesn't fully support app link authentication, but you still need to authenticate to perform the rest of the self-test. Because there is no section for app link authentication, you will use the <deviceLink> object in the getAppLink request to populate the [Device Link] section of the configuration file. Follow these steps:

  1. Use a tool like SoapUI to send a getAppLink request to your service. Make sure to create a householdId and include it in your request. This household ID doesn't need to be valid, but it does need to be consistent throughout your configuration file.
  2. Take the <regUrl> and <linkCode> in your service's response and use a browser to authenticate with your service.
  3. Use the householdId and linkCode from your getAppLink response to send a getDeviceAuthToken request to your service. You service should return a token in the response.
  4. Copy the token into in the [Device Link] section of your configuration file. Enter the householdId that you used here as well.

How to set up session authentication

This section is for services that use sessionID authentication. These tests use the different account types to test different authentication scenarios. One test authenticates supported accounts and uses them to run more tests. Another test uses unsupported, expired, and unsupported territory accounts to test error conditions and messaging. If your service only has one type of account, just add account information in the supportedAccount entry. If your service has multiple tiers of accounts and Sonos only supports one of those, add an unsupported account. If accounts can expire, add an expired account. If you have territories that are not supported on Sonos, add an unsupported territory account. Leave account types you don’t have blank. In all cases, use the accounts you have supplied in the Sonos Labs application. In the example below, the service has more than one account type and has supplied the account information for a supported account, an unsupported account, and an account in a country that isn’t supported on Sonos. The service does not have expired accounts so they left that entry blank.

Required for services that use sessionID or Stateless authentication.

Example:

[Accounts]
supportedAccount = supportedOnSonos@example.com
supportedPassword = supportedPassword
unsupportedAccount = unsupportedOnSonos@example.com
unsupportedPassword = unsupportedPassword
expiredAccount =
expiredPassword =
unsupportedTerritoryAccount = countryNotSupportedOnSonos@example.com
unsupportedTerritoryPassword = countryNotSuportedPassword

select your service Capabilities

This section distinguishes the features of your service. The self-test uses information in this section to determine which tests to run or skip based on the feature set of your service. The capabilities listed match those found in your Sonos Labs application. Set the capabilities that you enabled in your Sonos Labs application to "True". Leave the capabilities that you didn’t enable set to "False". In the example below, the service supports search, favoriteTracks, userContentPlaylists (playlist editing), and extendedMetadata. Note that extenededMetadata is required and must be set to "True" and favoriteArtists is not supported and should remain “False”.

This is required for all services.

Example:

[Capabilities]
search = True
favoritesTracks = True
favoritesAlbums = False
favoritesArtists = False
userContentPlaylists = True
playbackLogging = False
extendedMetadata = True
eventAndDurationLoggingDuringPlayback = False
accountLogging = False

configure Additional settings for hls and ephemeral content

This section identifies certain attributes of the service so that the self-test can run in an accommodating manner if necessary. The self-test uses the information in this section to determine if certain tests need to be run and to determine if test content should be updated dynamically as the tests run (sometimes IDs expire once playback is completed as a security measure). The first flag, "hlscontent", designates whether hlscontent is present on the service. The flags listed below which are prepended with "ephemeral" identify what content types are ephemeral (frequently changing/expiring) and need to be updated dynamically throughout the tests. In the example below, the service has ephemeral track IDs but all other content types are constant/non-changing and HLS content is not present in the service.

This is required for all services.

Example:

[Additional Settings]
hlscontent = False
ephemeraltrackid = True
ephemeralartistid = False
ephemeralalbumid = False
ephemeralstreamid = False
ephemeralprogramid = False

set up Favorites containers

Use this section if your service supports adding favorites using the Sonos app. The self-test will attempt to add and remove the supported content type using createItem and deleteItem calls. The test will then check the appropriate favorites container to verify the content was successfully added and removed.

In this section, add the ID to the container that will house the favorites content. For instance if your service adds all favorited tracks to a container with an ID of "user:favorite:tracks", put that ID in the faveTracks entry. If a user can create a station from a streaming track, use the ID of the container that the newly created station is placed in. Leave the entries your service does not support blank. In the example below the service only supports favoriting tracks. Note that faveArtists should remain blank as that functionality is not supported on Sonos.

This is required if your supports adding favorites using the Sonos app.

Example:

[Favorite Containers]
faveArtists =
faveAlbums =
faveTracks = user:favorite:tracks
faveOther =

set up Search containers

Use this section if your service supports search. Enter the IDs for your search categories. These are the IDs that are returned when running a getMetadata(search) call. The self-test will use the IDs to run a series of search requests against each search category. The searchOther entry is for any type of search that is not covered by artist, album, track, stream, or program. In the example below, the service supports searching on artists, tracks, programs, and playlists.

This is required if your service supports search.

Example:

[Search Containers]
searchArtist = search:artists
searchAlbum =
searchTrack = search:tracks
searchStream =
searchProgram = search:programs
searchOther = search:playlists

set up Test content

The test uses this section to grab sample content without having to crawl your service to get applicable IDs. Each content type entry is an ID that maps back to content in your service and the corresponding title associated with that piece of content. Please include IDs and titles for all the content types your service supports. This test will use the sample content for browse requests, search queries and validation, and favorites functionality (if applicable). Leave the entry blank for content types your service doesn’t support. Use the “other” field if your service supports searching for something other than artist, album, track, stream, or program. If your service supports userContentPlaylists, the “playlist folder” field should be the ID of the container that houses user editable playlists. If your service supports subscribing to other user’s playlists, please add the ID of a subscribed to playlist in the “playlist share” field. The example below indicates the service supports tracks, artists, and program radio.  

This is required for all services.

Example:

[Test Content]
track = track:1234
track title = Stairway To Heaven
album = album:12
album title = name of album
artist = artist:45
artist name = name of artist
stream =
stream title =
program = program:123
program title = name of program
other =
other title =
playlist = playlist:123
playlist title = title of playlist
playlist folder = testuser:playlists
playlist share = testuser2:playlist:123

set up ExtendedMetadata text

Use this section if your service implementation returns a relatedText node in your getExtendedMetadata response. You will enter in the type that you have configured in your getExtendedMetadataResponse. In the example below, the service can return an ARTIST_BIO ExentededMetadata Text type.

This is required if your service returns a relatedText node in your getExtendedMetadata response for any supported content.

set up ExtendedMetadata browse

Use this section if your service implementation returns a relatedBrowse node in your getExtendedMetadata response. Enter in the types that you have configured in your getExtendedMetadataResponse. In the example below, the service can return RELATED_ARTISTS and RELATED_PROGRAMS ExtendedMetadata text types.

This is required if your service returns a relatedBrowse node in your getExendedMetadata response for any supported content.

Example

[ExtendedMetadata Browse]
browseArtist = RELATED_ARTISTS
browseAlbum =
browseTrack =
browseProgram = RELATED_PROGRAMS
browseStream =
browseOther =

enter the same Polling interval as in your Sonos labs application

Fill this section out with the same polling interval value (in seconds) that you entered in your Sonos Labs application. In the example below, the service has configured a polling interval of 60 seconds.

This is required for all services.

Example:

[Polling Interval]
interval = 60

Set strict Validation settings to true

This section houses the Validation Settings. Currently, the only Validation Setting available is 'strict' which should be set to True to enforce strict WSDL compliance.

Example:

[Validation Settings]
strict = True

Run the self-test suite

The python script, suite_selftest.py includes calls to all functional test modules provided in the package except for the Device Link Test explained in the next section. The suite_selftest.py script is in the smapi/content_workflow directory and you should run it from there. By default, the suite will load the configuration defined by smapiConfig.cfg in the smapi/service_configs directory.

Example: 

Run "python suite_selftest.py" 
The test suite uses the default configuration file 'smapiConfig.cfg'.

Optionally, you can add the --config parameter to use a different .cfg file.

Example:

python suite_selftest.py --config yourname.cfg

Run the devicelink test

This is a semi-automated test that takes several steps. This is only relevant to services that use the older device link authentication, using getDeviceLinkCode. If you have implemented browser authentication using getAppLink, we don’t have an updated test for you yet.

Before starting the test:

  • Make sure you have enabled device link authentication in your configurations file by setting the oauth field to “True” under [Authentication Type].
  • Make sure that you have filled in the householdid field under [Device Link].

To run the test:

  1. Run devicelink_manual.py to start the test. The device link code gets generated based on the household ID entered in the configuration file and is displayed in the console along with a registration URL.
  2. Navigate to the registration URL and log in.
  3. Enter the registration code.
    You have 8 minutes to complete these steps. The test will ping every five seconds for an authentication token. Note that NotLinkedRetry faults are normal during this phase.

Once the device link process completes, the key and token will be displayed in the console.