1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest;
  28 
  29 import java.io.FileInputStream;
  30 import java.io.FileOutputStream;
  31 import java.io.IOException;
  32 import java.util.*;
  33 
  34 /**
  35  * Information about the last or current test run.  This is an interface onto
  36  * this meta-information stored in a work directory.
  37  */
  38 public class LastRunInfo {
  39     private LastRunInfo() {
  40     }
  41 
  42     private LastRunInfo(WorkDirectory wd) throws IOException {
  43         this();
  44 
  45         Properties p;
  46         try (FileInputStream in = new FileInputStream(wd.getSystemFile(FILENAME))) {
  47             p = new Properties();
  48             p.load(in);
  49         }
  50 
  51         String val = p.getProperty(START);
  52 
  53         try {
  54             startTime = Long.parseLong(val);
  55         }
  56         catch (NumberFormatException e) {
  57         }
  58 
  59         val = p.getProperty(FINISH);
  60         try {
  61             finishTime = Long.parseLong(val);
  62         }
  63         catch (NumberFormatException e) {
  64         }
  65 
  66         configName = p.getProperty(CONFIG);
  67         testURLs = split(p.getProperty(TEST_URLS));
  68     }
  69 
  70     /**
  71      * When did the last test run start.
  72      * Warning - the time information stored in a test result is only accurate to
  73      * one second, so everything below a 1000ms can't be compared reliably.  If you are
  74      * comparing times to a TestResult, it is suggested that you either remove the ms
  75      * from the return value or do something other than compare the integers.
  76      * @return The time (in milliseconds) at which the last test run started.
  77      * @see java.util.Date
  78      */
  79     public long getStartTime() {
  80         return startTime;
  81     }
  82 
  83     /**
  84      * When did the last test run end.
  85      * Warning - the time information stored in a test result is only accurate to
  86      * one second, so everything below a 1000ms can't be compared reliably.  If you are
  87      * comparing times to a TestResult, it is suggested that you either remove the ms
  88      * from the return value or do something other than compare the integers.
  89      * @return The time (in milliseconds) at which the last test run completed (for
  90      *         any reason).
  91      * @see java.util.Date
  92      */
  93     public long getFinishTime() {
  94         return finishTime;
  95     }
  96 
  97     /**
  98      * When did the last test run start.
  99      * @return The time (in milliseconds) at which the last test run started.
 100      *         May be zero if the information is not available.
 101      * @see java.util.Date
 102      */
 103     public Date getStartDate() {
 104         return new Date(startTime);
 105     }
 106 
 107     /**
 108      * When did the last test run end.
 109      * @return The time (in milliseconds) at which the last test run completed (for
 110      *         any reason).  May be zero if the information is not available.
 111      * @see java.util.Date
 112      */
 113     public Date getFinishDate() {
 114         return new Date(finishTime);
 115     }
 116 
 117     /**
 118      * Get the name of the configuration that was used in the last
 119      * test run.
 120      * @return Configuration name as it appeared in the configuration.  May be
 121      *         null or empty string if this information is not available.
 122      */
 123     public String getConfigName() {
 124         return configName;
 125     }
 126     /**
 127      * Get the URLs of the tests that were executed in the last test run.
 128      * @return String array of testURLs executed.
 129      */
 130     public List<String> getTestURLs() {
 131         return testURLs;
 132     }
 133 
 134     /**
 135      * Joins list of String into a single space separated String
 136      * @param list
 137      * @return A single string with all the items in the list joined.
 138      */
 139     private static String join(List<String> list) {
 140         if (list == null) {
 141             return "";
 142         }
 143         StringBuffer sb = new StringBuffer();
 144         for (Iterator<String> it = list.iterator(); it.hasNext();) {
 145             sb.append(it.next());
 146             sb.append(SEP);
 147         }
 148 
 149         // remove trailing space
 150         if (sb.length() > 0 && sb.charAt(sb.length()-1) == ' ')
 151             sb.deleteCharAt(sb.length()-1);
 152 
 153         return sb.toString();
 154     }
 155     /**
 156      * Split the string into list
 157      * @param joined - string to split
 158      * @return array list, never null.
 159      */
 160     private static List<String> split(String joined) {
 161         List<String> list = new ArrayList<>();
 162         if (joined == null || joined.trim().length() == 0) {
 163             return list;
 164         }
 165         // emulate StringTokenizer(joined, SEP) to find tokens
 166         int begin = 0;
 167         int end = joined.indexOf(SEP);
 168         while (end >= 0) {
 169             list.add(joined.substring(begin, end));
 170             begin = end + SEP.length();
 171             end = joined.indexOf(SEP, begin);
 172         }
 173         list.add(joined.substring(begin));
 174         return list;
 175     }
 176 
 177     /**
 178      * Given a work directory, attempt to create an instance using the information
 179      * found in it.
 180      * @param wd The work directory to create the information from.
 181      * @return Configuration name as it appeared in the configuration.  May be
 182      *         null or empty string if this information is not available.
 183      * @throws IOException Occurs if the last run info is not available or if the
 184      *         system has a problem while reading the file.
 185      */
 186     public static LastRunInfo readInfo(WorkDirectory wd) throws IOException {
 187         return new LastRunInfo(wd);
 188     }
 189 
 190     /**
 191      * Given a work directory, write the given run information in it.
 192      * @param workdir The work directory to modify.  Must be able to read-write
 193      *                files inside it.
 194      * @param start Time in milliseconds at which the last test run started.
 195      *              Must be a non-negative number.
 196      * @param stop Time in milliseconds at which the last test run terminated.
 197      *             Must be a non-negative number.
 198      * @param config Configuration name which was used to do the last test run.
 199      *               May be null or empty string if necessary.
 200      * @throws IOException If for any reason the information file cannot be
 201      *                     created, opened, written into or deleted.
 202      */
 203     public static void writeInfo(WorkDirectory workdir, long start, long stop,
 204             String config, List<String> testURLs)
 205                 throws IOException {
 206         Properties p = new Properties();
 207         p.setProperty(CONFIG, config);
 208         p.setProperty(START, Long.toString(start));
 209         p.setProperty(FINISH, Long.toString(stop));
 210         p.setProperty(TEST_URLS, join(testURLs));
 211 
 212         try (FileOutputStream out = new FileOutputStream(workdir.getSystemFile(FILENAME))) {
 213 
 214             // this is a date file, does not need i18n
 215             p.store(out, "Last test run info");
 216         }
 217     }
 218 
 219     private String configName;
 220     private long startTime;
 221     private long finishTime;
 222     private List<String> testURLs;
 223 
 224     // file in the work dir
 225     private static final String FILENAME = "lastRun.txt";
 226 
 227     // keys for properties
 228     private static final String START = "startTime";
 229     private static final String FINISH = "finishTime";
 230     private static final String CONFIG = "configName";
 231     private static final String TEST_URLS="testURLs";
 232 
 233     private static final String SEP = " ";
 234 }