Skip to content

Commit 3d3cf31

Browse files
committed
Some basic clean up and refactoring
1 parent a5b9579 commit 3d3cf31

File tree

4 files changed

+695
-380
lines changed

4 files changed

+695
-380
lines changed

Src/PEx/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@
278278
</distributionManagement>
279279

280280
<properties>
281-
<java.version>17</java.version>
281+
<java.version>23</java.version>
282282
<maven.compiler.source>${java.version}</maven.compiler.source>
283283
<maven.compiler.target>${java.version}</maven.compiler.target>
284284
<log4j2.configurationFile>${project.basedir}/src/main/resources/log4j2.xml</log4j2.configurationFile>

Src/PEx/src/main/java/pex/PEx.java

Lines changed: 121 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -27,70 +27,101 @@ public class PEx {
2727
/**
2828
* Main entry point for PEx runtime.
2929
*/
30+
/**
31+
* Exit codes:
32+
* 0 - Success
33+
* 2 - Bug found or too many choices
34+
* 3 - Timeout
35+
* 4 - Out of memory
36+
* 5 - Runtime error
37+
* 6 - Test driver error
38+
*/
3039
public static void main(String[] args) {
3140
// configure Log4J
3241
Log4JConfig.configureLog4J();
3342

34-
// parse the commandline arguments to create the configuration
35-
PExGlobal.setConfig(PExOptions.ParseCommandlineArgs(args));
36-
PExGlobal.setChoiceSelector();
37-
PExLogger.Initialize(PExGlobal.getConfig().getVerbosity());
38-
ComputeHash.Initialize();
39-
40-
// get reflections corresponding to the model
41-
Reflections reflections = new Reflections("pex.model");
42-
43-
try {
44-
// get all classes extending PModel
45-
Set<Class<? extends PModel>> subTypesPModel = reflections.getSubTypesOf(PModel.class);
46-
if (subTypesPModel.isEmpty()) {
47-
throw new Exception("No PModel found.");
48-
}
49-
Optional<Class<? extends PModel>> pModel = subTypesPModel.stream().findFirst();
50-
51-
// set model instance
52-
PExGlobal.setModel(pModel.get().getDeclaredConstructor().newInstance());
53-
54-
// set project name
55-
setProjectName();
56-
} catch (Exception ex) {
57-
ex.printStackTrace();
58-
System.exit(5);
59-
}
60-
61-
// setup loggers, random number gen, time and memory monitors
62-
setup();
63-
64-
int exit_code = 0;
43+
// Parse command line arguments and initialize global settings
44+
initializeEnvironment(args);
45+
46+
int exitCode = 0;
6547
try {
66-
// set test driver
48+
// Get model and test driver
49+
Reflections reflections = initializeModel();
50+
51+
// Setup loggers, random number gen, time and memory monitors
52+
setup();
53+
54+
// Set test driver and run analysis
6755
setTestDriver(reflections);
68-
69-
// run the analysis
7056
RuntimeExecutor.run();
71-
} catch (TooManyChoicesException e) {
72-
exit_code = 2;
7357
} catch (BugFoundException e) {
74-
exit_code = 2;
58+
PExLogger.logInfo("Bug found or too many choices: " + e.getMessage());
59+
PExLogger.logTrace(e);
60+
exitCode = 2;
7561
} catch (InvocationTargetException ex) {
76-
ex.printStackTrace();
77-
exit_code = 5;
62+
PExLogger.logInfo("Invocation target exception: " + ex.getMessage());
63+
PExLogger.logTrace(ex);
64+
exitCode = 5;
7865
} catch (Exception ex) {
79-
if (ex.getMessage().equals("TIMEOUT")) {
80-
exit_code = 3;
81-
} else if (ex.getMessage().equals("MEMOUT")) {
82-
exit_code = 4;
66+
if ("TIMEOUT".equals(ex.getMessage())) {
67+
PExLogger.logInfo("Execution timed out");
68+
exitCode = 3;
69+
} else if ("MEMOUT".equals(ex.getMessage())) {
70+
PExLogger.logInfo("Out of memory: " + MemoryMonitor.getMemSpent() + " MB used");
71+
exitCode = 4;
8372
} else {
84-
ex.printStackTrace();
85-
exit_code = 5;
73+
PExLogger.logInfo("Runtime exception: " + ex.getMessage());
74+
PExLogger.logTrace(ex);
75+
exitCode = 5;
8676
}
8777
} finally {
88-
// log end-of-run metrics
89-
StatWriter.log("exit-code", String.format("%d", exit_code));
90-
91-
// exit
92-
System.exit(exit_code);
78+
// Log end-of-run metrics
79+
StatWriter.log("exit-code", String.format("%d", exitCode));
80+
81+
// Exit
82+
System.exit(exitCode);
83+
}
84+
}
85+
86+
/**
87+
* Initialize global environment settings
88+
*
89+
* @param args Command line arguments
90+
*/
91+
private static void initializeEnvironment(String[] args) {
92+
PExGlobal.setConfig(PExOptions.ParseCommandlineArgs(args));
93+
PExGlobal.setChoiceSelector();
94+
PExLogger.Initialize(PExGlobal.getConfig().getVerbosity());
95+
ComputeHash.Initialize();
96+
}
97+
98+
/**
99+
* Initialize the model
100+
*
101+
* @return Reflections object for model package
102+
* @throws Exception if model initialization fails
103+
*/
104+
private static Reflections initializeModel() throws Exception {
105+
// Get reflections corresponding to the model
106+
Reflections reflections = new Reflections("pex.model");
107+
108+
// Get all classes extending PModel
109+
Set<Class<? extends PModel>> subTypesPModel = reflections.getSubTypesOf(PModel.class);
110+
if (subTypesPModel.isEmpty()) {
111+
throw new Exception("No PModel implementation found in pex.model package.");
93112
}
113+
114+
// Get first model and instantiate it
115+
Class<? extends PModel> modelClass = subTypesPModel.stream()
116+
.findFirst()
117+
.orElseThrow(() -> new Exception("Failed to get PModel instance."));
118+
119+
PExGlobal.setModel(modelClass.getDeclaredConstructor().newInstance());
120+
121+
// Set project name
122+
setProjectName();
123+
124+
return reflections;
94125
}
95126

96127
/**
@@ -134,45 +165,50 @@ private static void setProjectName() {
134165
* @param reflections reflections corresponding to the pex.model
135166
* @throws Exception Throws exception if test driver is not found
136167
*/
137-
private static void setTestDriver(Reflections reflections)
138-
throws Exception {
139-
final String name = PExGlobal.getConfig().getTestDriver();
168+
private static void setTestDriver(Reflections reflections) throws Exception {
169+
final String requestedName = PExGlobal.getConfig().getTestDriver();
140170
final String defaultTestDriver = PExGlobal.getConfig().getTestDriverDefault();
141-
142-
Set<Class<? extends PTestDriver>> subTypesDriver = reflections.getSubTypesOf(PTestDriver.class);
143-
PTestDriver driver = null;
144-
for (Class<? extends PTestDriver> td : subTypesDriver) {
145-
if (PTestDriver.getTestName(td).equals(name)) {
146-
driver = td.getDeclaredConstructor().newInstance();
147-
break;
148-
}
171+
final Set<Class<? extends PTestDriver>> availableDrivers = reflections.getSubTypesOf(PTestDriver.class);
172+
173+
// Try to find driver by name
174+
Optional<Class<? extends PTestDriver>> driverClass = availableDrivers.stream()
175+
.filter(d -> PTestDriver.getTestName(d).equals(requestedName))
176+
.findFirst();
177+
178+
// If not found but using default driver name and only one driver exists, use that one
179+
if (driverClass.isEmpty() && requestedName.equals(defaultTestDriver) && availableDrivers.size() == 1) {
180+
driverClass = availableDrivers.stream().findFirst();
149181
}
150-
if (driver == null && name.equals(defaultTestDriver) && subTypesDriver.size() == 1) {
151-
for (Class<? extends PTestDriver> td : subTypesDriver) {
152-
driver = td.getDeclaredConstructor().newInstance();
153-
break;
154-
}
182+
183+
// If we found a driver, instantiate and configure it
184+
if (driverClass.isPresent()) {
185+
PTestDriver driver = driverClass.get().getDeclaredConstructor().newInstance();
186+
PExGlobal.getConfig().setTestDriver(PTestDriver.getTestName(driver.getClass()));
187+
PExGlobal.getModel().setTestDriver(driver);
188+
return;
155189
}
156-
if (driver == null) {
157-
if (!name.equals(defaultTestDriver)) {
158-
PExLogger.logInfo("No test driver found named \"" + name + "\"");
159-
}
160-
PExLogger.logInfo(
161-
String.format(
162-
"Error: We found '%d' test cases. Please provide a more precise name of the test case you wish to check using (--testcase | -tc).",
163-
subTypesDriver.size()));
164-
PExLogger.logInfo("Possible options are:");
165-
for (Class<? extends PTestDriver> td : subTypesDriver) {
166-
PExLogger.logInfo(String.format("%s", PTestDriver.getTestName(td)));
167-
}
168-
if (!name.equals(defaultTestDriver)) {
169-
throw new Exception("No test driver found named \"" + PExGlobal.getConfig().getTestDriver() + "\"");
170-
} else {
171-
System.exit(6);
172-
}
190+
191+
// No driver found, report error with available options
192+
if (!requestedName.equals(defaultTestDriver)) {
193+
PExLogger.logInfo("No test driver found named \"" + requestedName + "\"");
194+
}
195+
196+
PExLogger.logInfo(String.format(
197+
"Error: We found %d test cases. Please provide a more precise name using (--testcase | -tc).",
198+
availableDrivers.size()));
199+
200+
if (!availableDrivers.isEmpty()) {
201+
PExLogger.logInfo("Available test driver options:");
202+
availableDrivers.forEach(td ->
203+
PExLogger.logInfo(String.format(" - %s", PTestDriver.getTestName(td))));
204+
}
205+
206+
// Exit with appropriate error
207+
if (!requestedName.equals(defaultTestDriver)) {
208+
throw new Exception("No test driver found named \"" + requestedName + "\"");
209+
} else {
210+
System.exit(6);
173211
}
174-
PExGlobal.getConfig().setTestDriver(PTestDriver.getTestName(driver.getClass()));
175-
PExGlobal.getModel().setTestDriver(driver);
176212
}
177213

178214
}

0 commit comments

Comments
 (0)