Skip to content

Commit 0579c86

Browse files
committed
Add includeExplicitDelete in GetHighestPrecedence()
1 parent 7036511 commit 0579c86

File tree

11 files changed

+84
-41
lines changed

11 files changed

+84
-41
lines changed

pkg/tree/entry.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type Entry interface {
5757
// GetHighesPrio return the new cache.Update entried from the tree that are the highes priority.
5858
// If the onlyNewOrUpdated option is set to true, only the New or Updated entries will be returned
5959
// It will append to the given list and provide a new pointer to the slice
60-
GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool) LeafVariantSlice
60+
GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) LeafVariantSlice
6161
// getHighestPrecedenceLeafValue returns the highest LeafValue of the Entry at hand
6262
// will return an error if the Entry is not a Leaf
6363
getHighestPrecedenceLeafValue(context.Context) (*LeafEntry, error)
@@ -167,7 +167,7 @@ type LeafVariantEntry interface {
167167

168168
type LeafVariantEntries interface {
169169
MarkOwnerForDeletion(owner string, onlyIntended bool) *LeafEntry
170-
GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool) *LeafEntry
170+
GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDeletes bool) *LeafEntry
171171
GetRunning() *LeafEntry
172172
DeleteByOwner(owner string) *LeafEntry
173173
AddExplicitDeleteEntry(owner string, priority int32) *LeafEntry

pkg/tree/entry_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
743743
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 1, owner2, ts), flagsExisting, nil))
744744
lv.les[1].MarkDelete(false)
745745

746-
le := lv.GetHighestPrecedence(true, false)
746+
le := lv.GetHighestPrecedence(true, false, false)
747747

748748
if le != lv.les[0] {
749749
t.Errorf("expected to get entry %v, got %v", lv.les[0], le)
@@ -760,7 +760,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
760760
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 1, owner1, ts), flagsExisting, nil))
761761
lv.les[0].MarkDelete(false)
762762

763-
le := lv.GetHighestPrecedence(true, false)
763+
le := lv.GetHighestPrecedence(true, false, false)
764764

765765
if le != nil {
766766
t.Errorf("expected to get entry %v, got %v", nil, le)
@@ -777,7 +777,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
777777
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 6, owner2, ts), flagsNew, nil))
778778
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil))
779779

780-
le := lv.GetHighestPrecedence(true, false)
780+
le := lv.GetHighestPrecedence(true, false, false)
781781

782782
if le != nil {
783783
t.Errorf("expected to get entry %v, got %v", nil, le)
@@ -793,7 +793,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
793793
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 5, owner1, ts), flagsExisting, nil))
794794
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 6, owner1, ts), flagsNew, nil))
795795

796-
le := lv.GetHighestPrecedence(false, false)
796+
le := lv.GetHighestPrecedence(false, false, false)
797797

798798
if le != lv.les[0] {
799799
t.Errorf("expected to get entry %v, got %v", lv.les[0], le)
@@ -811,7 +811,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
811811
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 6, owner2, ts), flagsNew, nil))
812812
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, RunningValuesPrio, RunningIntentName, ts), flagsExisting, nil))
813813

814-
le := lv.GetHighestPrecedence(true, false)
814+
le := lv.GetHighestPrecedence(true, false, false)
815815

816816
if le != nil {
817817
t.Errorf("expected to get entry %v, got %v", nil, le)
@@ -828,7 +828,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
828828
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 5, owner1, ts), flagsExisting, nil))
829829
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 6, owner2, ts), flagsNew, nil))
830830

831-
le := lv.GetHighestPrecedence(true, false)
831+
le := lv.GetHighestPrecedence(true, false, false)
832832

833833
if le != lv.les[0] {
834834
t.Errorf("expected to get entry %v, got %v", lv.les[0], le)
@@ -842,7 +842,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
842842
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 5, owner1, ts), flagsExisting, nil))
843843
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 6, owner2, ts), flagsNew, nil))
844844

845-
le := lv.GetHighestPrecedence(false, false)
845+
le := lv.GetHighestPrecedence(false, false, false)
846846

847847
if le != lv.les[0] {
848848
t.Errorf("expected to get entry %v, got %v", lv.les[0], le)
@@ -855,7 +855,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
855855
func(t *testing.T) {
856856
lv := LeafVariants{}
857857

858-
le := lv.GetHighestPrecedence(true, false)
858+
le := lv.GetHighestPrecedence(true, false, false)
859859

860860
if le != nil {
861861
t.Errorf("expected to get entry %v, got %v", nil, le)
@@ -871,7 +871,7 @@ func TestLeafVariants_GetHighesPrio(t *testing.T) {
871871
lv.les[0].MarkDelete(false)
872872
lv.Add(NewLeafEntry(types.NewUpdate(path, nil, 2, owner2, ts), flagsExisting, nil))
873873

874-
le := lv.GetHighestPrecedence(true, false)
874+
le := lv.GetHighestPrecedence(true, false, false)
875875

876876
if le != lv.les[1] {
877877
t.Errorf("expected to get entry %v, got %v", lv.les[1], le)

pkg/tree/json.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool)
9292
if s.leafVariants.shouldDelete() {
9393
return nil, nil
9494
}
95-
le := s.leafVariants.GetHighestPrecedence(false, false)
96-
if onlyNewOrUpdated && !(le.IsNew || le.IsUpdated) {
95+
le := s.leafVariants.GetHighestPrecedence(false, false, false)
96+
if le == nil || onlyNewOrUpdated && !(le.IsNew || le.IsUpdated) {
9797
return nil, nil
9898
}
9999
}
@@ -121,7 +121,7 @@ func (s *sharedEntryAttributes) toJsonInternal(onlyNewOrUpdated bool, ietf bool)
121121
if s.leafVariants.shouldDelete() {
122122
return nil, nil
123123
}
124-
le := s.leafVariants.GetHighestPrecedence(onlyNewOrUpdated, false)
124+
le := s.leafVariants.GetHighestPrecedence(onlyNewOrUpdated, false, false)
125125
if le == nil {
126126
return nil, nil
127127
}

pkg/tree/leaf_variants.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ func (lv *LeafVariants) canDeleteBranch(keepDefault bool) bool {
7171
return true
7272
}
7373

74+
highest := lv.GetHighestPrecedence(false, false, true)
75+
if highest != nil && highest.IsExplicitDelete {
76+
return true
77+
}
78+
7479
// go through all variants
7580
for _, l := range lv.les {
7681
// if the LeafVariant is not owned by running or default
@@ -100,8 +105,8 @@ func (lv *LeafVariants) canDelete() bool {
100105
}
101106

102107
// check if highest is explicit delete
103-
highest := lv.GetHighestPrecedence(false, false)
104-
if highest != nil && highest.IsExplicitDelete && lv.GetRunning() != nil {
108+
highest := lv.GetHighestPrecedence(false, false, true)
109+
if highest != nil && highest.IsExplicitDelete {
105110
return true
106111
}
107112

@@ -131,7 +136,7 @@ func (lv *LeafVariants) shouldDelete() bool {
131136
}
132137

133138
// check if highest is explicit delete
134-
highest := lv.GetHighestPrecedence(false, false)
139+
highest := lv.GetHighestPrecedence(false, false, true)
135140
if highest != nil && highest.IsExplicitDelete && lv.GetRunning() != nil {
136141
return true
137142
}
@@ -166,6 +171,12 @@ func (lv *LeafVariants) remainsToExist() bool {
166171
return false
167172
}
168173

174+
highest := lv.GetHighestPrecedence(false, false, true)
175+
176+
if highest != nil && highest.IsExplicitDelete {
177+
return false
178+
}
179+
169180
// go through all variants
170181
for _, l := range lv.les {
171182
// if an entry exists that does not have the delete flag set,
@@ -236,7 +247,7 @@ func (lv *LeafVariants) GetRunning() *LeafEntry {
236247

237248
// GetHighesNewUpdated returns the LeafEntry with the highes priority
238249
// nil if no leaf entry exists.
239-
func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool) *LeafEntry {
250+
func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) *LeafEntry {
240251
lv.lesMutex.RLock()
241252
defer lv.lesMutex.RUnlock()
242253
if len(lv.les) == 0 {
@@ -274,6 +285,10 @@ func (lv *LeafVariants) GetHighestPrecedence(onlyNewOrUpdated bool, includeDefau
274285
return nil
275286
}
276287

288+
if highest.IsExplicitDelete && !includeExplicitDelete {
289+
return nil
290+
}
291+
277292
// if it does not matter if the highes update is also
278293
// New or Updated return it
279294
if !onlyNewOrUpdated {

pkg/tree/root_entry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (r *RootEntry) GetDeletesForOwner(owner string) types.PathSlices {
175175
// If the onlyNewOrUpdated option is set to true, only the New or Updated entries will be returned
176176
// It will append to the given list and provide a new pointer to the slice
177177
func (r *RootEntry) GetHighestPrecedence(onlyNewOrUpdated bool) LeafVariantSlice {
178-
return r.sharedEntryAttributes.GetHighestPrecedence(make(LeafVariantSlice, 0), onlyNewOrUpdated, false)
178+
return r.sharedEntryAttributes.GetHighestPrecedence(make(LeafVariantSlice, 0), onlyNewOrUpdated, false, false)
179179
}
180180

181181
// GetDeletes returns the paths that due to the Tree content are to be deleted from the southbound device.

pkg/tree/sharedEntryAttributes.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -925,23 +925,23 @@ func (s *sharedEntryAttributes) deleteBranchInternal(ctx context.Context, owner
925925

926926
// GetHighestPrecedence goes through the whole branch and returns the new and updated cache.Updates.
927927
// These are the updated that will be send to the device.
928-
func (s *sharedEntryAttributes) GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool) LeafVariantSlice {
928+
func (s *sharedEntryAttributes) GetHighestPrecedence(result LeafVariantSlice, onlyNewOrUpdated bool, includeDefaults bool, includeExplicitDelete bool) LeafVariantSlice {
929929
// get the highes precedence LeafeVariant and add it to the list
930-
lv := s.leafVariants.GetHighestPrecedence(onlyNewOrUpdated, includeDefaults)
930+
lv := s.leafVariants.GetHighestPrecedence(onlyNewOrUpdated, includeDefaults, includeExplicitDelete)
931931
if lv != nil {
932932
result = append(result, lv)
933933
}
934934

935935
// continue with childs. Childs are part of choices, process only the "active" (highes precedence) childs
936936
for _, c := range s.GetChilds(DescendMethodActiveChilds) {
937-
result = c.GetHighestPrecedence(result, onlyNewOrUpdated, includeDefaults)
937+
result = c.GetHighestPrecedence(result, onlyNewOrUpdated, includeDefaults, includeExplicitDelete)
938938
}
939939
return result
940940
}
941941

942942
func (s *sharedEntryAttributes) getHighestPrecedenceLeafValue(ctx context.Context) (*LeafEntry, error) {
943943
for _, x := range []string{"existing", "default"} {
944-
lv := s.leafVariants.GetHighestPrecedence(false, true)
944+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
945945
if lv != nil {
946946
return lv, nil
947947
}
@@ -998,6 +998,10 @@ func (s *sharedEntryAttributes) Validate(ctx context.Context, resultChan chan<-
998998
wg := sync.WaitGroup{}
999999
defer wg.Wait()
10001000
for _, c := range s.GetChilds(DescendMethodActiveChilds) {
1001+
if c.canDeleteBranch(false) {
1002+
// skip validation of branches that can be deleted
1003+
continue
1004+
}
10011005
wg.Add(1)
10021006
valFunc := func(x Entry) {
10031007
x.Validate(ctx, resultChan, statChan, vCfg)
@@ -1051,7 +1055,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio
10511055
return
10521056
}
10531057

1054-
lv := s.leafVariants.GetHighestPrecedence(false, true)
1058+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
10551059
if lv == nil {
10561060
return
10571061
}
@@ -1128,7 +1132,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio
11281132
func (s *sharedEntryAttributes) validateLeafListMinMaxAttributes(resultChan chan<- *types.ValidationResultEntry, statChan chan<- *types.ValidationStat) {
11291133
if schema := s.schema.GetLeaflist(); schema != nil {
11301134
if schema.GetMinElements() > 0 || schema.GetMaxElements() < math.MaxUint64 {
1131-
if lv := s.leafVariants.GetHighestPrecedence(false, true); lv != nil {
1135+
if lv := s.leafVariants.GetHighestPrecedence(false, true, false); lv != nil {
11321136
tv := lv.Update.Value()
11331137

11341138
if val := tv.GetLeaflistVal(); val != nil {
@@ -1156,7 +1160,7 @@ func (s *sharedEntryAttributes) validateLength(resultChan chan<- *types.Validati
11561160

11571161
stat := types.NewValidationStat(types.StatTypeLength)
11581162

1159-
lv := s.leafVariants.GetHighestPrecedence(false, true)
1163+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
11601164
if lv == nil {
11611165
return
11621166
}
@@ -1186,7 +1190,10 @@ func (s *sharedEntryAttributes) validatePattern(resultChan chan<- *types.Validat
11861190
return
11871191
}
11881192
stat := types.NewValidationStat(types.StatTypePattern)
1189-
lv := s.leafVariants.GetHighestPrecedence(false, true)
1193+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
1194+
if lv == nil {
1195+
return
1196+
}
11901197
value := lv.Value().GetStringVal()
11911198
for _, pattern := range schema.Type.Patterns {
11921199
if p := pattern.GetPattern(); p != "" {

pkg/tree/sorter.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ func getListEntrySortFunc(parent Entry) func(a, b Entry) int {
1414
if !exists {
1515
return 0
1616
}
17-
aLvSlice := achild.GetHighestPrecedence(LeafVariantSlice{}, false, true)
18-
bLvSlice := bchild.GetHighestPrecedence(LeafVariantSlice{}, false, true)
17+
aLvSlice := achild.GetHighestPrecedence(LeafVariantSlice{}, false, true, true)
18+
bLvSlice := bchild.GetHighestPrecedence(LeafVariantSlice{}, false, true, true)
1919

2020
aEntry := aLvSlice[0]
2121
bEntry := bLvSlice[0]

pkg/tree/validation_entry_leafref.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]Entry, e
131131
return nil, fmt.Errorf("error not a leafref %s", s.Path().String())
132132
}
133133

134-
lv := s.leafVariants.GetHighestPrecedence(false, true)
135-
134+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
135+
if lv == nil {
136+
return nil, fmt.Errorf("no leafvariant found")
137+
}
136138
// value of node with type leafref
137139
tv := lv.Value()
138140

@@ -195,7 +197,10 @@ func (s *sharedEntryAttributes) resolve_leafref_key_path(ctx context.Context, ke
195197
return err
196198
}
197199

198-
lvs := keyValue.GetHighestPrecedence(LeafVariantSlice{}, false, false)
200+
lvs := keyValue.GetHighestPrecedence(LeafVariantSlice{}, false, false, false)
201+
if lvs == nil {
202+
return fmt.Errorf("no leafentry found")
203+
}
199204
tv := lvs[0].Value()
200205
keys[k].Value = tv.GetStringVal()
201206
keys[k].DoNotResolve = true
@@ -220,14 +225,22 @@ func (s *sharedEntryAttributes) validateLeafRefs(ctx context.Context, resultChan
220225
generateOptionalWarning(ctx, s, lref, resultChan)
221226
return
222227
}
228+
owner := "unknown"
229+
highest := s.leafVariants.GetHighestPrecedence(false, false, false)
230+
if highest != nil {
231+
owner = highest.Owner()
232+
}
223233
// if required, issue error
224-
resultChan <- types.NewValidationResultEntry(s.leafVariants.GetHighestPrecedence(false, false).Owner(), fmt.Errorf("missing leaf reference: failed resolving leafref %s for %s: %v", lref, s.Path().String(), err), types.ValidationResultEntryTypeError)
234+
resultChan <- types.NewValidationResultEntry(owner, fmt.Errorf("missing leaf reference: failed resolving leafref %s for %s: %v", lref, s.Path().String(), err), types.ValidationResultEntryTypeError)
225235
return
226236
}
227237

228238
// Only if the value remains, even after the SetIntent made it through, the LeafRef can be considered resolved.
229239
if entry[0].shouldDelete() {
230-
lv := s.leafVariants.GetHighestPrecedence(false, true)
240+
lv := s.leafVariants.GetHighestPrecedence(false, true, false)
241+
if lv == nil {
242+
return
243+
}
231244
EntryPath, _ := s.SdcpbPath()
232245

233246
// check if the OptionalInstance (!require-instances [https://datatracker.ietf.org/doc/html/rfc7950#section-9.9.3])

pkg/tree/validation_entry_must.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ func (s *sharedEntryAttributes) validateMustStatements(ctx context.Context, resu
4343
lexer.Parse()
4444
prog, err := lexer.CreateProgram(exprStr)
4545
if err != nil {
46-
resultChan <- types.NewValidationResultEntry(s.leafVariants.GetHighestPrecedence(false, false).Owner(), err, types.ValidationResultEntryTypeError)
46+
owner := "unknown"
47+
highest := s.leafVariants.GetHighestPrecedence(false, false, false)
48+
if highest != nil {
49+
owner = highest.Owner()
50+
}
51+
resultChan <- types.NewValidationResultEntry(owner, err, types.ValidationResultEntryTypeError)
4752
return
4853
}
4954
machine := xpath.NewMachine(exprStr, prog, exprStr)
@@ -66,7 +71,10 @@ func (s *sharedEntryAttributes) validateMustStatements(ctx context.Context, resu
6671
owner := "unknown"
6772
// must statement might be assigned on a container, hence we might not have any LeafVariants
6873
if s.leafVariants.Length() > 0 {
69-
owner = s.leafVariants.GetHighestPrecedence(false, true).Owner()
74+
highest := s.leafVariants.GetHighestPrecedence(false, false, false)
75+
if highest != nil {
76+
owner = highest.Owner()
77+
}
7078
}
7179
resultChan <- types.NewValidationResultEntry(owner, err, types.ValidationResultEntryTypeError)
7280
}

pkg/tree/visitor_blame_config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (b *BlameConfigVisitor) Visit(ctx context.Context, e Entry) error {
3333
skipAdd := false
3434

3535
// process Value
36-
highestLe := e.GetLeafVariantEntries().GetHighestPrecedence(false, true)
36+
highestLe := e.GetLeafVariantEntries().GetHighestPrecedence(false, true, true)
3737
if highestLe != nil {
3838
if highestLe.Update.Owner() != DefaultsIntentName || b.includeDefaults {
3939
result.SetValue(highestLe.Update.Value()).SetOwner(highestLe.Update.Owner())

0 commit comments

Comments
 (0)