/* * Copyright (C) 2014 RetailMeNot, Inc. * 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, either version 3 of the License, or * (at your option) any later version. * 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. */ package com.rmn.qa.servlet; import com.rmn.qa.*; import junit.framework.Assert; import org.junit.After; import org.junit.Test; import org.openqa.grid.common.SeleniumProtocol; import org.openqa.grid.internal.ProxySet; import org.openqa.grid.internal.TestSlot; import org.openqa.selenium.remote.CapabilityType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; public class AutomationTestRunServletTest { @After public void cleanUp() { AutomationContext.refreshContext(); } @Test // Makes sure that the query string parameter 'uuid' is required public void testUuidRequired() throws IOException, ServletException{ MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, new MockVmManager(), new MockRequestMatcher()); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request,response); Assert.assertEquals("Response code should be an error since the uuid was not passed in", HttpServletResponse.SC_BAD_REQUEST,response.getErrorCode()); Assert.assertEquals("Response message should be an error since the uuid was not passed in", "Parameter 'uuid' must be passed in as a query string parameter", response.getErrorMessage()); } @Test // Makes sure that the query string parameter 'browser' is required public void testBrowserRequired() throws IOException, ServletException{ MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, new MockVmManager(), new MockRequestMatcher()); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid", "testUuid"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request,response); Assert.assertEquals("Response code should be an error since browser was not passed in", HttpServletResponse.SC_BAD_REQUEST,response.getErrorCode()); Assert.assertEquals("Response message should be an error since browser was not passed in", "Parameter 'browser' must be passed in as a query string parameter", response.getErrorMessage()); } @Test // Makes sure that the query string parameter 'threadCount' is required public void testThreadCountRequired() throws IOException, ServletException{ MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, new MockVmManager(), new MockRequestMatcher()); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid", "testUuid"); request.setParameter("browser", "firefox"); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request,response); Assert.assertEquals("Response code should be an error since threadCount was not passed in", HttpServletResponse.SC_BAD_REQUEST,response.getErrorCode()); Assert.assertEquals("Response message should be an error since threadCount was not passed in", "Parameter 'threadCount' must be passed in as a query string parameter", response.getErrorMessage()); } @Test // Tests if a hub has maxed out its configurable thread count that the hub will not attempt // to fulfill the request public void testHubThreadCountMaxedOut() throws IOException, ServletException{ MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, new MockVmManager(), new MockRequestMatcher()); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","firefox"); request.setParameter("threadCount", "50"); AutomationContext.getContext().addRun(new AutomationRunRequest("runUUid",50,"firefox")); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request,response); Assert.assertEquals("Response code should be an error since the max thread count was reached", HttpServletResponse.SC_CONFLICT,response.getErrorCode()); Assert.assertEquals("Response code should be an error since the max thread count was reached", "Server cannot fulfill request due to configured node limit being reached.", response.getErrorMessage()); } @Test // Tests that the configurable maximum thread count works with multiple nodes public void testHubThreadCountMaxedOutMultipleRuns() throws IOException, ServletException{ MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, new MockVmManager(), new MockRequestMatcher()); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","firefox"); request.setParameter("threadCount","50"); AutomationContext.getContext().addRun(new AutomationRunRequest("runUUid",25,"firefox")); AutomationContext.getContext().addRun(new AutomationRunRequest("runUUid",25,"firefox")); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request,response); Assert.assertEquals("Response code should be an error since the max thread count was reached", HttpServletResponse.SC_CONFLICT,response.getErrorCode()); Assert.assertEquals("Response code should be an error since the max thread count was reached", "Server cannot fulfill request due to configured node limit being reached.", response.getErrorMessage()); } @Test // Tests the happy path that a hub says a request can be fulfilled when it can be public void testRequestCanFulfill() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(10); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","firefox"); request.setParameter("threadCount","10"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"firefox"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_ACCEPTED,response.getStatusCode()); } @Test // Tests that a run request with a duplicate uuid of another run is rejected public void testDuplicateUuids() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(10); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); String uuid = "testUUid"; request.setParameter("uuid",uuid); request.setParameter("browser","firefox"); request.setParameter("threadCount","10"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"firefox"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); // Submit a 2nd request with the same UUID MockHttpServletResponse response2 = new MockHttpServletResponse(); servlet.doGet(request, response2); Assert.assertEquals("Hub should not able to fulfill request due to duplicate uuid",HttpServletResponse.SC_BAD_REQUEST,response2.getErrorCode()); Assert.assertEquals("Hub should not able to fulfill request due to duplicate uuid","Test run already exists with the same UUID.",response2.getErrorMessage()); } @Test // Tests a request can be fulfilled when nodes have to be spun up public void testRequestCanFulfillSpinUpNodes() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","firefox"); request.setParameter("threadCount","6"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"firefox"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_CREATED,response.getStatusCode()); } @Test // Tests a request can be fulfilled when chrome nodes have to be spun up public void testRequestCanFulfillSpinUpNodesChrome() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","chrome"); request.setParameter("threadCount","7"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"chrome"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_CREATED,response.getStatusCode()); } @Test // Tests a request can be fulfilled when IE nodes have to be spun up public void testRequestCanFulfillSpinUpNodesIe() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); System.setProperty(AutomationConstants.IP_ADDRESS,"192.168.1.1"); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","internetexplorer"); request.setParameter("threadCount","1"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"internetexplorer"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_CREATED,response.getStatusCode()); } @Test // Tests a request cannot be fulfilled when the browser is not a supported browser to spin up public void testRequestCantFulfillUnsupportedBrowser() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","unknown"); request.setParameter("threadCount","7"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"chrome"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should not be able to fulfill request", HttpServletResponse.SC_GONE,response.getErrorCode()); } @Test // Tests that the cleanup threads are started public void testInitCleanupThreads() throws IOException, ServletException{ System.setProperty(AutomationConstants.INSTANCE_ID,"dummyId"); MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,true, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","chrome"); request.setParameter("threadCount","7"); request.setParameter("browserVersion","21"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"chrome"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_CREATED,response.getStatusCode()); } @Test public void testInitCleanupThreadsNoInstanceId() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,true, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","chrome"); request.setParameter("threadCount","7"); request.setParameter("browserVersion","21"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"chrome"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_CREATED,response.getStatusCode()); } @Test //TODO Update descriptions public void testRequestStartNodesFailed() throws IOException, ServletException{ MockVmManager manageEc2 = new MockVmManager(); manageEc2.setThrowException(); MockRequestMatcher matcher = new MockRequestMatcher(); matcher.setThreadsToReturn(0); MockAutomationTestRunServlet servlet = new MockAutomationTestRunServlet(null,false, manageEc2,matcher); MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("uuid","testUuid"); request.setParameter("browser","firefox"); request.setParameter("threadCount","10"); String nodeId = "nodeId"; // Add a node that is not running to make sure its not included in the available calculation AutomationDynamicNode node = new AutomationDynamicNode("testUuid",nodeId,null,null,new Date(),50); AutomationContext.getContext().addNode(node); ProxySet proxySet = new ProxySet(false); MockRemoteProxy proxy = new MockRemoteProxy(); proxy.setMaxNumberOfConcurrentTestSessions(50); proxy.setCapabilityMatcher(new AutomationCapabilityMatcher()); Map<String,Object> config = new HashMap<String, Object>(); config.put(AutomationConstants.INSTANCE_ID,nodeId); proxy.setConfig(config); Map<String,Object> capabilities = new HashMap<String,Object>(); capabilities.put(CapabilityType.BROWSER_NAME,"firefox"); TestSlot testSlot = new TestSlot(proxy, SeleniumProtocol.WebDriver,null,capabilities); proxy.setMultipleTestSlots(testSlot, 10); proxySet.add(proxy); servlet.setProxySet(proxySet); AutomationContext.getContext().setTotalNodeCount(50); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); Assert.assertEquals("Hub should be able to fulfill request", HttpServletResponse.SC_INTERNAL_SERVER_ERROR,response.getErrorCode()); Assert.assertEquals("Error message should return if nodes can't be started","Nodes could not be started: Can't start nodes",response.getErrorMessage()); } }