in pilot/pkg/xds/deltatest.go [43:145]
func (s *DiscoveryServer) compareDiff(
con *Connection,
w *model.WatchedResource,
full model.Resources,
resp model.Resources,
deleted model.DeletedResources,
usedDelta bool,
delta model.ResourceDelta,
) {
current := con.Watched(w.TypeUrl).LastResources
if current == nil {
log.Debugf("ADS:%s: resources initialized", v3.GetShortType(w.TypeUrl))
return
}
if resp == nil && deleted == nil && len(full) == 0 {
// TODO: it suspicious full is never nil - are there case where we should be deleting everything?
// Both SotW and Delta did not respond, nothing to compare
return
}
newByName := map[string]*discovery.Resource{}
for _, v := range full {
newByName[v.Name] = v
}
curByName := map[string]*discovery.Resource{}
for _, v := range current {
curByName[v.Name] = v
}
watched := sets.New(w.ResourceNames...)
details := fmt.Sprintf("last:%v sotw:%v delta:%v-%v", len(current), len(full), len(resp), len(deleted))
wantDeleted := sets.New()
wantChanged := sets.New()
wantUnchanged := sets.New()
for _, c := range current {
n := newByName[c.Name]
if n == nil {
// We had a resource, but SotW didn't generate it.
if watched.Contains(c.Name) {
// We only need to delete it if Envoy is watching. Otherwise, it may have simply unsubscribed
wantDeleted.Insert(c.Name)
}
} else if diff := cmp.Diff(c.Resource, n.Resource, protocmp.Transform()); diff != "" {
// Resource was modified
wantChanged.Insert(c.Name)
} else {
// No diff. Ideally delta doesn't send any update here
wantUnchanged.Insert(c.Name)
}
}
for _, v := range full {
if _, f := curByName[v.Name]; !f {
// Resource is added. Delta doesn't distinguish add vs update, so just put it with changed
wantChanged.Insert(v.Name)
}
}
gotDeleted := sets.New()
if usedDelta {
gotDeleted.InsertAll(deleted...)
}
gotChanged := sets.New()
for _, v := range resp {
gotChanged.Insert(v.Name)
}
// BUGS
extraDeletes := gotDeleted.Difference(wantDeleted).SortedList()
missedDeletes := wantDeleted.Difference(gotDeleted).SortedList()
missedChanges := wantChanged.Difference(gotChanged).SortedList()
// Optimization Potential
extraChanges := gotChanged.Difference(wantChanged).Difference(knownOptimizationGaps).SortedList()
if len(delta.Subscribed) > 0 {
// Delta is configured to build only the request resources. Make sense we didn't build anything extra
if !wantChanged.SupersetOf(gotChanged) {
log.Errorf("%s: TEST for node:%s unexpected resources: %v %v", v3.GetShortType(w.TypeUrl), con.proxy.ID, details, wantChanged.Difference(gotChanged))
}
// Still make sure we didn't delete anything extra
if len(extraDeletes) > 0 {
log.Errorf("%s: TEST for node:%s unexpected deletions: %v %v", v3.GetShortType(w.TypeUrl), con.proxy.ID, details, extraDeletes)
}
} else {
if len(extraDeletes) > 0 {
log.Errorf("%s: TEST for node:%s unexpected deletions: %v %v", v3.GetShortType(w.TypeUrl), con.proxy.ID, details, extraDeletes)
}
if len(missedDeletes) > 0 {
log.Errorf("%s: TEST for node:%s missed deletions: %v %v", v3.GetShortType(w.TypeUrl), con.proxy.ID, details, missedDeletes)
}
if len(missedChanges) > 0 {
log.Errorf("%s: TEST for node:%s missed changes: %v %v", v3.GetShortType(w.TypeUrl), con.proxy.ID, details, missedChanges)
}
if len(extraChanges) > 0 {
if usedDelta {
log.Infof("%s: TEST for node:%s missed possible optimization: %v. deleted:%v changed:%v",
v3.GetShortType(w.TypeUrl), con.proxy.ID, extraChanges, len(gotDeleted), len(gotChanged))
} else {
log.Debugf("%s: TEST for node:%s missed possible optimization: %v. deleted:%v changed:%v",
v3.GetShortType(w.TypeUrl), con.proxy.ID, extraChanges, len(gotDeleted), len(gotChanged))
}
}
}
}