go.ligato.io/vpp-agent/v3@v3.5.0/plugins/kvscheduler/internal/graph/utils_for_test.go (about)

     1  // Copyright (c) 2018 Cisco and/or its affiliates.
     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  
    15  package graph
    16  
    17  import (
    18  	"strings"
    19  
    20  	. "github.com/onsi/gomega"
    21  
    22  	"go.ligato.io/cn-infra/v2/idxmap"
    23  
    24  	. "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/internal/test"
    25  )
    26  
    27  const (
    28  	value1Label = "value1"
    29  	value2Label = "value2"
    30  	value3Label = "value3"
    31  	value4Label = "value4"
    32  
    33  	prefixA = "/prefixA/"
    34  	prefixB = "/prefixB/"
    35  
    36  	keyA1 = prefixA + "key1"
    37  	keyA2 = prefixA + "key2"
    38  	keyA3 = prefixA + "key3"
    39  	keyB1 = prefixB + "key4"
    40  
    41  	metadataMapA = "mapA"
    42  	metadataMapB = "mapB"
    43  
    44  	relation1 = "relation1"
    45  	relation2 = "relation2"
    46  )
    47  
    48  var (
    49  	value1 = NewStringValue("this is value1")
    50  	value2 = NewStringValue("this is value2")
    51  	value3 = NewStringValue("this is value3")
    52  	value4 = NewStringValue("this is value4")
    53  
    54  	commonOpts = Opts{RecordOldRevs: true, RecordAgeLimit: minutesInOneDay, PermanentInitPeriod: minutesInOneHour}
    55  )
    56  
    57  func prefixASelector(key string) bool {
    58  	return strings.HasPrefix(key, prefixA)
    59  }
    60  
    61  func prefixBSelector(key string) bool {
    62  	return strings.HasPrefix(key, prefixB)
    63  }
    64  
    65  func keySelector(keys ...string) func(key string) bool {
    66  	return func(key string) bool {
    67  		for _, k := range keys {
    68  			if key == k {
    69  				return true
    70  			}
    71  		}
    72  		return false
    73  	}
    74  }
    75  
    76  func selectNodesToBuild(ids ...int) map[int]struct{} {
    77  	nodeIDs := make(map[int]struct{})
    78  	for _, id := range ids {
    79  		nodeIDs[id] = struct{}{}
    80  	}
    81  	return nodeIDs
    82  }
    83  
    84  func buildGraph(graph Graph, wInPlace bool, record, regMaps bool, nodes map[int]struct{}) Graph {
    85  	if graph == nil {
    86  		graph = NewGraph(commonOpts)
    87  	}
    88  	graphW := graph.Write(wInPlace, record)
    89  	Expect(graphW.ValidateEdges()).To(BeNil())
    90  
    91  	if regMaps {
    92  		graphW.RegisterMetadataMap(metadataMapA, NewNameToInteger(metadataMapA))
    93  		graphW.RegisterMetadataMap(metadataMapB, NewNameToInteger(metadataMapB))
    94  	}
    95  
    96  	var (
    97  		node1, node2, node3, node4 NodeRW
    98  	)
    99  
   100  	if _, addNode1 := nodes[1]; addNode1 {
   101  		node1 = graphW.SetNode(keyA1)
   102  		node1.SetLabel(value1Label)
   103  		node1.SetValue(value1)
   104  		node1.SetMetadata(&OnlyInteger{Integer: 1})
   105  		node1.SetMetadataMap(metadataMapA)
   106  		node1.SetFlags(ColorFlag(Red), AbstractFlag())
   107  		node1.SetTargets([]RelationTargetDef{
   108  			{relation1, "node3", keyA3, TargetSelector{}},
   109  			{relation2, "node2", keyA2, TargetSelector{}},
   110  		})
   111  		Expect(graphW.ValidateEdges()).To(BeNil())
   112  		// targets changed
   113  		node1.SetTargets([]RelationTargetDef{
   114  			{relation1, "node2", keyA2, TargetSelector{}},
   115  			{relation2, "prefixB", "", TargetSelector{KeySelector: prefixBSelector}},
   116  		})
   117  		Expect(graphW.ValidateEdges()).To(BeNil())
   118  	}
   119  
   120  	if _, addNode2 := nodes[2]; addNode2 {
   121  		node2 = graphW.SetNode(keyA2)
   122  		Expect(graphW.ValidateEdges()).To(BeNil())
   123  		node2.SetLabel(value2Label)
   124  		node2.SetValue(value2)
   125  		node2.SetMetadata(&OnlyInteger{Integer: 2})
   126  		node2.SetMetadataMap(metadataMapA)
   127  		node2.SetFlags(ColorFlag(Blue))
   128  		node2.SetTargets([]RelationTargetDef{
   129  			{relation1, "node3", keyA1, TargetSelector{}},
   130  		})
   131  		Expect(graphW.ValidateEdges()).To(BeNil())
   132  		// targets changed
   133  		node2.SetTargets([]RelationTargetDef{
   134  			{relation1, "node3", keyA3, TargetSelector{}},
   135  		})
   136  		Expect(graphW.ValidateEdges()).To(BeNil())
   137  	}
   138  
   139  	if _, addNode3 := nodes[3]; addNode3 {
   140  		node3 = graphW.SetNode(keyA3)
   141  		Expect(graphW.ValidateEdges()).To(BeNil())
   142  		node3.SetLabel(value3Label)
   143  		node3.SetValue(value3)
   144  		node3.SetMetadata(&OnlyInteger{Integer: 3})
   145  		node3.SetMetadataMap(metadataMapA)
   146  		node3.SetFlags(ColorFlag(Green), AbstractFlag(), TemporaryFlag())
   147  		node3.SetTargets([]RelationTargetDef{
   148  			{relation2, "node1+node2", "", TargetSelector{KeySelector: keySelector(keyA1, keyA2)}},
   149  			{relation2, "prefixB", keyB1, TargetSelector{}},
   150  		})
   151  		Expect(graphW.ValidateEdges()).To(BeNil())
   152  		// targets changed
   153  		node3.SetTargets([]RelationTargetDef{
   154  			{relation2, "node1+node2", "", TargetSelector{KeySelector: keySelector(keyA1, keyA2)}},
   155  			{relation2, "prefixB", "", TargetSelector{KeySelector: prefixBSelector}},
   156  		})
   157  		Expect(graphW.ValidateEdges()).To(BeNil())
   158  	}
   159  
   160  	if _, addNode4 := nodes[4]; addNode4 {
   161  		node4 = graphW.SetNode(keyB1)
   162  		Expect(graphW.ValidateEdges()).To(BeNil())
   163  		node4.SetLabel(value4Label)
   164  		node4.SetValue(value4)
   165  		node4.SetMetadata(&OnlyInteger{Integer: 1})
   166  		node4.SetMetadataMap(metadataMapB)
   167  		node4.SetFlags(TemporaryFlag())
   168  		node4.SetTargets([]RelationTargetDef{
   169  			{relation1, "prefixA", "", TargetSelector{KeySelector: prefixASelector}},
   170  			{relation2, "non-existing-key", "non-existing-key", TargetSelector{}},
   171  			{relation2, "non-existing-key2", "non-existing-key2", TargetSelector{}},
   172  		})
   173  		Expect(graphW.ValidateEdges()).To(BeNil())
   174  		// targets changed
   175  		node4.SetTargets([]RelationTargetDef{
   176  			{relation1, "prefixA", "", TargetSelector{KeySelector: prefixASelector}},
   177  			{relation2, "non-existing-key", "non-existing-key", TargetSelector{}},
   178  		})
   179  		Expect(graphW.ValidateEdges()).To(BeNil())
   180  	}
   181  
   182  	if !wInPlace {
   183  		graphW.Save()
   184  
   185  		// make changes that will not be saved and thus should have no effect
   186  		if node1 != nil {
   187  			node1.SetTargets([]RelationTargetDef{
   188  				{relation1, "node3", keyA3, TargetSelector{}},
   189  				{relation2, "node2", keyA2, TargetSelector{}},
   190  			})
   191  			Expect(graphW.ValidateEdges()).To(BeNil())
   192  		}
   193  		if node3 != nil {
   194  			node3.SetTargets([]RelationTargetDef{})
   195  			Expect(graphW.ValidateEdges()).To(BeNil())
   196  		}
   197  		if node4 != nil {
   198  			node4.SetTargets([]RelationTargetDef{
   199  				{relation1, "prefixA", "use-key-instead-of-selector", TargetSelector{}},
   200  				{relation2, "non-existing-key", keyA3, TargetSelector{}},
   201  			})
   202  			Expect(graphW.ValidateEdges()).To(BeNil())
   203  		}
   204  	}
   205  
   206  	graphW.Release()
   207  	return graph
   208  }
   209  
   210  func flags(flags ...Flag) (flagArray [maxFlags]Flag) {
   211  	for _, f := range flags {
   212  		flagArray[f.GetIndex()] = f
   213  	}
   214  	return
   215  }
   216  
   217  func checkTargets(node Node, relation string, label string, targetKeys ...string) {
   218  	targets := node.GetTargets(relation)
   219  	forLabel := targets.GetTargetForLabel(label)
   220  	targetNodes := make(map[string]struct{})
   221  	for _, targetNode := range forLabel.Nodes {
   222  		targetNodes[targetNode.GetKey()] = struct{}{}
   223  	}
   224  	for _, targetKey := range targetKeys {
   225  		Expect(targetNodes).To(HaveKey(targetKey))
   226  	}
   227  	Expect(targetNodes).To(HaveLen(len(targetKeys)))
   228  }
   229  
   230  func checkRecordedTargets(recordedTargets Targets, relation string, labelCnt int, label string, targetKeys ...string) {
   231  	cnt := 0
   232  	for i := recordedTargets.RelationBegin(relation); i < len(recordedTargets); i++ {
   233  		if recordedTargets[i].Relation != relation {
   234  			break
   235  		}
   236  		cnt++
   237  	}
   238  	Expect(cnt).To(Equal(labelCnt))
   239  	t, _ := recordedTargets.GetTargetForLabel(relation, label)
   240  	Expect(t).ToNot(BeNil())
   241  	Expect(t.Label).To(Equal(label))
   242  	for _, targetKey := range targetKeys {
   243  		Expect(t.MatchingKeys.Has(targetKey)).To(BeTrue())
   244  	}
   245  	Expect(t.MatchingKeys.Length()).To(Equal(len(targetKeys)))
   246  }
   247  
   248  func checkNodes(nodes []Node, keys ...string) {
   249  	for _, key := range keys {
   250  		found := false
   251  		for _, node := range nodes {
   252  			if node.GetKey() == key {
   253  				found = true
   254  				break
   255  			}
   256  		}
   257  		Expect(found).To(BeTrue())
   258  	}
   259  	Expect(nodes).To(HaveLen(len(keys)))
   260  }
   261  
   262  func checkRecordedNodes(nodes []*RecordedNode, keys ...string) {
   263  	recordedNodes := make(map[string]struct{})
   264  	for _, node := range nodes {
   265  		recordedNodes[node.Key] = struct{}{}
   266  	}
   267  	Expect(nodes).To(HaveLen(len(keys)))
   268  }
   269  
   270  func checkSources(node Node, relation string, sourceKeys ...string) {
   271  	sourceNodes := make(map[string]struct{})
   272  	for _, perLabel := range node.GetSources(relation) {
   273  		for _, sourceNode := range perLabel.Nodes {
   274  			sourceNodes[sourceNode.GetKey()] = struct{}{}
   275  		}
   276  	}
   277  	for _, sourceKey := range sourceKeys {
   278  		Expect(sourceNodes).To(HaveKey(sourceKey))
   279  	}
   280  	Expect(sourceNodes).To(HaveLen(len(sourceKeys)))
   281  }
   282  
   283  func checkMetadataValues(mapping idxmap.NamedMapping, labels ...string) {
   284  	allLabels := make(map[string]struct{})
   285  	for _, label := range mapping.ListAllNames() {
   286  		allLabels[label] = struct{}{}
   287  	}
   288  	for _, label := range labels {
   289  		Expect(allLabels).To(HaveKey(label))
   290  	}
   291  	Expect(mapping.ListAllNames()).To(HaveLen(len(labels)))
   292  }