Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: emit unreachable host events for http and grpc triggers #2283

Merged
merged 2 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions server/executor/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package executor

import (
"context"
"errors"
"fmt"
"strings"

"github.com/kubeshop/tracetest/server/executor/trigger"
"github.com/kubeshop/tracetest/server/expression"
Expand Down Expand Up @@ -229,6 +231,10 @@ func (r persistentRunner) processExecQueue(job execReq) {
response, err := triggerer.Trigger(job.ctx, resolvedTest, triggerOptions)
run = r.handleExecutionResult(run, response, err)
if err != nil {
if isConnectionError(err) {
r.emitUnreachableEndpointEvent(job, err)
}

emitErr := r.eventEmitter.Emit(job.ctx, events.TriggerExecutionError(job.run.TestID, job.run.ID, err))
if emitErr != nil {
r.handleError(job.run, emitErr)
Expand Down Expand Up @@ -265,3 +271,36 @@ func (r persistentRunner) handleExecutionResult(run model.Run, response trigger.

return run.SuccessfullyTriggered()
}

func (r persistentRunner) emitUnreachableEndpointEvent(job execReq, err error) {
var event model.TestRunEvent
switch job.test.ServiceUnderTest.Type {
case model.TriggerTypeHTTP:
event = events.TriggerHTTPUnreachableHostError(job.run.TestID, job.run.ID, err)
case model.TriggerTypeGRPC:
event = events.TriggergRPCUnreachableHostError(job.run.TestID, job.run.ID, err)
}

emitErr := r.eventEmitter.Emit(job.ctx, event)
if emitErr != nil {
r.handleError(job.run, emitErr)
}
}

func isConnectionError(err error) bool {
for err != nil {
// a dial error means we couldn't open a TCP connection (either host is not available or DNS doesn't exist)
if strings.HasPrefix(err.Error(), "dial ") {
return true
}

// it means a trigger timeout
if errors.Is(err, context.DeadlineExceeded) {
return true
}

err = errors.Unwrap(err)
}

return false
}
8 changes: 4 additions & 4 deletions server/model/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ func TriggerExecutionError(testID id.ID, runID int, err error) model.TestRunEven
}
}

func TriggerHTTPUnreachableHostError(testID id.ID, runID int) model.TestRunEvent {
func TriggerHTTPUnreachableHostError(testID id.ID, runID int, err error) model.TestRunEvent {
return model.TestRunEvent{
TestID: testID,
RunID: runID,
Stage: model.StageTrigger,
Type: "HTTP_UNREACHABLE_HOST_ERROR",
Title: "Tracetest could not reach the defined host in the trigger",
Description: "Tracetest could not reach the defined host in the trigger",
Description: fmt.Sprintf("Tracetest could not reach the defined host in the trigger: %s", err.Error()),
CreatedAt: time.Now(),
DataStoreConnection: model.ConnectionResult{},
Polling: model.PollingInfo{},
Expand All @@ -143,14 +143,14 @@ func TriggerDockerComposeHostMismatchError(testID id.ID, runID int) model.TestRu
}
}

func TriggergRPCUnreachableHostError(testID id.ID, runID int) model.TestRunEvent {
func TriggergRPCUnreachableHostError(testID id.ID, runID int, err error) model.TestRunEvent {
return model.TestRunEvent{
TestID: testID,
RunID: runID,
Stage: model.StageTrigger,
Type: "GRPC_UNREACHABLE_HOST_ERROR",
Title: "Tracetest could not reach the defined host in the trigger",
Description: "Tracetest could not reach the defined host in the trigger",
Description: fmt.Sprintf("Tracetest could not reach the defined host in the trigger: %s", err.Error()),
CreatedAt: time.Now(),
DataStoreConnection: model.ConnectionResult{},
Polling: model.PollingInfo{},
Expand Down