github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/edgehub/clients/wsclient/websocket_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 wsclient
    18  
    19  import (
    20  	"crypto/tls"
    21  	"fmt"
    22  	"reflect"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/satori/go.uuid"
    27  	"k8s.io/klog"
    28  
    29  	"github.com/kubeedge/beehive/pkg/core/model"
    30  	"github.com/kubeedge/kubeedge/edge/pkg/common/util"
    31  	"github.com/kubeedge/viaduct/pkg/api"
    32  	"github.com/kubeedge/viaduct/pkg/conn"
    33  	"github.com/kubeedge/viaduct/pkg/mux"
    34  	"github.com/kubeedge/viaduct/pkg/server"
    35  )
    36  
    37  //init() starts the test server and generates test certificates for testing
    38  func init() {
    39  	err := util.GenerateTestCertificate("/tmp/", "edge", "edge")
    40  	if err != nil {
    41  		panic("Error in creating fake certificates")
    42  	}
    43  
    44  	newTestServer()
    45  }
    46  
    47  func newTestWebSocketClient(api string, certPath string, keyPath string) *WebSocketClient {
    48  	return &WebSocketClient{
    49  		config: &WebSocketConfig{
    50  			URL:              "wss://localhost:9890/" + api,
    51  			CertFilePath:     certPath,
    52  			KeyFilePath:      keyPath,
    53  			HandshakeTimeout: 500 * time.Second,
    54  			WriteDeadline:    100 * time.Second,
    55  			ReadDeadline:     100 * time.Second,
    56  			NodeID:           "test-nodeid",
    57  			ProjectID:        "test-projectid",
    58  		},
    59  	}
    60  }
    61  
    62  func handleServer(container *mux.MessageContainer, writer mux.ResponseWriter) {
    63  	klog.Infof("receive message: %s", container.Message.GetContent())
    64  	writer.WriteResponse(&model.Message{}, container.Message.GetContent())
    65  
    66  }
    67  
    68  func initServerEntries() {
    69  	mux.Entry(mux.NewPattern("*").Op("*"), handleServer)
    70  }
    71  
    72  func connNotify(conn conn.Connection) {
    73  	klog.Info("receive a connection")
    74  }
    75  
    76  //newTestServer() starts a fake server for testing
    77  func newTestServer() {
    78  	exOpts := api.WSServerOption{
    79  		Path: "/",
    80  	}
    81  
    82  	cert, err := tls.LoadX509KeyPair("/tmp/edge.crt", "/tmp/edge.key")
    83  	if err != nil {
    84  		klog.Errorf("Failed to load x509 key pair: %v", err)
    85  		return
    86  	}
    87  
    88  	tlsConfig := &tls.Config{
    89  		Certificates: []tls.Certificate{cert},
    90  	}
    91  
    92  	server := server.Server{
    93  		Type:       "websocket",
    94  		Addr:       "localhost:9890",
    95  		TLSConfig:  tlsConfig,
    96  		AutoRoute:  true,
    97  		ConnNotify: connNotify,
    98  		ExOpts:     exOpts,
    99  	}
   100  
   101  	initServerEntries()
   102  	go func() {
   103  		err = server.ListenAndServeTLS("", "")
   104  		if err != nil {
   105  			klog.Errorf("listen and serve tls failed, error: %+v", err)
   106  		}
   107  	}()
   108  }
   109  
   110  //TestNewWebSocketClient tests the NewWebSocketClient function that creates the WebSocketClient object
   111  func TestNewWebSocketClient(t *testing.T) {
   112  	tests := []struct {
   113  		name string
   114  		conf *WebSocketConfig
   115  		want *WebSocketClient
   116  	}{
   117  		{"TestNewWebSocketClient: ",
   118  			&WebSocketConfig{
   119  				URL:              "wss://localhost:9890/normal",
   120  				CertFilePath:     "/tmp/edge.crt",
   121  				KeyFilePath:      "/tmp/edge.key",
   122  				HandshakeTimeout: 500 * time.Second,
   123  				WriteDeadline:    100 * time.Second,
   124  				ReadDeadline:     100 * time.Second,
   125  				NodeID:           "test-nodeid",
   126  				ProjectID:        "test-projectid",
   127  			},
   128  			newTestWebSocketClient("normal", "/tmp/edge.crt", "/tmp/edge.key"),
   129  		},
   130  	}
   131  	for _, tt := range tests {
   132  		t.Run(tt.name, func(t *testing.T) {
   133  			if got := NewWebSocketClient(tt.conf); !reflect.DeepEqual(got, tt.want) {
   134  				t.Errorf("NewWebSocketClient() got = %v, want %v", got, tt.want)
   135  			}
   136  		})
   137  	}
   138  }
   139  
   140  //TestInit tests the procurement of the WebSocketClient
   141  func TestInit(t *testing.T) {
   142  	tests := []struct {
   143  		name          string
   144  		fields        *WebSocketClient
   145  		expectedError error
   146  	}{
   147  		{name: "TestInit: Success in connection ",
   148  			fields:        newTestWebSocketClient("normal", "/tmp/edge.crt", "/tmp/edge.key"),
   149  			expectedError: nil,
   150  		},
   151  		{name: "TestInit: If Certificate files not loaded properly",
   152  			fields:        newTestWebSocketClient("normal", "/wrong_path.crt", "/wrong_path.key"),
   153  			expectedError: fmt.Errorf("failed to load x509 key pair, error: open /wrong_path.crt: no such file or directory"),
   154  		},
   155  	}
   156  	for _, tt := range tests {
   157  		t.Run(tt.name, func(t *testing.T) {
   158  			wcc := tt.fields
   159  			err := wcc.Init()
   160  			if !reflect.DeepEqual(err, tt.expectedError) {
   161  				t.Errorf("WebSocketClient.Init() error = %v, expectedError =  %v", err, tt.expectedError)
   162  			}
   163  		})
   164  	}
   165  }
   166  
   167  //TestUninit tests the Uninit function by trying to access the connection object
   168  func TestUninit(t *testing.T) {
   169  	tests := []struct {
   170  		name   string
   171  		fields *WebSocketClient
   172  	}{
   173  		{name: "TestUninit ",
   174  			fields: newTestWebSocketClient("normal", "/tmp/edge.crt", "/tmp/edge.key"),
   175  		},
   176  	}
   177  	for _, tt := range tests {
   178  		t.Run(tt.name, func(t *testing.T) {
   179  			wcc := tt.fields
   180  			wcc.Init()
   181  			wcc.Uninit()
   182  			err := wcc.connection.WriteMessageAsync(&model.Message{})
   183  			if err == nil {
   184  				t.Errorf("WebSocketClient.Uninit")
   185  			}
   186  		})
   187  	}
   188  }
   189  
   190  //TestSend checks send function by sending message to server
   191  func TestSend(t *testing.T) {
   192  	var msg = model.Message{
   193  		Header: model.MessageHeader{
   194  			ID:        uuid.NewV4().String(),
   195  			ParentID:  "12",
   196  			Timestamp: time.Now().UnixNano() / 1e6,
   197  		},
   198  		Content: "test",
   199  	}
   200  	tests := []struct {
   201  		name          string
   202  		fields        *WebSocketClient
   203  		message       model.Message
   204  		expectedError error
   205  	}{
   206  		{
   207  			name:          "Test sending small message: ",
   208  			fields:        newTestWebSocketClient("normal", "/tmp/edge.crt", "/tmp/edge.key"),
   209  			message:       msg,
   210  			expectedError: nil,
   211  		},
   212  	}
   213  	for _, tt := range tests {
   214  		t.Run(tt.name, func(t *testing.T) {
   215  			wcc := tt.fields
   216  			//First run init
   217  			wcc.Init()
   218  
   219  			if err := wcc.Send(tt.message); !reflect.DeepEqual(err, tt.expectedError) {
   220  				t.Errorf("WebSocketClient.Send() error = %v, expectedError = %v", err, tt.expectedError)
   221  			}
   222  		})
   223  	}
   224  }
   225  
   226  //TestReceive sends the message through send function then calls receive function to see same message is received or not
   227  func TestReceive(t *testing.T) {
   228  	var msg = model.Message{
   229  		Header: model.MessageHeader{
   230  			ID:        uuid.NewV4().String(),
   231  			ParentID:  "12",
   232  			Timestamp: time.Now().UnixNano() / 1e6,
   233  		},
   234  		Content: "test",
   235  	}
   236  	tests := []struct {
   237  		name          string
   238  		fields        *WebSocketClient
   239  		want          model.Message
   240  		sent          model.Message
   241  		expectedError error
   242  	}{
   243  		{name: "Test Receiving the send message: Success in receiving",
   244  			fields:        newTestWebSocketClient("normal", "/tmp/edge.crt", "/tmp/edge.key"),
   245  			want:          msg,
   246  			sent:          msg,
   247  			expectedError: nil,
   248  		},
   249  	}
   250  
   251  	for _, tt := range tests {
   252  		t.Run(tt.name, func(t *testing.T) {
   253  			wcc := tt.fields
   254  			//First run init
   255  			wcc.Init()
   256  			//Run send
   257  			err := wcc.Send(tt.sent)
   258  
   259  			if err != nil {
   260  				t.Errorf("error = %v", err)
   261  			}
   262  
   263  			got, err := wcc.Receive()
   264  			if !reflect.DeepEqual(err, tt.expectedError) {
   265  				t.Errorf("WebSocketClient.Receive() error = %v, expectedError = %v", err, tt.expectedError)
   266  				return
   267  			}
   268  			if !reflect.DeepEqual(fmt.Sprintf("%s", got.GetContent()), fmt.Sprintf("%s", tt.want.GetContent())) {
   269  				t.Errorf("WebSocketClient.Receive() message content: got = %s, want = %s", got.GetContent(), tt.want.GetContent())
   270  			}
   271  			wcc.Uninit()
   272  		})
   273  	}
   274  }