blob: 5023cc81f5dc0d74804b5d577fad4c5766589593 [file] [log] [blame]
Jonathan Hart4b110f62020-03-13 17:36:19 -07001/*
2 Copyright 2020 the original author or 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
17package openflow
18
19import (
Rohan Agrawalc32d9932020-06-15 11:01:47 +000020 "context"
Jonathan Hart828908c2020-04-15 14:23:45 -070021 ofp "github.com/opencord/goloxi/of13"
Jonathan Hart4b110f62020-03-13 17:36:19 -070022 "github.com/stretchr/testify/assert"
23 "testing"
24)
25
26type testRoleManager struct {
27 role ofp.ControllerRole
28 generationId uint64
29 from string
30
31 generateError bool
32}
33
Rohan Agrawalc32d9932020-06-15 11:01:47 +000034func (trm *testRoleManager) UpdateRoles(ctx context.Context, from string, request *ofp.RoleRequest) bool {
Jonathan Hart4b110f62020-03-13 17:36:19 -070035 trm.from = from
36 trm.role = request.Role
37 trm.generationId = request.GenerationId
38
39 return !trm.generateError
40}
41
42func createOFClient() *OFClient {
43 endpoints := []string{"e1", "e2", "e3"}
44
45 // create a client object
46 ofclient := &OFClient{
47 OFControllerEndPoints: endpoints,
48 connections: make(map[string]*OFConnection),
49 }
50
51 // create a connection object for each endpoint
52 for _, ep := range endpoints {
53 conn := &OFConnection{OFControllerEndPoint: ep, role: ofcRoleNone}
54 ofclient.connections[ep] = conn
55 }
56
57 return ofclient
58}
59
60func createRoleRequest(role ofp.ControllerRole, genId uint64) *ofp.RoleRequest {
61 rr := ofp.NewRoleRequest()
62 rr.Role = role
63 rr.GenerationId = genId
64 return rr
65}
66
67func TestRoleChange(t *testing.T) {
68 endpoints := []string{"e1", "e2", "e3"}
69 ofclient := &OFClient{
70 OFControllerEndPoints: endpoints, connections: make(map[string]*OFConnection),
71 }
72
73 for _, ep := range endpoints {
74 conn := &OFConnection{OFControllerEndPoint: ep, role: ofcRoleNone}
75 ofclient.connections[ep] = conn
76 }
77
78 assert.Equal(t, ofclient.connections["e1"].role, ofcRoleNone)
79
80 // change role of e1 to master
81 rr := createRoleRequest(ofp.OFPCRRoleMaster, 1)
82
Rohan Agrawalc32d9932020-06-15 11:01:47 +000083 ctx := context.Background()
84
85 ok := ofclient.UpdateRoles(ctx, "e1", rr)
Jonathan Hart4b110f62020-03-13 17:36:19 -070086 assert.True(t, ok)
87 assert.Equal(t, ofclient.connections["e1"].role, ofcRoleMaster)
88
89 // change role of e2 to master
Rohan Agrawalc32d9932020-06-15 11:01:47 +000090 ok = ofclient.UpdateRoles(ctx, "e2", rr)
Jonathan Hart4b110f62020-03-13 17:36:19 -070091 assert.True(t, ok)
92 assert.Equal(t, ofclient.connections["e2"].role, ofcRoleMaster)
93 // e1 should now have reverted to slave
94 assert.Equal(t, ofclient.connections["e1"].role, ofcRoleSlave)
95
96 // change role of e2 to slave
97 rr = createRoleRequest(ofp.OFPCRRoleSlave, 1)
98
Rohan Agrawalc32d9932020-06-15 11:01:47 +000099 ok = ofclient.UpdateRoles(ctx, "e2", rr)
Jonathan Hart4b110f62020-03-13 17:36:19 -0700100 assert.True(t, ok)
101 assert.Equal(t, ofclient.connections["e2"].role, ofcRoleSlave)
102}
103
104func TestStaleRoleRequest(t *testing.T) {
105 ofclient := createOFClient()
106
107 rr1 := createRoleRequest(ofp.OFPCRRoleMaster, 2)
108
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000109 ctx := context.Background()
110
111 ok := ofclient.UpdateRoles(ctx, "e1", rr1)
Jonathan Hart4b110f62020-03-13 17:36:19 -0700112 assert.True(t, ok)
113 assert.Equal(t, ofclient.connections["e1"].role, ofcRoleMaster)
114
115 // 'stale' role request
116 rr2 := createRoleRequest(ofp.OFPCRRoleSlave, 1)
117
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000118 ok = ofclient.UpdateRoles(ctx, "e1", rr2)
Jonathan Hart4b110f62020-03-13 17:36:19 -0700119 // should not have succeeded
120 assert.False(t, ok)
121 // role should remain master
122 assert.Equal(t, ofclient.connections["e1"].role, ofcRoleMaster)
123}
124
125func TestHandleRoleRequest(t *testing.T) {
126
127 trm := &testRoleManager{}
128
129 connection := &OFConnection{
130 OFControllerEndPoint: "e1",
131 roleManager: trm,
132 sendChannel: make(chan Message, 10),
133 }
134
135 rr := createRoleRequest(ofp.OFPCRRoleMaster, 1)
136
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000137 connection.handleRoleRequest(context.Background(), rr)
Jonathan Hart4b110f62020-03-13 17:36:19 -0700138
139 assert.Equal(t, "e1", trm.from)
140 assert.EqualValues(t, ofp.OFPCRRoleMaster, trm.role)
141 assert.EqualValues(t, 1, trm.generationId)
142
143 resp := (<-connection.sendChannel).(*ofp.RoleReply)
144
145 assert.EqualValues(t, resp.Role, ofp.OFPCRRoleMaster)
146}
147
148func TestHandleRoleRequestError(t *testing.T) {
149
150 trm := &testRoleManager{generateError: true}
151
152 connection := &OFConnection{
153 OFControllerEndPoint: "e1",
154 roleManager: trm,
155 sendChannel: make(chan Message, 10),
156 }
157
158 rr := createRoleRequest(ofp.OFPCRRoleMaster, 1)
159
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000160 connection.handleRoleRequest(context.Background(), rr)
Jonathan Hart4b110f62020-03-13 17:36:19 -0700161
162 resp := (<-connection.sendChannel).(*ofp.RoleRequestFailedErrorMsg)
163
164 assert.EqualValues(t, resp.Code, ofp.OFPRRFCStale)
165}