Skip to content

Commit

Permalink
feat: make the assertion engine return a different error when no spans (
Browse files Browse the repository at this point in the history
#3666)

* feat: make the assertion engine return a different error when no spans

* fix tests

* add message suggestion from Julianne
  • Loading branch information
mathnogueira authored Feb 20, 2024
1 parent 3e1352f commit 46e50da
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
7 changes: 7 additions & 0 deletions server/expression/data_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func (ds AttributeDataStore) getFromAlias(name string) (string, error) {
}

func (ds AttributeDataStore) Get(name string) (string, error) {
if !ds.Span.ID.IsValid() {
// It's probably a nil span and we never got a matching selector,
// so instead of returning a resolution error, let's return a non-matching
// span error instead
return "", fmt.Errorf(`there are no matching spans to retrieve the attribute "%s" from. To fix this error, create a selector matching at least one span.`, name)
}

value := ds.Span.Attributes.Get(name)
if value == "" {
return ds.getFromAlias(name)
Expand Down
38 changes: 38 additions & 0 deletions server/expression/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/kubeshop/tracetest/server/expression"
"github.com/kubeshop/tracetest/server/pkg/id"
"github.com/kubeshop/tracetest/server/traces"
"github.com/kubeshop/tracetest/server/variableset"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -103,6 +104,7 @@ func TestAttributeExecution(t *testing.T) {

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"my_attribute": "42",
}),
Expand All @@ -116,12 +118,39 @@ func TestAttributeExecution(t *testing.T) {

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"dapr-app-id": "42",
}),
},
},
},
{
Name: "should_return_error_when_attribute_doesnt_exist",
Query: "attr:dapr-app-id = 43",
ShouldPass: false,
ExpectedErrorMessage: `resolution error: attribute "dapr-app-id" not found`,

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
},
},
},
{
Name: "should_return_error_when_no_matching_spans",
Query: "attr:dapr-app-id = 42",
ShouldPass: false,
ExpectedErrorMessage: `resolution error: there are no matching spans to retrieve the attribute "dapr-app-id" from. To fix this error, create a selector matching at least one span.`,

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
// An span without an id is an invalid span
// this is the value received when we don't have any matching
// spans in the assertion.
},
},
},
}

executeTestCases(t, testCases)
Expand All @@ -135,6 +164,7 @@ func TestStringInterpolationExecution(t *testing.T) {
ShouldPass: true,
AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"text": "this run took 25ms",
}),
Expand All @@ -159,6 +189,7 @@ func TestFilterExecution(t *testing.T) {
ShouldPass: true,
AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"tracetest.response.body": `{"id": 8, "name": "john doe"}`,
}),
Expand Down Expand Up @@ -345,6 +376,9 @@ func executeTestCases(t *testing.T, testCases []executorTestCase) {
assert.NoError(t, err, debugMessage)
} else {
assert.Error(t, err, debugMessage)
if testCase.ExpectedErrorMessage != "" {
assert.Equal(t, testCase.ExpectedErrorMessage, err.Error())
}
}
})
}
Expand Down Expand Up @@ -376,6 +410,7 @@ func TestResolveStatementAttributeExecution(t *testing.T) {

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"my_attribute": "42",
}),
Expand All @@ -395,6 +430,7 @@ func TestResolveStatementStringInterpolationExecution(t *testing.T) {
ShouldPass: true,
AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"text": "this run took 25ms",
}),
Expand All @@ -419,6 +455,7 @@ func TestResolveStatementFilterExecution(t *testing.T) {
ShouldPass: true,
AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"tracetest.response.body": `{"id": 8, "name": "john doe"}`,
}),
Expand Down Expand Up @@ -480,6 +517,7 @@ func TestFailureCases(t *testing.T) {

AttributeDataStore: expression.AttributeDataStore{
Span: traces.Span{
ID: id.NewRandGenerator().SpanID(),
Attributes: traces.NewAttributes(map[string]string{
"attr1": "1",
"attr2": "2",
Expand Down

0 comments on commit 46e50da

Please sign in to comment.