Skip to content

Commit

Permalink
Cleaning, release prep, tests work
Browse files Browse the repository at this point in the history
  • Loading branch information
baalimago committed Mar 2, 2024
1 parent e96b387 commit 0911242
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 36 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 1.2
* Upgraded worker pattern to guarantee amount of runs
* Introduced flag retryOnFail
- If set, the task will be retried if it fails
- If set to false, the task will simply be started -n amount of times
- Previous behavoiur were to simply repeat a command -n amonut of times, now the default is to successfully run the task -n amount of times (felt more useful)
* Upgraded progress print to include amount of failures

## 1.1
* Changed default behaviour of result from STDOUT to HIDDEN
* Changed name of REPORT_FILE -> FILE
Expand Down
3 changes: 3 additions & 0 deletions configured_oper.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type configuredOper struct {
amIdleWorkers int
amSuccess int
workPlanMu *sync.Mutex
retryOnFail bool
}

type userQuitError string
Expand Down Expand Up @@ -60,6 +61,7 @@ func New(am, workers int,
outputFileMode string,
increment bool,
resultFlag string,
retryOnFail bool,
) (configuredOper, error) {
shouldHaveReportFile := pMode == output.BOTH || pMode == output.FILE ||
oMode == output.BOTH || oMode == output.FILE
Expand Down Expand Up @@ -89,6 +91,7 @@ func New(am, workers int,
workerWg: &sync.WaitGroup{},
amIdleWorkers: workers,
workPlanMu: &sync.Mutex{},
retryOnFail: retryOnFail,
}

c.workerWg.Add(workers)
Expand Down
57 changes: 32 additions & 25 deletions configured_oper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"sync"
"testing"
"time"

"github.com/baalimago/go_away_boilerplate/pkg/testboil"
"github.com/baalimago/repeater/internal/output"
Expand All @@ -32,14 +33,15 @@ func Test_configuredOper(t *testing.T) {
testFile := testboil.CreateTestFile(t, "tFile")
outputString := "test"
co := configuredOper{
am: 1,
args: []string{"printf", fmt.Sprintf("%v", outputString)},
color: false,
progress: output.HIDDEN,
output: outputMode,
outputFile: testFile,
workPlanMu: &sync.Mutex{},
workerWg: &sync.WaitGroup{},
am: 1,
args: []string{"printf", fmt.Sprintf("%v", outputString)},
color: false,
progress: output.HIDDEN,
output: outputMode,
outputFile: testFile,
amIdleWorkers: 1,
workPlanMu: &sync.Mutex{},
workerWg: &sync.WaitGroup{},
}
co.workerWg.Add(1)

Expand All @@ -66,13 +68,14 @@ func Test_configuredOper(t *testing.T) {
runTest := func(outputMode output.Mode, wantProgress bool) {
testFile := testboil.CreateTestFile(t, "tFile")
outputString := "something"
progFormat := "%v/%v"
progFormat := "%v/%v/%v"
co := configuredOper{
am: 1,
args: []string{"printf", fmt.Sprintf("%v", outputString)},
color: false,
progressFormat: progFormat,
progress: outputMode,
amIdleWorkers: 1,
output: output.HIDDEN,
outputFile: testFile,
workPlanMu: &sync.Mutex{},
Expand All @@ -88,7 +91,7 @@ func Test_configuredOper(t *testing.T) {
if err != nil {
t.Fatalf("failed to get report file: %v", err)
}
wantStr := fmt.Sprintf("%v\n", fmt.Sprintf(progFormat, 0, 1))
wantStr := fmt.Sprintf("%v", fmt.Sprintf(progFormat, 1, 0, 1))
if got != wantStr && wantProgress {
t.Fatalf("for: %s, expected: %v, got: %v", outputMode, wantStr, got)
} else if got == wantStr && !wantProgress {
Expand All @@ -102,12 +105,13 @@ func Test_configuredOper(t *testing.T) {
})

t.Run("it should follow format set in progressFormat", func(t *testing.T) {
wantFormat := "lol%vtest%v"
wantFormat := "lol%vtest%vhere%v"
testFile := testboil.CreateTestFile(t, "testFile")
c := configuredOper{
am: 1,
args: []string{"true"},
color: false,
amIdleWorkers: 1,
progress: output.FILE,
progressFormat: wantFormat,
output: output.HIDDEN,
Expand All @@ -124,7 +128,7 @@ func Test_configuredOper(t *testing.T) {
if err != nil {
t.Fatalf("failed to get report file: %v", err)
}
want := fmt.Sprintf("%v\n", fmt.Sprintf(wantFormat, 0, 1))
want := fmt.Sprintf("%v", fmt.Sprintf(wantFormat, 1, 0, 1))
if got != want {
t.Fatalf("expected: %v, got: %v", want, got)
}
Expand All @@ -136,10 +140,11 @@ func Test_results(t *testing.T) {
// This should ouput "test"
want := "test"
c := configuredOper{
am: 1,
args: []string{"printf", want},
workPlanMu: &sync.Mutex{},
workerWg: &sync.WaitGroup{},
am: 1,
args: []string{"printf", want},
workPlanMu: &sync.Mutex{},
amIdleWorkers: 1,
workerWg: &sync.WaitGroup{},
}
c.workerWg.Add(1)

Expand All @@ -160,12 +165,14 @@ func Test_results(t *testing.T) {
c := configuredOper{
am: wantAm,
// Date is most likely to exist in most OS's running this test
args: []string{"date"},
workerWg: &sync.WaitGroup{},
workPlanMu: &sync.Mutex{},
args: []string{"date"},
workerWg: &sync.WaitGroup{},
workPlanMu: &sync.Mutex{},
amIdleWorkers: 1,
}
c.workerWg.Add(1)
c.run(context.Background())
time.Sleep(time.Millisecond)
gotLen := len(c.results)
// ensure that the correc amount is output
if gotLen != wantAm {
Expand All @@ -186,7 +193,7 @@ func Test_results(t *testing.T) {
func Test_configuredOper_New(t *testing.T) {
t.Run("it should return incrementConfigError if increment is true and no args contains 'INC'", func(t *testing.T) {
args := []string{"test", "abc"}
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "")
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "", false)
if gotErr == nil {
t.Fatal("expected to get error, got nil")
}
Expand All @@ -205,15 +212,15 @@ func Test_configuredOper_New(t *testing.T) {

t.Run("it should not return an error if increment is true and one argument is 'INC'", func(t *testing.T) {
args := []string{"test", "abc", "INC"}
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "")
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "", false)
if gotErr != nil {
t.Fatalf("expected nil, got: %v", gotErr)
}
})

t.Run("it should not return an error if increment is true and one argument contains 'INC'", func(t *testing.T) {
args := []string{"test", "abc", "another-argument/INC"}
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "")
_, gotErr := New(0, 0, args, output.HIDDEN, "testing", output.HIDDEN, "", "", true, "", false)
if gotErr != nil {
t.Fatalf("expected nil, got: %v", gotErr)
}
Expand All @@ -223,7 +230,7 @@ func Test_configuredOper_New(t *testing.T) {
am := 1
workers := 2
args := []string{"test", "abc"}
_, gotErr := New(am, workers, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "")
_, gotErr := New(am, workers, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "", false)
if gotErr == nil {
t.Fatal("expected to get error, got nil")
}
Expand All @@ -237,14 +244,14 @@ func Test_configuredOper_New(t *testing.T) {

t.Run("it should not return an error if the number of workers is lower than the number of times to repeat the command", func(t *testing.T) {
args := []string{"test", "abc"}
_, gotErr := New(2, 1, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "")
_, gotErr := New(2, 1, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "", false)
if gotErr != nil {
t.Fatalf("expected nil, got: %v", gotErr)
}
})
t.Run("it should not return an error if the number of workers is equal to the number of times to repeat the command", func(t *testing.T) {
args := []string{"test", "abc"}
_, gotErr := New(2, 2, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "")
_, gotErr := New(2, 2, args, output.HIDDEN, "testing", output.HIDDEN, "", "", false, "", false)
if gotErr != nil {
t.Fatalf("expected nil, got: %v", gotErr)
}
Expand Down
12 changes: 4 additions & 8 deletions configured_oper_work.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (c *configuredOper) setupWorkers(workCtx context.Context, workChan chan int
// The current amount of workers is enough to reach the requested
// amount of tasks in parallel so kill off this worker to not overshoot
// the amount of repetitions
if workingWorkrs+c.amSuccess >= requestedTasks {
if workingWorkrs+c.amSuccess >= requestedTasks || (!c.retryOnFail && taskIdx >= requestedTasks) {
c.workerWg.Done()
c.workPlanMu.Unlock()
return
Expand Down Expand Up @@ -121,13 +121,9 @@ func (c *configuredOper) runResultCollector(ctx context.Context, resultChan chan
}

emptyResChan := func() {
for {
select {
case res := <-resultChan:
handleRes(res)
default:
return
}
for len(resultChan) > 0 {
res := <-resultChan
handleRes(res)
}
}
for {
Expand Down
13 changes: 12 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
statisticsFlag = flag.Bool("statistics", true, "Set to true if you don't wish to see statistics of the repeated command.")
incrementFlag = flag.Bool("increment", false, "Set to true and add an argument 'INC', to have 'INC' be replaced with the iteration. If increment == true && 'INC' is not set, repeater will panic.")
resultFlag = flag.String("result", "", "Set this to some filename and get a json-formated output of all the performed tasks. This output is the basis of the statistics.")
retryOnFailFlag = flag.Bool("retryOnFail", false, "Set to true to retry failed commands, effectively making repeate run until all commands are successful.")
)

func main() {
Expand All @@ -39,7 +40,17 @@ func main() {
printErr(fmt.Sprintf("error: %v", "you need to supply at least 1 argument\n"))
os.Exit(1)
}
c, err := New(*amRunsFlag, *workersFlag, args, output.New(progressFlag), *progressFormatFlag, output.New(outputFlag), *fileFlag, *fileModeFlag, *incrementFlag, *resultFlag)
c, err := New(
*amRunsFlag,
*workersFlag,
args, output.New(progressFlag),
*progressFormatFlag,
output.New(outputFlag),
*fileFlag,
*fileModeFlag,
*incrementFlag,
*resultFlag,
*retryOnFailFlag)

if *verboseFlag {
fmt.Printf("Operation:\n%v\n------\n", &c)
Expand Down
3 changes: 1 addition & 2 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func Test_do(t *testing.T) {
}
})

for i := 0; i < 1000; i++ {
for i := 0; i < 10; i++ {
t.Run("it should run command am amount of times, 10 workers", func(t *testing.T) {
expectedCalls := 123
amWorkers := 10
Expand All @@ -61,5 +61,4 @@ func Test_do(t *testing.T) {
}
})
}

}

0 comments on commit 0911242

Please sign in to comment.