From 9fb6eaa132f8e7a6897ba1cb6e01123e2fe016d4 Mon Sep 17 00:00:00 2001 From: Berger Eugene Date: Sat, 8 Jul 2023 02:01:48 +0300 Subject: [PATCH] Scale tests --- .../process-compose-chain-exit.yaml | 0 .../process-compose-chain.yaml | 0 fixtures-code/process-compose-circular.yaml | 25 +++ fixtures-code/process-compose-scale.yaml | 23 +++ .../process-compose-with-log.yaml | 0 src/app/process.go | 18 ++- src/app/system_test.go | 149 ++++++++++++++++-- 7 files changed, 198 insertions(+), 17 deletions(-) rename {fixtures => fixtures-code}/process-compose-chain-exit.yaml (100%) rename {fixtures => fixtures-code}/process-compose-chain.yaml (100%) create mode 100644 fixtures-code/process-compose-circular.yaml create mode 100644 fixtures-code/process-compose-scale.yaml rename {fixtures => fixtures-code}/process-compose-with-log.yaml (100%) diff --git a/fixtures/process-compose-chain-exit.yaml b/fixtures-code/process-compose-chain-exit.yaml similarity index 100% rename from fixtures/process-compose-chain-exit.yaml rename to fixtures-code/process-compose-chain-exit.yaml diff --git a/fixtures/process-compose-chain.yaml b/fixtures-code/process-compose-chain.yaml similarity index 100% rename from fixtures/process-compose-chain.yaml rename to fixtures-code/process-compose-chain.yaml diff --git a/fixtures-code/process-compose-circular.yaml b/fixtures-code/process-compose-circular.yaml new file mode 100644 index 0000000..83a46c7 --- /dev/null +++ b/fixtures-code/process-compose-circular.yaml @@ -0,0 +1,25 @@ +version: "0.5" +processes: + process1: + command: "echo process1" + depends_on: + process2: + condition: process_completed_successfully + + process2: + command: "echo process2" + availability: + restart: "on_failure" + depends_on: + process3: + condition: process_completed_successfully + + process3: + command: "echo process3" + availability: + restart: "on_failure" + backoff_seconds: 2 +# depends_on: +# process1: +# condition: process_completed_successfully + diff --git a/fixtures-code/process-compose-scale.yaml b/fixtures-code/process-compose-scale.yaml new file mode 100644 index 0000000..8ed06b3 --- /dev/null +++ b/fixtures-code/process-compose-scale.yaml @@ -0,0 +1,23 @@ +version: "0.5" +processes: + process1: + command: "echo process1 ; sleep 2" + replicas: 2 + depends_on: + process2: + condition: process_completed_successfully + + process2: + command: "echo process2; sleep 2" + availability: + restart: "on_failure" + depends_on: + process3: + condition: process_completed_successfully + + process3: + command: "echo process3; sleep 2" + availability: + restart: "on_failure" + backoff_seconds: 2 + diff --git a/fixtures/process-compose-with-log.yaml b/fixtures-code/process-compose-with-log.yaml similarity index 100% rename from fixtures/process-compose-with-log.yaml rename to fixtures-code/process-compose-with-log.yaml diff --git a/src/app/process.go b/src/app/process.go index 641d004..6cb1919 100644 --- a/src/app/process.go +++ b/src/app/process.go @@ -45,6 +45,7 @@ type Process struct { logger pclog.PcLogger command Commander done bool + timeMutex sync.Mutex startTime time.Time liveProber *health.Prober readyProber *health.Prober @@ -96,8 +97,10 @@ func (p *Process) run() int { return 1 } - p.startTime = time.Now() + p.setStartTime(time.Now()) + p.stateMtx.Lock() p.procState.Pid = p.command.Pid() + p.stateMtx.Unlock() log.Info().Msgf("%s started", p.getName()) p.startProbes() @@ -331,13 +334,24 @@ func (p *Process) getCommand() string { func (p *Process) updateProcState() { if p.isRunning() { - dur := time.Since(p.startTime) + dur := time.Since(p.getStartTime()) p.procState.SystemTime = durationToString(dur) p.procState.Age = dur p.procState.IsRunning = true p.procState.Name = p.getName() } } +func (p *Process) setStartTime(startTime time.Time) { + p.timeMutex.Lock() + defer p.timeMutex.Unlock() + p.startTime = startTime +} + +func (p *Process) getStartTime() time.Time { + p.timeMutex.Lock() + defer p.timeMutex.Unlock() + return p.startTime +} func (p *Process) handleInput(pipe io.WriteCloser) { reader := bufio.NewReader(os.Stdin) diff --git a/src/app/system_test.go b/src/app/system_test.go index 9f13408..81aaba7 100644 --- a/src/app/system_test.go +++ b/src/app/system_test.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" "reflect" - "strings" "testing" + "time" ) func getFixtures() []string { @@ -20,17 +20,6 @@ func getFixtures() []string { func TestSystem_TestFixtures(t *testing.T) { fixtures := getFixtures() for _, fixture := range fixtures { - - if strings.Contains(fixture, "process-compose-with-log.yaml") { - //there is a dedicated test for that TestSystem_TestComposeWithLog - continue - } - - if strings.Contains(fixture, "process-compose-chain-exit.yaml") { - //there is a dedicated test for that TestSystem_TestComposeWithLog - continue - } - t.Run(fixture, func(t *testing.T) { project, err := loader.Load(&loader.LoaderOptions{ FileNames: []string{fixture}, @@ -50,7 +39,7 @@ func TestSystem_TestFixtures(t *testing.T) { } func TestSystem_TestComposeWithLog(t *testing.T) { - fixture := filepath.Join("..", "..", "fixtures", "process-compose-with-log.yaml") + fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-with-log.yaml") t.Run(fixture, func(t *testing.T) { project, err := loader.Load(&loader.LoaderOptions{ FileNames: []string{fixture}, @@ -83,7 +72,7 @@ func TestSystem_TestComposeWithLog(t *testing.T) { } func TestSystem_TestComposeChain(t *testing.T) { - fixture := filepath.Join("..", "..", "fixtures", "process-compose-chain.yaml") + fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-chain.yaml") t.Run(fixture, func(t *testing.T) { project, err := loader.Load(&loader.LoaderOptions{ FileNames: []string{fixture}, @@ -119,7 +108,7 @@ func TestSystem_TestComposeChain(t *testing.T) { } func TestSystem_TestComposeChainExit(t *testing.T) { - fixture := filepath.Join("..", "..", "fixtures", "process-compose-chain-exit.yaml") + fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-chain-exit.yaml") t.Run(fixture, func(t *testing.T) { project, err := loader.Load(&loader.LoaderOptions{ FileNames: []string{fixture}, @@ -140,3 +129,133 @@ func TestSystem_TestComposeChainExit(t *testing.T) { } }) } + +//func TestSystem_TestComposeCircular(t *testing.T) { +// fixture := filepath.Join("..", "..", "fixtures", "process-compose-circular.yaml") +// t.Run(fixture, func(t *testing.T) { +// project, err := loader.Load(&loader.LoaderOptions{ +// FileNames: []string{fixture}, +// }) +// if err != nil { +// t.Errorf(err.Error()) +// return +// } +// runner, err := NewProjectRunner(project, []string{}, false) +// if err != nil { +// t.Errorf(err.Error()) +// return +// } +// exitCode := runner.Run() +// want := 42 +// if want != exitCode { +// t.Errorf("Project.Run() = %v, want %v", exitCode, want) +// } +// }) +//} + +func TestSystem_TestComposeScale(t *testing.T) { + fixture := filepath.Join("..", "..", "fixtures-code", "process-compose-scale.yaml") + t.Run(fixture, func(t *testing.T) { + project, err := loader.Load(&loader.LoaderOptions{ + FileNames: []string{fixture}, + }) + if err != nil { + t.Errorf(err.Error()) + return + } + runner, err := NewProjectRunner(project, []string{}, false) + if err != nil { + t.Errorf(err.Error()) + return + } + go runner.Run() + time.Sleep(200 * time.Millisecond) + states, err := runner.GetProcessesState() + if err != nil { + t.Errorf(err.Error()) + return + } + want := 4 + if len(states.States) != want { + t.Errorf("len(states.States) = %d, want %d", len(states.States), want) + } + + //scale to 10 + err = runner.ScaleProcess("process1-0", 10) + if err != nil { + t.Errorf(err.Error()) + return + } + states, err = runner.GetProcessesState() + if err != nil { + t.Errorf(err.Error()) + return + } + want = 12 + if len(states.States) != want { + t.Errorf("len(states.States) = %d, want %d", len(states.States), want) + } + + //check scale to 0 - should fail + err = runner.ScaleProcess("process1-00", 0) + if err == nil { + t.Errorf("should fail on scale 0") + return + } + + //scale to 1 and new name with -00 + err = runner.ScaleProcess("process1-00", 1) + if err != nil { + t.Errorf(err.Error()) + return + } + states, err = runner.GetProcessesState() + if err != nil { + t.Errorf(err.Error()) + return + } + want = 3 + if len(states.States) != want { + t.Errorf("len(states.States) = %d, want %d", len(states.States), want) + } + + //scale to 5 process2 + err = runner.ScaleProcess("process2", 5) + if err != nil { + t.Errorf(err.Error()) + return + } + states, err = runner.GetProcessesState() + if err != nil { + t.Errorf(err.Error()) + return + } + want = 7 + if len(states.States) != want { + t.Errorf("len(states.States) = %d, want %d", len(states.States), want) + } + + //check no change + err = runner.ScaleProcess("process2-0", 5) + if err != nil { + t.Errorf(err.Error()) + return + } + states, err = runner.GetProcessesState() + if err != nil { + t.Errorf(err.Error()) + return + } + want = 7 + if len(states.States) != want { + t.Errorf("len(states.States) = %d, want %d", len(states.States), want) + } + + //wrong process name + err = runner.ScaleProcess("process2-00", 5) + if err == nil { + t.Errorf("should fail on wrong process name") + return + } + }) +}