package fr.inria.diversify.testamplification.logger; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * Verbose log for humans to understand * <p/> * Created by marodrig on 25/06/2014. */ @Deprecated public class AssertLogWriter extends LogWriter { ///File writer for each thread. Each one saved in a different file private Map<Thread, PrintWriter> fileWriters; private String separator = ":;:"; private String simpleSeparator = ";"; private String end = "$$$\n"; private Map<Class, String[]> previousValues; private Map<Class, Method[]> getters; private Map<Class, Field[]> fields; private Map<Class, String> classToId; private static int testCount = 0; private static long monitoringCount = 0; private static long assertCount = 0; private static int count = 0; public AssertLogWriter() { super(); previousValues = new HashMap<Class, String[]>(); getters = new HashMap<Class, Method[]>(); fields = new HashMap<Class, Field[]>(); classToId = new HashMap<Class, String>(); fileWriters = new HashMap<Thread, PrintWriter>(); } public void writeTestStart(Thread thread, String testSignature) { testCount++; String semaphore = ""; try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(end); stringBuilder.append("TS"); stringBuilder.append(simpleSeparator); stringBuilder.append(testSignature); String string = stringBuilder.toString(); PrintWriter fileWriter = getFileWriter(thread); semaphore = fileWriter.toString() + fileWriter.hashCode(); fileWriter.append(string); } catch (Exception e) { e.printStackTrace(); } finally { releaseFileWriter(semaphore); } } public void writeTestStart(Thread thread, Object thisObject, String testSignature) { writeTestStart(thread, thisObject.getClass().getName() + "." + testSignature); } @Override public void writeTestFinish(Thread t) { for (Thread thread : fileWriters.keySet()) { String semaphore = ""; try { PrintWriter flw = getFileWriter(thread); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(end); stringBuilder.append("TE"); stringBuilder.append(simpleSeparator); stringBuilder.append(System.currentTimeMillis()); semaphore = flw.toString() + flw.hashCode(); flw.append(stringBuilder.toString()); flw.flush(); } catch (Exception e) { e.printStackTrace(); } releaseFileWriter(semaphore); } } public void assertCount(String signature) { assertCount++; } protected String observe(Thread thread, Object object) throws IOException, InterruptedException { Class objectClass; if(object == null) { objectClass = null; } else { objectClass = object.getClass(); } Method[] classGetters = getGetters(thread, objectClass); Field[] classPublicFields = getPublicFields(thread, objectClass); String[] results = new String[classGetters.length + classPublicFields.length]; int i = 0; for(; i < classGetters.length ; i++) { try { results[i] = formatVar(classGetters[i].invoke(object)); } catch (Exception e) { results[i] = "null"; } } int j= 0; for(; i < results.length ; i++) { try { results[i] = formatVar(classPublicFields[j].get(object)); } catch (Exception e) { results[i] = "null"; } j++; } monitoringCount += results.length; StringBuilder sameValue = new StringBuilder(); List<String> result = new ArrayList<String>(); boolean sameValues = true; if(previousValues.containsKey(objectClass)) { String[] pValues = previousValues.get(objectClass); for (i = 0; i < results.length; i++) { if (pValues[i].equals(results[i])) { sameValue.append("0"); } else { sameValues = false; sameValue.append("1"); result.add(results[i]); pValues[i] = results[i]; } } } else { sameValues = false; String[] pValues = new String[results.length]; for (i = 0; i < results.length; i++) { sameValue.append("1"); result.add(results[i]); pValues[i] = results[i]; } previousValues.put(objectClass, pValues); } String classId = getClassId(thread, objectClass); if(sameValues) { return classId; } else { return classId + simpleSeparator + sameValue.toString() + separator + join(result, separator); } } protected String getClassId(Thread thread, Class objectClass) throws IOException, InterruptedException { String className; if(objectClass == null) { className = "NullClass"; } else { className = objectClass.getName(); } if(!classToId.containsKey(objectClass)) { classToId.put(objectClass, count + ""); PrintWriter fileWriter = getFileWriter(thread); String semaphore = fileWriter.toString() + fileWriter.hashCode(); fileWriter.append(end + "Cl" + simpleSeparator + className + simpleSeparator + count); releaseFileWriter(semaphore); count++; } return classToId.get(objectClass); } protected String join(List<String> list, String conjunction) { StringBuilder sb = new StringBuilder(); boolean first = true; for (String item : list) { if (first) first = false; else sb.append(conjunction); sb.append(item); } return sb.toString(); } protected String formatVar(Object object) { if (object == null) { return "null"; } String string; if (object.getClass().isArray()) { string = Arrays.toString((Object[]) object); } else { string = object + ""; } if(string.length() > 1000) string = string.length() + ""; return string; } public void logAssertArgument(Thread thread, int idAssertTarget, Object target, int idAssertInvocation, Object invocation) { logAssertArgument(thread, idAssertTarget, target); logAssertArgument(thread, idAssertInvocation, invocation); } public void logAssertArgument(Thread thread, int idAssert, Object invocation) { String semaphore = ""; if (getLogMethod(thread)) { try { StringBuilder string = new StringBuilder(); string.append(end); string.append("A"); string.append(simpleSeparator); string.append(idAssert + ""); stopLogMethod(thread); String varsString = observe(thread, invocation); string.append(simpleSeparator); string.append(varsString); startLogMethod(thread); PrintWriter fileWriter = getFileWriter(thread); semaphore = fileWriter.toString() + fileWriter.hashCode(); fileWriter.append(string.toString()); } catch (Exception e) { e.printStackTrace(); } finally { startLogMethod(thread); releaseFileWriter(semaphore); } } } public void close() { printCount(); for (Thread thread : fileWriters.keySet()) { String semaphore = ""; try { PrintWriter flw = getFileWriter(thread); semaphore = flw.toString() + flw.hashCode(); flw.close(); } catch (Exception e) { e.printStackTrace(); } releaseFileWriter(semaphore); } } protected void printCount() { try { String countFileName = dir.getAbsolutePath() + "/count"; PrintWriter f = new PrintWriter(new FileWriter(countFileName)); f.append("test count: "+testCount); f.append("\nmonitoring point count: "+monitoringCount); f.append("\nassert count: "+assertCount); f.close(); } catch (IOException e) { e.printStackTrace(); } } protected synchronized PrintWriter getFileWriter(Thread thread) throws IOException, InterruptedException { if (!fileWriters.containsKey(thread)) { String fileName = getThreadLogFilePath(thread) + "_" + System.currentTimeMillis(); PrintWriter f = new PrintWriter(new BufferedWriter(new FileWriter(fileName))); fileWriters.put(thread, f); semaphores.put(f.toString() + f.hashCode(), new Semaphore(1)); } PrintWriter f = fileWriters.get(thread); semaphores.get(f.toString() + f.hashCode()).tryAcquire(50, TimeUnit.MILLISECONDS); return f; } protected void releaseFileWriter(String id) { if (semaphores.containsKey(id)) semaphores.get(id).release(); } protected Field[] getPublicFields(Thread thread, Class aClass) throws IOException, InterruptedException { // if(!fields.containsKey(aClass)) { // intGettersAndFields(thread, aClass); // } return fields.get(aClass); } protected Method[] getGetters(Thread thread, Class aClass) throws IOException, InterruptedException { if(!getters.containsKey(aClass)) { intGettersAndFields(thread,aClass); } return getters.get(aClass); } protected void intGettersAndFields(Thread thread, Class aClass) throws IOException, InterruptedException { Method[] methods; Field[] publicFields; if(aClass == null) { methods = new Method[0]; publicFields = new Field[0]; } else { methods = findGetters(aClass); publicFields = findFields(aClass); } fields.put(aClass,publicFields); getters.put(aClass, methods); String classId = getClassId(thread, aClass); PrintWriter fileWriter = getFileWriter(thread); String semaphore = fileWriter.toString() + fileWriter.hashCode(); fileWriter.append(end + "Gt" + simpleSeparator + classId); for(Method method : methods) { fileWriter.append(simpleSeparator + method.getName()); } for(Field field : publicFields) { fileWriter.append(simpleSeparator + field.getName()); } releaseFileWriter(semaphore); } protected Field[] findFields(Class aClass) { List<Field> fields = new ArrayList<Field>(); for(Field field : aClass.getFields()) { if(Modifier.isPublic(field.getModifiers())) { fields.add(field); } } Field[] ret = new Field[fields.size()]; for(int i = 0; i < fields.size(); i++) { ret[i] = fields.get(i); } return ret; } protected Method[] findGetters(Class aClass){ List<Method> getters = new ArrayList<Method>(); for(Method method : aClass.getMethods()){ if((isGetter(method) || isIs(method)) && !methodDefinedInObject(method)) { getters.add(method); } } try { Method toStringMethod = aClass.getMethod("toString"); if(!methodDefinedInObject(toStringMethod)) { getters.add(toStringMethod); } } catch (NoSuchMethodException e) {} Method[] ret = new Method[getters.size()]; for(int i = 0; i< ret.length; i++ ) { ret[i] = getters.get(i); } return ret; } protected boolean isIs(Method method) { return method.getName().startsWith("is") && method.getParameterTypes().length == 0; } protected boolean isGetter(Method method) { return method.getName().startsWith("get") && method.getParameterTypes().length == 0; } protected boolean methodDefinedInObject(Method method) { for(Method objectMethod : Object.class.getMethods()) { if(objectMethod.equals(method)) { return true; } } return false; } }