blob: 35bda8d5f56c67d7d28b5f4c34c916c9720b82fb [file] [log] [blame]
/*
* 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.maven.wagon.tck.http;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.codehaus.plexus.util.IOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.codehaus.plexus.util.FileUtils.fileRead;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
*
*/
public final class Assertions {
public static final int NO_RESPONSE_STATUS_CODE = -1;
protected static final Logger LOGGER = LoggerFactory.getLogger(Assertions.class);
public static void assertFileContentsFromResource(
final String resourceBase, final String resourceName, final File output, final String whyWouldItFail)
throws IOException {
String content = readResource(resourceBase, resourceName);
String test = fileRead(output);
assertEquals(whyWouldItFail, content, test);
}
private static String readResource(final String base, final String name) throws IOException {
String url = base;
if (!url.endsWith("/") && !name.startsWith("/")) {
url += "/";
}
url += name;
ClassLoader cloader = Thread.currentThread().getContextClassLoader();
InputStream stream = cloader.getResourceAsStream(url);
if (stream == null) {
return null;
}
final String resource = IOUtil.toString(stream);
stream.close();
return resource;
}
/**
* Assert a WagonException message contains required format and context based on the status code we expected to
* trigger it in the first place.
* <p>
* This implementation represents the most desired assertions, but HttpWagonTestCase sub-classes could override
* this method if a specific wagon representation makes it impossible to meet these assertions.
*
* @param e an instance of {@link WagonException}
* @param forStatusCode the response status code that triggered the exception
* @param forUrl the url that triggered the exception
* @param forReasonPhrase the optional status line reason phrase the server returned
*/
public static void assertWagonExceptionMessage(
Exception e, int forStatusCode, String forUrl, String forReasonPhrase, ProxyInfo proxyInfo) {
// TODO: handle AuthenticationException for Wagon.connect() calls
assertNotNull(e);
try {
assertTrue("only verify instances of WagonException", e instanceof WagonException);
String reasonPhrase;
String assertMessageForBadMessage = "exception message not described properly";
if (proxyInfo != null) {
assertTrue(
"message should end with proxy information if proxy was used",
e.getMessage().endsWith(proxyInfo.toString()));
}
switch (forStatusCode) {
case HttpServletResponse.SC_NOT_FOUND:
// TODO: add test for 410: Gone?
assertTrue(
"404 not found response should throw ResourceDoesNotExistException",
e instanceof ResourceDoesNotExistException);
reasonPhrase = (forReasonPhrase == null || forReasonPhrase.isEmpty())
? " Not Found"
: (" " + forReasonPhrase);
assertEquals(
assertMessageForBadMessage,
"resource missing at " + forUrl + ", status: 404" + reasonPhrase,
e.getMessage());
break;
case HttpServletResponse.SC_UNAUTHORIZED:
// FIXME assumes Wagon.get()/put() returning 401 instead of Wagon.connect()
assertTrue(
"401 Unauthorized should throw AuthorizationException since "
+ " AuthenticationException is not explicitly declared as thrown from wagon "
+ "methods",
e instanceof AuthorizationException);
reasonPhrase = (forReasonPhrase == null || forReasonPhrase.isEmpty())
? " Unauthorized"
: (" " + forReasonPhrase);
assertEquals(
assertMessageForBadMessage,
"authentication failed for " + forUrl + ", status: 401" + reasonPhrase,
e.getMessage());
break;
case HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED:
assertTrue(
"407 Proxy authentication required should throw AuthorizationException",
e instanceof AuthorizationException);
reasonPhrase = (forReasonPhrase == null || forReasonPhrase.isEmpty())
? " Proxy Authentication Required"
: (" " + forReasonPhrase);
assertEquals(
assertMessageForBadMessage,
"proxy authentication failed for " + forUrl + ", status: 407" + reasonPhrase,
e.getMessage());
break;
case HttpServletResponse.SC_FORBIDDEN:
assertTrue(
"403 Forbidden should throw AuthorizationException", e instanceof AuthorizationException);
reasonPhrase = (forReasonPhrase == null || forReasonPhrase.isEmpty())
? " Forbidden"
: (" " + forReasonPhrase);
assertEquals(
assertMessageForBadMessage,
"authorization failed for " + forUrl + ", status: 403" + reasonPhrase,
e.getMessage());
break;
default:
assertTrue(
"transfer failures should at least be wrapped in a TransferFailedException",
e instanceof TransferFailedException);
// the status code and reason phrase cannot always be learned due to implementation limitations
// so the message may not include them, but the implementation should use a consistent format
assertTrue(
"message should always include url tried: " + e.getMessage(),
e.getMessage().startsWith("transfer failed for " + forUrl));
String statusCodeStr = forStatusCode == NO_RESPONSE_STATUS_CODE ? "" : ", status: " + forStatusCode;
if (forStatusCode != NO_RESPONSE_STATUS_CODE) {
assertTrue(
"if there was a response status line, the status code should be >= 400",
forStatusCode >= HttpServletResponse.SC_BAD_REQUEST);
if (e.getMessage().length() > ("transfer failed for " + forUrl).length()) {
assertTrue(
"message should include url and status code: " + e.getMessage(),
e.getMessage().startsWith("transfer failed for " + forUrl + statusCodeStr));
}
reasonPhrase = forReasonPhrase == null ? "" : " " + forReasonPhrase;
if (reasonPhrase.length() > 0
&& e.getMessage().length()
> ("transfer failed for " + forUrl + statusCodeStr).length()) {
assertTrue(
"message should include url and status code and reason phrase: " + e.getMessage(),
e.getMessage()
.startsWith(
"transfer failed for " + forUrl + statusCodeStr + reasonPhrase));
}
}
break;
}
} catch (AssertionError assertionError) {
LOGGER.error("Exception which failed assertions: ", e);
throw assertionError;
}
}
}