Skip to content

Commit 0953024

Browse files
Add abstract class for TraceSpan test (finos#3711)
1 parent 81b5d24 commit 0953024

File tree

5 files changed

+574
-18
lines changed
  • legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-functions-unclassified
    • legend-engine-pure-functions-unclassified-pure
    • legend-engine-pure-runtime-java-extension-compiled-functions-unclassified/src/test/java/org/finos/legend/pure/runtime/java/compiled/generation/processors/support/function/base/tracing
    • legend-engine-pure-runtime-java-extension-interpreted-functions-unclassified/src/test/java/org/finos/legend/pure/runtime/java/interpreted/function/base/tracing

5 files changed

+574
-18
lines changed

legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-functions-unclassified/legend-engine-pure-functions-unclassified-pure/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,15 @@
135135
<artifactId>eclipse-collections-testutils</artifactId>
136136
<scope>test</scope>
137137
</dependency>
138+
<dependency>
139+
<groupId>io.opentracing</groupId>
140+
<artifactId>opentracing-util</artifactId>
141+
<scope>test</scope>
142+
</dependency>
143+
<dependency>
144+
<groupId>io.opentracing</groupId>
145+
<artifactId>opentracing-api</artifactId>
146+
<scope>test</scope>
147+
</dependency>
138148
</dependencies>
139149
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// Copyright 2025 Goldman Sachs
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package org.finos.legend.engine.pure.code.core.functions.unclassified.base.tracing;
16+
17+
import io.opentracing.util.GlobalTracer;
18+
import org.finos.legend.pure.m3.exception.PureAssertFailException;
19+
import org.finos.legend.pure.m3.tests.AbstractPureTestWithCoreCompiled;
20+
import org.junit.After;
21+
import org.junit.AfterClass;
22+
import org.junit.Assert;
23+
import org.junit.Test;
24+
25+
import java.lang.reflect.Field;
26+
import java.util.Map;
27+
28+
public abstract class AbstractTestTraceSpan extends AbstractPureTestWithCoreCompiled
29+
{
30+
@After
31+
public void cleanRuntime()
32+
{
33+
runtime.delete("fromString.pure");
34+
runtime.compile();
35+
}
36+
37+
protected static final InMemoryTracer tracer = new InMemoryTracer();
38+
39+
@Test
40+
public void testTraceSpan()
41+
{
42+
compileTestSource("fromString.pure", "function testTraceSpan():Nil[0]\n" +
43+
"{\n" +
44+
" meta::pure::functions::tracing::traceSpan(|print('Hello World',1), 'Test Execute');\n" +
45+
"}\n");
46+
this.execute("testTraceSpan():Nil[0]");
47+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
48+
Assert.assertTrue(tracer.spanExists("Test Execute"));
49+
}
50+
51+
@Test
52+
public void testTraceSpanWithReturnValue()
53+
{
54+
compileTestSource("fromString.pure", "function testTraceSpan():Nil[0]\n" +
55+
"{\n" +
56+
" let text = meta::pure::functions::tracing::traceSpan(|' World', 'Test Execute');\n" +
57+
" print('Hello' + $text, 1);\n" +
58+
"}\n");
59+
this.execute("testTraceSpan():Nil[0]");
60+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
61+
}
62+
63+
@Test
64+
public void testTraceSpanWithAnnotations()
65+
{
66+
compileTestSource("fromString.pure", "function testTraceSpan():Nil[0]\n" +
67+
"{\n" +
68+
" let annotations = newMap([\n" +
69+
" pair('key1', 'value1'), \n" +
70+
" pair('key2', 'value2')\n" +
71+
" ]); \n" +
72+
" meta::pure::functions::tracing::traceSpan(|print('Hello World',1), 'Test Execute', |$annotations);\n" +
73+
"}\n");
74+
this.execute("testTraceSpan():Nil[0]");
75+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
76+
Assert.assertTrue(tracer.spanExists("Test Execute"));
77+
Map<Object, Object> tags = this.tracer.getTags("Test Execute");
78+
Assert.assertEquals(tags.get("key1"), "value1");
79+
Assert.assertEquals(tags.get("key2"), "value2");
80+
}
81+
82+
@Test
83+
public void testTraceSpanUsingEval()
84+
{
85+
compileTestSource("fromString.pure", "function testTraceSpan():Nil[0]\n" +
86+
"{\n" +
87+
" let res = meta::pure::functions::tracing::traceSpan_Function_1__String_1__V_m_->eval(|'Hello World', 'Test Execute');\n" +
88+
" print($res,1);" +
89+
"}\n");
90+
this.execute("testTraceSpan():Nil[0]");
91+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
92+
Assert.assertTrue(tracer.spanExists("Test Execute"));
93+
}
94+
95+
@Test
96+
public void testDoNoTraceIfTracerNotRegistered()
97+
{
98+
tracer.reset();
99+
unregisterTracer();
100+
compileTestSource("fromString.pure", "function testTraceSpan():Nil[0]\n" +
101+
"{\n" +
102+
" meta::pure::functions::tracing::traceSpan(|print('Hello World',1), 'Test Execute');\n" +
103+
"}\n");
104+
this.execute("testTraceSpan():Nil[0]");
105+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
106+
Assert.assertFalse(tracer.spanExists("Test Execute"));
107+
GlobalTracer.registerIfAbsent(tracer);
108+
}
109+
110+
@Test
111+
public void testTraceSpanShouldHandleErrorWhileEvaluatingTagsLamda()
112+
{
113+
compileTestSource("fromString.pure", "function getTags(): Map<String, String>[1] {" +
114+
" assert('a' == 'b', |''); " +
115+
" newMap([ \n" +
116+
" pair('key1', '') \n" +
117+
" ]); \n" +
118+
"}" +
119+
"function testTraceSpan():Nil[0]\n" +
120+
"{\n" +
121+
" meta::pure::functions::tracing::traceSpan(|print('Hello World',1), 'Test Execute', |getTags(), false);\n" +
122+
"}\n");
123+
this.execute("testTraceSpan():Nil[0]");
124+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
125+
Assert.assertTrue(tracer.spanExists("Test Execute"));
126+
Map<Object, Object> tags = this.tracer.getTags("Test Execute");
127+
Assert.assertTrue(tags.get("Exception").toString().startsWith("Unable to resolve tags - "));
128+
}
129+
130+
@Test
131+
public void testTraceSpanShouldHandleStackOverflowErrorWhileEvaluatingTagsLamda()
132+
{
133+
compileTestSource("fromString.pure", "function getTags(): Map<String, String>[1] {" +
134+
" getTags(); \n" +
135+
"}" +
136+
"function testTraceSpan():Nil[0]\n" +
137+
"{\n" +
138+
" meta::pure::functions::tracing::traceSpan(|print('Hello World', 1), 'Test Execute', |getTags(), false);\n" +
139+
"}\n");
140+
this.execute("testTraceSpan():Nil[0]");
141+
Assert.assertEquals("'Hello World'", this.functionExecution.getConsole().getLine(0));
142+
Assert.assertTrue(tracer.spanExists("Test Execute"));
143+
Map<Object, Object> tags = this.tracer.getTags("Test Execute");
144+
Assert.assertTrue(tags.get("Exception").toString().startsWith("Unable to resolve tags - "));
145+
}
146+
147+
@Test(expected = PureAssertFailException.class)
148+
public void testTraceSpanShouldNotHandleErrorWhileEvaluatingTagsLamda()
149+
{
150+
compileTestSource("fromString.pure", "function getTags(): Map<String, String>[1] {" +
151+
" assert('a' == 'b', |''); " +
152+
" newMap([ \n" +
153+
" pair('key1', '') \n" +
154+
" ]); \n" +
155+
"}" +
156+
"function testTraceSpan():Nil[0]\n" +
157+
"{\n" +
158+
" meta::pure::functions::tracing::traceSpan(|print('Hello World',1), 'Test Execute', |getTags());\n" +
159+
"}\n");
160+
this.execute("testTraceSpan():Nil[0]");
161+
}
162+
163+
@AfterClass
164+
public static void tearDown()
165+
{
166+
tracer.reset();
167+
unregisterTracer();
168+
}
169+
170+
private static void unregisterTracer()
171+
{
172+
try
173+
{
174+
// HACK since GlobalTracer api doesnt provide a way to reset the tracer which is needed for testing
175+
Field tracerField = GlobalTracer.get().getClass().getDeclaredField("isRegistered");
176+
tracerField.setAccessible(true);
177+
tracerField.set(GlobalTracer.get(), false);
178+
Assert.assertFalse(GlobalTracer.isRegistered());
179+
}
180+
catch (Exception ignored)
181+
{
182+
}
183+
}
184+
185+
}

0 commit comments

Comments
 (0)