1 /* 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.glass.ui.monocle; 27 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Formatter; 31 import java.util.List; 32 33 public class TestLogShim { 34 35 private static final boolean verbose = Boolean.getBoolean("verbose"); 36 private static final double timeScale = Double.parseDouble( 37 System.getProperty("timeScale", "1")); 38 39 private static final long DEFAULT_TIMEOUT = 3000l; 40 41 private static final List<String> log = new ArrayList<>(); 42 private static final Object lock = new Object(); 43 44 private static long startTime = System.currentTimeMillis(); 45 46 public static class TestLogAssertion extends Exception { 47 public TestLogAssertion(String message) { 48 super(message); 49 } 50 } 51 52 public static void log(String s) { 53 synchronized (lock) { 54 if (verbose) { 55 System.out.println(timestamp() + " TestLog: " + s); 56 } 57 log.add(s); 58 lock.notifyAll(); 59 } 60 } 61 62 public static void format(String format, Object... args) { 63 log(new Formatter().format(format, args).toString()); 64 } 65 66 public static List<String> getLog() { 67 return new ArrayList<>(log); 68 } 69 70 public static void clear() { 71 synchronized (lock) { 72 log.clear(); 73 } 74 } 75 76 public static void reset() { 77 synchronized (lock) { 78 log.clear(); 79 startTime = System.currentTimeMillis(); 80 } 81 } 82 83 public static String timestamp() { 84 long time = System.currentTimeMillis() - startTime; 85 StringBuffer sb = new StringBuffer().append(time); 86 while (sb.length() < 4) { 87 sb.insert(0, "0"); 88 } 89 while (sb.length() < 8) { 90 sb.insert(0, " "); 91 } 92 sb.insert(sb.length() - 3, "."); 93 return sb.toString(); 94 } 95 96 public static Object getLock() { 97 return lock; 98 } 99 100 public static int countLog(String s, int startIndex, boolean exact) { 101 int count = 0; 102 for (int i = startIndex; i < log.size(); i++) { 103 String line = log.get(i); 104 if (exact) { 105 if (line.equals(s)) { 106 count ++; 107 } 108 } else { 109 if (line.indexOf(s) >= 0) { 110 count ++; 111 } 112 } 113 } 114 return count; 115 } 116 117 public static int countLog(String s) { 118 return countLog(s, 0, true); 119 } 120 121 public static int countLogContaining(String s) { 122 return countLog(s, 0, false); 123 } 124 125 private static String checkLog(String[] matches, int startIndex, boolean exact) { 126 for (int i = startIndex; i < log.size(); i++) { 127 String line = log.get(i); 128 if (matches.length == 1) { 129 if (exact) { 130 if (line.equals(matches[0])) { 131 return line; 132 } 133 } else { 134 if (line.indexOf(matches[0]) >= 0) { 135 return line; 136 } 137 } 138 } else { 139 boolean isMatch = true; 140 for (String match : matches) { 141 if (line.indexOf(match) < 0) { 142 isMatch = false; 143 break; 144 } 145 } 146 if (isMatch) { 147 return line; 148 } 149 } 150 } 151 return null; 152 } 153 154 public static boolean checkLog(String s) { 155 return checkLog(new String[] {s}, 0, true) != null; 156 } 157 158 public static boolean checkLogContaining(String s) { 159 return checkLog(new String[] {s}, 0, false) != null; 160 } 161 162 public static void assertLog(String s) throws TestLogAssertion { 163 synchronized (lock) { 164 if (!checkLog(s)) { 165 String err = "No line '" + s + "' in log"; 166 if (verbose) { 167 System.out.println(err); 168 } 169 throw new TestLogAssertion(err); 170 } 171 } 172 } 173 174 public static void assertLogContaining(String s) throws TestLogAssertion { 175 synchronized (lock) { 176 if (!checkLogContaining(s)) { 177 String err = "No line containing '" + s + "' in log"; 178 if (verbose) { 179 System.out.println(err); 180 } 181 throw new TestLogAssertion(err); 182 } 183 } 184 } 185 186 private static String waitForLog(String[] s, long timeout, boolean exact) throws InterruptedException, TestLogAssertion { 187 long startTime = System.currentTimeMillis(); 188 long timeNow = startTime; 189 long endTime = timeNow + (long) (timeout * timeScale); 190 String line; 191 String logString = Arrays.toString(s).substring(1, Arrays.toString(s).length() - 1); 192 synchronized (lock) { 193 int index = 0; 194 while ((line = checkLog(s, index, exact)) == null) { 195 index = log.size(); 196 if (endTime - timeNow > 0) { 197 lock.wait(endTime - timeNow); 198 } 199 timeNow = System.currentTimeMillis(); 200 if (timeNow >= endTime) { 201 String message = "Timed out after " + (timeNow - startTime) 202 + "ms waiting for '" + logString + "'"; 203 if (!verbose) { 204 System.out.flush(); 205 System.err.flush(); 206 for (String logLine: log) { 207 System.out.println(logLine); 208 } 209 } 210 System.out.println(message); 211 throw new TestLogAssertion(message); 212 } 213 } 214 } 215 long matchTime = System.currentTimeMillis() - startTime; 216 if (verbose) { 217 if (exact) { 218 System.out.println("TestLog matched '" 219 + logString + "' in " 220 + matchTime + "ms"); 221 222 } else { 223 System.out.println("TestLog matched '" 224 + logString + "' with '" 225 + line + "' in " 226 + matchTime + "ms"); 227 } 228 } 229 return line; 230 } 231 232 public static String waitForLog(String s, long timeout) throws InterruptedException, TestLogAssertion { 233 return waitForLog(new String [] {s}, timeout, true); 234 } 235 236 public static String waitForLogContaining(String s, long timeout) throws InterruptedException, TestLogAssertion { 237 return waitForLog(new String [] {s}, timeout, false); 238 } 239 240 public static String waitForLog(String format, Object... args) throws InterruptedException, TestLogAssertion { 241 return waitForLog(new Formatter().format(format, args).toString(), 242 DEFAULT_TIMEOUT); 243 } 244 245 public static String waitForLogContaining(String format, Object... args) throws InterruptedException, TestLogAssertion { 246 return waitForLogContaining(new Formatter().format(format, args).toString(), 247 DEFAULT_TIMEOUT); 248 } 249 250 public static String waitForLogContainingSubstrings(String... s) throws InterruptedException, TestLogAssertion { 251 return waitForLog(s, DEFAULT_TIMEOUT, false); 252 } 253 }