diff --git a/execution/stream/stream.go b/execution/stream/stream.go index 41018f138..a37753631 100644 --- a/execution/stream/stream.go +++ b/execution/stream/stream.go @@ -62,18 +62,18 @@ func execute(specDirs []string, stream gm.Execution_ExecuteServer, debug bool) { return } event.InitRegistry() - listenExecutionEvents(stream) + listenExecutionEvents(stream, res.Runner.Pid()) rerun.ListenFailedScenarios() execution.Execute(res.SpecCollection, res.Runner, nil, res.ErrMap, execution.InParallel, 0, debug) } -func listenExecutionEvents(stream gm.Execution_ExecuteServer) { +func listenExecutionEvents(stream gm.Execution_ExecuteServer, pid int) { ch := make(chan event.ExecutionEvent, 0) event.Register(ch, event.SuiteStart, event.SpecStart, event.SpecEnd, event.ScenarioStart, event.ScenarioEnd, event.SuiteEnd) go func() { for { e := <-ch - res := getResponse(e) + res := getResponse(e, pid) if stream.Send(res) != nil || res.Type == gm.ExecutionResponse_SuiteEnd.Enum() { util.SetWorkingDir(config.ProjectRoot) return @@ -82,19 +82,21 @@ func listenExecutionEvents(stream gm.Execution_ExecuteServer) { }() } -func getResponse(e event.ExecutionEvent) *gm.ExecutionResponse { +func getResponse(e event.ExecutionEvent, pid int) *gm.ExecutionResponse { switch e.Topic { case event.SuiteStart: - return &gm.ExecutionResponse{Type: gm.ExecutionResponse_SuiteStart.Enum()} + return &gm.ExecutionResponse{Type: gm.ExecutionResponse_SuiteStart.Enum(), RunnerProcessId: proto.Int32(int32(pid))} case event.SpecStart: return &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SpecStart.Enum(), - ID: e.ExecutionInfo.CurrentSpec.FileName, + Type: gm.ExecutionResponse_SpecStart.Enum(), + ID: e.ExecutionInfo.CurrentSpec.FileName, + RunnerProcessId: proto.Int32(int32(pid)), } case event.ScenarioStart: return &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_ScenarioStart.Enum(), - ID: proto.String(fmt.Sprintf("%s:%d", e.ExecutionInfo.CurrentSpec.GetFileName(), e.Item.(*gauge.Scenario).Heading.LineNo)), + Type: gm.ExecutionResponse_ScenarioStart.Enum(), + ID: proto.String(fmt.Sprintf("%s:%d", e.ExecutionInfo.CurrentSpec.GetFileName(), e.Item.(*gauge.Scenario).Heading.LineNo)), + RunnerProcessId: proto.Int32(int32(pid)), Result: &gm.Result{ TableRowNumber: proto.Int64(int64(getDataTableRowNumber(e.Item.(*gauge.Scenario)))), }, @@ -102,8 +104,9 @@ func getResponse(e event.ExecutionEvent) *gm.ExecutionResponse { case event.ScenarioEnd: scn := e.Item.(*gauge.Scenario) return &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_ScenarioEnd.Enum(), - ID: proto.String(fmt.Sprintf("%s:%d", e.ExecutionInfo.CurrentSpec.GetFileName(), scn.Heading.LineNo)), + Type: gm.ExecutionResponse_ScenarioEnd.Enum(), + ID: proto.String(fmt.Sprintf("%s:%d", e.ExecutionInfo.CurrentSpec.GetFileName(), scn.Heading.LineNo)), + RunnerProcessId: proto.Int32(int32(pid)), Result: &gm.Result{ Status: getStatus(e.Result.(*result.ScenarioResult)), ExecutionTime: proto.Int64(e.Result.ExecTime()), @@ -115,8 +118,9 @@ func getResponse(e event.ExecutionEvent) *gm.ExecutionResponse { } case event.SpecEnd: return &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SpecEnd.Enum(), - ID: e.ExecutionInfo.CurrentSpec.FileName, + Type: gm.ExecutionResponse_SpecEnd.Enum(), + ID: e.ExecutionInfo.CurrentSpec.FileName, + RunnerProcessId: proto.Int32(int32(pid)), Result: &gm.Result{ BeforeHookFailure: getHookFailure(e.Result.GetPreHook()), AfterHookFailure: getHookFailure(e.Result.GetPostHook()), @@ -124,7 +128,8 @@ func getResponse(e event.ExecutionEvent) *gm.ExecutionResponse { } case event.SuiteEnd: return &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SuiteEnd.Enum(), + Type: gm.ExecutionResponse_SuiteEnd.Enum(), + RunnerProcessId: proto.Int32(int32(pid)), Result: &gm.Result{ BeforeHookFailure: getHookFailure(e.Result.GetPreHook()), AfterHookFailure: getHookFailure(e.Result.GetPostHook()), diff --git a/execution/stream/stream_test.go b/execution/stream/stream_test.go index 04aa20bee..46c225f78 100644 --- a/execution/stream/stream_test.go +++ b/execution/stream/stream_test.go @@ -200,12 +200,13 @@ func (s *MySuite) TestListenSuiteStartExecutionEvent(c *C) { event.InitRegistry() actual := make(chan *gm.ExecutionResponse) - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) event.Notify(event.NewExecutionEvent(event.SuiteStart, nil, nil, 0, gm.ExecutionInfo{})) defer sendSuiteEnd(actual) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SuiteStart.Enum(), + Type: gm.ExecutionResponse_SuiteStart.Enum(), + RunnerProcessId: proto.Int32(1234), } c.Assert(<-actual, DeepEquals, expected) @@ -218,13 +219,14 @@ func (s *MySuite) TestListenSpecStartExecutionEvent(c *C) { CurrentSpec: &gm.SpecInfo{FileName: proto.String("example.spec")}, } - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) defer sendSuiteEnd(actual) event.Notify(event.NewExecutionEvent(event.SpecStart, nil, nil, 0, ei)) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SpecStart.Enum(), - ID: proto.String("example.spec"), + Type: gm.ExecutionResponse_SpecStart.Enum(), + ID: proto.String("example.spec"), + RunnerProcessId: proto.Int32(1234), } c.Assert(<-actual, DeepEquals, expected) } @@ -236,13 +238,14 @@ func (s *MySuite) TestListenScenarioStartExecutionEvent(c *C) { CurrentSpec: &gm.SpecInfo{FileName: proto.String("example.spec")}, } - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) defer sendSuiteEnd(actual) event.Notify(event.NewExecutionEvent(event.ScenarioStart, &gauge.Scenario{Heading: &gauge.Heading{LineNo: 1}}, nil, 0, ei)) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_ScenarioStart.Enum(), - ID: proto.String("example.spec:1"), + Type: gm.ExecutionResponse_ScenarioStart.Enum(), + ID: proto.String("example.spec:1"), + RunnerProcessId: proto.Int32(1234), Result: &gm.Result{ TableRowNumber: proto.Int64(0), }, @@ -258,15 +261,16 @@ func (s *MySuite) TestListenSpecEndExecutionEvent(c *C) { } hookFailure := &gm.ProtoHookFailure{ErrorMessage: proto.String("err msg")} - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) defer sendSuiteEnd(actual) event.Notify(event.NewExecutionEvent(event.SpecEnd, nil, &result.SpecResult{ ProtoSpec: &gm.ProtoSpec{PreHookFailure: hookFailure, PostHookFailure: hookFailure}, }, 0, ei)) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SpecEnd.Enum(), - ID: proto.String("example.spec"), + Type: gm.ExecutionResponse_SpecEnd.Enum(), + ID: proto.String("example.spec"), + RunnerProcessId: proto.Int32(1234), Result: &gm.Result{ BeforeHookFailure: &gm.Result_ExecutionError{ErrorMessage: proto.String("err msg")}, AfterHookFailure: &gm.Result_ExecutionError{ErrorMessage: proto.String("err msg")}, @@ -280,11 +284,12 @@ func (s *MySuite) TestListenSuiteEndExecutionEvent(c *C) { actual := make(chan *gm.ExecutionResponse) hookFailure := &gm.ProtoHookFailure{ErrorMessage: proto.String("err msg")} - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) event.Notify(event.NewExecutionEvent(event.SuiteEnd, nil, &result.SuiteResult{PreSuite: hookFailure, PostSuite: hookFailure}, 0, gm.ExecutionInfo{})) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_SuiteEnd.Enum(), + Type: gm.ExecutionResponse_SuiteEnd.Enum(), + RunnerProcessId: proto.Int32(1234), Result: &gm.Result{ BeforeHookFailure: &gm.Result_ExecutionError{ErrorMessage: proto.String("err msg")}, AfterHookFailure: &gm.Result_ExecutionError{ErrorMessage: proto.String("err msg")}, @@ -304,12 +309,13 @@ func (s *MySuite) TestListenScenarioEndExecutionEvent(c *C) { ExecutionTime: proto.Int64(1), } - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) defer sendSuiteEnd(actual) event.Notify(event.NewExecutionEvent(event.ScenarioEnd, &gauge.Scenario{Heading: &gauge.Heading{LineNo: 1}}, result.NewScenarioResult(scn), 0, ei)) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_ScenarioEnd.Enum(), + Type: gm.ExecutionResponse_ScenarioEnd.Enum(), + RunnerProcessId: proto.Int32(1234), Result: &gm.Result{ ExecutionTime: proto.Int64(1), Status: gm.Result_PASSED.Enum(), @@ -334,13 +340,14 @@ func (s *MySuite) TestListenScenarioEndExecutionEventForFailedScenario(c *C) { ExecutionStatus: gm.ExecutionStatus_FAILED.Enum(), } - listenExecutionEvents(&dummyServer{response: actual}) + listenExecutionEvents(&dummyServer{response: actual}, 1234) defer sendSuiteEnd(actual) event.Notify(event.NewExecutionEvent(event.ScenarioEnd, &gauge.Scenario{Heading: &gauge.Heading{LineNo: 1}}, result.NewScenarioResult(scn), 0, ei)) expected := &gm.ExecutionResponse{ - Type: gm.ExecutionResponse_ScenarioEnd.Enum(), - ID: proto.String("example.spec:1"), + Type: gm.ExecutionResponse_ScenarioEnd.Enum(), + ID: proto.String("example.spec:1"), + RunnerProcessId: proto.Int32(1234), Result: &gm.Result{ ExecutionTime: proto.Int64(1), Status: gm.Result_FAILED.Enum(), diff --git a/gauge-proto b/gauge-proto index 3b953973f..93b60becb 160000 --- a/gauge-proto +++ b/gauge-proto @@ -1 +1 @@ -Subproject commit 3b953973fb6bb1ada132b200a25a6e3014abac38 +Subproject commit 93b60becb5a7ab032e8aa257cba269bba84ed409 diff --git a/gauge_messages/api_v2.pb.go b/gauge_messages/api_v2.pb.go index b4a3a5de7..0647ade88 100644 --- a/gauge_messages/api_v2.pb.go +++ b/gauge_messages/api_v2.pb.go @@ -408,7 +408,7 @@ type ExecutionResponse struct { ID *string `protobuf:"bytes,2,opt,name=ID" json:"ID,omitempty"` // Contains all the result details. This field is populated only for ScenarioStart, ScenaioEnd, SpecEnd, SuiteEnd, ErrorResult Result *Result `protobuf:"bytes,3,opt,name=result" json:"result,omitempty"` - // Contains the processId of the language runner used for execution. This field is populated only for SuiteStart + // Contains the processId of the language runner used for execution. RunnerProcessId *int32 `protobuf:"varint,4,opt,name=RunnerProcessId" json:"RunnerProcessId,omitempty"` XXX_unrecognized []byte `json:"-"` } diff --git a/runner/runner.go b/runner/runner.go index b89b9552a..2f8c19d50 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -48,6 +48,7 @@ type Runner interface { IsProcessRunning() bool Kill() error Connection() net.Conn + Pid() int } type LanguageRunner struct { @@ -171,6 +172,10 @@ func (r *LanguageRunner) killRunner() error { return r.Cmd.Process.Kill() } +func (r *LanguageRunner) Pid() int { + return r.Cmd.Process.Pid +} + func (r *LanguageRunner) ExecuteAndGetStatus(message *gauge_messages.Message) *gauge_messages.ProtoExecutionResult { response, err := conn.GetResponseForGaugeMessage(message, r.connection) if err != nil {