@Override protected void after() { for (int i=0; i< classNames.length;i++) { String classNameToReset = classNames[i]; try { org.evosuite.runtime.classhandling.ClassResetter.getInstance().reset(classNameToReset); } catch (Throwable t) { } } } }
public StaticStateResetter(String... classesToReset) { classNames = Arrays.copyOf(classesToReset, classesToReset.length); org.evosuite.Properties.RESET_STATIC_FIELDS = true; /* * FIXME: tmp hack done during refactoring */ org.evosuite.runtime.classhandling.ClassResetter.getInstance().setClassLoader( TestGenerationContext.getInstance().getClassLoaderForSUT()); }
public Method getResetMethod(String classNameWithDots) { cacheResetMethod(classNameWithDots); return resetMethodCache.get(loader).get(classNameWithDots); }
@Test public void testResetOfEnum() throws Exception{ ClassLoader loader = new EvoClassLoader(); RuntimeSettings.resetStaticState = true; ClassResetter.getInstance().setClassLoader(loader); String cut = "com.examples.with.different.packagename.classhandling.FooEnum"; Class<?> klass = loader.loadClass(cut); Method m = klass.getDeclaredMethod("check"); boolean val = false; val = (Boolean) m.invoke(null); Assert.assertTrue(val); ClassResetter.getInstance().reset(cut); //make sure that the reset does not create new enum instance values val = (Boolean) m.invoke(null); Assert.assertTrue(val); }
Method resetMethod = ClassResetter.getInstance().getResetMethod(className); if (resetMethod != null) { LoopCounter.getInstance().setActive(false); ClassResetter.getInstance().logWarn(className, e.getClass() + " thrown during execution of method __STATIC_RESET() for class " + className + ", " + e.getCause());
Method m = getResetMethod(classNameWithDots); if(m == null) { return; logWarn(classNameWithDots, e.toString() + ", caused by: "+cause.toString()); } else { StringWriter errors = new StringWriter(); cause.printStackTrace(new PrintWriter(errors)); logWarn(classNameWithDots, e.toString() + ", caused by: "+cause.toString()+"\n"+errors.toString());
private void cacheResetMethod(String classNameWithDots) { if (!resetMethodCache.containsKey(loader)) { resetMethodCache.put(loader, new HashMap<>()); } Map<String, Method> methodMap = resetMethodCache.get(loader); if (methodMap.containsKey(classNameWithDots)) { return; } try { Class<?> clazz = loader.loadClass(classNameWithDots); if(clazz.isInterface() || clazz.isAnonymousClass()) { return; } Method m = clazz.getDeclaredMethod(STATIC_RESET, (Class<?>[]) null); m.setAccessible(true); methodMap.put(classNameWithDots, m); } catch (NoSuchMethodException e) { //this can happen if class was not instrumented with a static reset logger.debug("__STATIC_RESET() method does not exists in class {}", classNameWithDots); } catch (Exception | Error e) { logWarn(classNameWithDots, e.getClass() + " thrown while loading method __STATIC_RESET() for class " + classNameWithDots); } }
@Ignore @Test public void testResetOfMutableEnum() throws Exception{ ClassLoader loader = new EvoClassLoader(); RuntimeSettings.resetStaticState = true; ClassResetter.getInstance().setClassLoader(loader); String cut = MutableEnum.class.getCanonicalName(); Class<?> klass = (Class<MutableEnum>) loader.loadClass(cut); Object[] enums = klass.getEnumConstants(); Assert.assertEquals(2, enums.length); Method getter = klass.getDeclaredMethod("getLetter"); Assert.assertEquals("a", getter.invoke(enums[0])); Assert.assertEquals("b", getter.invoke(enums[1])); Method m = klass.getDeclaredMethod("changeLetter"); m.invoke(enums[0]); Assert.assertEquals("X", getter.invoke(enums[0])); Assert.assertEquals("b", getter.invoke(enums[1])); ClassResetter.getInstance().reset(cut); Assert.assertEquals("a", getter.invoke(enums[0])); Assert.assertEquals("b", getter.invoke(enums[1])); } }
/** * Reset the static state of all the given classes. * * <p> * This method will be usually called after a test is executed, ie in a @After * </p> * * @param classNames */ public static void resetClasses(String... classNames) { for (int i=0; i< classNames.length;i++) { String classNameToReset = classNames[i]; ClassResetter.getInstance().reset(classNameToReset); } }
/** * Resets the classes passes in the list using the given class loader * * @param classesToReset * @param loader */ public void resetClasses(List<String> classesToReset, ClassLoader loader) { // try to reset each collected class ClassResetter.getInstance().setClassLoader(loader); long start = System.currentTimeMillis(); for (String className : classesToReset) { // re-initialization can be expensive long elapsed = System.currentTimeMillis() - start; if (!className.equals(Properties.TARGET_CLASS) && (!TimeController.getInstance().isThereStillTimeInThisPhase() || elapsed > Properties.TIMEOUT_RESET)) { // Note: we no longer cancel the class re-initialization since // it might leave the static data in an inconsistent state } resetClass(className); } }