Skip to content

Commit

Permalink
Provide integration tests via the key Ditto features - ContainerFactory
Browse files Browse the repository at this point in the history
[eclipse-kanto#70] Provide integration tests via the key Ditto features - ContainerFactory
- refactor the code to use the common logic

Signed-off-by: Guzgunova Antonia <Antonia.Guzgunova@bosch.io>
  • Loading branch information
antoniyatrifonova committed Nov 18, 2022
1 parent e2e9b4f commit d49f79b
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 661 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/containerd/typeurl v1.0.2
github.com/containers/ocicrypt v1.1.6
github.com/docker/docker v20.10.17+incompatible
github.com/eclipse-kanto/kanto/integration/util v0.0.0-20221114101725-fadc1f231801
github.com/eclipse/ditto-clients-golang v0.0.0-20220225085802-cf3b306280d3
github.com/eclipse/paho.mqtt.golang v1.4.1
github.com/gogo/protobuf v1.3.2
Expand All @@ -29,7 +30,6 @@ require (
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
github.com/stretchr/testify v1.8.1
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
google.golang.org/grpc v1.50.1
Expand All @@ -43,6 +43,7 @@ require (
github.com/armon/go-radix v1.0.0 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/caarlos0/env/v6 v6.10.1 // indirect
github.com/containerd/fifo v1.0.0 // indirect
github.com/containerd/ttrpc v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
Expand Down Expand Up @@ -385,6 +387,8 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eclipse-kanto/kanto/integration/util v0.0.0-20221114101725-fadc1f231801 h1:pO3v/fQt7Z4RLB4oTsrx58xI/l95nPJhgOyB/E5EU/0=
github.com/eclipse-kanto/kanto/integration/util v0.0.0-20221114101725-fadc1f231801/go.mod h1:mhkMBNIG+JDz35JAj8JVWMe0/ROpKmk/i6RYHU6Rea4=
github.com/eclipse/ditto-clients-golang v0.0.0-20220225085802-cf3b306280d3 h1:bfFGs26yNSfhSi6xmnmykB0jZn1Vu5e1/7JA5Wu5aGc=
github.com/eclipse/ditto-clients-golang v0.0.0-20220225085802-cf3b306280d3/go.mod h1:ey7YwfHSQJsinGkGbgeEgqZA7qJnoB0YiFVTFEY50Jg=
github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
Expand Down
129 changes: 0 additions & 129 deletions integration/common.go

This file was deleted.

181 changes: 181 additions & 0 deletions integration/container_factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright (c) 2022 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0

package integration

import (
"fmt"
"net/http"
"strings"
"testing"

"github.com/eclipse-kanto/kanto/integration/util"
"github.com/eclipse/ditto-clients-golang/protocol"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"golang.org/x/net/websocket"
)

const (
statusCreated = "CREATED"
statusRunning = "RUNNING"
requestURL = "http://127.0.0.1:5000"
httpResponse = "<html><body><h1>It works!</h1></body></html>\n"
ctrFactoryFeatureDefinition = "[\"com.bosch.iot.suite.edge.containers:ContainerFactory:1.2.0\"]"
)

type ctrFactorySuite struct {
containerManagementSuite
ctrFeatureID string
}

func (suite *ctrFactorySuite) SetupSuite() {
suite.init()
suite.assertContainerFactoryFeature()
}

func (suite *ctrFactorySuite) TearDownSuite() {
suite.suiteInit.TearDown()
}

func TestContainerFactorySuite(t *testing.T) {
suite.Run(t, new(ctrFactorySuite))
}

func (suite *ctrFactorySuite) TestCreateOperation() {
connEvents, err := util.NewDigitalTwinWSConnection(suite.suiteInit.Cfg)
require.Nil(suite.T(), err, "failed to create websocket connection")
defer connEvents.Close()

suite.startListening(connEvents, "START-SEND-EVENTS", "/features/Container:*")

params := make(map[string]interface{})
params["imageRef"] = "docker.io/library/influxdb:1.8.4"
params["start"] = true

suite.execCreateCommand("create", params)

err = util.ProcessWSMessages(suite.suiteInit.Cfg, connEvents, suite.processCtrFeatureCreated)

require.NoError(suite.T(), err, "error while creating container feature")
require.Equal(suite.T(), statusRunning, suite.getActualCtrStatus(), "container status is not expected")

suite.processCtrFeatureRemoved(connEvents)
}

func (suite *ctrFactorySuite) TestCreateWithConfigOperation() {
connEvents, err := util.NewDigitalTwinWSConnection(suite.suiteInit.Cfg)
require.Nil(suite.T(), err, "failed to create websocket connection")
defer connEvents.Close()

suite.startListening(connEvents, "START-SEND-EVENTS", "/features/Container:*")

params := make(map[string]interface{})
params["imageRef"] = "docker.io/library/influxdb:1.8.4"
params["start"] = true
params["config"] = make(map[string]interface{})

suite.execCreateCommand("createWithConfig", params)

err = util.ProcessWSMessages(suite.suiteInit.Cfg, connEvents, suite.processCtrFeatureCreated)

require.NoError(suite.T(), err, "error while creating container feature")
require.Equal(suite.T(), statusRunning, suite.getActualCtrStatus(), "container status is not expected")

suite.processCtrFeatureRemoved(connEvents)
}

func (suite *ctrFactorySuite) TestCreateWithConfigPortMapping() {
connEvents, err := util.NewDigitalTwinWSConnection(suite.suiteInit.Cfg)
require.Nil(suite.T(), err, "failed to create websocket connection")
defer connEvents.Close()

suite.startListening(connEvents, "START-SEND-EVENTS", "/features/Container:*")

config := make(map[string]interface{})
config["extraHosts"] = []string{"ctrhost:host_ip"}
config["portMappings"] = []map[string]interface{}{
{
"hostPort": 5000,
"containerPort": 80,
},
}

params := make(map[string]interface{})
params["imageRef"] = "docker.io/library/httpd:latest"
params["start"] = true
params["config"] = config

suite.execCreateCommand("createWithConfig", params)

err = util.ProcessWSMessages(suite.suiteInit.Cfg, connEvents, suite.processCtrFeatureCreated)

body, err := util.SendDigitalTwinRequest(suite.suiteInit.Cfg, http.MethodGet, requestURL, nil)

require.Nil(suite.T(), err, "error while getting the requested URL")
require.Equal(suite.T(), httpResponse, string(body), "HTTP response is not expected")

suite.processCtrFeatureRemoved(connEvents)
}

func (suite *containerManagementSuite) assertContainerFactoryFeature() {
ctrFactoryFeature := fmt.Sprintf("%s/features/%s", suite.ctrThingURL, ctrFactoryFeatureID)
body, err := util.SendDigitalTwinRequest(suite.suiteInit.Cfg, http.MethodGet, ctrFactoryFeature, nil)
require.Nil(suite.T(), err, "error while getting the container factory feature")

ctrFactoryDefinition := fmt.Sprintf("%s/definition", ctrFactoryFeature)
body, err = util.SendDigitalTwinRequest(suite.suiteInit.Cfg, http.MethodGet, ctrFactoryDefinition, nil)
require.Nil(suite.T(), err, "error while getting the container factory feature definition")

require.Equal(suite.T(), ctrFactoryFeatureDefinition, string(body), "container factory definition is not expected")
}

func (suite *ctrFactorySuite) getActualCtrStatus() string {
ctrPropertyPath := fmt.Sprintf("%s/features/%s/properties/status/state/status", suite.ctrThingURL, suite.ctrFeatureID)
body, err := util.SendDigitalTwinRequest(suite.suiteInit.Cfg, http.MethodGet, ctrPropertyPath, nil)
require.Nil(suite.T(), err, "error while getting the container feature property status")

return strings.Trim(string(body), "\"")
}

func (suite *ctrFactorySuite) processCtrFeatureCreated(event *protocol.Envelope) (bool, error) {
if event.Topic.String() == suite.topicCreated {
suite.ctrFeatureID = getCtrFeatureID(event.Path)
return false, nil
}
if event.Topic.String() == suite.topicModify {
if suite.ctrFeatureID == "" {
return false, fmt.Errorf("container feature is not created")
}
status, check := event.Value.(map[string]interface{})
if status["status"].(string) == statusCreated {
return false, nil
}
return check && status["status"].(string) == statusRunning, nil
}
return false, fmt.Errorf("event for creating feature not received")
}

func (suite *ctrFactorySuite) processCtrFeatureRemoved(connEvents *websocket.Conn) {
suite.startListening(connEvents, "START-SEND-EVENTS", fmt.Sprintf("/features/%s", suite.ctrFeatureID))

suite.execRemoveCommand(suite.ctrFeatureID)

err := util.ProcessWSMessages(suite.suiteInit.Cfg, connEvents, func(event *protocol.Envelope) (bool, error) {
if event.Topic.String() == suite.topicDeleted {
return true, nil
}
return false, fmt.Errorf("event for deleting feature not received")
})

require.NoError(suite.T(), err, "error while deleting container feature")
}
Loading

0 comments on commit d49f79b

Please sign in to comment.