blob: f32c6f8f279568c4518603452fdacbf82ee3d41c [file] [log] [blame]
Matteo Scandolo47e69bb2019-08-28 15:41:12 -07001/*
2 * Copyright 2018-present Open Networking Foundation
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 eapol
18
19import (
Matteo Scandolo075b1892019-10-07 12:11:07 -070020 "errors"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070021 "github.com/looplab/fsm"
22 "github.com/opencord/voltha-protos/go/openolt"
23 "google.golang.org/grpc"
24 "gotest.tools/assert"
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070025 "net"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070026 "testing"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070027)
28
Matteo Scandolo075b1892019-10-07 12:11:07 -070029// MOCKS
Matteo Scandolo075b1892019-10-07 12:11:07 -070030
31var eapolStateMachine = fsm.NewFSM(
32 "auth_started",
33 fsm.Events{
34 {Name: "eap_start_sent", Src: []string{"auth_started"}, Dst: "eap_start_sent"},
35 {Name: "eap_response_identity_sent", Src: []string{"eap_start_sent"}, Dst: "eap_response_identity_sent"},
36 {Name: "eap_response_challenge_sent", Src: []string{"eap_response_identity_sent"}, Dst: "eap_response_challenge_sent"},
37 {Name: "eap_response_success_received", Src: []string{"eap_response_challenge_sent"}, Dst: "eap_response_success_received"},
38 {Name: "auth_failed", Src: []string{"auth_started", "eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent"}, Dst: "auth_failed"},
39 },
40 fsm.Callbacks{},
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070041)
42
Matteo Scandolo27428702019-10-11 16:21:16 -070043// params for the function under test
44var onuId uint32 = 1
45var gemPortId uint16 = 1
46var ponPortId uint32 = 0
47var serialNumber string = "BBSM00000001"
48var macAddress = net.HardwareAddr{0x01, 0x80, 0xC2, 0x00, 0x00, 0x03}
49var portNo uint32 = 16
50
51type mockStream struct {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070052 grpc.ServerStream
Matteo Scandolo27428702019-10-11 16:21:16 -070053 CallCount int
54 Calls map[int]*openolt.PacketIndication
55 fail bool
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070056}
57
Matteo Scandolo27428702019-10-11 16:21:16 -070058func (s *mockStream) Send(ind *openolt.Indication) error {
59 s.CallCount++
60 if s.fail {
61 return errors.New("fake-error")
62 }
63 s.Calls[s.CallCount] = ind.GetPktInd()
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070064 return nil
65}
66
Matteo Scandolo075b1892019-10-07 12:11:07 -070067// TESTS
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070068
Matteo Scandolo075b1892019-10-07 12:11:07 -070069func TestSendEapStartSuccess(t *testing.T) {
Matteo Scandolo075b1892019-10-07 12:11:07 -070070 eapolStateMachine.SetState("auth_started")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070071
Matteo Scandolo075b1892019-10-07 12:11:07 -070072 // Save current function and restore at the end:
73 old := GetGemPortId
74 defer func() { GetGemPortId = old }()
75
76 GetGemPortId = func(intfId uint32, onuId uint32) (uint16, error) {
Matteo Scandolo27428702019-10-11 16:21:16 -070077 return gemPortId, nil
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070078 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070079
Matteo Scandolo27428702019-10-11 16:21:16 -070080 stream := &mockStream{
81 Calls: make(map[int]*openolt.PacketIndication),
82 fail: false,
83 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070084
Matteo Scandolo27428702019-10-11 16:21:16 -070085 if err := SendEapStart(onuId, ponPortId, serialNumber, portNo, macAddress, eapolStateMachine, stream); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -070086 t.Errorf("SendEapStart returned an error: %v", err)
87 t.Fail()
88 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070089
Matteo Scandolo27428702019-10-11 16:21:16 -070090 assert.Equal(t, stream.CallCount, 1)
91 assert.Equal(t, stream.Calls[1].PortNo, portNo)
92 assert.Equal(t, stream.Calls[1].IntfId, ponPortId)
93 assert.Equal(t, stream.Calls[1].IntfType, "pon")
94 assert.Equal(t, stream.Calls[1].GemportId, uint32(gemPortId))
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070095
Matteo Scandolo075b1892019-10-07 12:11:07 -070096 assert.Equal(t, eapolStateMachine.Current(), "eap_start_sent")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070097
Matteo Scandolo075b1892019-10-07 12:11:07 -070098}
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070099
Matteo Scandolo075b1892019-10-07 12:11:07 -0700100func TestSendEapStartFailNoGemPort(t *testing.T) {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700101 eapolStateMachine.SetState("auth_started")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700102
Matteo Scandolo075b1892019-10-07 12:11:07 -0700103 // Save current function and restore at the end:
104 old := GetGemPortId
105 defer func() { GetGemPortId = old }()
106
107 GetGemPortId = func(intfId uint32, onuId uint32) (uint16, error) {
108 return 0, errors.New("no-gem-port")
109 }
110
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700111 var macAddress = net.HardwareAddr{0x01, 0x80, 0xC2, 0x00, 0x00, 0x03}
112
Matteo Scandolo27428702019-10-11 16:21:16 -0700113 stream := &mockStream{
114 Calls: make(map[int]*openolt.PacketIndication),
115 fail: false,
116 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700117
Matteo Scandolo27428702019-10-11 16:21:16 -0700118 err := SendEapStart(onuId, ponPortId, serialNumber, portNo, macAddress, eapolStateMachine, stream)
Matteo Scandolo075b1892019-10-07 12:11:07 -0700119 if err == nil {
120 t.Errorf("SendEapStart did not return an error")
121 t.Fail()
122 }
123
124 assert.Equal(t, err.Error(), "no-gem-port")
125
126 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
127}
128
129func TestSendEapStartFailStreamError(t *testing.T) {
Matteo Scandolo27428702019-10-11 16:21:16 -0700130
Matteo Scandolo075b1892019-10-07 12:11:07 -0700131 eapolStateMachine.SetState("auth_started")
132
133 // Save current function and restore at the end:
134 old := GetGemPortId
135 defer func() { GetGemPortId = old }()
136
137 GetGemPortId = func(intfId uint32, onuId uint32) (uint16, error) {
138 return 1, nil
139 }
140
Matteo Scandolo27428702019-10-11 16:21:16 -0700141 stream := &mockStream{
142 Calls: make(map[int]*openolt.PacketIndication),
143 fail: true,
144 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700145
Matteo Scandolo27428702019-10-11 16:21:16 -0700146 err := SendEapStart(onuId, ponPortId, serialNumber, portNo, macAddress, eapolStateMachine, stream)
Matteo Scandolo075b1892019-10-07 12:11:07 -0700147 if err == nil {
148 t.Errorf("SendEapStart did not return an error")
149 t.Fail()
150 }
151
Matteo Scandolo27428702019-10-11 16:21:16 -0700152 assert.Equal(t, err.Error(), "fake-error")
Matteo Scandolo075b1892019-10-07 12:11:07 -0700153
154 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
155}
156
157// TODO test eapol.HandleNextPacket
158
159func TestUpdateAuthFailed(t *testing.T) {
160
161 var onuId uint32 = 1
162 var ponPortId uint32 = 0
163 var serialNumber string = "BBSM00000001"
164
165 eapolStateMachine.SetState("auth_started")
166 updateAuthFailed(onuId, ponPortId, serialNumber, eapolStateMachine)
167 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
168
169 eapolStateMachine.SetState("eap_start_sent")
170 updateAuthFailed(onuId, ponPortId, serialNumber, eapolStateMachine)
171 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
172
173 eapolStateMachine.SetState("eap_response_identity_sent")
174 updateAuthFailed(onuId, ponPortId, serialNumber, eapolStateMachine)
175 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
176
177 eapolStateMachine.SetState("eap_response_challenge_sent")
178 updateAuthFailed(onuId, ponPortId, serialNumber, eapolStateMachine)
179 assert.Equal(t, eapolStateMachine.Current(), "auth_failed")
180
181 eapolStateMachine.SetState("eap_response_success_received")
182 err := updateAuthFailed(onuId, ponPortId, serialNumber, eapolStateMachine)
183 if err == nil {
184 t.Errorf("updateAuthFailed did not return an error")
185 t.Fail()
186 }
187 assert.Equal(t, err.Error(), "event auth_failed inappropriate in current state eap_response_success_received")
188
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700189}