1// Copyright 2017 Istio Authors 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 15package checker 16 17import ( 18 "fmt" 19 "strings" 20 "testing" 21 22 cfgpb "istio.io/api/policy/v1beta1" 23 "istio.io/pkg/attribute" 24) 25 26func TestTypeCheck(t *testing.T) { 27 af := newAF([]*ad{ 28 {"int", cfgpb.INT64}, 29 {"bool", cfgpb.BOOL}, 30 {"double", cfgpb.DOUBLE}, 31 {"string", cfgpb.STRING}, 32 {"timestamp", cfgpb.TIMESTAMP}, 33 {"ip", cfgpb.IP_ADDRESS}, 34 {"email", cfgpb.EMAIL_ADDRESS}, 35 {"uri", cfgpb.URI}, 36 {"dns", cfgpb.DNS_NAME}, 37 {"duration", cfgpb.DURATION}, 38 {"stringmap", cfgpb.STRING_MAP}, 39 }) 40 41 tests := []struct { 42 in string 43 out cfgpb.ValueType 44 err string 45 }{ 46 // identity 47 {"int", cfgpb.INT64, ""}, 48 {"bool", cfgpb.BOOL, ""}, 49 {"double", cfgpb.DOUBLE, ""}, 50 {"string", cfgpb.STRING, ""}, 51 {"timestamp", cfgpb.TIMESTAMP, ""}, 52 {"ip", cfgpb.IP_ADDRESS, ""}, 53 {"email", cfgpb.EMAIL_ADDRESS, ""}, 54 {"uri", cfgpb.URI, ""}, 55 {"dns", cfgpb.DNS_NAME, ""}, 56 {"duration", cfgpb.DURATION, ""}, 57 {"stringmap", cfgpb.STRING_MAP, ""}, 58 // expressions 59 {"int == 2", cfgpb.BOOL, ""}, 60 {"double == 2.0", cfgpb.BOOL, ""}, 61 {`string | "foobar"`, cfgpb.STRING, ""}, 62 // invalid expressions 63 {"int | bool", cfgpb.VALUE_TYPE_UNSPECIFIED, "typeError"}, 64 {"stringmap | ", cfgpb.VALUE_TYPE_UNSPECIFIED, "failed to parse"}, 65 } 66 67 for idx, tt := range tests { 68 t.Run(fmt.Sprintf("[%d] %s", idx, tt.in), func(t *testing.T) { 69 ev := NewTypeChecker(af) 70 vt, err := ev.EvalType(tt.in) 71 if tt.err != "" || err != nil { 72 if !strings.Contains(err.Error(), tt.err) { 73 t.Fatalf("EvalType(%s, adf) = %v, wanted err %v", tt.in, err, tt.err) 74 } 75 } 76 if vt != tt.out { 77 t.Fatalf("EvalType(%s, adf) = %v, wanted type %v", tt.in, vt, tt.out) 78 } 79 }) 80 } 81} 82 83type ad struct { 84 name string 85 v cfgpb.ValueType 86} 87 88func newAF(ds []*ad) attribute.AttributeDescriptorFinder { 89 m := make(map[string]*cfgpb.AttributeManifest_AttributeInfo) 90 for _, aa := range ds { 91 m[aa.name] = &cfgpb.AttributeManifest_AttributeInfo{ValueType: aa.v} 92 } 93 return attribute.NewFinder(m) 94} 95