summaryrefslogtreecommitdiff
path: root/executor
diff options
context:
space:
mode:
authorWill Hawkins <[email protected]>2023-12-13 19:56:03 -0500
committerWill Hawkins <[email protected]>2024-01-04 19:10:37 -0500
commitf3990f950277c2f61e0e1811b4b8a81fc0219da4 (patch)
tree6969e4ac2c4e94e75fe2e0c5581da5c07785dce8 /executor
parent552f01ad73248474553ce471695745db58c862ea (diff)
[Feature] Support for testing upload/download in parallel
Use the `--rpm.parallel` to test in parallel mode. The default testing mode is serial. Signed-off-by: Will Hawkins <[email protected]>
Diffstat (limited to 'executor')
-rw-r--r--executor/executor.go53
-rw-r--r--executor/executor_test.go56
2 files changed, 109 insertions, 0 deletions
diff --git a/executor/executor.go b/executor/executor.go
new file mode 100644
index 0000000..22c1235
--- /dev/null
+++ b/executor/executor.go
@@ -0,0 +1,53 @@
+package executor
+
+import (
+ "sync"
+)
+
+type ExecutionMethod int
+
+const (
+ Parallel ExecutionMethod = iota
+ Serial
+)
+
+type ExecutionUnit func()
+
+func (ep ExecutionMethod) ToString() string {
+ switch ep {
+ case Parallel:
+ return "Parallel"
+ case Serial:
+ return "Serial"
+ }
+ return "Unrecognized execution method"
+}
+
+func Execute(executionMethod ExecutionMethod, executionUnits []ExecutionUnit) *sync.WaitGroup {
+ waiter := &sync.WaitGroup{}
+
+ // Make sure that we Add to the wait group all the execution units
+ // before starting to run any -- there is a potential race condition
+ // otherwise.
+ (*waiter).Add(len(executionUnits))
+
+ for _, executionUnit := range executionUnits {
+ // Stupid capture in Go! Argh.
+ executionUnit := executionUnit
+
+ invoker := func() {
+ executionUnit()
+ (*waiter).Done()
+ }
+ switch executionMethod {
+ case Parallel:
+ go invoker()
+ case Serial:
+ invoker()
+ default:
+ panic("Invalid execution method value given.")
+ }
+ }
+
+ return waiter
+}
diff --git a/executor/executor_test.go b/executor/executor_test.go
new file mode 100644
index 0000000..9c3af7e
--- /dev/null
+++ b/executor/executor_test.go
@@ -0,0 +1,56 @@
+package executor_test
+
+import (
+ "testing"
+ "time"
+
+ "github.com/network-quality/goresponsiveness/executor"
+)
+
+var countToFive = func() {
+ time.Sleep(5 * time.Second)
+}
+
+var countToThree = func() {
+ time.Sleep(3 * time.Second)
+}
+
+var executionUnits = []executor.ExecutionUnit{countToFive, countToThree}
+
+func TestSerial(t *testing.T) {
+ then := time.Now()
+ waiter := executor.Execute(executor.Serial, executionUnits)
+ waiter.Wait()
+ when := time.Now()
+
+ if when.Sub(then) < 7*time.Second {
+ t.Fatalf("Execution did not happen serially -- the wait was too short: %v", when.Sub(then).Seconds())
+ }
+}
+
+func TestParallel(t *testing.T) {
+ then := time.Now()
+ waiter := executor.Execute(executor.Parallel, executionUnits)
+ waiter.Wait()
+ when := time.Now()
+
+ if when.Sub(then) > 6*time.Second {
+ t.Fatalf("Execution did not happen in parallel -- the wait was too long: %v", when.Sub(then).Seconds())
+ }
+}
+
+func TestExecutionMethodParallelToString(t *testing.T) {
+ executionMethod := executor.Parallel
+
+ if executionMethod.ToString() != "Parallel" {
+ t.Fatalf("Incorrect result from ExecutionMethod.ToString; expected Parallel but got %v", executionMethod.ToString())
+ }
+}
+
+func TestExecutionMethodSerialToString(t *testing.T) {
+ executionMethod := executor.Serial
+
+ if executionMethod.ToString() != "Serial" {
+ t.Fatalf("Incorrect result from ExecutionMethod.ToString; expected Serial but got %v", executionMethod.ToString())
+ }
+}