Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Unified Diff: go/src/infra/appengine/test-results/model/merge.go

Issue 2231393002: test-results: Add merge and trim methods (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Fix typo in comment Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: go/src/infra/appengine/test-results/model/merge.go
diff --git a/go/src/infra/appengine/test-results/model/merge.go b/go/src/infra/appengine/test-results/model/merge.go
new file mode 100644
index 0000000000000000000000000000000000000000..72d2d53742d6bc09f5af3dc37ac6d187ccdb74ec
--- /dev/null
+++ b/go/src/infra/appengine/test-results/model/merge.go
@@ -0,0 +1,167 @@
+package model
martiniss 2016/08/12 00:14:24 I don't see the need for a merge.go file; why don'
nishanths 2016/08/12 02:37:39 As discussed offline, will move the contents of me
nishanths 2016/08/16 01:01:53 Done in patch set 7.
+
+import "errors"
+
+var (
+ // ErrBuildNumberConflict is returned when the build numbers
+ // are the same when merging.
+ ErrBuildNumberConflict = errors.New("build number conflict")
martiniss 2016/08/12 00:14:24 It's not obvious to me from reading this file why
nishanths 2016/08/12 02:37:39 Done.
+
+ // ErrBuilderNameConflict is returned when the builder names
+ // do not match when merging.
+ ErrBuilderNameConflict = errors.New("builder name conflict")
+)
+
+// Merge merges x into ar. After merging, ar's fields may reference the same
+// objects referenced by x.
+func (ar *AggregateResult) Merge(x *AggregateResult) error {
martiniss 2016/08/12 00:14:24 nit: "other" is a bit more descriptive than "x".
nishanths 2016/08/12 02:37:39 Done, thanks.
+ if ar == nil {
+ return errors.New("model: Merge: nil *AggregateResult")
+ }
+ if ar.Builder != x.Builder {
+ return ErrBuilderNameConflict
+ }
+ if ar.BuilderInfo == nil {
+ ar.BuilderInfo = &BuilderInfo{}
+ }
+ ar.Version = ResultsVersion
+ return ar.BuilderInfo.Merge(x.BuilderInfo)
+}
+
+// Merge merges x into info. After merging, info's fields may reference the same
martiniss 2016/08/12 00:14:24 Does the reference comment matter? Would that ever
nishanths 2016/08/12 02:37:39 Removed, thanks.
+// objects referenced by x.
+func (info *BuilderInfo) Merge(x *BuilderInfo) error {
martiniss 2016/08/12 00:14:24 nit: "x" variable name.
nishanths 2016/08/12 02:37:39 Done: used "other".
+ if info == nil {
martiniss 2016/08/12 00:14:24 Why would info ever be nil?
nishanths 2016/08/12 02:37:39 Removed the check (also removed at similar locatio
+ return errors.New("model: Merge: nil *BuilderInfo")
+ }
+
+ if len(info.BuildNumbers) > 0 && len(x.BuildNumbers) > 0 {
+ if info.BuildNumbers[0] == x.BuildNumbers[0] {
+ return ErrBuildNumberConflict
+ }
+ }
+
+ info.SecondsEpoch = append(x.SecondsEpoch, info.SecondsEpoch...)
+ info.BlinkRevs = append(x.BlinkRevs, info.BlinkRevs...)
+ info.BuildNumbers = append(x.BuildNumbers, info.BuildNumbers...)
+ info.ChromeRevs = append(x.ChromeRevs, info.ChromeRevs...)
+
+ for k, v := range x.FailuresByType {
+ if info.FailuresByType == nil {
martiniss 2016/08/12 00:14:24 Move outside for loop.
nishanths 2016/08/12 02:37:39 Done.
+ info.FailuresByType = make(map[string][]int)
+ }
+ info.FailuresByType[k] = append(v, info.FailuresByType[k]...)
+ }
+
+ info.FailureMap = FailureLongNames
+
+ if info.Tests == nil {
+ info.Tests = AggregateTest{}
+ }
+
+ info.Tests.WalkLeaves(func(_ string, leaf *AggregateTestLeaf) {
+ leaf.Expected = nil
+ leaf.Bugs = nil
+ })
+
+ return info.Tests.Merge(x.Tests)
+}
+
+// Merge merges x into at. After merging, at's fields may reference the same
+// objects referenced by x.
+func (at *AggregateTest) Merge(x AggregateTest) error {
+ if at == nil {
+ return errors.New("model: Merge: nil *AggregateTest")
+ }
+
+ // Shallow copy but OK. We take care to not modify xcopy
+ // values; instead always create new objects
+ // and assign to xcopy[key].
+ xcopy := make(AggregateTest, len(x))
martiniss 2016/08/12 00:14:24 shouldn't this be make([]AggregateTest, len(x)) ?
nishanths 2016/08/12 02:37:39 AggregateTest is a map[string]Node.
+ for k, v := range x {
+ xcopy[k] = v
+ }
+
+ for k, v := range *at {
+ if _, ok := xcopy[k]; !ok {
+ switch v.(type) {
+ case *AggregateTestLeaf:
+ l := &AggregateTestLeaf{}
+ l.defaultFields()
+ xcopy[k] = l
+ case AggregateTest:
+ xcopy[k] = AggregateTest{}
+ }
+ }
+ }
+
+ for k, v := range xcopy {
+ // Key does not exist: assign entire subtree.
+ if _, ok := (*at)[k]; !ok {
+ if *at == nil {
+ *at = AggregateTest{}
+ }
+ (*at)[k] = v
+ continue
+ }
+
+ // Leaf node.
+ if leaf1, ok := (*at)[k].(*AggregateTestLeaf); ok {
+ leaf2, ok := v.(*AggregateTestLeaf)
+ if !ok {
+ return errors.New("model: Merge: expected *AggregateTestLeaf")
+ }
+ if err := leaf1.Merge(leaf2); err != nil {
+ return err
+ }
+ continue
+ }
+
+ // Not leaf node: merge subtree recursively.
+ at1, ok := (*at)[k].(AggregateTest)
+ if !ok {
+ return errors.New("model: Merge: expected AggregateTest")
+ }
+ at2, ok := v.(AggregateTest)
+ if !ok {
+ return errors.New("model: Merge: expected AggregateTest")
+ }
+ if err := at1.Merge(at2); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Merge merges x into leaf. After merging, leaf's fields may reference the same
+// objects referenced by x.
+func (leaf *AggregateTestLeaf) Merge(x *AggregateTestLeaf) error {
+ if leaf == nil {
martiniss 2016/08/12 00:14:24 Same comment; seems unnecessary
nishanths 2016/08/12 02:37:39 Done, removed check.
+ return errors.New("model: Merge: nil *AggregateTestLeaf")
+ }
+
+ // Bugs and Expected should come from from x only.
+ leaf.Bugs = x.Bugs
+ if len(x.Expected) == 1 && x.Expected[0] != "PASS" {
+ leaf.Expected = x.Expected
+ }
+
+ for _, r := range x.Results {
+ if len(leaf.Results) > 0 && r.Type == leaf.Results[0].Type {
+ leaf.Results[0].Count += r.Count
+ } else {
+ leaf.Results = append([]ResultSummary{r}, leaf.Results...)
+ }
+ }
+
+ for _, r := range x.Runtimes {
+ if len(leaf.Runtimes) > 0 && r.Runtime == leaf.Runtimes[0].Runtime {
+ leaf.Runtimes[0].Count += r.Count
+ } else {
+ leaf.Runtimes = append([]RuntimeSummary{r}, leaf.Runtimes...)
+ }
+ }
+
+ return nil
+}

Powered by Google App Engine
This is Rietveld 408576698