All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.yandex.qatools.allure.utils.AllureResultsUtils Maven / Gradle / Ivy

There is a newer version: 1.4.0.RC9
Show newest version
package ru.yandex.qatools.allure.utils;

import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MimeTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.yandex.qatools.allure.config.AllureConfig;
import ru.yandex.qatools.allure.exceptions.AllureException;
import ru.yandex.qatools.allure.model.Attachment;
import ru.yandex.qatools.allure.model.ObjectFactory;
import ru.yandex.qatools.allure.model.TestSuiteResult;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.security.MessageDigest;

import static javax.xml.bind.Marshaller.JAXB_ENCODING;
import static javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT;
import static org.apache.tika.mime.MimeTypes.getDefaultMimeTypes;
import static ru.yandex.qatools.allure.config.AllureConfig.getDefaultResultsDirectory;
import static ru.yandex.qatools.allure.config.AllureNamingUtils.generateTestSuiteFileName;

/**
 * @author Artem Eroshenko [email protected]
 *         Date: 1/17/14
 *         

* Using to write test results (test suites and attachments) to result directory */ public final class AllureResultsUtils { private static File resultsDirectory; private static final int POSITIVE = 1; private static final int HEX = 16; private static final String UTF_8 = "UTF-8"; private static final String ESCAPE_HANDLER_PROPERTY = CharacterEscapeHandler.class.getName(); private static final Object RESULT_DIRECTORY_LOCK = new Object(); private static final Object ATTACHMENTS_LOCK = new Object(); private static final AllureConfig CONFIG = AllureConfig.newInstance(); private static final Logger LOGGER = LoggerFactory.getLogger(AllureResultsUtils.class); /** * Don't use instance */ AllureResultsUtils() { throw new IllegalStateException("Don't instance AllureResultsUtils"); } /** * Returns results directory. If {@link #resultsDirectory} not set create new * directory uses {@link #createResultsDirectory()} method. * * @return results directory */ public static File getResultsDirectory() { synchronized (RESULT_DIRECTORY_LOCK) { if (resultsDirectory == null) { resultsDirectory = createResultsDirectory(); } } return resultsDirectory; } /** * Create results directory. First step try to create {@link #CONFIG#getResultsDirectory()}, * if cannot, try to create {@link ru.yandex.qatools.allure.config.AllureConfig#getDefaultResultsDirectory}, * and if cannot, returns a new File instance by converting the "allure-results" * pathname string into an abstract pathname. * * @return created results directory */ private static File createResultsDirectory() { File resultsDirectory = CONFIG.getResultsDirectory(); if (createDirectories(resultsDirectory)) { return resultsDirectory; } LOGGER.error(String.format( "Results directory <%s> doesn't exists and can't be created, using default directory", resultsDirectory.getAbsolutePath() )); resultsDirectory = getDefaultResultsDirectory(); if (createDirectories(resultsDirectory)) { return resultsDirectory; } LOGGER.error(String.format( "Default results directory <%s> doesn't exists and can't be created, using temp directory", resultsDirectory.getAbsolutePath() )); try { return Files.createTempDirectory("allure-results").toFile(); } catch (IOException e) { throw new AllureException("Can't create results directory", e); } } /** * Try to create the directory named by this abstract pathname, including any * necessary but nonexistent parent directories. * * @param dir to create * @return true, if directory successfully created, false otherwise */ public static boolean createDirectories(File dir) { return dir.exists() || dir.mkdirs(); } /** * Sets results directory. Use only for tests * * @param resultsDirectory results directory to set */ public static void setResultsDirectory(File resultsDirectory) { AllureResultsUtils.resultsDirectory = resultsDirectory; } /** * Marshal {@link ru.yandex.qatools.allure.model.TestSuiteResult} to {@link #resultsDirectory} * uses {@link BadXmlCharacterEscapeHandler}. Name of file generated uses * {@link ru.yandex.qatools.allure.config.AllureNamingUtils#generateTestSuiteFileName()} * * @param testSuite to marshal */ public static void writeTestSuiteResult(TestSuiteResult testSuite) { File testSuiteResultFile = new File(getResultsDirectory(), generateTestSuiteFileName()); try { marshaller(TestSuiteResult.class).marshal( new ObjectFactory().createTestSuite(testSuite), testSuiteResultFile ); } catch (Exception e) { LOGGER.error("Error while marshaling testSuite", e); } } /** * Creates a new {@link javax.xml.bind.Marshaller} for given class. * If marshaller created successfully, try to set following properties: * {@link Marshaller#JAXB_FORMATTED_OUTPUT}, {@link Marshaller#JAXB_ENCODING}, * {@link #ESCAPE_HANDLER_PROPERTY} using {@link #setPropertySafely(javax.xml.bind.Marshaller, String, Object)} * * @param clazz specified class * @return a created marshaller * @throws AllureException if can't create marshaller for given class. */ public static Marshaller marshaller(Class clazz) { Marshaller m = createMarshallerForClass(clazz); setPropertySafely(m, JAXB_FORMATTED_OUTPUT, true); setPropertySafely(m, JAXB_ENCODING, UTF_8); setPropertySafely(m, ESCAPE_HANDLER_PROPERTY, BadXmlCharacterEscapeHandler.getInstance()); return m; } /** * Creates a new {@link javax.xml.bind.Marshaller} for given class. * * @param clazz specified class * @return a created marshaller * @throws AllureException if can't create marshaller for given class. */ public static Marshaller createMarshallerForClass(Class clazz) { try { return JAXBContext.newInstance(clazz).createMarshaller(); } catch (JAXBException e) { throw new AllureException("Can't create marshaller for class " + clazz); } } /** * Try to set specified property to given marshaller * * @param marshaller specified marshaller * @param name name of property to set * @param value value of property to set */ public static void setPropertySafely(Marshaller marshaller, String name, Object value) { try { marshaller.setProperty(name, value); } catch (PropertyException e) { LOGGER.warn(String.format("Can't set \"%s\" property to given marshaller", name), e); } } /** * Remove attachment form {@link #resultsDirectory} * * @param attachment to remove * @return true, if attachment removed successfully, false otherwise */ public static boolean deleteAttachment(Attachment attachment) { File attachmentFile = new File(getResultsDirectory(), attachment.getSource()); return attachmentFile.exists() && attachmentFile.canWrite() && attachmentFile.delete(); } /** * Write attachment uses {@link #writeAttachment(byte[], String, String)} (if * specified attachment type not empty) or {@link #writeAttachment(byte[], String)} * otherwise. If something went wrong uses * {@link #writeAttachmentWithErrorMessage(Throwable, String)} * * @param attachment which will write * @param title attachment title * @param type attachment type (should be valid mime-type, empty string or null) * @return Created {@link ru.yandex.qatools.allure.model.Attachment} */ public static Attachment writeAttachmentSafely(byte[] attachment, String title, String type) { try { return type == null || type.isEmpty() ? writeAttachment(attachment, title) : writeAttachment(attachment, title, type); } catch (Exception e) { return writeAttachmentWithErrorMessage(e, title); } } /** * Write throwable as attachment. * * @param throwable to write * @param title title of attachment * @return Created {@link ru.yandex.qatools.allure.model.Attachment} */ public static Attachment writeAttachmentWithErrorMessage(Throwable throwable, String title) { String message = throwable.getMessage(); try { return writeAttachment(message.getBytes(CONFIG.getAttachmentsEncoding()), title); } catch (Exception e) { e.addSuppressed(throwable); LOGGER.error(String.format("Can't write attachment \"%s\"", title), e); } return new Attachment(); } /** * Write attachment with specified type. Generate attachment name uses * {@link #generateAttachmentName(byte[])}, attachment extension uses * {@link #getExtensionByMimeType(String)} * * @param attachment byte array with attachment * @param title attachment title * @param type valid mime-type of attachment * @return Created {@link ru.yandex.qatools.allure.model.Attachment} * @throws IOException if can't write attachment */ public static Attachment writeAttachment(byte[] attachment, String title, String type) throws IOException { String name = generateAttachmentName(attachment); String extension = getExtensionByMimeType(type); String source = name + extension; File file = new File(getResultsDirectory(), source); synchronized (ATTACHMENTS_LOCK) { if (!file.exists()) { try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(attachment); } } } return new Attachment().withTitle(title).withSource(source).withType(type).withSize(attachment.length); } /** * Write attachment without specified type. Using {@link org.apache.tika.mime.MimeTypes#detect} * to autodetect attachment type from attachment content. * * @param attachment to write * @param title attachment title * @return Created {@link ru.yandex.qatools.allure.model.Attachment} * @throws IOException if can't write attachment */ public static Attachment writeAttachment(byte[] attachment, String title) throws IOException { String type = getDefaultMimeTypes().detect(new ByteArrayInputStream(attachment), new Metadata()).toString(); return writeAttachment(attachment, title, type); } /** * Generate attachment name. As prefix uses sha256 of given content * * @param attachment content * @return generated name, looks like \"{sha256}-attachment\" */ public static String generateAttachmentName(byte[] attachment) { String prefix = "unknown"; try { byte[] bytes = MessageDigest.getInstance("SHA-256").digest(attachment); prefix = new BigInteger(POSITIVE, bytes).toString(HEX); } catch (Exception ignored) { } return prefix + CONFIG.getAttachmentFileSuffix(); } /** * Generate attachment extension from mime type * * @param type valid mime-type * @return extension if it's known for specified mime-type, or empty string * otherwise */ public static String getExtensionByMimeType(String type) { MimeTypes types = getDefaultMimeTypes(); try { return types.forName(type).getExtension(); } catch (Exception e) { LOGGER.warn("Can't detect extension for MIME-type", e); return ""; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy