Skip to content

Commit

Permalink
Merge pull request #2688 from dsankouski/implement_yaml_load_classes_…
Browse files Browse the repository at this point in the history
…flag
  • Loading branch information
juherr committed Dec 8, 2021
2 parents e8f17fe + 3c964b8 commit 2a756e5
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Current
Fixed: GITHUB-2689: Yaml parser: implement loadClasses flag (Dzmitry Sankouski)
Fixed: GITHUB-2676: NPE is triggered when working with ITestObjectFactory (Krishnan Mahadevan)
Fixed: GITHUB-2674: Run onTestSkipped for each value from data provider (Krishnan Mahadevan)
Fixed: GITHUB-2672: Log real stacktrace when test times out. (cdalexndr)
Expand Down
46 changes: 45 additions & 1 deletion testng-core/src/main/java/org/testng/internal/Yaml.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.testng.TestNGException;
import org.testng.internal.objects.InstanceCreator;
import org.testng.util.Strings;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
Expand All @@ -27,7 +29,8 @@ public final class Yaml {

private Yaml() {}

public static XmlSuite parse(String filePath, InputStream is) throws FileNotFoundException {
public static XmlSuite parse(String filePath, InputStream is, boolean loadClasses)
throws FileNotFoundException {
Constructor constructor = new TestNGConstructor(XmlSuite.class);
{
TypeDescription suiteDescription = new TypeDescription(XmlSuite.class);
Expand All @@ -46,6 +49,9 @@ public static XmlSuite parse(String filePath, InputStream is) throws FileNotFoun
constructor.addTypeDescription(testDescription);
}

TypeDescription xmlClassDescription = new XmlClassTypeDescriptor(loadClasses);
constructor.addTypeDescription(xmlClassDescription);

org.yaml.snakeyaml.Yaml y = new org.yaml.snakeyaml.Yaml(constructor);
if (is == null) {
is = new FileInputStream(new File(filePath));
Expand Down Expand Up @@ -347,4 +353,42 @@ public Object construct(Node node) {
}
}
}

private static class XmlClassTypeDescriptor extends TypeDescription {

private final boolean loadClasses;

public XmlClassTypeDescriptor(boolean loadClasses) {
super(XmlClass.class);
this.loadClasses = loadClasses;
}

@Override
public Object newInstance(Node node) {
String className;

try {
java.lang.reflect.Constructor<?> c =
XmlClass.class.getDeclaredConstructor(String.class, boolean.class);
c.setAccessible(true);
if (node instanceof MappingNode) {
Node valueNode =
((MappingNode) node)
.getValue().stream()
.filter(
nodeTuple ->
((ScalarNode) nodeTuple.getKeyNode()).getValue().equals("name"))
.findFirst()
.orElseThrow(() -> new TestNGException("Node 'name' not found"))
.getValueNode();
className = ((ScalarNode) valueNode).getValue();
} else {
className = ((ScalarNode) node).getValue();
}
return InstanceCreator.newInstance(c, className, loadClasses);
} catch (Exception e) {
throw new TestNGException("Failed to instantiate class", e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class YamlParser implements ISuiteParser {
public XmlSuite parse(String filePath, InputStream is, boolean loadClasses)
throws TestNGException {
try {
return Yaml.parse(filePath, is);
return Yaml.parse(filePath, is, loadClasses);
} catch (FileNotFoundException e) {
throw new TestNGException(e);
}
Expand Down
24 changes: 24 additions & 0 deletions testng-core/src/test/java/test/yaml/YamlTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.internal.Yaml;
import org.testng.internal.YamlParser;
import org.testng.reporters.Files;
import org.testng.xml.SuiteXmlParser;
import org.testng.xml.XmlSuite;
import org.testng.xml.internal.Parser;
import test.SimpleBaseTest;

public class YamlTest extends SimpleBaseTest {
public static final String CLASS_NOT_FOUND_MESSAGE = "Cannot find class in classpath";

@DataProvider
public Object[][] dp() {
Expand Down Expand Up @@ -69,4 +71,26 @@ public void testXmlDependencyGroups() throws IOException {
java.nio.file.Files.readAllBytes(Paths.get(expectedYamlFile)), StandardCharsets.UTF_8);
assertThat(Yaml.toYaml(actualXmlSuite).toString()).isEqualToNormalizingNewlines(expectedYaml);
}

@Test(description = "GITHUB-2689")
public void testLoadClassesFlag() throws IOException {
YamlParser yamlParser = new YamlParser();
String yamlSuiteFile = "src/test/resources/yaml/suiteWithNonExistentTest.yaml";

try {
yamlParser.parse(yamlSuiteFile, new FileInputStream(yamlSuiteFile), false);
} catch (Throwable throwable) {
Throwable rootCause = getRootCause(throwable);
String rootCauseMessage = rootCause.getMessage();
if (rootCauseMessage.contains(CLASS_NOT_FOUND_MESSAGE)) {
throw new AssertionError("TestNG shouldn't attempt to load test class", throwable);
}

throw new AssertionError("Yaml parser failed to parse suite", throwable);
}
}

private Throwable getRootCause(Throwable throwable) {
return throwable.getCause() != null ? getRootCause(throwable.getCause()) : throwable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: My_Suite
tests:
- name: My_test
classes:
- this.class.does.not.Exists

0 comments on commit 2a756e5

Please sign in to comment.