jmespath / jmespath/go-jmespath

Comparison expressions don't evaluate operand type

Open
#40 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
621
Forks
101
PR merge metrics
No merged PRs in 30d

Description

### Description

Comparison expressions do not evaluate as expected in cases where one operand is a literal value and the other is a pointer to a value. This results in expressions such as `AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']` used in the AWS SDK for Go's Autoscaling waiter `WaitUntilGroupInService` not evaluating correctly since `LifecycleState` is a pointer to a string that is being evaluated against the literal string `InService`.

### Steps to reproduce

Save this code as `main_test.go` and run `go test -v`:

```go
package main

import (
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/aws/aws-sdk-go/service/autoscaling"
)

func TestWaitUntilGroupInService(t *testing.T) {
mockResponse := &autoscaling.DescribeAutoScalingGroupsOutput{
AutoScalingGroups: []*autoscaling.Group{
&autoscaling.Group{
Instances: []*autoscaling.Instance{
&autoscaling.Instance{
LifecycleState: aws.String("InService"),
},
&autoscaling.Instance{
LifecycleState: aws.String("InService"),
},
},
MaxSize: aws.Int64(4),
MinSize: aws.Int64(2),
DesiredCapacity: aws.Int64(2),
},
&autoscaling.Group{
Instances: []*autoscaling.Instance{
&autoscaling.Instance{
LifecycleState: aws.String("InService"),
},
&autoscaling.Instance{
LifecycleState: aws.String("Pending"),
},
},
MaxSize: aws.Int64(4),
MinSize: aws.Int64(2),
DesiredCapacity: aws.Int64(2),
},
},
}

var testCases = []struct {
expect []interface{}
data interface{}
path string
}{
{[]interface{}{true}, mockResponse, "contains(AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][], `false`)"},
{[]interface{}{true, false}, mockResponse, "AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][]"},
{[]interface{}{2, 1}, mockResponse, "AutoScalingGroups[].[length(Instances[?LifecycleState=='InService'])][]"},
}
for i, c := range testCases {
v, err := awsutil.ValuesAtPath(c.data, c.path)
if err != nil {
t.Errorf("case %v, expected no error, %v", i, c.path)
}
if e, a := c.expect, v; !awsutil.DeepEqual(e, a) {

t.Errorf("case %v, %v, expected: %#v, but got: %#v", i, c.path, e, a)
}
}
}

```

```
$ go get -u github.com/aws/aws-sdk-go

$ go test -v
=== RUN TestWaitUntilGroupInService
--- FAIL: TestWaitUntilGroupInService (0.00s)
main_test.go:59: case 0, contains(AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][], `false`), expected: []interface {}{true}, but got: []interface {}{false}
main_test.go:59: case 1, AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][], expected: []interface {}{true, false}, but got: []interface {}{}
main_test.go:59: case 2, AutoScalingGroups[].[length(Instances[?LifecycleState=='InService'])][], expected: []interface {}{2, 1}, but got: []interface {}{0, 0}
FAIL
exit status 1
FAIL _/Users/masayuki-morita/work/tmp/20190228 0.019s
```

### Related items

Originating issue: https://github.com/aws/aws-sdk-go/issues/2478
Related to #15 and #20.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.