Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Commit

Permalink
refactor: separate event data mapping from handling and remove redund…
Browse files Browse the repository at this point in the history
…ant EventHandler attributes

Signed-off-by: Paolo Chila <paolo.chila@dynatrace.com>
  • Loading branch information
pchila authored Apr 11, 2022
1 parent 7760759 commit dfe009d
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 178 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

TAG ?= latest

generate-mocks:
@echo "(Re)Generating mocks in */fake packages"
mockgen -source=pkg/k8sutils/connect.go -destination=pkg/k8sutils/fake/connect_mock.go -package fake
mockgen -source=pkg/keptn/config_service.go -destination=pkg/keptn/fake/config_service_mock.go -package fake

build-lint:
@echo "Compiling job executor service lint for every OS and Platform"
GOOS=linux GOARCH=amd64 go build -o bin/job-lint-linux-amd64 ./cmd/job-executor-service-lint
Expand Down
35 changes: 10 additions & 25 deletions cmd/job-executor-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package main
import (
"context"
"encoding/json"
"errors"
v1 "k8s.io/api/core/v1"
"keptn-contrib/job-executor-service/pkg/utils"
"fmt"
"log"
"net/http"
"os"

v1 "k8s.io/api/core/v1"

"keptn-contrib/job-executor-service/pkg/utils"

"keptn-contrib/job-executor-service/pkg/eventhandler"
"keptn-contrib/job-executor-service/pkg/k8sutils"

Expand Down Expand Up @@ -62,18 +64,6 @@ const ServiceName = "job-executor-service"
// startup from env (treat as const)
var /* const */ DefaultResourceRequirements *v1.ResourceRequirements

/**
* Parses a Keptn Cloud Event payload (data attribute)
*/
func parseKeptnCloudEventPayload(event cloudevents.Event, data interface{}) error {
err := event.DataAs(data)
if err != nil {
log.Fatalf("Got Data Error: %s", err.Error())
return err
}
return nil
}

/**
* This method gets called when a new event is received from the Keptn Event Distributor
* Depending on the Event Type will call the specific event handler functions, e.g: handleDeploymentFinishedEvent
Expand All @@ -84,22 +74,15 @@ func processKeptnCloudEvent(ctx context.Context, event cloudevents.Event, allowL
log.Printf("Initializing Keptn Handler")
myKeptn, err := keptnv2.NewKeptn(&event, keptnOptions)
if err != nil {
return errors.New("Could not create Keptn Handler: " + err.Error())
return fmt.Errorf("could not create Keptn Handler: %w", err)
}

log.Printf("gotEvent(%s): %s - %s", event.Type(), myKeptn.KeptnContext, event.Context.GetID())

eventData := &keptnv2.EventData{}
err = parseKeptnCloudEventPayload(event, eventData)
if err != nil {
log.Printf("failed to convert incoming cloudevent to event data: %v", err)
}

var eventHandler = &eventhandler.EventHandler{
Keptn: myKeptn,
Event: event,
EventData: eventData,
ServiceName: ServiceName,
Mapper: new(eventhandler.KeptnCloudEventMapper),
ImageFilter: imageFilterImpl{
imageFilterList: allowList,
},
Expand Down Expand Up @@ -180,7 +163,9 @@ func _main(args []string, env envConfig) int {
log.Printf("Creating new http handler")

// configure http server to receive cloudevents
p, err := cloudevents.NewHTTP(cloudevents.WithPath(env.Path), cloudevents.WithPort(env.Port), cloudevents.WithGetHandlerFunc(HTTPGetHandler))
p, err := cloudevents.NewHTTP(
cloudevents.WithPath(env.Path), cloudevents.WithPort(env.Port), cloudevents.WithGetHandlerFunc(HTTPGetHandler),
)

if err != nil {
log.Fatalf("failed to create client, %v", err)
Expand Down
66 changes: 12 additions & 54 deletions pkg/eventhandler/eventhandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
k8sutilsfake "keptn-contrib/job-executor-service/pkg/k8sutils/fake"

cloudevents "github.com/cloudevents/sdk-go/v2"
"github.com/cloudevents/sdk-go/v2/binding/spec"
"github.com/cloudevents/sdk-go/v2/event"
"github.com/golang/mock/gomock"
"github.com/keptn/go-utils/pkg/lib/keptn"
keptnv2 "github.com/keptn/go-utils/pkg/lib/v0_2_0"
Expand Down Expand Up @@ -88,55 +86,24 @@ func initializeTestObjects(eventFileName string) (*keptnv2.Keptn, *cloudevents.E
return myKeptn, incomingEvent, fakeEventSender, err
}

func TestInitializeEventPayloadAsInterface(t *testing.T) {

context := spec.V1.NewContext()
context.SetID("0123")
context.SetSource("sourcysource")
now := time.Now()
context.SetTime(now)
context.SetExtension("shkeptncontext", interface{}("mycontext"))

eh := EventHandler{
Event: event.Event{
Context: context,
DataEncoded: []byte(testEvent),
},
}

eventPayloadAsInterface, err := eh.createEventPayloadAsInterface()
require.NoError(t, err)

assert.Equal(t, eventPayloadAsInterface["id"], "0123")
assert.Equal(t, eventPayloadAsInterface["source"], "sourcysource")
assert.Equal(t, eventPayloadAsInterface["time"], now)
assert.Equal(t, eventPayloadAsInterface["shkeptncontext"], "mycontext")

data := eventPayloadAsInterface["data"]
dataAsMap := data.(map[string]interface{})

assert.Equal(t, dataAsMap["project"], "sockshop")
}

func TestStartK8s(t *testing.T) {
jobNamespace1 := "keptn"
jobNamespace2 := "keptn-2"
myKeptn, event, fakeEventSender, err := initializeTestObjects("../../test-events/action.triggered.json")
myKeptn, _, fakeEventSender, err := initializeTestObjects("../../test-events/action.triggered.json")
require.NoError(t, err)

eventData := &keptnv2.EventData{}
myKeptn.CloudEvent.DataAs(eventData)
eh := EventHandler{
ServiceName: "job-executor-service",
Keptn: myKeptn,
EventData: eventData,
Event: *event,
ImageFilter: acceptAllImagesFilter{},
JobSettings: k8sutils.JobSettings{
JobNamespace: jobNamespace1,
},
}
eventPayloadAsInterface, _ := eh.createEventPayloadAsInterface()
mapper := new(KeptnCloudEventMapper)
eventPayloadAsInterface, err := mapper.Map(*eh.Keptn.CloudEvent)

maxPollDuration := 1006
action := config.Action{
Expand Down Expand Up @@ -167,8 +134,6 @@ func TestStartK8s(t *testing.T) {
k8sMock.EXPECT().AwaitK8sJobDone(gomock.Eq(jobName2), 60, 5, jobNamespace2).Times(1)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName1), jobNamespace1).Times(1)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName2), jobNamespace2).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName1), jobNamespace1).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName2), jobNamespace2).Times(1)

eh.startK8sJob(k8sMock, &action, eventPayloadAsInterface)

Expand All @@ -181,19 +146,18 @@ func TestStartK8s(t *testing.T) {
}

func TestStartK8sJobSilent(t *testing.T) {
myKeptn, event, fakeEventSender, err := initializeTestObjects("../../test-events/action.triggered.json")
myKeptn, _, fakeEventSender, err := initializeTestObjects("../../test-events/action.triggered.json")
require.NoError(t, err)

eventData := &keptnv2.EventData{}
myKeptn.CloudEvent.DataAs(eventData)
eh := EventHandler{
ServiceName: "job-executor-service",
Keptn: myKeptn,
EventData: eventData,
Event: *event,
ImageFilter: acceptAllImagesFilter{},
}
eventPayloadAsInterface, _ := eh.createEventPayloadAsInterface()
mapper := new(KeptnCloudEventMapper)
eventPayloadAsInterface, err := mapper.Map(*eh.Keptn.CloudEvent)

action := config.Action{
Name: "Run locust",
Expand Down Expand Up @@ -221,8 +185,6 @@ func TestStartK8sJobSilent(t *testing.T) {
k8sMock.EXPECT().AwaitK8sJobDone(gomock.Any(), 60, 5, "").Times(2)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName1), gomock.Any()).Times(1)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName2), gomock.Any()).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName1), gomock.Any()).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName2), gomock.Any()).Times(1)

eh.startK8sJob(k8sMock, &action, eventPayloadAsInterface)

Expand All @@ -231,19 +193,18 @@ func TestStartK8sJobSilent(t *testing.T) {
}

func TestStartK8s_TestFinishedEvent(t *testing.T) {
myKeptn, event, fakeEventSender, err := initializeTestObjects("../../test-events/test.triggered.json")
myKeptn, _, fakeEventSender, err := initializeTestObjects("../../test-events/test.triggered.json")
require.NoError(t, err)

eventData := &keptnv2.EventData{}
myKeptn.CloudEvent.DataAs(eventData)
eh := EventHandler{
ServiceName: "job-executor-service",
Keptn: myKeptn,
EventData: eventData,
Event: *event,
ImageFilter: acceptAllImagesFilter{},
}
eventPayloadAsInterface, _ := eh.createEventPayloadAsInterface()
mapper := new(KeptnCloudEventMapper)
eventPayloadAsInterface, err := mapper.Map(*eh.Keptn.CloudEvent)

action := config.Action{
Name: "Run locust",
Expand All @@ -262,7 +223,6 @@ func TestStartK8s_TestFinishedEvent(t *testing.T) {
).Times(1)
k8sMock.EXPECT().AwaitK8sJobDone(gomock.Eq(jobName1), gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName1), gomock.Any()).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName1), gomock.Any()).Times(1)

// set the global timezone for testing
local, err := time.LoadLocation("UTC")
Expand Down Expand Up @@ -302,19 +262,18 @@ func (f disallowAllImagesFilter) IsImageAllowed(_ string) bool {
}

func TestExpectImageNotAllowedError(t *testing.T) {
myKeptn, event, fakeEventSender, err := initializeTestObjects("../../test-events/test.triggered.json")
myKeptn, _, fakeEventSender, err := initializeTestObjects("../../test-events/test.triggered.json")
require.NoError(t, err)

eventData := &keptnv2.EventData{}
myKeptn.CloudEvent.DataAs(eventData)
eh := EventHandler{
ServiceName: "job-executor-service",
Keptn: myKeptn,
EventData: eventData,
Event: *event,
ImageFilter: disallowAllImagesFilter{},
}
eventPayloadAsInterface, _ := eh.createEventPayloadAsInterface()
mapper := new(KeptnCloudEventMapper)
eventPayloadAsInterface, err := mapper.Map(*eh.Keptn.CloudEvent)

notAllowedImageName := "alpine:latest"
action := config.Action{
Expand All @@ -335,7 +294,6 @@ func TestExpectImageNotAllowedError(t *testing.T) {
).Times(1)
k8sMock.EXPECT().AwaitK8sJobDone(gomock.Eq(jobName1), gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
k8sMock.EXPECT().GetLogsOfPod(gomock.Eq(jobName1), gomock.Any()).Times(1)
k8sMock.EXPECT().DeleteK8sJob(gomock.Eq(jobName1), gomock.Any()).Times(1)

// set the global timezone for testing
local, err := time.LoadLocation("UTC")
Expand Down
Loading

0 comments on commit dfe009d

Please sign in to comment.