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

Add E2E Integration tests #154

Merged
merged 4 commits into from
Aug 26, 2019
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.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ before_script:
- helm lint helm/botkube

script:
- make unit-test
- make test
- make

after_success:
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ IMAGE_REPO=infracloud/botkube
TAG=$(shell cut -d'=' -f2- .release)

.DEFAULT_GOAL := build
.PHONY: release git-tag check-git-status build container-image pre-build tag-image publish unit-test system-check
.PHONY: release git-tag check-git-status build container-image pre-build tag-image publish test system-check

#Docker Tasks
#Make a release
release: check-git-status unit-test container-image tag-image publish git-tag
release: check-git-status test container-image tag-image publish git-tag
@echo "Successfully releeased version $(TAG)"

#Create a git tag
Expand All @@ -25,10 +25,10 @@ check-git-status:
@if [ -z "$(shell git remote -v)" ] ; then echo 'ERROR: No remote to push tags to' && exit 1 ; fi
@if [ -z "$(shell git config user.email)" ] ; then echo 'ERROR: Unable to detect git credentials' && exit 1 ; fi

# unit-test
unit-test: system-check
@echo "Starting unit tests"
@./hack/unit-test.sh -v
# test
test: system-check
@echo "Starting unit and integration tests"
@./hack/runtests.sh

#Build the binary
build: pre-build
Expand Down
20 changes: 17 additions & 3 deletions cmd/botkube/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/infracloudio/botkube/pkg/config"
"github.com/infracloudio/botkube/pkg/controller"
log "github.com/infracloudio/botkube/pkg/logging"
"github.com/infracloudio/botkube/pkg/notify"
"github.com/infracloudio/botkube/pkg/utils"
)

Expand All @@ -29,14 +30,27 @@ func main() {
go mb.Start()
}

// List notifiers
var notifiers []notify.Notifier
if Config.Communications.Slack.Enabled {
notifiers = append(notifiers, notify.NewSlack(Config))
}
if Config.Communications.Mattermost.Enabled {
if notifier, err := notify.NewMattermost(Config); err == nil {
notifiers = append(notifiers, notifier)
}
}
if Config.Communications.ElasticSearch.Enabled {
notifiers = append(notifiers, notify.NewElasticSearch(Config))
}

if Config.Settings.UpgradeNotifier {
log.Logger.Info("Starting upgrade notifier")
go controller.UpgradeNotifier(Config)

go controller.UpgradeNotifier(Config, notifiers)
}

// Init KubeClient, InformerMap and start controller
utils.InitKubeClient()
utils.InitInformerMap()
controller.RegisterInformers(Config)
controller.RegisterInformers(Config, notifiers)
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ require (
github.com/mattermost/mattermost-server v5.11.1+incompatible
github.com/mattn/go-sqlite3 v1.11.0 // indirect
github.com/nicksnyder/go-i18n v1.10.1 // indirect
github.com/nlopes/slack v0.4.0
github.com/nlopes/slack v0.5.1-0.20190623232825-2891986e2a3e
github.com/olivere/elastic v6.2.21+incompatible
github.com/pborman/uuid v1.2.0 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.3.0
github.com/ziutek/mymysql v1.5.4 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYi
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
Expand Down Expand Up @@ -68,6 +69,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0=
github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
Expand Down Expand Up @@ -125,6 +127,8 @@ github.com/nicksnyder/go-i18n v1.10.1 h1:isfg77E/aCD7+0lD/D00ebR2MV5vgeQ276WYyDa
github.com/nicksnyder/go-i18n v1.10.1/go.mod h1:e4Di5xjP9oTVrC6y3C7C0HoSYXjSbhh/dU0eUV32nB4=
github.com/nlopes/slack v0.4.0 h1:OVnHm7lv5gGT5gkcHsZAyw++oHVFihbjWbL3UceUpiA=
github.com/nlopes/slack v0.4.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM=
github.com/nlopes/slack v0.5.1-0.20190623232825-2891986e2a3e h1:4X/3/ywN6f+XITaDoI9GjXbF7MHk7fuunXsEWZX1GLc=
github.com/nlopes/slack v0.5.1-0.20190623232825-2891986e2a3e/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
github.com/olivere/elastic v6.2.21+incompatible h1:QnTuofzxOCV5FrYLywjkMxOmOWhAeild1VXxKRksK9Y=
github.com/olivere/elastic v6.2.21+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand All @@ -140,6 +144,7 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down Expand Up @@ -251,6 +256,7 @@ k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 h1:di3XCwddOR9cWBNpfgXaskhh6cgJuwcK54rvtwUaC10=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=
Expand Down
6 changes: 4 additions & 2 deletions hack/unit-test.sh → hack/runtests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ set -o errexit
set -o nounset
set -o pipefail

PACKAGES=$(go list ./... | grep -v '/vendor/')
export CONFIG_PATH=`pwd`

# Run unit and integration tests excluding dependencies
PACKAGES=$(go list ./... | grep -v '/vendor/')
for package in $PACKAGES; do
go test ${@} "$package"
go test -tags=test ${@} "$package" -v
done
16 changes: 8 additions & 8 deletions pkg/bot/mattermost.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const (
WebSocketSecureProtocol = "wss://"
)

// mmBot listens for user's message, execute commands and sends back the response
type mmBot struct {
// MMBot listens for user's message, execute commands and sends back the response
type MMBot struct {
ServerURL string
Token string
TeamName string
Expand All @@ -56,7 +56,7 @@ func NewMattermostBot() Bot {
logging.Logger.Fatal(fmt.Sprintf("Error in loading configuration. Error:%s", err.Error()))
}

return &mmBot{
return &MMBot{
ServerURL: c.Communications.Mattermost.URL,
Token: c.Communications.Mattermost.Token,
TeamName: c.Communications.Mattermost.Team,
Expand All @@ -67,7 +67,7 @@ func NewMattermostBot() Bot {
}

// Start establishes mattermost connection and listens for messages
func (b *mmBot) Start() {
func (b *MMBot) Start() {
client = model.NewAPIv4Client(b.ServerURL)
client.SetOAuthToken(b.Token)

Expand Down Expand Up @@ -121,7 +121,7 @@ func (b *mmBot) Start() {
}

// Check incomming message and take action
func (mm *mattermostMessage) handleMessage(b *mmBot) {
func (mm *mattermostMessage) handleMessage(b *MMBot) {
post := model.PostFromJson(strings.NewReader(mm.Event.Data["post"].(string)))
channelType := mmChannelType(mm.Event.Data["channel_type"].(string))
if channelType == mmChannelPrivate || channelType == mmChannelPublic {
Expand Down Expand Up @@ -179,7 +179,7 @@ func checkServerConnection() error {
}

// Check if team exists in Mattermost
func (b *mmBot) getTeam() *model.Team {
func (b *MMBot) getTeam() *model.Team {
botTeam, resp := client.GetTeamByName(b.TeamName, "")
if resp.Error != nil {
logging.Logger.Fatal("There was a problem finding Mattermost team ", b.TeamName, "\nError: ", resp.Error)
Expand All @@ -188,7 +188,7 @@ func (b *mmBot) getTeam() *model.Team {
}

// Check if botkube user exists in Mattermost
func (b *mmBot) getUser() *model.User {
func (b *MMBot) getUser() *model.User {
users, resp := client.AutocompleteUsersInTeam(b.getTeam().Id, BotName, 1, "")
if resp.Error != nil {
logging.Logger.Fatal("There was a problem finding Mattermost user ", BotName, "\nError: ", resp.Error)
Expand All @@ -197,7 +197,7 @@ func (b *mmBot) getUser() *model.User {
}

// Create channel if not present and add botkube user in channel
func (b *mmBot) getChannel() *model.Channel {
func (b *MMBot) getChannel() *model.Channel {
// Checking if channel exists
botChannel, resp := client.GetChannelByName(b.ChannelName, b.getTeam().Id, "")
if resp.Error != nil {
Expand Down
55 changes: 35 additions & 20 deletions pkg/bot/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
"github.com/nlopes/slack"
)

// slackBot listens for user's message, execute commands and sends back the response
type slackBot struct {
// SlackBot listens for user's message, execute commands and sends back the response
type SlackBot struct {
Token string
AllowKubectl bool
ClusterName string
ChannelName string
SlackURL string
BotID string
}

// slackMessage contains message details to execute command and send back the result
Expand All @@ -26,6 +28,7 @@ type slackMessage struct {
Response string
IsAuthChannel bool
RTM *slack.RTM
SlackClient *slack.Client
}

// NewSlackBot returns new Bot object
Expand All @@ -34,7 +37,7 @@ func NewSlackBot() Bot {
if err != nil {
logging.Logger.Fatal(fmt.Sprintf("Error in loading configuration. Error:%s", err.Error()))
}
return &slackBot{
return &SlackBot{
Token: c.Communications.Slack.Token,
AllowKubectl: c.Settings.AllowKubectl,
ClusterName: c.Settings.ClusterName,
Expand All @@ -43,18 +46,24 @@ func NewSlackBot() Bot {
}

// Start starts the slacknot RTM connection and listens for messages
func (b *slackBot) Start() {
func (b *SlackBot) Start() {
var botID string
api := slack.New(b.Token)
authResp, err := api.AuthTest()
if err != nil {
logging.Logger.Fatal(err)
if len(b.SlackURL) != 0 {
api = slack.New(b.Token, slack.OptionAPIURL(b.SlackURL))
botID = b.BotID
} else {
authResp, err := api.AuthTest()
if err != nil {
logging.Logger.Fatal(err)
}
botID = authResp.UserID
}
botID := authResp.UserID

rtm := api.NewRTM()
go rtm.ManageConnection()
RTM := api.NewRTM()
go RTM.ManageConnection()

for msg := range rtm.IncomingEvents {
for msg := range RTM.IncomingEvents {
switch ev := msg.Data.(type) {
case *slack.ConnectedEvent:
logging.Logger.Debug("Connection Info: ", ev.Info)
Expand All @@ -65,9 +74,10 @@ func (b *slackBot) Start() {
continue
}
sm := slackMessage{
Event: ev,
BotID: botID,
RTM: rtm,
Event: ev,
BotID: botID,
RTM: RTM,
SlackClient: api,
}
sm.HandleMessage(b)

Expand All @@ -82,10 +92,11 @@ func (b *slackBot) Start() {
}
}

func (sm *slackMessage) HandleMessage(b *slackBot) {
func (sm *slackMessage) HandleMessage(b *SlackBot) {
logging.Logger.Debugf("Slack incoming message: %+v", sm.Event)

// Check if message posted in authenticated channel
info, err := slack.New(b.Token).GetConversationInfo(sm.Event.Channel, true)
info, err := sm.SlackClient.GetConversationInfo(sm.Event.Channel, true)
if err == nil {
if info.IsChannel || info.IsPrivate {
// Message posted in a channel
Expand All @@ -99,9 +110,16 @@ func (sm *slackMessage) HandleMessage(b *slackBot) {
}
}
}
// Serve only if current channel is in config
if b.ChannelName == sm.Event.Channel {
sm.IsAuthChannel = true
}

// Trim the @BotKube prefix
sm.Request = strings.TrimPrefix(sm.Event.Text, "<@"+sm.BotID+"> ")
if len(sm.Request) == 0 {
return
}

e := execute.NewDefaultExecutor(sm.Request, b.AllowKubectl, b.ClusterName, b.ChannelName, sm.IsAuthChannel)
sm.Response = e.Execute()
Expand All @@ -126,10 +144,7 @@ func (sm slackMessage) Send() {
return
}

params := slack.PostMessageParameters{
AsUser: true,
}
if _, _, err := sm.RTM.PostMessage(sm.Event.Channel, "```"+sm.Response+"```", params); err != nil {
if _, _, err := sm.RTM.PostMessage(sm.Event.Channel, slack.MsgOptionText("```"+sm.Response+"```", false), slack.MsgOptionAsUser(true)); err != nil {
logging.Logger.Error("Error in sending message:", err)
}
}
Loading