net.pms.configuration.RendererConfigurationTest.java Source code

Java tutorial

Introduction

Here is the source code for net.pms.configuration.RendererConfigurationTest.java

Source

/*
 * PS3 Media Server, for streaming any medias to your PS3.
 * Copyright (C) 2008  A.Brochard
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License only.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package net.pms.configuration;

import static net.pms.configuration.RendererConfiguration.getRendererConfigurationBySocketAddress;
import static net.pms.configuration.RendererConfiguration.getRendererConfigurationByUA;
import static net.pms.configuration.RendererConfiguration.getRendererConfigurationByUAAHH;
import static net.pms.configuration.RendererConfiguration.loadRendererConfigurations;
import static net.pms.configuration.RendererConfiguration.resetAddressAssociation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.configuration.ConfigurationException;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;

/**
 * Test the RendererConfiguration class
 */
public class RendererConfigurationTest {
    private final Map<String, String> testCases = new HashMap<String, String>();

    @Before
    public void setUp() {
        // Silence all log messages from the PMS code that is being tested
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        context.reset();

        // Set locale to EN to ignore translations for renderers
        Locale.setDefault(Locale.ENGLISH);

        // Cases that are too generic should not match anything
        testCases.put("User-Agent: UPnP/1.0 DLNADOC/1.50", null);
        testCases.put("User-Agent: Unknown Renderer", null);
        testCases.put("X-Unknown-Header: Unknown Content", null);

        // From AirPlayer.conf:
        testCases.put("User-Agent: AirPlayer/1.0.09 CFNetwork/485.13.9 Darwin/11.0.0", "AirPlayer");
        testCases.put("User-Agent: Lavf52.54.0", "AirPlayer");

        // From BraviaEX.conf:
        testCases.put("X-AV-Client-Info: av=5.0; cn=\"Sony Corporation\"; mn=\"BRAVIA KDL-32CX520\"; mv=\"1.7\";",
                "Sony Bravia EX");

        // From BraviaHX.conf:
        testCases.put("X-AV-Client-Info: av=5.0; cn=\"Sony Corporation\"; mn=\"BRAVIA KDL-55HX750\"; mv=\"1.7\";",
                "Sony Bravia HX");

        // From Dlink510.conf:
        testCases.put("User-Agent: DLNADOC/1.50 INTEL_NMPR/2.1", "D-Link DSM-510");

        // From iPad-iPhone.conf:
        testCases.put("User-Agent: 8player lite 2.2.3 (iPad; iPhone OS 5.0.1; nl_NL)", "iPad / iPhone");
        testCases.put("User-Agent: yxplayer2%20lite/1.2.7 CFNetwork/485.13.9 Darwin/11.0.0", "iPad / iPhone");
        testCases.put("User-Agent: MPlayer 1.0rc4-4.2.1", "iPad / iPhone");
        testCases.put("User-Agent: NSPlayer/4.1.0.3856", "iPad / iPhone");

        // From Philips.conf:
        testCases.put("User-Agent: Allegro-Software-WebClient/4.61 DLNADOC/1.00", "Philips Aurea");

        // From PhilipsPFL.conf:
        testCases.put("User-Agent: Windows2000/0.0 UPnP/1.0 PhilipsIntelSDK/1.4 DLNADOC/1.50", "Philips TV");

        // From PS3.conf:
        testCases.put("User-Agent: PLAYSTATION 3", "PlayStation 3");
        testCases.put(
                "X-AV-Client-Info: av=5.0; cn=\"Sony Computer Entertainment Inc.\"; mn=\"PLAYSTATION 3\"; mv=\"1.0\"",
                "PlayStation 3");

        // From Realtek.conf:
        // FIXME: Actual conflict here! Popcorn Hour is returned...
        //testCases.put("User-Agent: POSIX UPnP/1.0 Intel MicroStack/1.0.2718, RealtekMediaCenter, DLNADOC/1.50", "Realtek");
        testCases.put("User-Agent: RealtekVOD neon/0.27.2", "Realtek");

        // From SamsungAllShare.conf:
        testCases.put("User-Agent: SEC_HHP_[HT]D5500/1.0", "Samsung AllShare");
        testCases.put("User-Agent: SEC_HHP_[TV]UE32D5000/1.0", "Samsung AllShare");
        testCases.put("User-Agent: SEC_HHP_ Family TV/1.0", "Samsung AllShare");
        testCases.put("User-Agent: SEC_HHP_[TV]PS51D6900/1.0", "Samsung AllShare");
        testCases.put("User-Agent: DLNADOC/1.50 SEC_HHP_[TV]UE32D5000/1.0", "Samsung AllShare");
        testCases.put("User-Agent: DLNADOC/1.50 SEC_HHP_[TV]UN55D6050/1.0", "Samsung AllShare");
        testCases.put("User-Agent: DLNADOC/1.50 SEC_HHP_ Family TV/1.0", "Samsung AllShare");

        // From Samsung-SMT-G7400.conf:
        testCases.put("User-Agent: Linux/2.6.35 UPnP/1.0 NDS_MHF DLNADOC/1.50", "Samsung SMT-G7400");

        // From WDTVLive.conf:
        testCases.put("User-Agent: INTEL_NMPR/2.1 DLNADOC/1.50 Intel MicroStack/1.0.1423", "WD TV Live");

        // From XBMC.conf:
        testCases.put("User-Agent: XBMC/10.0 r35648 (Mac OS X; 11.2.0 x86_64; http://www.xbmc.org)", "XBMC");
        testCases.put("User-Agent: Platinum/0.5.3.0, DLNADOC/1.50", "XBMC");
    }

    /**
     * Test the RendererConfiguration class and the consistency of the renderer
     * .conf files it reads. This is done by feeding it known headers and
     * checking whether it recognizes the correct renderer.
     */
    @Test
    public void testKnownHeaders() {
        PmsConfiguration pmsConf = null;

        try {
            pmsConf = new PmsConfiguration(false);
        } catch (ConfigurationException e) {
            // This should be impossible since no configuration file will be loaded.
        }

        // Initialize the RendererConfiguration
        loadRendererConfigurations(pmsConf);

        // Test all header test cases
        Set<Entry<String, String>> set = testCases.entrySet();
        Iterator<Entry<String, String>> i = set.iterator();

        while (i.hasNext()) {
            Entry<String, String> entry = (Entry<String, String>) i.next();
            testHeader(entry.getKey(), entry.getValue());
        }
    }

    /**
     * Test recognition with a forced default renderer configured.
     */
    @Test
    public void testForcedDefault() {
        PmsConfiguration pmsConf = null;

        try {
            pmsConf = new PmsConfiguration(false);
        } catch (ConfigurationException e) {
            // This should be impossible since no configuration file will be loaded.
        }

        // Set default to PlayStation 3
        pmsConf.setRendererDefault("PlayStation 3");
        pmsConf.setRendererForceDefault(true);

        // Initialize the RendererConfiguration
        loadRendererConfigurations(pmsConf);

        // Known and unknown renderers should always return default
        testHeader("User-Agent: AirPlayer/1.0.09 CFNetwork/485.13.9 Darwin/11.0.0", "PlayStation 3");
        testHeader("User-Agent: Unknown Renderer", "PlayStation 3");
        testHeader("X-Unknown-Header: Unknown Content", "PlayStation 3");
    }

    /**
     * Test recognition with a forced bogus default renderer configured.
     */
    @Test
    public void testBogusDefault() {
        PmsConfiguration pmsConf = null;

        try {
            pmsConf = new PmsConfiguration(false);
        } catch (ConfigurationException e) {
            // This should be impossible since no configuration file will be loaded.
        }

        // Set default to non existent renderer
        pmsConf.setRendererDefault("Bogus Renderer");
        pmsConf.setRendererForceDefault(true);

        // Initialize the RendererConfiguration
        loadRendererConfigurations(pmsConf);

        // Known and unknown renderers should return "Unknown renderer"
        testHeader("User-Agent: AirPlayer/1.0.09 CFNetwork/485.13.9 Darwin/11.0.0", "Unknown renderer");
        testHeader("User-Agent: Unknown Renderer", "Unknown renderer");
        testHeader("X-Unknown-Header: Unknown Content", "Unknown renderer");
    }

    /**
     * Test one particular header line to see if it returns the correct
     * renderer. Set the correct renderer name to <code>null</code> to require
     * that nothing matches at all.
     * 
     * @param headerLine
     *            The header line to recognize.
     * @param correctRendererName
     *            The name of the renderer.
     */
    private void testHeader(String headerLine, String correctRendererName) {
        if (correctRendererName != null) {
            // Header is supposed to match a particular renderer
            if (headerLine != null && headerLine.toLowerCase().startsWith("user-agent")) {
                // Match by User-Agent
                RendererConfiguration rc = getRendererConfigurationByUA(headerLine);
                assertNotNull("Recognized renderer for header \"" + headerLine + "\"", rc);
                assertEquals(
                        "Expected renderer \"" + correctRendererName + "\", " + "instead renderer \""
                                + rc.getRendererName() + "\" was returned for header \"" + headerLine + "\"",
                        correctRendererName, rc.getRendererName());
            } else {
                // Match by additional header
                RendererConfiguration rc = getRendererConfigurationByUAAHH(headerLine);
                assertNotNull("Recognized renderer for header \"" + headerLine + "\"", rc);
                assertEquals("Expected renderer \"" + correctRendererName + "\" to be recognized, "
                        + "instead renderer \"" + rc.getRendererName() + "\" was returned for header \""
                        + headerLine + "\"", correctRendererName, rc.getRendererName());
            }
        } else {
            // Header is supposed to match no renderer at all
            if (headerLine != null && headerLine.toLowerCase().startsWith("user-agent")) {
                // Match by User-Agent
                RendererConfiguration rc = getRendererConfigurationByUA(headerLine);
                assertEquals("Expected no matching renderer to be found for header \"" + headerLine
                        + "\", instead renderer \"" + (rc != null ? rc.getRendererName() : "")
                        + "\" was recognized.", null, rc);
            } else {
                // Match by additional header
                RendererConfiguration rc = getRendererConfigurationByUAAHH(headerLine);
                assertEquals("Expected no matching renderer to be found for header \"" + headerLine
                        + "\", instead renderer \"" + (rc != null ? rc.getRendererName() : "")
                        + "\" was recognized.", null, rc);
            }
        }
    }

    /**
     * Test {@link RendererConfiguration#getRendererConfigurationBySocketAddress(InetAddress)}
     * @throws UnknownHostException
     */
    @Test
    public void testGetBySocketAddress() throws UnknownHostException {
        RendererConfiguration conf = null;
        PmsConfiguration pmsConf = null;

        try {
            pmsConf = new PmsConfiguration(false);
        } catch (ConfigurationException e) {
            // This should be impossible since no configuration file will be loaded.
        }

        // Initialize the RendererConfiguration
        loadRendererConfigurations(pmsConf);

        // Nothing forced
        pmsConf.setRendererForceIp("");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNull(conf);

        // Garbled configuration: no renderer name
        pmsConf.setRendererForceIp("@192.168.1.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNull(conf);

        // Garbled configuration: no IP address
        pmsConf.setRendererForceIp("PlayStation 3");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNull(conf);

        // Garbled configuration: invalid IP address
        pmsConf.setRendererForceIp("PlayStation 3@textip");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNull(conf);

        // Garbled configuration: unknown renderer name
        pmsConf.setRendererForceIp("No Match@192.168.1.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNull(conf);

        // Garbled configuration: incorrect entries plus correct entry
        pmsConf.setRendererForceIp("Sony Bravia EX,No Match@192.168.1.2,Playstation 3@192.168.1.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.2"));
        assertNull(conf);
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());

        // Set single forced IP address
        pmsConf.setRendererForceIp("PlayStation 3@192.168.1.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.2"));
        assertNull(conf);
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());

        // Set forced IP address range
        pmsConf.setRendererForceIp("PlayStation 3@192.168.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.23"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());

        // Set forced IP address range
        pmsConf.setRendererForceIp("PlayStation 3@192.168.0-1.*");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.2.1"));
        assertNull(conf);
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.0.1"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.23"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());

        // Set multiple forced IP addresses
        pmsConf.setRendererForceIp("Sony Bravia EX@192.168.1.1,Sony Bravia HX@192.168.1.2");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.2.1"));
        assertNull(conf);
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("Sony Bravia EX", conf.getRendererName());
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.2"));
        assertNotNull(conf);
        assertEquals("Sony Bravia HX", conf.getRendererName());

        // Multiple addresses with range overlap
        pmsConf.setRendererForceIp("Sony Bravia HX@192.168.1.2,Sony Bravia EX@192.168.0-1.*");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.2.1"));
        assertNull(conf);
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("Sony Bravia EX", conf.getRendererName());
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.2"));
        assertNotNull(conf);
        assertEquals("Sony Bravia HX", conf.getRendererName());

        // Renderer name matching is case insensitive
        pmsConf.setRendererForceIp("playstation 3@192.168.1.1");
        resetAddressAssociation();
        conf = getRendererConfigurationBySocketAddress(InetAddress.getByName("192.168.1.1"));
        assertNotNull(conf);
        assertEquals("PlayStation 3", conf.getRendererName());

    }
}