You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ho...@apache.org on 2021/02/28 08:49:23 UTC
[skywalking-infra-e2e] 01/01: implement the `contains` action
This is an automated email from the ASF dual-hosted git repository.
hoshea pushed a commit to branch verifier/action
in repository https://gitbox.apache.org/repos/asf/skywalking-infra-e2e.git
commit fc27a2cda657f5a5a3b2e654cc0522a302cf206b
Author: Hoshea <fg...@gmail.com>
AuthorDate: Sun Feb 28 16:48:46 2021 +0800
implement the `contains` action
---
internal/components/verifier/verifier.go | 1 +
test/verify/2.actual.yaml | 10 ++++++
test/verify/2.expected.yaml | 5 +++
third-party/go/template/exec.go | 48 +++++++++++++------------
third-party/go/template/parse/lex.go | 46 ++++++++++++------------
third-party/go/template/parse/node.go | 62 ++++++++++++++++----------------
third-party/go/template/parse/parse.go | 12 +++----
7 files changed, 101 insertions(+), 83 deletions(-)
diff --git a/internal/components/verifier/verifier.go b/internal/components/verifier/verifier.go
index 84150c1..2f4675a 100644
--- a/internal/components/verifier/verifier.go
+++ b/internal/components/verifier/verifier.go
@@ -94,6 +94,7 @@ func verify(actualData, expectedTemplate string) error {
}
if !cmp.Equal(expected, actual) {
+ // TODO: use a custom Reporter (suggested by the comment of cmp.Diff)
diff := cmp.Diff(expected, actual)
fmt.Println(diff)
return &MismatchError{}
diff --git a/test/verify/2.actual.yaml b/test/verify/2.actual.yaml
new file mode 100644
index 0000000..521f4a1
--- /dev/null
+++ b/test/verify/2.actual.yaml
@@ -0,0 +1,10 @@
+metrics:
+ - name: business-zone::projectA
+ id: YnVzaW5lc3Mtem9uZTo6cHJvamVjdEE=.1
+ value: 1
+ - name: system::load balancer1
+ id: c3lzdGVtOjpsb2FkIGJhbGFuY2VyMQ==.1
+ value: 0
+ - name: system::load balancer2
+ id: c3lzdGVtOjpsb2FkIGJhbGFuY2VyMg==.1
+ value: 0
\ No newline at end of file
diff --git a/test/verify/2.expected.yaml b/test/verify/2.expected.yaml
new file mode 100644
index 0000000..30819b0
--- /dev/null
+++ b/test/verify/2.expected.yaml
@@ -0,0 +1,5 @@
+metrics:
+{{- contains .metrics }}
+ - name: {{ notEmpty .name }}
+ value: {{ gt .value 0 }}
+{{- end }}
\ No newline at end of file
diff --git a/third-party/go/template/exec.go b/third-party/go/template/exec.go
index b4af1ad..6eca6a7 100644
--- a/third-party/go/template/exec.go
+++ b/third-party/go/template/exec.go
@@ -7,13 +7,16 @@ package template
import (
"bytes"
"fmt"
- "github.com/apache/skywalking-infra-e2e/third-party/go/internal/fmtsort"
- "github.com/apache/skywalking-infra-e2e/third-party/go/template/parse"
- "gopkg.in/yaml.v3"
"io"
+ "os"
"reflect"
"runtime"
"strings"
+
+ "github.com/apache/skywalking-infra-e2e/third-party/go/internal/fmtsort"
+ "github.com/apache/skywalking-infra-e2e/third-party/go/template/parse"
+
+ "gopkg.in/yaml.v2"
)
// maxExecDepth specifies the maximum stack depth of templates within
@@ -274,8 +277,8 @@ func (s *state) walk(dot reflect.Value, node parse.Node) {
}
case *parse.WithNode:
s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList)
- case *parse.AtLeastOnceNode:
- s.walkAtLeastOnce(dot, node)
+ case *parse.ContainsNode:
+ s.walkContains(dot, node)
default:
s.errorf("unknown node: %s", node)
}
@@ -398,7 +401,7 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
}
}
-func (s *state) walkAtLeastOnce(dot reflect.Value, r *parse.AtLeastOnceNode) {
+func (s *state) walkContains(dot reflect.Value, r *parse.ContainsNode) {
s.at(r)
defer s.pop(s.mark())
val, _ := indirect(s.evalPipeline(dot, r.Pipe))
@@ -431,25 +434,27 @@ func (s *state) walkAtLeastOnce(dot reflect.Value, r *parse.AtLeastOnceNode) {
if val.Len() == 0 {
break
}
- match := false
+ //match := false
sss := make([]interface{}, val.Len())
for i := 0; i < val.Len(); i++ {
actual := oneIteration(reflect.ValueOf(i), val.Index(i))
sss[i] = actual
value, _ := printableValue(val.Index(i))
- if fmt.Sprint(value) == fmt.Sprint(actual) {
- match = true
- break
- }
- }
- var marshal []byte
- if match {
- value, _ := printableValue(val)
- marshal, _ = yaml.Marshal(value)
- } else {
- marshal, _ = yaml.Marshal(sss)
+ io.WriteString(os.Stdout, fmt.Sprintln(actual))
+ io.WriteString(os.Stdout, fmt.Sprintln(value))
+ //if fmt.Sprint(value) == fmt.Sprint(actual) {
+ // match = true
+ // break
+ //}
}
- s.wr.Write(append([]byte("\n"), marshal...))
+ //var marshal []byte
+ //if match {
+ // value, _ := printableValue(val)
+ // marshal, _ = yaml.Marshal(value)
+ //} else {
+ // marshal, _ = yaml.Marshal(sss)
+ //}
+ //s.wr.Write(append([]byte("\n"), marshal...))
return
case reflect.Map:
if val.Len() == 0 {
@@ -479,10 +484,7 @@ func (s *state) walkAtLeastOnce(dot reflect.Value, r *parse.AtLeastOnceNode) {
case reflect.Invalid:
break // An invalid value is likely a nil map, etc. and acts like an empty map.
default:
- s.errorf("range can't iterate over %v", val)
- }
- if r.ElseList != nil {
- s.walk(dot, r.ElseList)
+ s.errorf("contains can't iterate over %v", val)
}
}
diff --git a/third-party/go/template/parse/lex.go b/third-party/go/template/parse/lex.go
index 8ebb789..19eed9a 100644
--- a/third-party/go/template/parse/lex.go
+++ b/third-party/go/template/parse/lex.go
@@ -59,32 +59,32 @@ const (
itemText // plain text
itemVariable // variable starting with '$', such as '$' or '$1' or '$hello'
// Keywords appear after all the rest.
- itemKeyword // used only to delimit the keywords
- itemBlock // block keyword
- itemDot // the cursor, spelled '.'
- itemDefine // define keyword
- itemElse // else keyword
- itemEnd // end keyword
- itemIf // if keyword
- itemNil // the untyped nil constant, easiest to treat as a keyword
- itemRange // range keyword
- itemTemplate // template keyword
- itemWith // with keyword
- itemAtLeastOnce // atLeastOnce keyword
+ itemKeyword // used only to delimit the keywords
+ itemBlock // block keyword
+ itemDot // the cursor, spelled '.'
+ itemDefine // define keyword
+ itemElse // else keyword
+ itemEnd // end keyword
+ itemIf // if keyword
+ itemNil // the untyped nil constant, easiest to treat as a keyword
+ itemRange // range keyword
+ itemTemplate // template keyword
+ itemWith // with keyword
+ itemContains // contains keyword
)
var key = map[string]itemType{
- ".": itemDot,
- "block": itemBlock,
- "define": itemDefine,
- "else": itemElse,
- "end": itemEnd,
- "if": itemIf,
- "range": itemRange,
- "nil": itemNil,
- "template": itemTemplate,
- "with": itemWith,
- "atLeastOnce": itemAtLeastOnce,
+ ".": itemDot,
+ "block": itemBlock,
+ "define": itemDefine,
+ "else": itemElse,
+ "end": itemEnd,
+ "if": itemIf,
+ "range": itemRange,
+ "nil": itemNil,
+ "template": itemTemplate,
+ "with": itemWith,
+ "contains": itemContains,
}
const eof = -1
diff --git a/third-party/go/template/parse/node.go b/third-party/go/template/parse/node.go
index 57ca52c..938d5bf 100644
--- a/third-party/go/template/parse/node.go
+++ b/third-party/go/template/parse/node.go
@@ -50,27 +50,27 @@ func (t NodeType) Type() NodeType {
}
const (
- NodeText NodeType = iota // Plain text.
- NodeAction // A non-control action such as a field evaluation.
- NodeBool // A boolean constant.
- NodeChain // A sequence of field accesses.
- NodeCommand // An element of a pipeline.
- NodeDot // The cursor, dot.
- nodeElse // An else action. Not added to tree.
- nodeEnd // An end action. Not added to tree.
- NodeField // A field or method name.
- NodeIdentifier // An identifier; always a function name.
- NodeIf // An if action.
- NodeList // A list of Nodes.
- NodeNil // An untyped nil constant.
- NodeNumber // A numerical constant.
- NodePipe // A pipeline of commands.
- NodeRange // A range action.
- NodeString // A string constant.
- NodeTemplate // A template invocation action.
- NodeVariable // A $ variable.
- NodeWith // A with action.
- NodeAtLeastOnce // An atLeastOnce action.
+ NodeText NodeType = iota // Plain text.
+ NodeAction // A non-control action such as a field evaluation.
+ NodeBool // A boolean constant.
+ NodeChain // A sequence of field accesses.
+ NodeCommand // An element of a pipeline.
+ NodeDot // The cursor, dot.
+ nodeElse // An else action. Not added to tree.
+ nodeEnd // An end action. Not added to tree.
+ NodeField // A field or method name.
+ NodeIdentifier // An identifier; always a function name.
+ NodeIf // An if action.
+ NodeList // A list of Nodes.
+ NodeNil // An untyped nil constant.
+ NodeNumber // A numerical constant.
+ NodePipe // A pipeline of commands.
+ NodeRange // A range action.
+ NodeString // A string constant.
+ NodeTemplate // A template invocation action.
+ NodeVariable // A $ variable.
+ NodeWith // A with action.
+ NodeContains // A contains action.
)
// Nodes.
@@ -829,8 +829,8 @@ func (b *BranchNode) writeTo(sb *strings.Builder) {
name = "range"
case NodeWith:
name = "with"
- case NodeAtLeastOnce:
- name = "atLeastOnce"
+ case NodeContains:
+ name = "contains"
default:
panic("unknown branch type")
}
@@ -859,8 +859,8 @@ func (b *BranchNode) Copy() Node {
return b.tr.newRange(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
case NodeWith:
return b.tr.newWith(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
- case NodeAtLeastOnce:
- return b.tr.newAtLeastOnce(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
+ case NodeContains:
+ return b.tr.newContains(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
default:
panic("unknown branch type")
}
@@ -905,17 +905,17 @@ func (w *WithNode) Copy() Node {
return w.tr.newWith(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList())
}
-// AtLeastOnce represents a {{atLeastOnce}} action and its commands.
-type AtLeastOnceNode struct {
+// Contains represents a {{contains}} action and its commands.
+type ContainsNode struct {
BranchNode
}
-func (t *Tree) newAtLeastOnce(pos Pos, line int, pipe *PipeNode, list *ListNode, elseList *ListNode) *AtLeastOnceNode {
- return &AtLeastOnceNode{BranchNode{tr: t, NodeType: NodeAtLeastOnce, Pos: pos, Line: line, Pipe: pipe, List: list}}
+func (t *Tree) newContains(pos Pos, line int, pipe *PipeNode, list *ListNode, elseList *ListNode) *ContainsNode {
+ return &ContainsNode{BranchNode{tr: t, NodeType: NodeContains, Pos: pos, Line: line, Pipe: pipe, List: list}}
}
-func (w *AtLeastOnceNode) Copy() Node {
- return w.tr.newAtLeastOnce(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList())
+func (w *ContainsNode) Copy() Node {
+ return w.tr.newContains(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList())
}
// TemplateNode represents a {{template}} action.
diff --git a/third-party/go/template/parse/parse.go b/third-party/go/template/parse/parse.go
index 6698aaf..ce46c8b 100644
--- a/third-party/go/template/parse/parse.go
+++ b/third-party/go/template/parse/parse.go
@@ -365,8 +365,8 @@ func (t *Tree) action() (n Node) {
return t.templateControl()
case itemWith:
return t.withControl()
- case itemAtLeastOnce:
- return t.atLeastOnceControl()
+ case itemContains:
+ return t.containsControl()
}
t.backup()
token := t.peek()
@@ -506,11 +506,11 @@ func (t *Tree) withControl() Node {
return t.newWith(t.parseControl(false, "with"))
}
-// AtLeastOnce:
-// {{atLeastOnce number}} itemList {{end}}
+// Contains:
+// {{contains number}} itemList {{end}}
// If keyword is past.
-func (t *Tree) atLeastOnceControl() Node {
- return t.newAtLeastOnce(t.parseControl(false, "atLeastOnce"))
+func (t *Tree) containsControl() Node {
+ return t.newContains(t.parseControl(false, "contains"))
}
// End: