diff --git a/server/model/proc.go b/server/model/proc.go index af81b4561b..6ed26d3170 100644 --- a/server/model/proc.go +++ b/server/model/proc.go @@ -71,17 +71,25 @@ func (p *Proc) IsParent() bool { // Tree creates a process tree from a flat process list. func Tree(procs []*Proc) ([]*Proc, error) { var nodes []*Proc - for _, proc := range procs { - if proc.PPID == 0 { - nodes = append(nodes, proc) - } else { - parent, err := findNode(nodes, proc.PPID) + + // init parent nodes + for i := range procs { + if procs[i].IsParent() { + nodes = append(nodes, procs[i]) + } + } + + // assign children to parrents + for i := range procs { + if !procs[i].IsParent() { + parent, err := findNode(nodes, procs[i].PPID) if err != nil { return nil, err } - parent.Children = append(parent.Children, proc) + parent.Children = append(parent.Children, procs[i]) } } + return nodes, nil } diff --git a/server/model/proc_test.go b/server/model/proc_test.go new file mode 100644 index 0000000000..5c876e4fd5 --- /dev/null +++ b/server/model/proc_test.go @@ -0,0 +1,69 @@ +// Copyright 2021 Woodpecker Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTree(t *testing.T) { + procs := []*Proc{{ + ID: 25, + PID: 2, + BuildID: 6, + PPID: 1, + PGID: 2, + Name: "clone", + State: StatusSuccess, + Error: "0", + }, { + ID: 24, + BuildID: 6, + PID: 1, + PPID: 0, + PGID: 1, + Name: "lint", + State: StatusFailure, + Error: "1", + }, { + ID: 26, + BuildID: 6, + PID: 3, + PPID: 1, + PGID: 3, + Name: "lint", + State: StatusFailure, + Error: "1", + }} + procs, err := Tree(procs) + assert.NoError(t, err) + assert.Len(t, procs, 1) + assert.Len(t, procs[0].Children, 2) + + procs = []*Proc{{ + ID: 25, + PID: 2, + BuildID: 6, + PPID: 1, + PGID: 2, + Name: "clone", + State: StatusSuccess, + Error: "0", + }} + _, err = Tree(procs) + assert.Error(t, err) +}