github.com/mattdotmatt/gauge@v0.3.2-0.20160421115137-425a4cdccb62/execution/stepExecutor.go (about)

     1  // Copyright 2015 ThoughtWorks, Inc.
     2  
     3  // This file is part of Gauge.
     4  
     5  // Gauge is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  
    10  // Gauge is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  
    15  // You should have received a copy of the GNU General Public License
    16  // along with Gauge.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package execution
    19  
    20  import (
    21  	"strings"
    22  
    23  	"github.com/getgauge/gauge/execution/result"
    24  	"github.com/getgauge/gauge/formatter"
    25  	"github.com/getgauge/gauge/gauge_messages"
    26  	"github.com/getgauge/gauge/parser"
    27  	"github.com/getgauge/gauge/plugin"
    28  	"github.com/getgauge/gauge/reporter"
    29  	"github.com/getgauge/gauge/runner"
    30  	"github.com/golang/protobuf/proto"
    31  )
    32  
    33  type stepExecutor struct {
    34  	runner               *runner.TestRunner
    35  	pluginHandler        *plugin.Handler
    36  	currentExecutionInfo *gauge_messages.ExecutionInfo
    37  	consoleReporter      reporter.Reporter
    38  }
    39  
    40  func (e *stepExecutor) executeStep(protoStep *gauge_messages.ProtoStep) *gauge_messages.ProtoStepExecutionResult {
    41  	stepRequest := e.createStepRequest(protoStep)
    42  	e.currentExecutionInfo.CurrentStep = &gauge_messages.StepInfo{Step: stepRequest, IsFailed: proto.Bool(false)}
    43  
    44  	stepText := formatter.FormatStep(parser.CreateStepFromStepRequest(stepRequest))
    45  	e.consoleReporter.StepStart(stepText)
    46  
    47  	protoStepExecResult := &gauge_messages.ProtoStepExecutionResult{ExecutionResult: &gauge_messages.ProtoExecutionResult{}}
    48  	e.notifyBeforeStepHook(protoStepExecResult)
    49  	if !protoStepExecResult.ExecutionResult.GetFailed() {
    50  		executeStepMessage := &gauge_messages.Message{MessageType: gauge_messages.Message_ExecuteStep.Enum(), ExecuteStepRequest: stepRequest}
    51  		stepExecutionStatus := executeAndGetStatus(e.runner, executeStepMessage)
    52  		if stepExecutionStatus.GetFailed() {
    53  			setStepFailure(e.currentExecutionInfo)
    54  		}
    55  		protoStepExecResult.ExecutionResult = stepExecutionStatus
    56  	}
    57  
    58  	e.notifyAfterStepHook(protoStepExecResult)
    59  
    60  	protoStepExecResult.Skipped = protoStep.StepExecutionResult.Skipped
    61  	protoStepExecResult.SkippedReason = protoStep.StepExecutionResult.SkippedReason
    62  
    63  	stepFailed := protoStepExecResult.GetExecutionResult().GetFailed()
    64  	if stepFailed {
    65  		result := protoStep.GetStepExecutionResult().GetExecutionResult()
    66  		e.consoleReporter.Errorf("\nFailed Step: %s", e.currentExecutionInfo.CurrentStep.Step.GetActualStepText())
    67  		e.consoleReporter.Errorf("Error Message: %s", strings.TrimSpace(result.GetErrorMessage()))
    68  		e.consoleReporter.Errorf("Stacktrace: \n%s", result.GetStackTrace())
    69  	}
    70  	e.consoleReporter.StepEnd(stepFailed)
    71  	return protoStepExecResult
    72  }
    73  
    74  func (e *stepExecutor) createStepRequest(protoStep *gauge_messages.ProtoStep) *gauge_messages.ExecuteStepRequest {
    75  	stepRequest := &gauge_messages.ExecuteStepRequest{ParsedStepText: proto.String(protoStep.GetParsedText()), ActualStepText: proto.String(protoStep.GetActualText())}
    76  	stepRequest.Parameters = getParameters(protoStep.GetFragments())
    77  	return stepRequest
    78  }
    79  
    80  func (e *stepExecutor) notifyBeforeStepHook(stepResult *gauge_messages.ProtoStepExecutionResult) {
    81  	msg := &gauge_messages.Message{
    82  		MessageType:                  gauge_messages.Message_StepExecutionStarting.Enum(),
    83  		StepExecutionStartingRequest: &gauge_messages.StepExecutionStartingRequest{CurrentExecutionInfo: e.currentExecutionInfo},
    84  	}
    85  	e.pluginHandler.NotifyPlugins(msg)
    86  	execRes := executeAndGetStatus(e.runner, msg)
    87  
    88  	if execRes.GetFailed() {
    89  		stepResult.PreHookFailure = result.GetProtoHookFailure(execRes)
    90  		stepResult.ExecutionResult = &gauge_messages.ProtoExecutionResult{Failed: proto.Bool(true)}
    91  		setStepFailure(e.currentExecutionInfo)
    92  		printStatus(execRes, e.consoleReporter)
    93  	}
    94  
    95  	execTime := stepResult.ExecutionResult.ExecutionTime
    96  	if execTime == nil {
    97  		stepResult.ExecutionResult.ExecutionTime = proto.Int64(execRes.GetExecutionTime())
    98  	} else {
    99  		stepResult.ExecutionResult.ExecutionTime = proto.Int64(*execTime + execRes.GetExecutionTime())
   100  	}
   101  }
   102  
   103  func (e *stepExecutor) notifyAfterStepHook(stepResult *gauge_messages.ProtoStepExecutionResult) {
   104  	message := &gauge_messages.Message{MessageType: gauge_messages.Message_StepExecutionEnding.Enum(),
   105  		StepExecutionEndingRequest: &gauge_messages.StepExecutionEndingRequest{CurrentExecutionInfo: e.currentExecutionInfo}}
   106  	e.pluginHandler.NotifyPlugins(message)
   107  	execRes := executeAndGetStatus(e.runner, message)
   108  
   109  	stepResult.ExecutionResult.Message = execRes.Message
   110  
   111  	if execRes.GetFailed() {
   112  		stepResult.PostHookFailure = result.GetProtoHookFailure(execRes)
   113  		stepResult.ExecutionResult.Failed = proto.Bool(true)
   114  		setStepFailure(e.currentExecutionInfo)
   115  		printStatus(execRes, e.consoleReporter)
   116  	}
   117  
   118  	execTime := stepResult.ExecutionResult.ExecutionTime
   119  	if execTime == nil {
   120  		stepResult.ExecutionResult.ExecutionTime = proto.Int64(execRes.GetExecutionTime())
   121  	} else {
   122  		stepResult.ExecutionResult.ExecutionTime = proto.Int64(*execTime + execRes.GetExecutionTime())
   123  	}
   124  }