/* * Sakuli - Testing and Monitoring-Tool for Websites and common UIs. * * Copyright 2013 - 2015 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.sakuli.datamodel; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.sakuli.datamodel.state.SakuliState; import org.sakuli.exceptions.SakuliExceptionHandler; import org.sakuli.exceptions.SakuliExceptionWithScreenshot; import org.sakuli.services.InitializingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.file.Path; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * @author tschneck * Date: 12.07.13 */ public abstract class AbstractTestDataEntity<E extends Throwable, S extends SakuliState> implements Comparable<AbstractTestDataEntity> { public final static DateFormat GUID_DATE_FORMATE = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SS"); public final static DateFormat PRINT_DATE_FORMATE = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); protected final Logger logger = LoggerFactory.getLogger(this.getClass()); protected Date startDate; protected Date stopDate; protected E exception; protected S state; protected String name; /** * is initial set to -1, if the database forwarder profile is enabled the service call {@link InitializingService#initTestSuite()} * should set the primary key. */ protected int dbPrimaryKey = -1; /** * needed to be set to -1, so the function {@link org.sakuli.actions.TestCaseAction#addTestCaseStep(String, String, String, int)} * can check if the method {@link org.sakuli.actions.TestCaseAction#initWarningAndCritical(int, int)} * have been called at the beginning of this test case. */ protected int warningTime = -1; protected int criticalTime = -1; protected String id; /** * represent the creation date for this entity, to enable effective sorting after it. * This is only for INTERNAL use. To get the date of starting this entity, see {@link #startDate}. **/ private DateTime creationDate; public AbstractTestDataEntity() { creationDate = new DateTime(); } protected static String getMessageOrClassName(Throwable e) { return StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage(); } /** * set the times to the format "time in millisec / 1000" * * @param date regular {@link Date} object * @return UNIX-Time formatted String */ protected String createUnixTimestamp(Date date) { if (date == null) { return "-1"; } else { String milliSec = String.valueOf(date.getTime()); return new StringBuilder(milliSec).insert(milliSec.length() - 3, ".").toString(); } } /** * calculate the duration * * @return the duration in seconds */ public float getDuration() { try { float result = (float) ((stopDate.getTime() - startDate.getTime()) / 1000.0); return (result < 0) ? -1 : result; } catch (NullPointerException e) { return -1; } } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } public Date getStopDate() { return stopDate; } public void setStopDate(Date stopDate) { this.stopDate = stopDate; } public String getStartDateAsUnixTimestamp() { return createUnixTimestamp(startDate); } public String getStopDateAsUnixTimestamp() { return createUnixTimestamp(stopDate); } public void addException(E e) { if (exception == null) { this.exception = e; } else { exception.addSuppressed(e); } } public Throwable getException() { return exception; } public void clearException() { this.exception = null; } public String getExceptionMessages(boolean flatFormatted) { if (exception != null) { String msg = getMessageOrClassName(exception); //add suppressed exceptions for (Throwable ee : exception.getSuppressed()) { if (flatFormatted) { msg += " -- Suppressed EXCEPTION: " + getMessageOrClassName(ee); } else { msg += "\n\t\tSuppressed EXCEPTION: " + getMessageOrClassName(ee); } } if (flatFormatted) { msg = StringUtils.replace(msg, "\n", " "); msg = StringUtils.replace(msg, "\t", " "); } return msg; } else { return null; } } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getDbPrimaryKey() { return dbPrimaryKey; } public void setDbPrimaryKey(int dbPrimaryKey) { this.dbPrimaryKey = dbPrimaryKey; } public int getWarningTime() { return warningTime; } /** * If the threshold is set to 0, the execution time will never exceed, so the state will be always OK! * * @param warningTime time in seconds */ public void setWarningTime(int warningTime) { this.warningTime = warningTime; } public int getCriticalTime() { return criticalTime; } /** * If the threshold is set to 0, the execution time will never exceed, so the state will be always OK! * * @param criticalTime time in seconds */ public void setCriticalTime(int criticalTime) { this.criticalTime = criticalTime; } public String getId() { return id; } public void setId(String id) { this.id = id; } /** * refresh the current state based on the set warning and critical times */ public abstract void refreshState(); public Path getScreenShotPath() { return SakuliExceptionHandler.getScreenshotFile(exception); } protected String getResultString() { String stout = "\nname: " + this.getName() + "\nRESULT STATE: " + this.getState(); if (this.getState() != null) { stout += "\nresult code: " + this.getState().getErrorCode(); } //if no exception is there, don't print it if (this.exception != null) { stout += "\nERRORS:" + this.getExceptionMessages(false); if (this.exception instanceof SakuliExceptionWithScreenshot) { stout += "\nERROR - SCREENSHOT: " + this.getScreenShotPath().toFile().getAbsolutePath(); } } stout += "\ndb primary key: " + this.getDbPrimaryKey() + "\nduration: " + this.getDuration() + " sec."; if (!(warningTime == -1)) { stout += "\nwarning time: " + this.getWarningTime() + " sec."; } if (!(criticalTime == -1)) { stout += "\ncritical time: " + this.getCriticalTime() + " sec."; } if (this.getStartDate() != null) { stout += "\nstart time: " + PRINT_DATE_FORMATE.format(this.getStartDate()); } if (this.getStopDate() != null) { stout += "\nend time: " + PRINT_DATE_FORMATE.format(this.getStopDate()); } return stout; } public S getState() { return state; } public void setState(S state) { this.state = state; } public DateTime getCreationDate() { return creationDate; } public void setCreationDate(DateTime creationDate) { this.creationDate = creationDate; } @Override public int compareTo(AbstractTestDataEntity abstractSakuliTest) { if (abstractSakuliTest == null) { return 1; } if (super.equals(abstractSakuliTest)) { return 0; } Date startDate2 = abstractSakuliTest.getStartDate(); if (this.startDate == null || startDate2 == null || this.startDate.compareTo(startDate2) == 0) { boolean boothNull = this.startDate == null && startDate2 == null; if (!boothNull) { if (this.startDate == null) { return 1; } if (startDate2 == null) { return -1; } } return creationDate.compareTo(abstractSakuliTest.getCreationDate()); } return this.startDate.compareTo(startDate2); } @Override public boolean equals(Object obj) { if (obj instanceof AbstractTestDataEntity) { return compareTo((AbstractTestDataEntity) obj) == 0; } return super.equals(obj); } @Override public String toString() { return "startDate=" + startDate + ", stopDate=" + stopDate + ", exception=" + exception + ", state=" + state + ", name='" + name + '\'' + ", dbPrimaryKey=" + dbPrimaryKey + ", warningTime=" + warningTime + ", criticalTime=" + criticalTime ; } public String toStringShort() { return String.format("%s [id = %s, name = %s]", this.getClass().getSimpleName(), id, name); } }