func TestValueAtPathFailure(t *testing.T) { assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "C.x")) assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, ".x")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "X.Y.Z")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[100].C")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[3].C")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "B.B.C.Z")) assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "z[-1].C")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(nil, "A.B.C")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(Struct{}, "A")) }
func TestValueAtPathSuccess(t *testing.T) { assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "C")) assert.Equal(t, []interface{}{"value1"}, awsutil.ValuesAtPath(data, "A[0].C")) assert.Equal(t, []interface{}{"value2"}, awsutil.ValuesAtPath(data, "A[1].C")) assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[2].C")) assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtAnyPath(data, "a[2].c")) assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[-1].C")) assert.Equal(t, []interface{}{"value1", "value2", "value3"}, awsutil.ValuesAtPath(data, "A[].C")) assert.Equal(t, []interface{}{"terminal"}, awsutil.ValuesAtPath(data, "B . B . C")) assert.Equal(t, []interface{}{"terminal", "terminal2"}, awsutil.ValuesAtPath(data, "B.*.C")) assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "A.D.X || C")) }
func TestValueAtPathFailure(t *testing.T) { var testCases = []struct { expect []interface{} errContains string data interface{} path string }{ {nil, "", data, "C.x"}, {nil, "SyntaxError: Invalid token: tDot", data, ".x"}, {nil, "", data, "X.Y.Z"}, {nil, "", data, "A[100].C"}, {nil, "", data, "A[3].C"}, {nil, "", data, "B.B.C.Z"}, {nil, "", data, "z[-1].C"}, {nil, "", nil, "A.B.C"}, {[]interface{}{}, "", Struct{}, "A"}, {nil, "", data, "A[0].B.C"}, {nil, "", data, "D"}, } for i, c := range testCases { v, err := awsutil.ValuesAtPath(c.data, c.path) if c.errContains != "" { assert.Contains(t, err.Error(), c.errContains, "case %d, expected error, %s", i, c.path) continue } else { assert.NoError(t, err, "case %d, expected no error, %s", i, c.path) } assert.Equal(t, c.expect, v, "case %d, %s", i, c.path) } }
func TestValueAtPathSuccess(t *testing.T) { var testCases = []struct { expect []interface{} data interface{} path string }{ {[]interface{}{"initial"}, data, "C"}, {[]interface{}{"value1"}, data, "A[0].C"}, {[]interface{}{"value2"}, data, "A[1].C"}, {[]interface{}{"value3"}, data, "A[2].C"}, {[]interface{}{"value3"}, data, "a[2].c"}, {[]interface{}{"value3"}, data, "A[-1].C"}, {[]interface{}{"value1", "value2", "value3"}, data, "A[].C"}, {[]interface{}{"terminal"}, data, "B . B . C"}, {[]interface{}{"initial"}, data, "A.D.X || C"}, {[]interface{}{"initial"}, data, "A[0].B || C"}, {[]interface{}{ Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}}, Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}}, }, data2, "A"}, } for i, c := range testCases { v, err := awsutil.ValuesAtPath(c.data, c.path) assert.NoError(t, err, "case %d, expected no error, %s", i, c.path) assert.Equal(t, c.expect, v, "case %d, %s", i, c.path) } }
// nextPageTokens returns the tokens to use when asking for the next page of // data. func (r *Request) nextPageTokens() []interface{} { if r.Operation.Paginator == nil { return nil } if r.Operation.TruncationToken != "" { tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) if len(tr) == 0 { return nil } switch v := tr[0].(type) { case *bool: if !aws.BoolValue(v) { return nil } case bool: if v == false { return nil } } } tokens := []interface{}{} tokenAdded := false for _, outToken := range r.Operation.OutputTokens { v, _ := awsutil.ValuesAtPath(r.Data, outToken) if len(v) > 0 { tokens = append(tokens, v[0]) tokenAdded = true } else { tokens = append(tokens, nil) } } if !tokenAdded { return nil } return tokens }
// Wait waits for an operation to complete, expire max attempts, or fail. Error // is returned if the operation fails. func (w *Waiter) Wait() error { client := reflect.ValueOf(w.Client) in := reflect.ValueOf(w.Input) method := client.MethodByName(w.Config.Operation + "Request") for i := 0; i < w.MaxAttempts; i++ { res := method.Call([]reflect.Value{in}) req := res[0].Interface().(*request.Request) req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter")) err := req.Send() for _, a := range w.Acceptors { if err != nil && a.Matcher != "error" { // Only matcher error is valid if there is a request error continue } result := false var vals []interface{} switch a.Matcher { case "pathAll", "path": // Require all matches to be equal for result to match vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) result = true for _, val := range vals { if !awsutil.DeepEqual(val, a.Expected) { result = false break } } case "pathAny": // Only a single match needs to equal for the result to match vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) for _, val := range vals { if awsutil.DeepEqual(val, a.Expected) { result = true break } } case "status": s := a.Expected.(int) result = s == req.HTTPResponse.StatusCode case "error": if aerr, ok := err.(awserr.Error); ok { result = aerr.Code() == a.Expected.(string) } case "pathList": // ignored matcher default: logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s", w.Config.Operation, a.Matcher) } if !result { // If there was no matching result found there is nothing more to do // for this response, retry the request. continue } switch a.State { case "success": // waiter completed return nil case "failure": // Waiter failure state triggered return awserr.New("ResourceNotReady", fmt.Sprintf("failed waiting for successful resource state"), err) case "retry": // clear the error and retry the operation err = nil default: logf(client, "WARNING: Waiter for %s encountered unexpected state: %s", w.Config.Operation, a.State) } } if err != nil { return err } time.Sleep(time.Second * time.Duration(w.Delay)) } return awserr.New("ResourceNotReady", fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil) }