Skip to content

Commit 77c6fbe

Browse files
Fix Cucumber JUnit 4 instrumentation to support empty scenario names (#7470)
1 parent 4679c0a commit 77c6fbe

File tree

7 files changed

+350
-4
lines changed

7 files changed

+350
-4
lines changed

dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/CucumberUtils.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public static String getVersion() {
5050
REFLECTION.constructor("io.cucumber.junit.PickleRunners$PickleId", Pickle.class);
5151
private static final MethodHandle PICKLE_ID_URI_GETTER =
5252
REFLECTION.privateFieldGetter("io.cucumber.junit.PickleRunners$PickleId", "uri");
53+
private static final MethodHandle PICKLE_ID_LINE_GETTER =
54+
REFLECTION.privateFieldGetter("io.cucumber.junit.PickleRunners$PickleId", "pickleLine");
5355
private static final MethodHandle PICKLE_RUNNER_GET_DESCRIPTION =
5456
REFLECTION.method("io.cucumber.junit.PickleRunners$PickleRunner", "getDescription");
5557

@@ -72,6 +74,11 @@ public static URI getPickleUri(Description scenarioDescription) {
7274
return REFLECTION.invoke(PICKLE_ID_URI_GETTER, pickleId);
7375
}
7476

77+
public static Integer getPickleLine(Description scenarioDescription) {
78+
Object pickleId = JUnit4Utils.getUniqueId(scenarioDescription);
79+
return REFLECTION.invoke(PICKLE_ID_LINE_GETTER, pickleId);
80+
}
81+
7582
public static String getTestSuiteNameForFeature(Description featureDescription) {
7683
Object uniqueId = JUnit4Utils.getUniqueId(featureDescription);
7784
return (uniqueId != null ? uniqueId + ":" : "") + featureDescription.getClassName();
@@ -99,12 +106,22 @@ private static String getFeatureNameForScenario(Description scenarioDescription)
99106
public static String getTestNameForScenario(Description scenarioDescription) {
100107
String scenarioDescriptionString = scenarioDescription.toString();
101108
int featureNameStart = getFeatureNameStartIdx(scenarioDescriptionString);
102-
if (featureNameStart >= 0) {
109+
if (featureNameStart > 0) { // if featureNameStart == 0, then test name is empty and of no use
103110
return scenarioDescriptionString.substring(0, featureNameStart);
104-
} else {
105-
// fallback to default method
106-
return scenarioDescription.getMethodName();
107111
}
112+
113+
// fallback to default method
114+
String methodName = scenarioDescription.getMethodName();
115+
if (Strings.isNotBlank(methodName)) {
116+
return methodName;
117+
}
118+
119+
Integer pickleLine = getPickleLine(scenarioDescription);
120+
if (pickleLine != null) {
121+
return "LINE:" + pickleLine + "";
122+
}
123+
124+
return "EMPTY_NAME";
108125
}
109126

110127
/**

dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/test/groovy/CucumberTest.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class CucumberTest extends CiVisibilityInstrumentationTest {
2929
"org/example/cucumber/calculator/basic_arithmetic_failed.feature"
3030
] | 3
3131
"test-name-with-brackets" | ["org/example/cucumber/calculator/name_with_brackets.feature"] | 2
32+
"test-empty-name-${version()}" | ["org/example/cucumber/calculator/empty_scenario_name.feature"] | 2
3233
}
3334

3435
def "test ITR #testcaseName"() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@foo
2+
Feature:
3+
4+
Background: A Calculator
5+
Given a calculator I just turned on
6+
7+
Scenario:
8+
# Try to change one of the values below to provoke a failure
9+
When I add 4 and 5
10+
Then the result is 9
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[ {
2+
"test_session_id" : ${content_test_session_id},
3+
"test_suite_id" : ${content_test_suite_id},
4+
"span_id" : ${content_span_id},
5+
"files" : [ {
6+
"filename" : "org/example/cucumber/calculator/empty_scenario_name.feature"
7+
} ]
8+
} ]
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
[ {
2+
"type" : "test_suite_end",
3+
"version" : 1,
4+
"content" : {
5+
"test_session_id" : ${content_test_session_id},
6+
"test_module_id" : ${content_test_module_id},
7+
"test_suite_id" : ${content_test_suite_id},
8+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
9+
"name" : "junit.test_suite",
10+
"resource" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
11+
"start" : ${content_start},
12+
"duration" : ${content_duration},
13+
"error" : 0,
14+
"metrics" : { },
15+
"meta" : {
16+
"test.type" : "test",
17+
"os.architecture" : ${content_meta_os_architecture},
18+
"test.module" : "cucumber-junit-4",
19+
"test.status" : "pass",
20+
"runtime.name" : ${content_meta_runtime_name},
21+
"runtime.vendor" : ${content_meta_runtime_vendor},
22+
"env" : "none",
23+
"os.platform" : ${content_meta_os_platform},
24+
"dummy_ci_tag" : "dummy_ci_tag_value",
25+
"os.version" : ${content_meta_os_version},
26+
"library_version" : ${content_meta_library_version},
27+
"component" : "junit",
28+
"span.kind" : "test_suite_end",
29+
"test.suite" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
30+
"runtime.version" : ${content_meta_runtime_version},
31+
"test.framework_version" : ${content_meta_test_framework_version},
32+
"test.framework" : "cucumber"
33+
}
34+
}
35+
}, {
36+
"type" : "test",
37+
"version" : 2,
38+
"content" : {
39+
"trace_id" : ${content_trace_id},
40+
"span_id" : ${content_span_id},
41+
"parent_id" : ${content_parent_id},
42+
"test_session_id" : ${content_test_session_id},
43+
"test_module_id" : ${content_test_module_id},
44+
"test_suite_id" : ${content_test_suite_id},
45+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
46+
"name" : "junit.test",
47+
"resource" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME.EMPTY_NAME",
48+
"start" : ${content_start_2},
49+
"duration" : ${content_duration_2},
50+
"error" : 0,
51+
"metrics" : {
52+
"process_id" : ${content_metrics_process_id},
53+
"_dd.profiling.enabled" : 0,
54+
"_dd.trace_span_attribute_schema" : 0
55+
},
56+
"meta" : {
57+
"os.architecture" : ${content_meta_os_architecture},
58+
"test.module" : "cucumber-junit-4",
59+
"test.status" : "pass",
60+
"language" : "jvm",
61+
"runtime.name" : ${content_meta_runtime_name},
62+
"os.platform" : ${content_meta_os_platform},
63+
"os.version" : ${content_meta_os_version},
64+
"library_version" : ${content_meta_library_version},
65+
"test.name" : "EMPTY_NAME",
66+
"span.kind" : "test",
67+
"test.suite" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
68+
"runtime.version" : ${content_meta_runtime_version},
69+
"runtime-id" : ${content_meta_runtime_id},
70+
"test.type" : "test",
71+
"test.traits" : "{\"category\":[\"foo\"]}",
72+
"runtime.vendor" : ${content_meta_runtime_vendor},
73+
"env" : "none",
74+
"dummy_ci_tag" : "dummy_ci_tag_value",
75+
"component" : "junit",
76+
"_dd.profiling.ctx" : "test",
77+
"test.framework_version" : ${content_meta_test_framework_version},
78+
"test.framework" : "cucumber"
79+
}
80+
}
81+
}, {
82+
"type" : "test_session_end",
83+
"version" : 1,
84+
"content" : {
85+
"test_session_id" : ${content_test_session_id},
86+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
87+
"name" : "junit.test_session",
88+
"resource" : "cucumber-junit-4",
89+
"start" : ${content_start_3},
90+
"duration" : ${content_duration_3},
91+
"error" : 0,
92+
"metrics" : {
93+
"process_id" : ${content_metrics_process_id},
94+
"_dd.profiling.enabled" : 0,
95+
"_dd.trace_span_attribute_schema" : 0
96+
},
97+
"meta" : {
98+
"test.type" : "test",
99+
"os.architecture" : ${content_meta_os_architecture},
100+
"test.status" : "pass",
101+
"language" : "jvm",
102+
"runtime.name" : ${content_meta_runtime_name},
103+
"runtime.vendor" : ${content_meta_runtime_vendor},
104+
"env" : "none",
105+
"os.platform" : ${content_meta_os_platform},
106+
"dummy_ci_tag" : "dummy_ci_tag_value",
107+
"os.version" : ${content_meta_os_version},
108+
"library_version" : ${content_meta_library_version},
109+
"component" : "junit",
110+
"_dd.profiling.ctx" : "test",
111+
"span.kind" : "test_session_end",
112+
"runtime.version" : ${content_meta_runtime_version},
113+
"runtime-id" : ${content_meta_runtime_id},
114+
"test.command" : "cucumber-junit-4",
115+
"test.framework_version" : ${content_meta_test_framework_version},
116+
"test.framework" : "cucumber"
117+
}
118+
}
119+
}, {
120+
"type" : "test_module_end",
121+
"version" : 1,
122+
"content" : {
123+
"test_session_id" : ${content_test_session_id},
124+
"test_module_id" : ${content_test_module_id},
125+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
126+
"name" : "junit.test_module",
127+
"resource" : "cucumber-junit-4",
128+
"start" : ${content_start_4},
129+
"duration" : ${content_duration_4},
130+
"error" : 0,
131+
"metrics" : { },
132+
"meta" : {
133+
"test.type" : "test",
134+
"os.architecture" : ${content_meta_os_architecture},
135+
"test.module" : "cucumber-junit-4",
136+
"test.status" : "pass",
137+
"runtime.name" : ${content_meta_runtime_name},
138+
"runtime.vendor" : ${content_meta_runtime_vendor},
139+
"env" : "none",
140+
"os.platform" : ${content_meta_os_platform},
141+
"dummy_ci_tag" : "dummy_ci_tag_value",
142+
"os.version" : ${content_meta_os_version},
143+
"library_version" : ${content_meta_library_version},
144+
"component" : "junit",
145+
"span.kind" : "test_module_end",
146+
"runtime.version" : ${content_meta_runtime_version},
147+
"test.framework_version" : ${content_meta_test_framework_version},
148+
"test.framework" : "cucumber"
149+
}
150+
}
151+
} ]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[ {
2+
"test_session_id" : ${content_test_session_id},
3+
"test_suite_id" : ${content_test_suite_id},
4+
"span_id" : ${content_span_id},
5+
"files" : [ {
6+
"filename" : "org/example/cucumber/calculator/empty_scenario_name.feature"
7+
} ]
8+
} ]
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
[ {
2+
"type" : "test_suite_end",
3+
"version" : 1,
4+
"content" : {
5+
"test_session_id" : ${content_test_session_id},
6+
"test_module_id" : ${content_test_module_id},
7+
"test_suite_id" : ${content_test_suite_id},
8+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
9+
"name" : "junit.test_suite",
10+
"resource" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
11+
"start" : ${content_start},
12+
"duration" : ${content_duration},
13+
"error" : 0,
14+
"metrics" : { },
15+
"meta" : {
16+
"test.type" : "test",
17+
"os.architecture" : ${content_meta_os_architecture},
18+
"test.module" : "cucumber-junit-4",
19+
"test.status" : "pass",
20+
"runtime.name" : ${content_meta_runtime_name},
21+
"runtime.vendor" : ${content_meta_runtime_vendor},
22+
"env" : "none",
23+
"os.platform" : ${content_meta_os_platform},
24+
"dummy_ci_tag" : "dummy_ci_tag_value",
25+
"os.version" : ${content_meta_os_version},
26+
"library_version" : ${content_meta_library_version},
27+
"component" : "junit",
28+
"span.kind" : "test_suite_end",
29+
"test.suite" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
30+
"runtime.version" : ${content_meta_runtime_version},
31+
"test.framework_version" : ${content_meta_test_framework_version},
32+
"test.framework" : "cucumber"
33+
}
34+
}
35+
}, {
36+
"type" : "test",
37+
"version" : 2,
38+
"content" : {
39+
"trace_id" : ${content_trace_id},
40+
"span_id" : ${content_span_id},
41+
"parent_id" : ${content_parent_id},
42+
"test_session_id" : ${content_test_session_id},
43+
"test_module_id" : ${content_test_module_id},
44+
"test_suite_id" : ${content_test_suite_id},
45+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
46+
"name" : "junit.test",
47+
"resource" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME.LINE:7",
48+
"start" : ${content_start_2},
49+
"duration" : ${content_duration_2},
50+
"error" : 0,
51+
"metrics" : {
52+
"process_id" : ${content_metrics_process_id},
53+
"_dd.profiling.enabled" : 0,
54+
"_dd.trace_span_attribute_schema" : 0
55+
},
56+
"meta" : {
57+
"os.architecture" : ${content_meta_os_architecture},
58+
"test.module" : "cucumber-junit-4",
59+
"test.status" : "pass",
60+
"language" : "jvm",
61+
"runtime.name" : ${content_meta_runtime_name},
62+
"os.platform" : ${content_meta_os_platform},
63+
"os.version" : ${content_meta_os_version},
64+
"library_version" : ${content_meta_library_version},
65+
"test.name" : "LINE:7",
66+
"span.kind" : "test",
67+
"test.suite" : "classpath:org/example/cucumber/calculator/empty_scenario_name.feature:EMPTY_NAME",
68+
"runtime.version" : ${content_meta_runtime_version},
69+
"runtime-id" : ${content_meta_runtime_id},
70+
"test.type" : "test",
71+
"test.traits" : "{\"category\":[\"foo\"]}",
72+
"runtime.vendor" : ${content_meta_runtime_vendor},
73+
"env" : "none",
74+
"dummy_ci_tag" : "dummy_ci_tag_value",
75+
"component" : "junit",
76+
"_dd.profiling.ctx" : "test",
77+
"test.framework_version" : ${content_meta_test_framework_version},
78+
"test.framework" : "cucumber"
79+
}
80+
}
81+
}, {
82+
"type" : "test_session_end",
83+
"version" : 1,
84+
"content" : {
85+
"test_session_id" : ${content_test_session_id},
86+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
87+
"name" : "junit.test_session",
88+
"resource" : "cucumber-junit-4",
89+
"start" : ${content_start_3},
90+
"duration" : ${content_duration_3},
91+
"error" : 0,
92+
"metrics" : {
93+
"process_id" : ${content_metrics_process_id},
94+
"_dd.profiling.enabled" : 0,
95+
"_dd.trace_span_attribute_schema" : 0
96+
},
97+
"meta" : {
98+
"test.type" : "test",
99+
"os.architecture" : ${content_meta_os_architecture},
100+
"test.status" : "pass",
101+
"language" : "jvm",
102+
"runtime.name" : ${content_meta_runtime_name},
103+
"runtime.vendor" : ${content_meta_runtime_vendor},
104+
"env" : "none",
105+
"os.platform" : ${content_meta_os_platform},
106+
"dummy_ci_tag" : "dummy_ci_tag_value",
107+
"os.version" : ${content_meta_os_version},
108+
"library_version" : ${content_meta_library_version},
109+
"component" : "junit",
110+
"_dd.profiling.ctx" : "test",
111+
"span.kind" : "test_session_end",
112+
"runtime.version" : ${content_meta_runtime_version},
113+
"runtime-id" : ${content_meta_runtime_id},
114+
"test.command" : "cucumber-junit-4",
115+
"test.framework_version" : ${content_meta_test_framework_version},
116+
"test.framework" : "cucumber"
117+
}
118+
}
119+
}, {
120+
"type" : "test_module_end",
121+
"version" : 1,
122+
"content" : {
123+
"test_session_id" : ${content_test_session_id},
124+
"test_module_id" : ${content_test_module_id},
125+
"service" : "worker.org.gradle.process.internal.worker.gradleworkermain",
126+
"name" : "junit.test_module",
127+
"resource" : "cucumber-junit-4",
128+
"start" : ${content_start_4},
129+
"duration" : ${content_duration_4},
130+
"error" : 0,
131+
"metrics" : { },
132+
"meta" : {
133+
"test.type" : "test",
134+
"os.architecture" : ${content_meta_os_architecture},
135+
"test.module" : "cucumber-junit-4",
136+
"test.status" : "pass",
137+
"runtime.name" : ${content_meta_runtime_name},
138+
"runtime.vendor" : ${content_meta_runtime_vendor},
139+
"env" : "none",
140+
"os.platform" : ${content_meta_os_platform},
141+
"dummy_ci_tag" : "dummy_ci_tag_value",
142+
"os.version" : ${content_meta_os_version},
143+
"library_version" : ${content_meta_library_version},
144+
"component" : "junit",
145+
"span.kind" : "test_module_end",
146+
"runtime.version" : ${content_meta_runtime_version},
147+
"test.framework_version" : ${content_meta_test_framework_version},
148+
"test.framework" : "cucumber"
149+
}
150+
}
151+
} ]

0 commit comments

Comments
 (0)