mirror of
https://github.com/F1bonacc1/process-compose.git
synced 2024-09-11 19:37:08 +03:00
Circular dependency check
This commit is contained in:
parent
9fb6eaa132
commit
08ddae986e
@ -8,18 +8,13 @@ processes:
|
|||||||
|
|
||||||
process2:
|
process2:
|
||||||
command: "echo process2"
|
command: "echo process2"
|
||||||
availability:
|
|
||||||
restart: "on_failure"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
process3:
|
process1:
|
||||||
condition: process_completed_successfully
|
condition: process_completed_successfully
|
||||||
|
|
||||||
process3:
|
process3:
|
||||||
command: "echo process3"
|
command: "echo process3"
|
||||||
availability:
|
depends_on:
|
||||||
restart: "on_failure"
|
process1:
|
||||||
backoff_seconds: 2
|
condition: process_completed_successfully
|
||||||
# depends_on:
|
|
||||||
# process1:
|
|
||||||
# condition: process_completed_successfully
|
|
||||||
|
|
||||||
|
11
fixtures-code/process-compose-non-circular.yaml
Normal file
11
fixtures-code/process-compose-non-circular.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
version: "0.5"
|
||||||
|
processes:
|
||||||
|
process1:
|
||||||
|
command: "echo process1"
|
||||||
|
|
||||||
|
process3:
|
||||||
|
command: "echo process3"
|
||||||
|
depends_on:
|
||||||
|
process1:
|
||||||
|
condition: process_completed_successfully
|
||||||
|
|
@ -130,28 +130,27 @@ func TestSystem_TestComposeChainExit(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//func TestSystem_TestComposeCircular(t *testing.T) {
|
func TestSystem_TestComposeCircular(t *testing.T) {
|
||||||
// fixture := filepath.Join("..", "..", "fixtures", "process-compose-circular.yaml")
|
fixture1 := filepath.Join("..", "..", "fixtures-code", "process-compose-circular.yaml")
|
||||||
// t.Run(fixture, func(t *testing.T) {
|
fixture2 := filepath.Join("..", "..", "fixtures-code", "process-compose-non-circular.yaml")
|
||||||
// project, err := loader.Load(&loader.LoaderOptions{
|
t.Run(fixture1, func(t *testing.T) {
|
||||||
// FileNames: []string{fixture},
|
_, err := loader.Load(&loader.LoaderOptions{
|
||||||
// })
|
FileNames: []string{fixture1},
|
||||||
// if err != nil {
|
})
|
||||||
// t.Errorf(err.Error())
|
if err == nil {
|
||||||
// return
|
t.Errorf("should fail on cirlcular dependency")
|
||||||
// }
|
return
|
||||||
// runner, err := NewProjectRunner(project, []string{}, false)
|
}
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf(err.Error())
|
_, err = loader.Load(&loader.LoaderOptions{
|
||||||
// return
|
FileNames: []string{fixture2},
|
||||||
// }
|
})
|
||||||
// exitCode := runner.Run()
|
if err != nil {
|
||||||
// want := 42
|
t.Errorf(err.Error())
|
||||||
// if want != exitCode {
|
return
|
||||||
// t.Errorf("Project.Run() = %v, want %v", exitCode, want)
|
}
|
||||||
// }
|
})
|
||||||
// })
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
func TestSystem_TestComposeScale(t *testing.T) {
|
func TestSystem_TestComposeScale(t *testing.T) {
|
||||||
fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-scale.yaml")
|
fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-scale.yaml")
|
||||||
|
@ -27,7 +27,7 @@ func Load(opts *LoaderOptions) (*types.Project, error) {
|
|||||||
opts.projects = append(opts.projects, p)
|
opts.projects = append(opts.projects, p)
|
||||||
}
|
}
|
||||||
mergedProject, err := merge(opts)
|
mergedProject, err := merge(opts)
|
||||||
mergedProject.ValidateAfterMerge()
|
err = mergedProject.ValidateAfterMerge()
|
||||||
return mergedProject, err
|
return mergedProject, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/f1bonacc1/process-compose/src/command"
|
"github.com/f1bonacc1/process-compose/src/command"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -14,9 +15,10 @@ func (p *Project) Validate() {
|
|||||||
p.validateProcessConfig()
|
p.validateProcessConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) ValidateAfterMerge() {
|
func (p *Project) ValidateAfterMerge() error {
|
||||||
p.assignDefaultProcessValues()
|
p.assignDefaultProcessValues()
|
||||||
p.cloneReplicas()
|
p.cloneReplicas()
|
||||||
|
return p.validateNoCircularDependencies()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) validateLogLevel() {
|
func (p *Project) validateLogLevel() {
|
||||||
@ -100,3 +102,41 @@ func (p *Project) cloneReplicas() {
|
|||||||
p.Processes[proc.ReplicaName] = proc
|
p.Processes[proc.ReplicaName] = proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Project) validateNoCircularDependencies() error {
|
||||||
|
visited := make(map[string]bool, len(p.Processes))
|
||||||
|
stack := make(map[string]bool)
|
||||||
|
for name := range p.Processes {
|
||||||
|
if !visited[name] {
|
||||||
|
if p.isCyclicHelper(name, visited, stack) {
|
||||||
|
return fmt.Errorf("circular dependency found in %s", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) isCyclicHelper(procName string, visited map[string]bool, stack map[string]bool) bool {
|
||||||
|
visited[procName] = true
|
||||||
|
stack[procName] = true
|
||||||
|
|
||||||
|
processes, err := p.getProcesses(procName)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, process := range processes {
|
||||||
|
dependencies := process.GetDependencies()
|
||||||
|
for _, neighbor := range dependencies {
|
||||||
|
if !visited[neighbor] {
|
||||||
|
if p.isCyclicHelper(neighbor, visited, stack) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if stack[neighbor] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[procName] = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user