blob: 38ea471da6286f1939fb96ecfabd2638f35bfc34 [file] [log] [blame]
Stephane Barbarie2940dac2017-08-18 14:15:17 -04001#!/usr/bin/env python
2#
3# Copyright 2017 the original author or authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17import logging
18import os
19import time
20import json
21
22from tests.itests.voltha.rest_base import RestBase
23
24this_dir = os.path.abspath(os.path.dirname(__file__))
25
26from tests.itests.docutests.test_utils import run_command_to_completion_with_raw_stdout
27
28log = logging.getLogger(__name__)
29
30DOCKER_COMPOSE_FILE = "compose/docker-compose-ofagent-test.yml"
31
32command_defs = dict(
33 docker_stop="docker stop {}",
34 docker_start="docker start {}",
35 docker_compose_start_all="docker-compose -f {} up -d "
36 .format(DOCKER_COMPOSE_FILE),
37 docker_compose_stop="docker-compose -f {} stop"
38 .format(DOCKER_COMPOSE_FILE),
39 docker_compose_rm_f="docker-compose -f {} rm -f"
40 .format(DOCKER_COMPOSE_FILE),
41 onos_form_cluster="./tests/itests/ofagent/onos-form-cluster",
42 onos1_ip="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos1",
43 onos2_ip="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos2",
44 onos3_ip="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos3",
45 add_olt='''curl -k -s -X POST -d '{"type": "simulated_olt"}' \
46 https://localhost:8881/api/v1/local/devices''',
47 enable_olt="curl -k -s -X POST https://localhost:8881/api/v1/local/devices/{}/enable",
48 get_onos_devices="curl -u karaf:karaf http://localhost:8181/onos/v1/devices")
49
50
51class OfagentRecoveryTest(RestBase):
52 def setUp(self):
53 # Run Voltha,OFAgent,3 ONOS and form ONOS cluster.
54 print "Starting all containers ..."
55 cmd = command_defs['docker_compose_start_all']
56 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
57 self.assertEqual(rc, 0)
58 print "Waiting for all containers to be ready ..."
59 time.sleep(60)
60 cmd = command_defs['onos1_ip']
61 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
62 self.assertEqual(rc, 0)
63 onos1_ip = out
64 print "ONOS1 IP is {}".format(onos1_ip)
65 cmd = command_defs['onos2_ip']
66 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
67 self.assertEqual(rc, 0)
68 onos2_ip = out
69 print "ONOS2 IP is {}".format(onos2_ip)
70 cmd = command_defs['onos3_ip']
71 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
72 self.assertEqual(rc, 0)
73 onos3_ip = out
74 print "ONOS3 IP is {}".format(onos3_ip)
75 cmd = command_defs['onos_form_cluster'] + ' {} {} {}'.format(onos1_ip.strip(),
76 onos2_ip.strip(),
77 onos3_ip.strip())
78 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
79 self.assertEqual(rc, 0)
80 print "Cluster Output :{} ".format(out)
81
82 def tearDown(self):
83 # Stopping and Removing Voltha,OFAgent,3 ONOS.
84 print "Stopping and removing all containers ..."
85 cmd = command_defs['docker_compose_stop']
86 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
87 self.assertEqual(rc, 0)
88 print "Waiting for all containers to be stopped ..."
89 time.sleep(1)
90 cmd = command_defs['docker_compose_rm_f']
91 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
92 self.assertEqual(rc, 0)
93
94 def add_device(self):
95 print "Adding device"
96
97 cmd = command_defs['add_olt']
98 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
99 self.assertEqual(rc, 0)
100 device = json.loads(out)
101
102 print "Added device - id:{}, type:{}".format(device['id'], device['type'])
103 time.sleep(5)
104
105 return device
106
107 def enable_device(self, device_id):
108 print "Enabling device - id:{}".format(device_id)
109
110 cmd = command_defs['enable_olt'].format(device_id)
111 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
112 self.assertEqual(rc, 0)
113
114 time.sleep(30)
115 print "Enabled device - id:{}".format(device_id)
116
117 def get_device(self, device_id, expected_code=200):
118 print "Getting device - id:{}".format(device_id)
119
120 device = self.get('/api/v1/local/devices/{}'.format(device_id),
121 expected_code=expected_code)
122
123 if device is not None:
124 print "Got device - id:{}, type:{}".format(device['id'], device['type'])
125 else:
126 print "Unable to get device - id:{}".format(device_id)
127
128 return device
129
130 def get_onos_devices(self):
131 print "Getting ONOS devices ..."
132 cmd = command_defs['get_onos_devices']
133 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
134 self.assertEqual(rc, 0)
135
136 if out is not None:
137 onos_devices = json.loads(out)
138 print "Got ONOS devices"
139 else:
140 onos_devices = None
141 print "Unable to get ONOS devices"
142
143 return onos_devices
144
145 def stop_container(self, container):
146 print "Stopping {} ...".format(container)
147
148 cmd = command_defs['docker_stop'].format(container)
149 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
150 self.assertEqual(rc, 0)
151
152 time.sleep(10)
153 print "Stopped {}".format(container)
154
155 def start_container(self, container):
156 print "Starting {} ...".format(container)
157
158 cmd = command_defs['docker_start'].format(container)
159 out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
160 self.assertEqual(rc, 0)
161
162 time.sleep(10)
163 print "Started {}".format(container)
164
165 def test_01_recovery_after_voltha_restart(self):
166 # Add and enable a new OLT device
167 device_1 = self.add_device()
168 self.enable_device(device_1['id'])
169
170 # Verify that the device was propagated in ONOS
171 onos_devices = self.get_onos_devices()
172
173 self.assertEqual(len(onos_devices['devices']), 1)
174
175 # Restart voltha
176 self.stop_container('compose_voltha_1')
177 self.assertEqual(self.get_device(device_1['id'], 503), None)
178 self.start_container('compose_voltha_1')
179
180 # Get the device from VOLTHA after restart
181 device_1_after = self.get_device(device_1['id'])
182 self.assertEqual(device_1_after['id'], device_1['id'])
183
184 # Get the device from ONOS after restart
185 onos_devices = self.get_onos_devices()
186
187 self.assertEqual(len(onos_devices['devices']), 1)
188
189 # Add a new device
190 device_2 = self.add_device()
191 self.enable_device(device_2['id'])
192
193 # Ensure that ONOS has picked up the new device
194 onos_devices = self.get_onos_devices()
195
196 self.assertEqual(len(onos_devices['devices']), 2)
197
198 def test_02_recovery_after_ofagent_restart(self):
199 # Add and enable a new OLT device
200 device_1 = self.add_device()
201 self.enable_device(device_1['id'])
202
203 # Verify that the device was propagated in ONOS
204 onos_devices = self.get_onos_devices()
205
206 self.assertEqual(len(onos_devices['devices']), 1)
207
208 # Restart ofagent
209 self.stop_container('compose_ofagent_1')
210
211 # Try to create a device while ofagent is down
212 # this will succeed from a voltha point of view
213 # but it will not be propagated to ONOS until ofagent is back up
214 device_fail = self.add_device()
215 self.enable_device(device_fail['id'])
216 onos_devices = self.get_onos_devices()
217
218 # Onos should only have 1 device
219 self.assertNotEqual(len(onos_devices['devices']), 2)
220
221 self.start_container('compose_ofagent_1')
222
223 # Get the device from VOLTHA after restart
224 device_1_after = self.get_device(device_1['id'])
225 self.assertEqual(device_1_after['id'], device_1['id'])
226
227 # Get the device from ONOS after restart
228 onos_devices = self.get_onos_devices()
229 self.assertEqual(len(onos_devices['devices']), 2)
230
231 # Add a new device
232 device_2 = self.add_device()
233 self.enable_device(device_2['id'])
234
235 # Ensure that ONOS has picked up the new device
236 onos_devices = self.get_onos_devices()
237
238 self.assertEqual(len(onos_devices['devices']), 3)