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

Commit

Permalink
test: add e2e test
Browse files Browse the repository at this point in the history
- normalize the bdd suite test entrance name
- adjust the integration test of adaptors
- change the env for launching the testing cluster
- add e2e test logic

BREAKING CHANGE: change the testing cluster type env from `LOCAL_CLUSTER_KIND` to `CLUSTER_TYPE`.
  • Loading branch information
Frank Mai authored and guangbochen committed Jun 22, 2020
1 parent 3a2e4bd commit 027e191
Show file tree
Hide file tree
Showing 39 changed files with 857 additions and 194 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Integration testing bases on [the envtest of sigs.k8s.io/controller-runtime](htt
- Adaptor: `make adaptors <adaptor directory name> verify only`
- Octopus: `make octopus verify only`
When running integration tests, the [framework](./test/framework) will launch a local Kubernetes cluster using Docker. There are two supported local clusters inside: `kind` and `k3d`, you can use environment variable `LOCAL_CLUSTER_KIND` to select, default is `k3d`. Instead of setting up a local cluster, you can also use environment variable `USE_EXISTING_CLUSTER=true` to point out an existing cluster, and then the integration tests will use the kubeconfig of the current environment to communicate with the existing cluster.
When running integration tests, the [framework](./test/framework) will launch a local Kubernetes cluster using Docker. There are two supported local clusters inside: `kind` and `k3d`, you can use environment variable `CLUSTER_TYPE` to select, default is `k3d`. Instead of setting up a local cluster, you can also use environment variable `USE_EXISTING_CLUSTER=true` to point out an existing cluster, and then the integration tests will use the kubeconfig of the current environment to communicate with the existing cluster.
### E2E testing
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./bin ./dist ./deploy ./pkg/adaptor/api ./api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
2 changes: 1 addition & 1 deletion adaptors/ble/Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./adaptors/ble/bin ./adaptors/ble/dist ./adaptors/ble/deploy ./adaptors/ble/api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
2 changes: 1 addition & 1 deletion adaptors/dummy/Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./adaptors/dummy/bin ./adaptors/dummy/dist ./adaptors/dummy/deploy ./adaptors/dummy/api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
17 changes: 16 additions & 1 deletion adaptors/dummy/test/integration/adaptor/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,22 @@ var _ = Describe("Connection", func() {
APIVersion: "devices.edge.cattle.io/v1alpha1",
Kind: "DummySpecialDevice",
},
Device: []byte(`{"apiVersion":"devices.edge.cattle.io/v1alpha1","kind":"DummySpecialDevice","metadata":{"name":"living-room-fan","namespace":"default"},"spec":{"protocol":{"location":"living-room"},"gear":"slow","on":true}}`),
Device: []byte(`
{
"apiVersion":"devices.edge.cattle.io/v1alpha1",
"kind":"DummySpecialDevice",
"metadata":{
"name":"living-room-fan",
"namespace":"default"
},
"spec":{
"protocol":{
"location":"living-room"
},
"gear":"slow",
"on":true
}
}`),
}, nil)
mockServer.EXPECT().Recv().Return(nil, io.EOF) // simulate to close the connection
err = service.Connect(mockServer)
Expand Down
2 changes: 1 addition & 1 deletion adaptors/dummy/test/integration/adaptor/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var (
testCtxCancel context.CancelFunc
)

func TestAPIs(t *testing.T) {
func TestAdaptor(t *testing.T) {
defer GinkgoRecover()

RegisterFailHandler(Fail)
Expand Down
2 changes: 1 addition & 1 deletion adaptors/dummy/test/integration/physical/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var (
testCtxCancel context.CancelFunc
)

func TestAPIs(t *testing.T) {
func TestPhysical(t *testing.T) {
defer GinkgoRecover()

RegisterFailHandler(Fail)
Expand Down
2 changes: 1 addition & 1 deletion adaptors/modbus/Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./adaptors/modbus/bin ./adaptors/modbus/dist ./adaptors/modbus/deploy ./adaptors/modbus/api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
36 changes: 31 additions & 5 deletions adaptors/modbus/test/integration/adaptor/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
. "github.com/onsi/gomega"
grpccodes "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/rancher/octopus/adaptors/modbus/pkg/adaptor"
"github.com/rancher/octopus/pkg/adaptor/api/v1alpha1"
Expand Down Expand Up @@ -73,21 +74,46 @@ var _ = Describe("Connection", func() {
It("should process the input device", func() {
// failed unmarshal
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Model: &metav1.TypeMeta{
APIVersion: "devices.edge.cattle.io/v1alpha1",
Kind: "ModbusDevice",
},
Device: []byte(`{this is an illegal json}`),
}, nil)
err = service.Connect(mockServer)
var sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.InvalidArgument))
Expect(sts.Message()).To(HavePrefix("failed to unmarshal device"))

// correct logic
mockServer.EXPECT().Send(gomock.Any()).Return(nil).AnyTimes()
// failed to connect a device
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Device: []byte(`{"apiVersion":"devices.edge.cattle.io/v1alpha1","kind":"ModbusDevice","metadata":{"name":"correct"},"spec":{"protocol":{"tcp":{"ip":"127.0.0.1","port":80,"slaveID":1}}}}`),
Model: &metav1.TypeMeta{
APIVersion: "devices.edge.cattle.io/v1alpha1",
Kind: "ModbusDevice",
},
Device: []byte(`
{
"apiVersion":"devices.edge.cattle.io/v1alpha1",
"kind":"ModbusDevice",
"metadata":{
"name":"correct",
"namespace":"default"
},
"spec":{
"protocol":{
"tcp":{
"ip":"127.0.0.1",
"port":80,
"slaveID":1
}
}
}
}`),
}, nil)
mockServer.EXPECT().Recv().Return(nil, io.EOF) // simulate to close the connection
err = service.Connect(mockServer)
Expect(err).ToNot(HaveOccurred())
sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.FailedPrecondition))
Expect(sts.Message()).To(Equal("failed to connect to modbus device endpoint: dial tcp 127.0.0.1:80: connect: connection refused"))
})

})
Expand Down
6 changes: 1 addition & 5 deletions adaptors/modbus/test/integration/adaptor/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var (
testCtx context.Context
testCtxCancel context.CancelFunc
)

func TestAPIs(t *testing.T) {
func TestAdaptor(t *testing.T) {
defer GinkgoRecover()

RegisterFailHandler(Fail)
Expand All @@ -29,8 +27,6 @@ func TestAPIs(t *testing.T) {
var _ = BeforeSuite(func(done Done) {
testCtx, testCtxCancel = context.WithCancel(context.Background())

logf.SetLogger(zap.New(zap.UseDevMode(true)))

close(done)
}, 600)

Expand Down
2 changes: 1 addition & 1 deletion adaptors/mqtt/Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./adaptors/mqtt/bin ./adaptors/mqtt/dist ./adaptors/mqtt/deploy ./adaptors/mqtt/api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
3 changes: 0 additions & 3 deletions adaptors/mqtt/deploy/e2e/roomlightcase1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ spec:
adaptor:
node: k3d-k3s-default-server
name: adaptors.edge.cattle.io/mqtt
parameters:
syncInterval: 5
timeout: 10
model:
apiVersion: "devices.edge.cattle.io/v1alpha1"
kind: "MqttDevice"
Expand Down
11 changes: 0 additions & 11 deletions adaptors/mqtt/pkg/adaptor/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,6 @@ func (s *Service) Connect(server api.Connection_ConnectServer) error {
return nil
}

var parameters = physical.DefaultParameters()
if req.GetParameters() != nil {
if err := jsoniter.Unmarshal(req.GetParameters(), &parameters); err != nil {
return status.Errorf(codes.InvalidArgument, "failed to unmarshal parameters: %v", err)
}
}

if err := parameters.Validate(); err != nil {
return status.Errorf(codes.InvalidArgument, "failed to validate parameters: %v", err)
}

// validate device
var mqtt v1alpha1.MqttDevice
if err := jsoniter.Unmarshal(req.GetDevice(), &mqtt); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
. "github.com/onsi/gomega"
grpccodes "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/rancher/octopus/adaptors/mqtt/pkg/adaptor"
"github.com/rancher/octopus/pkg/adaptor/api/v1alpha1"
Expand Down Expand Up @@ -71,50 +72,36 @@ var _ = Describe("Connection", func() {
Expect(err).To(HaveOccurred())
})

It("should process the input parameters", func() {
// failed unmarshal
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Parameters: []byte(`{this is an illegal json}`),
}, nil)
err = service.Connect(mockServer)
var sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.InvalidArgument))
Expect(sts.Message()).To(HavePrefix("failed to unmarshal parameters"))

// illegal parameters: blank IP
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Parameters: []byte(`{"ip":""}`),
}, nil)
err = service.Connect(mockServer)
sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.InvalidArgument))
Expect(sts.Message()).To(Equal("failed to validate parameters: ip is required"))
})

It("should process the input device", func() {
// failed unmarshal
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Parameters: []byte(`{"ip":"127.0.0.1"}`),
Device: []byte(`{this is an illegal json}`),
Model: &metav1.TypeMeta{
APIVersion: "devices.edge.cattle.io/v1alpha1",
Kind: "MqttDevice",
},
Device: []byte(`{this is an illegal json}`),
}, nil)
err = service.Connect(mockServer)
var sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.InvalidArgument))
Expect(sts.Message()).To(HavePrefix("failed to unmarshal device"))

// correct logic
mockServer.EXPECT().Send(gomock.Any()).Return(nil).AnyTimes()
// failed to connect a device
mockServer.EXPECT().Recv().Return(&v1alpha1.ConnectRequest{
Parameters: []byte(`{"ip":"127.0.0.1"}`),
Device: []byte(`{
Model: &metav1.TypeMeta{
APIVersion: "devices.edge.cattle.io/v1alpha1",
Kind: "MqttDevice",
},
Device: []byte(`
{
"apiVersion": "devices.edge.cattle.io/v1alpha1",
"kind": "MqttDevice",
"metadata": {
"creationTimestamp": null,
"name": "testDevice"
"name": "testDevice",
"namespace": "default"
},
"spec": {
"Config": {
"config": {
"broker": "tcp://127.0.0.1:1883",
"password": "parchk",
"username": "test123"
Expand All @@ -132,9 +119,10 @@ var _ = Describe("Connection", func() {
}
}`),
}, nil)
mockServer.EXPECT().Recv().Return(nil, io.EOF) // simulate to close the connection
err = service.Connect(mockServer)
Expect(err).ToNot(HaveOccurred())
sts = status.Convert(err)
Expect(sts.Code()).To(Equal(grpccodes.InvalidArgument))
Expect(sts.Message()).To(Equal("failed to connect mqtt: Network Error : dial tcp 127.0.0.1:1883: connect: connection refused"))
})

})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var (
testCtx context.Context
testCtxCancel context.CancelFunc
)

func TestAPIs(t *testing.T) {
func TestAdaptor(t *testing.T) {
defer GinkgoRecover()

RegisterFailHandler(Fail)
Expand All @@ -29,8 +27,6 @@ func TestAPIs(t *testing.T) {
var _ = BeforeSuite(func(done Done) {
testCtx, testCtxCancel = context.WithCancel(context.Background())

logf.SetLogger(zap.New(zap.UseDevMode(true)))

close(done)
}, 600)

Expand Down
2 changes: 1 addition & 1 deletion adaptors/opcua/Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
ENV DAPPER_RUN_ARGS --privileged --network host
ENV GO111MODULE=off
ENV CROSS=false
ENV DAPPER_ENV CROSS LOCAL_CLUSTER_KIND DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_ENV CROSS CLUSTER_TYPE DOCKER_USERNAME DOCKER_PASSWORD WITHOUT_MANIFEST ONLY_MANIFEST IGNORE_MISSING DRONE_TAG REPO TAG OS ARCH IMAGE_NAME DIRTY_CHECK
ENV DAPPER_SOURCE /go/src/github.com/rancher/octopus/
ENV DAPPER_OUTPUT ./adaptors/opcua/bin ./adaptors/opcua/dist ./adaptors/opcua/deploy ./adaptors/opcua/api
ENV DAPPER_DOCKER_SOCKET true
Expand Down
Loading

0 comments on commit 027e191

Please sign in to comment.