Skip to content

Commit 684a8f5

Browse files
committed
wip
1 parent 5bbad0a commit 684a8f5

40 files changed

Lines changed: 9669 additions & 2 deletions

client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/SutRunDto.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ public class SutRunDto {
4545
*/
4646
public String methodReplacementCategories;
4747

48+
/**
49+
* Whether to enable Dynamosa graphs generation in the Java agent
50+
*/
51+
public Boolean enableDynamosaGraphs;
52+
53+
/**
54+
* Whether to write generated graphs (DOT/PNGs) to disk on the agent side
55+
*/
56+
public Boolean writeCfg;
57+
4858

4959
public SutRunDto() {
5060
}

client-java/controller/src/main/java/org/evomaster/client/java/controller/ExternalSutController.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.evomaster.client.java.controller.internal.SutController;
1313
import org.evomaster.client.java.instrumentation.external.JarAgentLocator;
1414
import org.evomaster.client.java.instrumentation.external.ServerController;
15+
import org.evomaster.client.java.instrumentation.external.DynamosaConfigDto;
1516

1617
import java.io.BufferedReader;
1718
import java.io.IOException;
@@ -522,6 +523,28 @@ public final void setExecutingInitMongo(boolean executingInitMongo) {
522523
ExecutionTracer.setExecutingInitMongo(executingInitMongo);
523524
}
524525

526+
/**
527+
* Send Dynamosa configuration to the Java Agent.
528+
*/
529+
public final void setDynamosaGraphsEnabled(boolean enableGraphs) {
530+
checkInstrumentation();
531+
DynamosaConfigDto dto = new DynamosaConfigDto();
532+
dto.enableGraphs = enableGraphs;
533+
dto.writeCfg = null;
534+
serverController.setDynamosaConfig(dto);
535+
}
536+
537+
/**
538+
* Control whether the agent writes DOT/PNG graphs to disk.
539+
*/
540+
public final void setWriteCfgEnabled(boolean writeCfg) {
541+
checkInstrumentation();
542+
DynamosaConfigDto dto = new DynamosaConfigDto();
543+
dto.enableGraphs = null;
544+
dto.writeCfg = writeCfg;
545+
serverController.setDynamosaConfig(dto);
546+
}
547+
525548
@Override
526549
public final void setExecutingAction(boolean executingAction){
527550
checkInstrumentation();

client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/EMController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ public Response runSut(SutRunDto dto, @Context HttpServletRequest httpServletReq
377377
if (!noKillSwitch(() -> sutController.isSutRunning())) {
378378
noKillSwitch(() -> sutController.bootingSut(true));
379379
baseUrlOfSUT = noKillSwitch(() -> sutController.startSut());
380+
// Configure Dynamosa graphs on the agent, if requested by core
381+
Boolean enableGraphs = dto.enableDynamosaGraphs;
382+
if (enableGraphs != null) noKillSwitch(() -> sutController.setDynamosaGraphsEnabled(enableGraphs));
383+
Boolean writeCfg = dto.writeCfg;
384+
if (writeCfg != null) noKillSwitch(() -> sutController.setWriteCfgEnabled(writeCfg));
380385
noKillSwitch(() -> sutController.bootingSut(false));
381386
if (baseUrlOfSUT == null) {
382387
//there has been an internal failure in starting the SUT

client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,22 @@ public abstract List<TargetInfo> getTargetInfos(Collection<Integer> ids,
15641564

15651565
public abstract void setExecutingAction(boolean executingAction);
15661566

1567+
/**
1568+
* Enable/disable Dynamosa graphs generation in the Java agent.
1569+
* Default no-op; external controllers can override to send to agent.
1570+
*/
1571+
public void setDynamosaGraphsEnabled(boolean enableGraphs){
1572+
// no-op by default
1573+
}
1574+
1575+
/**
1576+
* Enable/disable writing graphs to disk in the Java agent.
1577+
* Default no-op; external controllers can override to send to agent.
1578+
*/
1579+
public void setWriteCfgEnabled(boolean writeCfg){
1580+
// no-op by default
1581+
}
1582+
15671583

15681584
/**
15691585
* specify whether the SUT is booting (ie starting up), or not.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
3+
* contributors
4+
*
5+
* This file is part of EvoSuite.
6+
*
7+
* EvoSuite is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Lesser General Public License as published
9+
* by the Free Software Foundation, either version 3.0 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* EvoSuite is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package org.evomaster.client.java.instrumentation;
22+
23+
import org.objectweb.asm.Label;
24+
import org.objectweb.asm.tree.LabelNode;
25+
26+
/**
27+
* Annotated labels are used to identify instrumented code
28+
* such that EvoSuite knows how to deal with
29+
*
30+
* @author fraser
31+
*/
32+
public class AnnotatedLabel extends Label {
33+
34+
private boolean isStart = false;
35+
36+
private boolean ignore = false;
37+
38+
private boolean ignoreFalse = false;
39+
40+
private LabelNode parent = null;
41+
42+
public AnnotatedLabel(boolean ignore, boolean start) {
43+
this.ignore = ignore;
44+
this.isStart = start;
45+
}
46+
47+
public AnnotatedLabel(boolean ignore, boolean start, LabelNode parent) {
48+
this.ignore = ignore;
49+
this.isStart = start;
50+
this.parent = parent;
51+
}
52+
53+
public boolean isStartTag() {
54+
return isStart;
55+
}
56+
57+
public boolean shouldIgnore() {
58+
return ignore;
59+
}
60+
61+
public void setIgnoreFalse(boolean value) {
62+
ignoreFalse = value;
63+
}
64+
65+
public boolean shouldIgnoreFalse() {
66+
return ignoreFalse;
67+
}
68+
69+
public LabelNode getParent() {
70+
return parent;
71+
}
72+
73+
public void setParent(LabelNode parent) {
74+
this.parent = parent;
75+
}
76+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
3+
* contributors
4+
*
5+
* This file is part of EvoSuite.
6+
*
7+
* EvoSuite is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Lesser General Public License as published
9+
* by the Free Software Foundation, either version 3.0 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* EvoSuite is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package org.evomaster.client.java.instrumentation;
22+
23+
import org.objectweb.asm.Label;
24+
import org.objectweb.asm.Opcodes;
25+
import org.objectweb.asm.tree.LabelNode;
26+
import org.objectweb.asm.tree.MethodNode;
27+
28+
/**
29+
* <p>AnnotatedMethodNode class.</p>
30+
*
31+
* @author fraser
32+
*/
33+
public class AnnotatedMethodNode extends MethodNode {
34+
35+
/**
36+
* <p>Constructor for AnnotatedMethodNode.</p>
37+
*
38+
* @param access a int.
39+
* @param name a {@link java.lang.String} object.
40+
* @param desc a {@link java.lang.String} object.
41+
* @param signature a {@link java.lang.String} object.
42+
* @param exceptions an array of {@link java.lang.String} objects.
43+
*/
44+
public AnnotatedMethodNode(int access, String name, String desc, String signature,
45+
String[] exceptions) {
46+
super(Opcodes.ASM9, access, name, desc, signature, exceptions);
47+
}
48+
49+
/**
50+
* {@inheritDoc}
51+
* <p>
52+
* Returns the LabelNode corresponding to the given Label. Creates a new
53+
* LabelNode if necessary. The default implementation of this method uses
54+
* the {@link Label#info} field to store associations between labels and
55+
* label nodes.
56+
*/
57+
@Override
58+
protected LabelNode getLabelNode(final Label l) {
59+
if (l instanceof AnnotatedLabel) {
60+
AnnotatedLabel al = (AnnotatedLabel) l;
61+
al.setParent(new LabelNode(al));
62+
return al.getParent();
63+
} else {
64+
if (!(l.info instanceof LabelNode)) {
65+
l.info = new LabelNode(l);
66+
}
67+
return (LabelNode) l.info;
68+
}
69+
}
70+
}

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/Instrumentator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.evomaster.client.java.instrumentation.shared.ClassName;
88
import org.evomaster.client.java.instrumentation.staticstate.UnitsInfoRecorder;
99
import org.evomaster.client.java.utils.SimpleLogger;
10+
import org.evomaster.client.java.instrumentation.dynamosa.DynamosaConfig;
11+
import org.evomaster.client.java.instrumentation.dynamosa.graphs.cfg.CFGClassAdapter;
1012
import org.objectweb.asm.ClassReader;
1113
import org.objectweb.asm.ClassVisitor;
1214
import org.objectweb.asm.ClassWriter;
@@ -71,6 +73,11 @@ public byte[] transformBytes(ClassLoader classLoader, ClassName className, Class
7173
cv = new ThirdPartyClassVisitor(cv, className);
7274
}
7375

76+
boolean dynamosaGraphs = DynamosaConfig.isGraphsEnabled();
77+
if (dynamosaGraphs) {
78+
cv = new CFGClassAdapter(classLoader, cv);
79+
}
80+
7481
try {
7582
cn.accept(cv);
7683
} catch(Throwable e){
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
3+
* contributors
4+
*
5+
* This file is part of EvoSuite.
6+
*
7+
* EvoSuite is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Lesser General Public License as published
9+
* by the Free Software Foundation, either version 3.0 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* EvoSuite is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
package org.evomaster.client.java.instrumentation;
21+
22+
import org.objectweb.asm.ClassVisitor;
23+
import org.objectweb.asm.MethodVisitor;
24+
import org.objectweb.asm.Opcodes;
25+
26+
import java.util.LinkedHashSet;
27+
import java.util.Set;
28+
29+
public class RemoveFinalClassAdapter extends ClassVisitor {
30+
31+
public static final Set<String> finalClasses = new LinkedHashSet<>();
32+
33+
public RemoveFinalClassAdapter(ClassVisitor cv) {
34+
super(Opcodes.ASM9, cv);
35+
}
36+
37+
/**
38+
* Remove "final" accessor from class definition
39+
*/
40+
@Override
41+
public void visit(int version, int access, String name, String signature,
42+
String superName, String[] interfaces) {
43+
if ((access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL) {
44+
finalClasses.add(name.replace('/', '.'));
45+
}
46+
if ((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT &&
47+
(access & Opcodes.ACC_PUBLIC) == 0 &&
48+
(access & Opcodes.ACC_PRIVATE) == 0 &&
49+
(access & Opcodes.ACC_PROTECTED) == 0) {
50+
// If a class is abstract and default-accessible, then we make it public to allow
51+
// Mockito to create mocks
52+
super.visit(version, (access & ~Opcodes.ACC_FINAL) | Opcodes.ACC_PUBLIC, name, signature, superName, interfaces);
53+
} else {
54+
super.visit(version, access & ~Opcodes.ACC_FINAL, name, signature, superName, interfaces);
55+
}
56+
}
57+
58+
/**
59+
* Remove "final" accessor from inner class definition
60+
*/
61+
@Override
62+
public void visitInnerClass(String name, String outerName, String innerName, int access) {
63+
if ((access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL) {
64+
finalClasses.add(name.replace('/', '.'));
65+
}
66+
super.visitInnerClass(name, outerName, innerName, access & ~Opcodes.ACC_FINAL);
67+
}
68+
69+
@Override
70+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
71+
return super.visitMethod(access & ~Opcodes.ACC_FINAL, name, desc, signature, exceptions);
72+
}
73+
74+
public static void reset() {
75+
finalClasses.clear();
76+
}
77+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.evomaster.client.java.instrumentation.dynamosa;
2+
3+
/**
4+
* Runtime configuration for DYNAMOSA-related instrumentation features.
5+
* Populated via the agent control channel.
6+
*/
7+
public class DynamosaConfig {
8+
9+
private static volatile boolean enableGraphs = false;
10+
private static volatile boolean writeCfg = false;
11+
12+
public static boolean isGraphsEnabled() {
13+
return enableGraphs;
14+
}
15+
16+
public static void setEnableGraphs(boolean value) {
17+
enableGraphs = value;
18+
}
19+
20+
public static boolean isWriteCfgEnabled() {
21+
return writeCfg;
22+
}
23+
24+
public static void setWriteCfgEnabled(boolean value) {
25+
writeCfg = value;
26+
}
27+
}
28+
29+

0 commit comments

Comments
 (0)