// latestBuild returns the latest build for the provided buildConfig. func latestBuild(g osgraph.Graph, bc graph.Node) *buildgraph.BuildNode { builds := []*buildapi.Build{} buildNameToNode := map[string]*buildgraph.BuildNode{} for _, buildNode := range g.SuccessorNodesByEdgeKind(bc, buildedges.BuildEdgeKind) { build := buildNode.(*buildgraph.BuildNode) buildNameToNode[build.Build.Name] = build builds = append(builds, build.Build) } if len(builds) == 0 { return nil } sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(builds))) return buildNameToNode[builds[0].Name] }
func (o *perBuildConfigResolver) Resolve() ([]*buildapi.Build, error) { buildConfigs, err := o.dataSet.ListBuildConfigs() if err != nil { return nil, err } completeStates := sets.NewString(string(buildapi.BuildPhaseComplete)) failedStates := sets.NewString(string(buildapi.BuildPhaseFailed), string(buildapi.BuildPhaseError), string(buildapi.BuildPhaseCancelled)) prunableBuilds := []*buildapi.Build{} for _, buildConfig := range buildConfigs { builds, err := o.dataSet.ListBuildsByBuildConfig(buildConfig) if err != nil { return nil, err } var completeBuilds, failedBuilds []*buildapi.Build for _, build := range builds { if completeStates.Has(string(build.Status.Phase)) { completeBuilds = append(completeBuilds, build) } else if failedStates.Has(string(build.Status.Phase)) { failedBuilds = append(failedBuilds, build) } } sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(completeBuilds))) sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(failedBuilds))) if o.keepComplete >= 0 && o.keepComplete < len(completeBuilds) { prunableBuilds = append(prunableBuilds, completeBuilds[o.keepComplete:]...) } if o.keepFailed >= 0 && o.keepFailed < len(failedBuilds) { prunableBuilds = append(prunableBuilds, failedBuilds[o.keepFailed:]...) } } return prunableBuilds, nil }
func TestPerBuildConfigResolver(t *testing.T) { BuildPhaseOptions := []buildapi.BuildPhase{ buildapi.BuildPhaseCancelled, buildapi.BuildPhaseComplete, buildapi.BuildPhaseError, buildapi.BuildPhaseFailed, buildapi.BuildPhaseNew, buildapi.BuildPhasePending, buildapi.BuildPhaseRunning, } buildConfigs := []*buildapi.BuildConfig{ mockBuildConfig("a", "build-config-1"), mockBuildConfig("b", "build-config-2"), } buildsPerStatus := 100 builds := []*buildapi.Build{} for _, buildConfig := range buildConfigs { for _, BuildPhaseOption := range BuildPhaseOptions { for i := 0; i < buildsPerStatus; i++ { build := withStatus(mockBuild(buildConfig.Namespace, fmt.Sprintf("%v-%v-%v", buildConfig.Name, BuildPhaseOption, i), buildConfig), BuildPhaseOption) builds = append(builds, build) } } } now := util.Now() for i := range builds { creationTimestamp := util.NewTime(now.Time.Add(-1 * time.Duration(i) * time.Hour)) builds[i].CreationTimestamp = creationTimestamp } // test number to keep at varying ranges for keep := 0; keep < buildsPerStatus*2; keep++ { dataSet := NewDataSet(buildConfigs, builds) expectedNames := sets.String{} buildCompleteStatusFilterSet := sets.NewString(string(buildapi.BuildPhaseComplete)) buildFailedStatusFilterSet := sets.NewString(string(buildapi.BuildPhaseCancelled), string(buildapi.BuildPhaseError), string(buildapi.BuildPhaseFailed)) for _, buildConfig := range buildConfigs { buildItems, err := dataSet.ListBuildsByBuildConfig(buildConfig) if err != nil { t.Errorf("Unexpected err %v", err) } var completeBuilds, failedBuilds []*buildapi.Build for _, build := range buildItems { if buildCompleteStatusFilterSet.Has(string(build.Status.Phase)) { completeBuilds = append(completeBuilds, build) } else if buildFailedStatusFilterSet.Has(string(build.Status.Phase)) { failedBuilds = append(failedBuilds, build) } } sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(completeBuilds))) sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(failedBuilds))) var purgeComplete, purgeFailed []*buildapi.Build if keep >= 0 && keep < len(completeBuilds) { purgeComplete = completeBuilds[keep:] } if keep >= 0 && keep < len(failedBuilds) { purgeFailed = failedBuilds[keep:] } for _, build := range purgeComplete { expectedNames.Insert(build.Name) } for _, build := range purgeFailed { expectedNames.Insert(build.Name) } } resolver := NewPerBuildConfigResolver(dataSet, keep, keep) results, err := resolver.Resolve() if err != nil { t.Errorf("Unexpected error %v", err) } foundNames := sets.String{} for _, result := range results { foundNames.Insert(result.Name) } if len(foundNames) != len(expectedNames) || !expectedNames.HasAll(foundNames.List()...) { expectedValues := expectedNames.List() actualValues := foundNames.List() sort.Strings(expectedValues) sort.Strings(actualValues) t.Errorf("keep %v\n, expected \n\t%v\n, actual \n\t%v\n", keep, expectedValues, actualValues) } } }