/* * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.glowroot.tests; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.Request; import com.ning.http.client.Response; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.rules.TestName; import org.junit.rules.TestWatcher; import org.openqa.selenium.WebDriver; import org.glowroot.agent.config.ImmutableAdvancedConfig; import org.glowroot.agent.config.ImmutableTransactionConfig; import org.glowroot.agent.config.ImmutableUiConfig; import org.glowroot.agent.config.ImmutableUserRecordingConfig; import org.glowroot.agent.it.harness.Container; public abstract class WebDriverIT { protected static final String agentId; static { if (WebDriverSetup.useCentral) { try { agentId = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { throw new IllegalStateException(e); } } else { agentId = ""; } } protected static WebDriverSetup setup; protected static Container container; protected static WebDriver driver; private static AsyncHttpClient asyncHttpClient; @Rule public TestName testName = new TestName(); @Rule public ScreenshotOnExceptionRule screenshotOnExceptionRule = new ScreenshotOnExceptionRule(); @BeforeClass public static void setUpBase() throws Exception { setup = WebDriverSetup.create(); container = setup.getContainer(); asyncHttpClient = new AsyncHttpClient(); } @AfterClass public static void tearDownBase() throws Exception { asyncHttpClient.close(); setup.close(); } @Before public void beforeEachBaseTest() throws Exception { setup.beforeEachTest(getClass().getName() + '.' + testName.getMethodName(), screenshotOnExceptionRule); driver = setup.getDriver(); } @After public void afterEachBaseTest() throws Exception { setup.afterEachTest(); if (WebDriverSetup.useCentral) { resetAllCentralConfig(); } } @Rule public TestWatcher getSauceLabsTestWatcher() { return setup.getSauceLabsTestWatcher(); } protected App app() throws Exception { return new App(driver, "http://localhost:" + getUiPort()); } protected GlobalNavbar globalNavbar() { return new GlobalNavbar(driver, WebDriverSetup.useCentral); } protected static int getUiPort() throws Exception { return setup.getUiPort(); } private static void resetAllCentralConfig() throws Exception { resetCentralConfig("transaction", false, ImmutableTransactionConfig.builder().build()); resetCentralConfig("ui", true, ImmutableUiConfig.builder().build()); resetCentralConfig("user-recording", false, ImmutableUserRecordingConfig.builder().build()); resetCentralConfig("advanced", true, ImmutableAdvancedConfig.builder().build()); deleteAllGauges(); deleteAllAlerts(); deleteAllInstrumentation(); resetUsers(); resetRoles(); resetCentralConfigAdmin("web", "{\"sessionTimeoutMinutes\":30," + "\"sessionCookieName\":\"GLOWROOT_SESSION_ID\"," + "\"version\":\"$version\"}"); resetCentralConfigAdmin("storage", "{\"rollupExpirationHours\":[72,336,2160,17520]," + "\"traceExpirationHours\":336," + "\"fullQueryTextExpirationHours\":336," + "\"version\":\"$version\"}"); resetCentralConfigAdmin("smtp", "{\"host\":\"\"," + "\"ssl\":false," + "\"username\":\"\"," + "\"passwordExists\":false," + "\"newPassword\":\"\"," + "\"additionalProperties\":{}," + "\"fromEmailAddress\":\"\"," + "\"fromDisplayName\":\"\"," + "\"version\":\"$version\"}"); resetCentralConfigAdmin("ldap", "{\"host\":\"\"," + "\"ssl\":false," + "\"username\":\"\"," + "\"passwordExists\":false," + "\"newPassword\":\"\"," + "\"userBaseDn\":\"\"," + "\"userSearchFilter\":\"\"," + "\"groupBaseDn\":\"\"," + "\"groupSearchFilter\":\"\"," + "\"version\":\"$version\"}"); } private static void resetCentralConfig(String type, boolean useAgentRollupId, Object config) throws Exception { String url = "http://localhost:" + getUiPort() + "/backend/config/" + type + "?agent"; if (useAgentRollupId) { url += "-rollup"; } url += "-id=" + agentId; Request request = asyncHttpClient .prepareGet(url) .build(); Response response = asyncHttpClient.executeRequest(request).get(); String version = getVersion(response.getResponseBody()); ObjectNode json = new ObjectMapper().valueToTree(config); json.put("version", version); request = asyncHttpClient .preparePost(url) .setBody(json.toString()) .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } private static void deleteAllGauges() throws Exception { Request request = asyncHttpClient .prepareGet("http://localhost:" + getUiPort() + "/backend/config/gauges?agent-id=" + agentId) .build(); Response response = asyncHttpClient.executeRequest(request).get(); ArrayNode gauges = (ArrayNode) new ObjectMapper().readTree(response.getResponseBody()); for (JsonNode gauge : gauges) { String name = gauge.get("config").get("mbeanObjectName").asText(); if (name.equals("java.lang:type=Memory") || name.equals("java.lang:type=GarbageCollector,name=*") || name.equals("java.lang:type=MemoryPool,name=*") || name.equals("java.lang:type=OperatingSystem")) { continue; } String version = gauge.get("config").get("version").asText(); request = asyncHttpClient .preparePost("http://localhost:" + getUiPort() + "/backend/config/gauges/remove?agent-id=" + agentId) .setBody("{\"version\":\"" + version + "\"}") .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } } private static void deleteAllAlerts() throws Exception { Request request = asyncHttpClient .prepareGet("http://localhost:" + getUiPort() + "/backend/config/alerts?agent-rollup-id=" + agentId) .build(); Response response = asyncHttpClient.executeRequest(request).get(); ArrayNode alerts = (ArrayNode) new ObjectMapper().readTree(response.getResponseBody()); for (JsonNode alert : alerts) { String version = alert.get("version").asText(); request = asyncHttpClient .preparePost("http://localhost:" + getUiPort() + "/backend/config/alerts/remove?agent-rollup-id=" + agentId) .setBody("{\"version\":\"" + version + "\"}") .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } } private static void deleteAllInstrumentation() throws Exception { Request request = asyncHttpClient .prepareGet("http://localhost:" + getUiPort() + "/backend/config/instrumentation?agent-id=" + agentId) .build(); Response response = asyncHttpClient.executeRequest(request).get(); ArrayNode instrumentations = (ArrayNode) new ObjectMapper().readTree(response.getResponseBody()).get("configs"); for (JsonNode instrumentation : instrumentations) { String version = instrumentation.get("version").asText(); request = asyncHttpClient .preparePost("http://localhost:" + getUiPort() + "/backend/config/instrumentation/remove?agent-id=" + agentId) .setBody("{\"versions\":[\"" + version + "\"]}") .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } } private static void resetUsers() throws Exception { Request request = asyncHttpClient .prepareGet("http://localhost:" + getUiPort() + "/backend/admin/users") .build(); Response response = asyncHttpClient.executeRequest(request).get(); ArrayNode users = (ArrayNode) new ObjectMapper().readTree(response.getResponseBody()); for (JsonNode user : users) { String username = user.get("username").asText(); if (username.equalsIgnoreCase("anonymous")) { continue; } request = asyncHttpClient .preparePost("http://localhost:" + getUiPort() + "/backend/admin/users/remove") .setBody("{\"username\":\"" + username + "\"}") .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } } private static void resetRoles() throws Exception { Request request = asyncHttpClient .prepareGet("http://localhost:" + getUiPort() + "/backend/admin/roles") .build(); Response response = asyncHttpClient.executeRequest(request).get(); ArrayNode roles = (ArrayNode) new ObjectMapper().readTree(response.getResponseBody()); for (JsonNode role : roles) { String name = role.get("name").asText(); if (name.equalsIgnoreCase("Administrator")) { continue; } request = asyncHttpClient .preparePost("http://localhost:" + getUiPort() + "/backend/admin/roles/remove") .setBody("{\"name\":\"" + name + "\"}") .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } } private static void resetCentralConfigAdmin(String type, String template) throws Exception { String url = "http://localhost:" + getUiPort() + "/backend/admin/" + type; Request request = asyncHttpClient .prepareGet(url) .build(); Response response = asyncHttpClient.executeRequest(request).get(); String version = getVersion(response.getResponseBody()); String content = template.replace("$version", version); request = asyncHttpClient .preparePost(url) .setBody(content) .build(); int statusCode = asyncHttpClient.executeRequest(request).get().getStatusCode(); if (statusCode != 200) { throw new AssertionError("Unexpected status code: " + statusCode); } } private static String getVersion(String content) throws IOException { JsonNode responseNode = new ObjectMapper().readTree(content); JsonNode versionNode = responseNode.get("version"); if (versionNode == null) { return responseNode.get("config").get("version").asText(); } return versionNode.asText(); } }