Repository: getgauge/gauge (go)
Issue: Inconsistency of raising ExecutionStartingRequest event for grpc plugins if running specs in parallel
I'm developer of plugin for gauge with grpc support.

When we execute specs using `gauge run` command, plugin gets following execution starting 2 events (json serialized):
```
{"CurrentExecutionInfo":null,"SuiteResult":null,"Stream":0}
{"CurrentExecutionInfo":null,"SuiteResult":{"SpecResults":[],"PreHookFailure":null,"PostHookFailure":null,"Failed":false,"SpecsFailedCount":0,"ExecutionTime":0,"SuccessRate":0,"Environment":"default","Tags":"","ProjectName":"sample-gauge-project-master","Timestamp":"Sep 4, 2020 at 7:48pm","SpecsSkippedCount":0,"PreHookMessages":[],"PostHookMessages":[],"PreHookMessage":[],"PostHookMessage":[],"PreHookScreenshots":[],"PostHookScreenshots":[],"Chunked":false,"ChunkSize":0,"PreHookScreenshotFiles":[],"PostHookScreenshotFiles":[]},"Stream":0}
```

Plugin expects that 2 events are raised. It's true for gauge v1.0.7 and v1.1.1.

But if we run specs in parallel `gauge run -p` then only 1 event is raised in gauge v1.1.1:
```
{"CurrentExecutionInfo":{"CurrentSpec":null,"CurrentScenario":null,"CurrentStep":null,"Stacktrace":"","ProjectName":"","ExecutionArgs":[],"NumberOfExecutionStreams":0,"RunnerId":0},"SuiteResult":null,"Stream":1}
```

Note: With gauge v1.0.7 parallel execution fires 2 events as expected.
Pull request description: Raising missing events #1741
fixes #1741 

Patch:
diff --git a/execution/parallelGrpcExecution.go b/execution/parallelGrpcExecution.go
index f1b9bb77..fb1bacb0 100644
--- a/execution/parallelGrpcExecution.go
+++ b/execution/parallelGrpcExecution.go
@@ -57,8 +57,8 @@ func (e *parallelExecution) notifyBeforeSuite() {
 			CurrentExecutionInfo: &gauge_messages.ExecutionInfo{},
 			Stream:               1},
 	}
-	res := e.runners[0].ExecuteAndGetStatus(m)
 	e.pluginHandler.NotifyPlugins(m)
+	res := e.runners[0].ExecuteAndGetStatus(m)
 	e.suiteResult.PreHookMessages = res.Message
 	e.suiteResult.PreHookScreenshotFiles = res.ScreenshotFiles
 	e.suiteResult.PreHookScreenshots = res.Screenshots
@@ -66,6 +66,7 @@ func (e *parallelExecution) notifyBeforeSuite() {
 		result.AddPreHook(e.suiteResult, res)
 	}
 	m.ExecutionStartingRequest.SuiteResult = gauge.ConvertToProtoSuiteResult(e.suiteResult)
+	e.pluginHandler.NotifyPlugins(m)
 }
 
 func (e *parallelExecution) notifyAfterSuite() {
@@ -75,8 +76,8 @@ func (e *parallelExecution) notifyAfterSuite() {
 			Stream:               1,
 		},
 	}
-	res := e.runners[0].ExecuteAndGetStatus(m)
 	e.pluginHandler.NotifyPlugins(m)
+	res := e.runners[0].ExecuteAndGetStatus(m)
 	e.suiteResult.PostHookMessages = res.Message
 	e.suiteResult.PostHookScreenshotFiles = res.ScreenshotFiles
 	e.suiteResult.PostHookScreenshots = res.Screenshots
@@ -84,4 +85,5 @@ func (e *parallelExecution) notifyAfterSuite() {
 		result.AddPostHook(e.suiteResult, res)
 	}
 	m.ExecutionEndingRequest.SuiteResult = gauge.ConvertToProtoSuiteResult(e.suiteResult)
+	e.pluginHandler.NotifyPlugins(m)
 }
diff --git a/version/version.go b/version/version.go
index ccfef658..9f48a922 100644
--- a/version/version.go
+++ b/version/version.go
@@ -14,7 +14,7 @@ import (
 )
 
 // CurrentGaugeVersion represents the current version of Gauge
-var CurrentGaugeVersion = &Version{1, 1, 3}
+var CurrentGaugeVersion = &Version{1, 1, 4}
 
 // BuildMetadata represents build information of current release (e.g, nightly build information)
 var BuildMetadata = ""


Test patch:
diff --git a/execution/parallelGrpcExecution_test.go b/execution/parallelGrpcExecution_test.go
index 72637f80..b96ea4ba 100644
--- a/execution/parallelGrpcExecution_test.go
+++ b/execution/parallelGrpcExecution_test.go
@@ -19,16 +19,20 @@ import (
 
 func TestSuiteHooksAreExecutedOncePerRun(t *testing.T) {
 	specs := createSpecsList(6)
+	var receivedMesseges []*gauge_messages.Message
 	runner1 := &fakeGrpcRunner{messageCount: make(map[gauge_messages.Message_MessageType]int)}
 	runner2 := &fakeGrpcRunner{messageCount: make(map[gauge_messages.Message_MessageType]int)}
 	e := parallelExecution{
 		numberOfExecutionStreams: 5,
 		specCollection:           gauge.NewSpecCollection(specs, false),
 		runners:                  []runner.Runner{runner1, runner2},
-		pluginHandler:            &mockPluginHandler{NotifyPluginsfunc: func(m *gauge_messages.Message) {}},
+		pluginHandler: &mockPluginHandler{NotifyPluginsfunc: func(m *gauge_messages.Message) {
+			receivedMesseges = append(receivedMesseges, m)
+		}},
 	}
 
 	t.Run("BeforeSuite", func(t *testing.T) {
+		receivedMesseges = []*gauge_messages.Message{}
 		e.suiteResult = result.NewSuiteResult("", time.Now())
 		runner1.mockResult = &gauge_messages.ProtoExecutionResult{}
 		e.notifyBeforeSuite()
@@ -40,9 +44,13 @@ func TestSuiteHooksAreExecutedOncePerRun(t *testing.T) {
 		if r2count != 0 {
 			t.Errorf("Expected runner2 to have received 0 ExecutionStarting request, got %d", r2count)
 		}
+		if len(receivedMesseges) != 2 {
+			t.Errorf("Expected plugins to have received 2 ExecutionStarting notifications, got %d", len(receivedMesseges))
+		}
 	})
 
 	t.Run("AfterSuite", func(t *testing.T) {
+		receivedMesseges = []*gauge_messages.Message{}
 		e.notifyAfterSuite()
 		e.suiteResult = result.NewSuiteResult("", time.Now())
 		runner1.mockResult = &gauge_messages.ProtoExecutionResult{}
@@ -54,6 +62,9 @@ func TestSuiteHooksAreExecutedOncePerRun(t *testing.T) {
 		if r2count != 0 {
 			t.Errorf("Expected runner2 to have received 0 ExecutionEnding request, got %d", r2count)
 		}
+		if len(receivedMesseges) != 2 {
+			t.Errorf("Expected plugins to have received 2 ExecutionStarting notifications, got %d", len(receivedMesseges))
+		}
 	})
 }