github.com/midokura/kubeedge@v1.2.0-mido.0/tests/e2e/mapper/bluetooth/bluetooth_test.go (about)

     1  /*
     2  Copyright 2019 The KubeEdge Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8     http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package bluetooth
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"io/ioutil"
    23  	"net/http"
    24  	"path"
    25  	"reflect"
    26  	"time"
    27  
    28  	MQTT "github.com/eclipse/paho.mqtt.golang"
    29  	. "github.com/onsi/ginkgo"
    30  	. "github.com/onsi/gomega"
    31  
    32  	"github.com/kubeedge/kubeedge/cloud/pkg/apis/devices/v1alpha1"
    33  	"github.com/kubeedge/kubeedge/edge/test/integration/utils/common"
    34  	"github.com/kubeedge/kubeedge/edge/test/integration/utils/helpers"
    35  	"github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/scheduler"
    36  	"github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/watcher"
    37  	"github.com/kubeedge/kubeedge/tests/e2e/utils"
    38  )
    39  
    40  var TokenClient Token
    41  var ClientOpts *MQTT.ClientOptions
    42  var Client MQTT.Client
    43  var timesSpecified int
    44  var timesExecuted int
    45  
    46  type ScheduleResult struct {
    47  	EventName   string
    48  	TimeStamp   int64
    49  	EventResult string
    50  }
    51  
    52  var scheduleResult ScheduleResult
    53  var dataConverted bool
    54  var readWrittenData bool
    55  
    56  // DataConversion checks whether data is properly as expected by the data converter.
    57  func DataConversion(client MQTT.Client, message MQTT.Message) {
    58  	topic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
    59  	expectedTemp := "32.375000"
    60  	dataConverted = false
    61  	if message.Topic() == topic {
    62  		devicePayload := message.Payload()
    63  		err := json.Unmarshal(devicePayload, &scheduleResult)
    64  		if err != nil {
    65  			utils.Fatalf("Unmarshall failed %s", err)
    66  		} else {
    67  			if reflect.DeepEqual(scheduleResult.EventResult, expectedTemp) {
    68  				dataConverted = true
    69  			}
    70  		}
    71  	}
    72  }
    73  
    74  // WriteDataReceived checks whether data is properly written to connected device.
    75  func WriteDataReceived(client MQTT.Client, message MQTT.Message) {
    76  	topic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
    77  	readWrittenData = false
    78  	if message.Topic() == topic {
    79  		devicePayload := message.Payload()
    80  		err := json.Unmarshal(devicePayload, &scheduleResult)
    81  		data := []byte{1}
    82  		if err != nil {
    83  			utils.Fatalf("Unmarshall failed %s", err)
    84  		} else {
    85  			if reflect.DeepEqual(string(data), scheduleResult.EventResult) {
    86  				readWrittenData = true
    87  			}
    88  		}
    89  	}
    90  }
    91  
    92  // ScheculeExecute counts the number of times schedule is executed by the Scheduler.
    93  func ScheduleExecute(client MQTT.Client, message MQTT.Message) {
    94  	topic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
    95  	expectedTemp := "36"
    96  	if message.Topic() == topic {
    97  		devicePayload := message.Payload()
    98  		err := json.Unmarshal(devicePayload, &scheduleResult)
    99  		if err != nil {
   100  			utils.Fatalf("Unmarshall failed %s", err)
   101  		} else {
   102  			if reflect.DeepEqual(scheduleResult.EventResult, expectedTemp) {
   103  				timesExecuted++
   104  			}
   105  		}
   106  	}
   107  }
   108  
   109  // Checks whether mapper has written data correctly to connected device
   110  var _ = Describe("Application deployment test in E2E scenario", func() {
   111  	Context("Test write characteristic of mapper", func() {
   112  		BeforeEach(func() {
   113  			// Subscribing to topic where scheduler publishes the data
   114  			ClientOpts = helpers.HubClientInit(ctx.Cfg.MqttEndpoint, "bluetoothmapper", "", "")
   115  			Client = MQTT.NewClient(ClientOpts)
   116  			if TokenClient = Client.Connect(); TokenClient.Wait() && TokenClient.Error() != nil {
   117  				utils.Fatalf("client.Connect() Error is %s", TokenClient.Error())
   118  			} else {
   119  				utils.Infof("Connection successful")
   120  			}
   121  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   122  			scheduletopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
   123  			Token := Client.Subscribe(scheduletopic, 0, WriteDataReceived)
   124  			if Token.Wait() && TokenClient.Error() != nil {
   125  				utils.Fatalf("Subscribe to Topic  Failed  %s, %s", TokenClient.Error(), scheduletopic)
   126  			}
   127  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   128  		})
   129  		AfterEach(func() {
   130  			Client.Disconnect(1)
   131  			common.PrintTestcaseNameandStatus()
   132  		})
   133  		It("E2E_WRITE: Ensure whether mapper is able to write data and read it back from connected device", func() {
   134  			//creating deployment from deployment yaml of bluetooth mapper
   135  			curpath := getpwd()
   136  			file := path.Join(curpath, deployPath)
   137  			body, err := ioutil.ReadFile(file)
   138  			Expect(err).Should(BeNil())
   139  			client := &http.Client{}
   140  			BodyBuf := bytes.NewReader(body)
   141  			req, err := http.NewRequest(http.MethodPost, ctx.Cfg.K8SMasterForKubeEdge+deploymentHandler, BodyBuf)
   142  			Expect(err).Should(BeNil())
   143  			req.Header.Set("Content-Type", "application/yaml")
   144  			resp, err := client.Do(req)
   145  			Expect(err).To(BeNil())
   146  			Expect(resp.StatusCode).Should(Equal(http.StatusCreated))
   147  			podlist, err := utils.GetPods(ctx.Cfg.K8SMasterForKubeEdge+appHandler, nodeName)
   148  			utils.WaitforPodsRunning(ctx.Cfg.KubeConfigPath, podlist, 240*time.Second)
   149  			Eventually(func() bool {
   150  				return readWrittenData
   151  			}, "120s", "0.5s").ShouldNot(Equal(false), "Message is not recieved in expected time !!")
   152  		})
   153  	})
   154  
   155  	// Checking whether dataconverter works correctly
   156  	Context("Test whether dataconverter works properly", func() {
   157  		BeforeEach(func() {
   158  			// Subscribing to topic where scheduler publishes the data
   159  			ClientOpts = helpers.HubClientInit(ctx.Cfg.MqttEndpoint, "bluetoothmapper", "", "")
   160  			Client = MQTT.NewClient(ClientOpts)
   161  			if TokenClient = Client.Connect(); TokenClient.Wait() && TokenClient.Error() != nil {
   162  				utils.Fatalf("client.Connect() Error is %s", TokenClient.Error())
   163  			} else {
   164  				utils.Infof("Subscribe Connection Successful")
   165  			}
   166  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   167  			scheduletopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
   168  			Token := Client.Subscribe(scheduletopic, 0, DataConversion)
   169  			if Token.Wait() && TokenClient.Error() != nil {
   170  				utils.Fatalf("Subscribe to Topic  Failed  %s, %s", TokenClient.Error(), scheduletopic)
   171  			}
   172  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   173  			var expectedSchedule []scheduler.Schedule
   174  			// Create and publish run time data schedule for data conversion.
   175  			schedule := scheduler.Schedule{Name: "temperatureconversion", Interval: 3000, OccurrenceLimit: 1, Actions: []string{"ConvertTemperatureData"}}
   176  			expectedSchedule = []scheduler.Schedule{schedule}
   177  			scheduleCreateTopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/create"
   178  			scheduleCreate, err := json.Marshal(expectedSchedule)
   179  			if err != nil {
   180  				utils.Fatalf("Error in marshalling: %s", err)
   181  			}
   182  			TokenClient = Client.Publish(scheduleCreateTopic, 0, false, scheduleCreate)
   183  			if TokenClient.Wait() && TokenClient.Error() != nil {
   184  				utils.Fatalf("Publish to Topic  Failed  %s, %s", TokenClient.Error(), scheduleCreateTopic)
   185  			}
   186  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   187  		})
   188  		It("E2E_DATACONVERTER: Test whether dataconverter has performed conversion correctly", func() {
   189  			Eventually(func() bool {
   190  				return dataConverted
   191  			}, "30s", "0.5s").Should(Equal(true))
   192  		})
   193  		AfterEach(func() {
   194  			Client.Disconnect(1)
   195  			common.PrintTestcaseNameandStatus()
   196  		})
   197  	})
   198  
   199  	// Checking whether schedule executed the expected number of times using runtime update
   200  	Context("Test whether schedule is executed properly", func() {
   201  		BeforeEach(func() {
   202  			// Subscribing to topic where scheduler publishes the data
   203  			ClientOpts = helpers.HubClientInit(ctx.Cfg.MqttEndpoint, "bluetoothmapper", "", "")
   204  			Client = MQTT.NewClient(ClientOpts)
   205  			if TokenClient = Client.Connect(); TokenClient.Wait() && TokenClient.Error() != nil {
   206  				utils.Fatalf("client.Connect() Error is %s", TokenClient.Error())
   207  			} else {
   208  				utils.Infof("Subscribe Connection successful")
   209  			}
   210  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   211  			scheduletopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/result"
   212  			Token := Client.Subscribe(scheduletopic, 0, ScheduleExecute)
   213  			if Token.Wait() && TokenClient.Error() != nil {
   214  				utils.Fatalf("Subscribe to Topic  Failed  %s, %s", TokenClient.Error(), scheduletopic)
   215  			}
   216  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   217  			var expectedSchedule []scheduler.Schedule
   218  			// Create and publish run time data for scheduler
   219  			schedule := scheduler.Schedule{Name: "temperature", Interval: 1000, OccurrenceLimit: 5, Actions: []string{"IRTemperatureData"}}
   220  			expectedSchedule = []scheduler.Schedule{schedule}
   221  			scheduleCreateTopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/scheduler/create"
   222  			scheduleCreate, err := json.Marshal(expectedSchedule)
   223  			if err != nil {
   224  				utils.Fatalf("Error in marshalling: %s", err)
   225  			}
   226  			TokenClient = Client.Publish(scheduleCreateTopic, 0, false, scheduleCreate)
   227  			if TokenClient.Wait() && TokenClient.Error() != nil {
   228  				utils.Fatalf("Publish to Topic  Failed  %s, %s", TokenClient.Error(), scheduleCreateTopic)
   229  			}
   230  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   231  		})
   232  		It("E2E_SCHEDULER: Test whether the schedule is executed the specified number of times", func() {
   233  			timesSpecified = 5
   234  			time.Sleep(10 * time.Second)
   235  			Expect(timesExecuted).To(Equal(timesSpecified))
   236  		})
   237  		AfterEach(func() {
   238  			Client.Disconnect(1)
   239  			common.PrintTestcaseNameandStatus()
   240  		})
   241  	})
   242  
   243  	// check whether watcher has performed its operation successfully.
   244  	Context("Test whether watcher has succesfully updated the twin state as desired", func() {
   245  		BeforeEach(func() {
   246  			var expectedWatchAttribute watcher.Watcher
   247  			// Create and publish scheduler run time data
   248  			watchAttribute := watcher.Attribute{Name: "io-data", Actions: []string{"IOData"}}
   249  			devTwinAtt := []watcher.Attribute{watchAttribute}
   250  			expectedWatchAttribute = watcher.Watcher{devTwinAtt}
   251  			// Subscribing to topic where scheduler publishes the data
   252  			ClientOpts = helpers.HubClientInit(ctx.Cfg.MqttEndpoint, "bluetoothmapper", "", "")
   253  			Client = MQTT.NewClient(ClientOpts)
   254  			if TokenClient = Client.Connect(); TokenClient.Wait() && TokenClient.Error() != nil {
   255  				utils.Fatalf("client.Connect() Error is %s", TokenClient.Error())
   256  			} else {
   257  				utils.Infof("Publish Connection successful")
   258  			}
   259  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   260  			watcherCreateTopic := "$ke/device/bluetooth-mapper/mock-temp-sensor-instance/watcher/create"
   261  			scheduleCreate, err := json.Marshal(expectedWatchAttribute)
   262  			if err != nil {
   263  				utils.Fatalf("Error in marshalling: %s", err)
   264  			}
   265  			TokenClient = Client.Publish(watcherCreateTopic, 0, false, scheduleCreate)
   266  			if TokenClient.Wait() && TokenClient.Error() != nil {
   267  				utils.Fatalf("Publish to Topic  Failed  %s, %s", TokenClient.Error(), watcherCreateTopic)
   268  			}
   269  			Expect(TokenClient.Error()).NotTo(HaveOccurred())
   270  		})
   271  		It("E2E_WATCHER: Test whether the watcher performs it operation correctly", func() {
   272  			var deviceList v1alpha1.DeviceList
   273  			newLedDevice := utils.NewMockInstance(nodeName)
   274  			time.Sleep(20 * time.Second)
   275  			list, err := utils.GetDevice(&deviceList, ctx.Cfg.K8SMasterForKubeEdge+mockInstanceHandler, &newLedDevice)
   276  			Expect(err).To(BeNil())
   277  			Expect(list[0].Status.Twins[0].PropertyName).To(Equal("io-data"))
   278  			Expect(list[0].Status.Twins[0].Reported.Value).To(Equal("Red"))
   279  		})
   280  		AfterEach(func() {
   281  			Client.Disconnect(1)
   282  			common.PrintTestcaseNameandStatus()
   283  		})
   284  	})
   285  })