| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.sling.junit.remote.ide; |
| |
| import java.io.ObjectInputStream; |
| |
| import org.apache.http.HttpEntity; |
| import org.apache.sling.junit.remote.httpclient.RemoteTestHttpClient; |
| import org.apache.sling.testing.tools.http.Request; |
| import org.apache.sling.testing.tools.http.RequestCustomizer; |
| import org.apache.sling.testing.tools.http.RequestExecutor; |
| import org.junit.rules.MethodRule; |
| import org.junit.runners.model.FrameworkMethod; |
| import org.junit.runners.model.Statement; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** JUnit MethodRule that executes tests remotely if the |
| * {@link #SLING_REMOTE_TEST_URL} property is set. |
| * Used to execute tests from an IDE and have then run |
| * on a remote Sling instance. |
| */ |
| public class SlingRemoteExecutionRule implements MethodRule, RequestCustomizer { |
| private static final Logger log = |
| LoggerFactory.getLogger(SlingRemoteExecutionRule.class); |
| |
| /** Name of the system property that activates remote test execution */ |
| public static final String SLING_REMOTE_TEST_URL = "sling.remote.test.url"; |
| public static final String SLING_REMOTE_TEST_USERNAME = "sling.remote.test.username"; |
| public static final String SLING_REMOTE_TEST_PASSWORD = "sling.remote.test.password"; |
| |
| public Statement apply(final Statement base, final FrameworkMethod method, Object target) { |
| return new Statement() { |
| @Override |
| public void evaluate() throws Throwable { |
| if (tryRemoteEvaluation(method)) { |
| return; |
| } |
| base.evaluate(); |
| } |
| }; |
| } |
| |
| /** |
| * Execute test remotely if the corresponding system property is set |
| * |
| * @return <code>true</code> if the method was executed remotely and passed. |
| * If the test was <b>not</b> executed remotely then |
| * <code>false</code> is returned to indicate that test should be |
| * executed locally |
| */ |
| private boolean tryRemoteEvaluation(FrameworkMethod method) throws Throwable { |
| String remoteUrl = System.getProperty(SLING_REMOTE_TEST_URL); |
| String remoteUsername = System.getProperty(SLING_REMOTE_TEST_USERNAME); |
| String remotePassword = System.getProperty(SLING_REMOTE_TEST_PASSWORD); |
| |
| if(remoteUrl != null) { |
| remoteUrl = remoteUrl.trim(); |
| if(remoteUrl.length() > 0) { |
| invokeRemote(remoteUrl, remoteUsername, remotePassword, method); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private void invokeRemote(String remoteUrl, String remoteUsername, String remotePassword, FrameworkMethod method) throws Throwable { |
| final String testClassesSelector = method.getMethod().getDeclaringClass().getName(); |
| final String methodName = method.getMethod().getName(); |
| |
| final RemoteTestHttpClient testHttpClient = new RemoteTestHttpClient(remoteUrl, remoteUsername, remotePassword, false); |
| testHttpClient.setRequestCustomizer(this); |
| final RequestExecutor executor = testHttpClient.runTests( |
| testClassesSelector, methodName, "serialized" |
| ); |
| log.debug("Ran test {} method {} at URL {}", |
| new Object[] { testClassesSelector, methodName, remoteUrl }); |
| |
| final HttpEntity entity = executor.getResponse().getEntity(); |
| if (entity != null) { |
| try { |
| final Object o = new ObjectInputStream(entity.getContent()).readObject(); |
| if( !(o instanceof ExecutionResult) ) { |
| throw new IllegalStateException("Expected an ExecutionResult, got a " + o.getClass().getName()); |
| } |
| final ExecutionResult result = (ExecutionResult)o; |
| if (result.isFailure()) { |
| throw result.getException(); |
| } |
| } finally { |
| entity.consumeContent(); |
| } |
| } |
| } |
| |
| /** @inheritDoc */ |
| public void customizeRequest(Request r) { |
| // Do nothing by default, tests that use this rule can |
| // customize this method |
| } |
| } |