This is an automated email from the ASF dual-hosted git repository. bdelacretaz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter.git
commit 9db5b09bce14fea95c4500ea8f845cda7a274756 Author: Bertrand Delacretaz <[email protected]> AuthorDate: Fri Jul 23 12:42:33 2021 +0200 SLING-10656 - retries for SmokeIT URL checking tests --- .../java/org/apache/sling/launchpad/SmokeIT.java | 39 +++++---- .../apache/sling/launchpad/StarterReadyRule.java | 94 +++++++--------------- .../java/org/apache/sling/launchpad/UrlCheck.java | 86 ++++++++++++++++++++ 3 files changed, 131 insertions(+), 88 deletions(-) diff --git a/src/test/java/org/apache/sling/launchpad/SmokeIT.java b/src/test/java/org/apache/sling/launchpad/SmokeIT.java index 05291cd..eee9122 100644 --- a/src/test/java/org/apache/sling/launchpad/SmokeIT.java +++ b/src/test/java/org/apache/sling/launchpad/SmokeIT.java @@ -22,12 +22,10 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; import javax.xml.parsers.DocumentBuilder; @@ -61,7 +59,6 @@ import org.w3c.dom.Node; @RunWith(Parameterized.class) public class SmokeIT { private static final String CHECK_PATHS_PROPERTY = "starter.check.paths"; - private static final int MAX_READABLE_INDEX = 50; private final int slingHttpPort; private static final int STARTER_MIN_BUNDLES_COUNT = Integer.getInteger("starter.min.bundles.count", Integer.MAX_VALUE); @@ -210,27 +207,27 @@ public class SmokeIT { * For testing the SLING-10402 scenario */ @Test - public void verifyReadableUrls() throws Exception { - final AtomicInteger checkedPaths = new AtomicInteger(); + public void checkReadableUrls() throws Exception { + final int minTests = 6; + final int TRIES = 10; + final int WAIT_BETWEEN_TRIES_MILLIS = 1000; + + final String baseURL = String.format("http://localhost:%d", slingHttpPort); + final List<UrlCheck> checks = new ArrayList<>(); + Stream.of(System.getProperty(CHECK_PATHS_PROPERTY).split(",")) + .map(path -> path.trim()) + .filter(path -> !path.isEmpty()) + .forEach(path -> checks.add(new UrlCheck(baseURL, path)) + ); + try ( CloseableHttpClient client = newClient() ) { - Stream.of(System.getProperty(CHECK_PATHS_PROPERTY).split(",")) - .map(path -> path.trim()) - .filter(path -> !path.isEmpty()) - .forEach(path -> { - HttpGet get = new HttpGet(String.format("http://localhost:%d%s", slingHttpPort, path)); - try (CloseableHttpResponse response = client.execute(get, httpClientContext)) { - checkedPaths.incrementAndGet(); - if ( response.getStatusLine().getStatusCode() != 200 ) { - fail(String.format("Unexpected status line \"%s\" for %s", response.getStatusLine(), path)); - } - } catch(Exception ex) { - throw new RuntimeException(ex); - } - }); + UrlCheck.runAll(client, TRIES, WAIT_BETWEEN_TRIES_MILLIS, checks); } - final int minTests = 6; - assertTrue(String.format("Expecting at least %d tests, got %d", minTests, checkedPaths.get()), checkedPaths.get() >= minTests); + assertTrue( + String.format("Expecting at least %d tests, got %d", minTests, checks.size()), + checks.size() >= minTests + ); } static class BundleStatus { diff --git a/src/test/java/org/apache/sling/launchpad/StarterReadyRule.java b/src/test/java/org/apache/sling/launchpad/StarterReadyRule.java index bffac80..4f9a15e 100644 --- a/src/test/java/org/apache/sling/launchpad/StarterReadyRule.java +++ b/src/test/java/org/apache/sling/launchpad/StarterReadyRule.java @@ -18,104 +18,64 @@ package org.apache.sling.launchpad; import java.io.BufferedReader; import java.io.InputStreamReader; -import java.net.ConnectException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.http.HttpResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.junit.rules.ExternalResource; public class StarterReadyRule extends ExternalResource { - private static final int TRIES = 60; - private static final int WAIT_BETWEEN_TRIES_MILLIS = 1000; - - private final List<Check> checks = new ArrayList<>(); + private final List<UrlCheck> checks = new ArrayList<>(); + private final int launchpadPort; + private static final Map<Integer, Throwable> previousFailures = new HashMap<>(); public StarterReadyRule(int launchpadPort) { - - checks.add(new Check("http://localhost:" + launchpadPort + "/server/default/jcr:root/content")); - checks.add(new Check("http://localhost:" + launchpadPort + "/content/starter.html") { + this.launchpadPort = launchpadPort; + final String baseURL = String.format("http://localhost:%d", launchpadPort); + checks.add(new UrlCheck(baseURL, "/server/default/jcr:root/content")); + checks.add(new UrlCheck(baseURL, "/content/starter.html") { + final String READY_MARKER = "Do not remove this comment, used for Starter integration tests"; @Override - public String runCheck(HttpResponse response) throws Exception { + public String run(HttpResponse response) throws Exception { try (InputStreamReader isr = new InputStreamReader(response.getEntity().getContent()); BufferedReader reader = new BufferedReader(isr)) { String line; while ((line = reader.readLine()) != null) { - if (line.contains("Do not remove this comment, used for Starter integration tests")) { + if (line.contains(READY_MARKER)) { return null; } } } - return "Did not find 'ready' marker in the response body"; + return String.format("Did not find 'ready' marker [%s] in the response body", READY_MARKER); } }); } @Override protected void before() throws Throwable { - - try (CloseableHttpClient client = HttpClients.createDefault()) { - for (Check check : checks) { - runCheck(client, check); - } + final Throwable previous = previousFailures.get(launchpadPort); + if(previous != null) { + throw new RuntimeException( + String.format("%s failed previously on port %d, refusing to run more tests", getClass().getSimpleName(), launchpadPort), + previous + ); } - } - - private void runCheck(CloseableHttpClient client, Check check) throws Exception { - - String lastFailure = null; - HttpGet get = new HttpGet(check.getUrl()); - - for (int i = 0; i < TRIES; i++) { - try (CloseableHttpResponse response = client.execute(get)) { - - if (response.getStatusLine().getStatusCode() != 200) { - lastFailure = "Status code is " + response.getStatusLine(); - Thread.sleep(WAIT_BETWEEN_TRIES_MILLIS); - continue; - } - - lastFailure = check.runCheck(response); - if (lastFailure == null) { - return; - } - } catch ( ConnectException e ) { - lastFailure = e.getClass().getName() + " : " + e.getMessage(); + final int TRIES = 60; + final int WAIT_BETWEEN_TRIES_MILLIS = 1000; + try (CloseableHttpClient client = HttpClients.createDefault()) { + try { + UrlCheck.runAll(client, TRIES, WAIT_BETWEEN_TRIES_MILLIS, checks); + } catch(Throwable t) { + previousFailures.put(launchpadPort, t); + throw t; } - - Thread.sleep(WAIT_BETWEEN_TRIES_MILLIS); } - - throw new RuntimeException(String.format("Starter not ready. Failed check for URL %s with message '%s'", - check.getUrl(), lastFailure)); } - - static class Check { - private String url; - - public Check(String url) { - this.url = url; - } - - public String getUrl() { - return url; - } - - /** - * @param response the HttpResponse - * @return null if check check was successful, an error description otherwise - * @throws Exception - */ - public String runCheck(HttpResponse response) throws Exception { - return null; - } - } - } diff --git a/src/test/java/org/apache/sling/launchpad/UrlCheck.java b/src/test/java/org/apache/sling/launchpad/UrlCheck.java new file mode 100644 index 0000000..06d48a4 --- /dev/null +++ b/src/test/java/org/apache/sling/launchpad/UrlCheck.java @@ -0,0 +1,86 @@ +/* + * 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.launchpad; + +import java.net.ConnectException; +import java.util.Collection; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; + +class UrlCheck { + private final String url; + + UrlCheck(String baseURL, String path) { + final String separator = baseURL.endsWith("/") ? "" : "/"; + this.url = baseURL + separator + path; + } + + String getUrl() { + return url; + } + + /** + * @param response the HttpResponse + * @return null if check check was successful, an error description otherwise + * @throws Exception + */ + String run(HttpResponse response) throws Exception { + return null; + } + + /** Run all supplied checks */ + static void runAll(CloseableHttpClient client, int retryCount, int msecBetweenRetries, Collection<UrlCheck> checks) throws Exception { + for(UrlCheck check : checks) { + String lastFailure = null; + HttpGet get = new HttpGet(check.getUrl()); + int requestCount = 0; + final long start = System.currentTimeMillis(); + for (int i = 0; i < retryCount; i++) { + try (CloseableHttpResponse response = client.execute(get)) { + requestCount++; + if (response.getStatusLine().getStatusCode() != 200) { + lastFailure = "Status code is " + response.getStatusLine(); + Thread.sleep(msecBetweenRetries); + continue; + } + + lastFailure = check.run(response); + if (lastFailure == null) { + break; + } + } catch ( ConnectException e ) { + lastFailure = e.getClass().getName() + " : " + e.getMessage(); + } + + Thread.sleep(msecBetweenRetries); + } + + if(lastFailure != null) { + throw new RuntimeException( + String.format("Starter not ready or path not found after %d tries (%d msec). Request to URL %s failed with message '%s'", + requestCount, + System.currentTimeMillis() - start, + check.getUrl(), + lastFailure)); + } + } + } + +} \ No newline at end of file
