1#!/usr/bin/env python3 2# 3# Copyright (C) 2016 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# 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, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16""" 17Test script to execute Bluetooth basic functionality test cases. 18This test was designed to be run in a shield box. 19""" 20 21from random import randint 22 23from acts.test_decorators import test_tracker_info 24from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 25from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 26from acts_contrib.test_utils.bt.bt_test_utils import orchestrate_rfcomm_connection 27from acts_contrib.test_utils.bt.bt_test_utils import write_read_verify_data 28 29 30class RfcommLongevityTest(BluetoothBaseTest): 31 default_timeout = 10 32 longev_iterations = 200 33 write_iterations = 5000 34 generic_message = ( 35 "Space: the final frontier. These are the voyages of " 36 "the starship Enterprise. Its continuing mission: to explore " 37 "strange new worlds, to seek out new life and new civilizations," 38 " to boldly go where no man has gone before.") 39 40 def setup_class(self): 41 super().setup_class() 42 self.client_ad = self.android_devices[0] 43 self.server_ad = self.android_devices[1] 44 45 @test_tracker_info(uuid='2790acad-1f6e-4216-aadf-83561dddcfa3') 46 def test_rfcomm_longev_read_write_message(self): 47 """Longevity test an RFCOMM connection's I/O with a generic message 48 49 Test the longevity of RFCOMM with a basic read/write 50 connect/disconnect sequence. 51 52 Steps: 53 1. Establish a bonding between two Android devices. 54 2. Write data to RFCOMM from the client droid. 55 3. Read data from RFCOMM from the server droid. 56 4. Verify data written matches data read. 57 5. Repeat steps 2-4 5000 times. 58 6. Disconnect RFCOMM connection. 59 7. Repeat steps 1-6 1000 times. 60 61 Expected Result: 62 Each iteration should read and write to the RFCOMM connection 63 successfully. Each connect and disconnect should be successful. 64 65 Returns: 66 Pass if True 67 Fail if False 68 69 TAGS: Classic, Longevity, RFCOMM 70 Priority: 2 71 """ 72 73 for i in range(self.longev_iterations): 74 self.log.info("iteration {} connection".format(i + 1)) 75 if not orchestrate_rfcomm_connection(self.client_ad, 76 self.server_ad): 77 return False 78 for n in range(self.write_iterations): 79 self.log.info("iteration {} data".format( 80 ((n + 1) + (i * self.write_iterations)))) 81 if not write_read_verify_data(self.client_ad, self.server_ad, 82 self.generic_message, False): 83 return False 84 self.log.info("Iteration {} completed".format(n)) 85 self.client_ad.droid.bluetoothRfcommStop() 86 self.server_ad.droid.bluetoothRfcommStop() 87 return True 88 89 @test_tracker_info(uuid='01c420b8-845a-4539-90bf-8d7747f471ca') 90 def test_rfcomm_longev_read_write_small_message(self): 91 """Longevity test an RFCOMM connection's I/O with a small message 92 93 Test the longevity of RFCOMM with a basic read/write 94 connect/disconnect sequence. The data being transfered is only 95 one character in size. 96 97 Steps: 98 1. Establish a bonding between two Android devices. 99 2. Write data to RFCOMM from the client droid. 100 3. Read data from RFCOMM from the server droid. 101 4. Verify data written matches data read. 102 5. Repeat steps 2-4 5000 times. 103 6. Disconnect RFCOMM connection. 104 7. Repeat steps 1-6 1000 times. 105 106 Expected Result: 107 Each iteration should read and write to the RFCOMM connection 108 successfully. Each connect and disconnect should be successful. 109 110 Returns: 111 Pass if True 112 Fail if False 113 114 TAGS: Classic, Longevity, RFCOMM 115 Priority: 2 116 """ 117 message = "x" 118 for i in range(self.longev_iterations): 119 self.log.info("iteration {} connection".format(i + 1)) 120 if not orchestrate_rfcomm_connection(self.client_ad, 121 self.server_ad): 122 return False 123 for n in range(self.write_iterations): 124 self.log.info("iteration {} data".format( 125 ((n + 1) + (i * self.write_iterations)))) 126 if not write_read_verify_data(self.client_ad, self.server_ad, 127 message, False): 128 return False 129 self.log.info("Iteration {} completed".format(n)) 130 self.client_ad.droid.bluetoothRfcommStop() 131 self.server_ad.droid.bluetoothRfcommStop() 132 return True 133 134 @test_tracker_info(uuid='8a92772a-511e-4f15-8e8b-194e499a46eb') 135 def test_rfcomm_longev_read_write_binary_message(self): 136 """Longevity test an RFCOMM connection's I/O with a binary message 137 138 Test the longevity of RFCOMM with a basic read/write 139 connect/disconnect sequence. The data being transfered is in a 140 binary format. 141 142 Steps: 143 1. Establish a bonding between two Android devices. 144 2. Write data to RFCOMM from the client droid. 145 3. Read data from RFCOMM from the server droid. 146 4. Verify data written matches data read. 147 5. Repeat steps 2-4 5000 times. 148 6. Disconnect RFCOMM connection. 149 7. Repeat steps 1-6 1000 times. 150 151 Expected Result: 152 Each iteration should read and write to the RFCOMM connection 153 successfully. Each connect and disconnect should be successful. 154 155 Returns: 156 Pass if True 157 Fail if False 158 159 TAGS: Classic, Longevity, RFCOMM 160 Priority: 2 161 """ 162 binary_message = "11010101" 163 for i in range(self.longev_iterations): 164 self.log.info("iteration {} connection".format(i + 1)) 165 if not orchestrate_rfcomm_connection(self.client_ad, 166 self.server_ad): 167 return False 168 for n in range(self.write_iterations): 169 self.log.info("iteration {} data".format( 170 ((n + 1) + (i * self.write_iterations)))) 171 if not write_read_verify_data(self.client_ad, self.server_ad, 172 binary_message, True): 173 return False 174 self.log.info("Iteration {} completed".format(n)) 175 self.client_ad.droid.bluetoothRfcommStop() 176 self.server_ad.droid.bluetoothRfcommStop() 177 return True 178 179 @test_tracker_info(uuid='ff0ab2e4-2a7d-45b9-b034-4cd32c0fa139') 180 def test_rfcomm_longev_read_write_large_message(self): 181 """Longevity test an RFCOMM connection's I/O with a large message 182 183 Test the longevity of RFCOMM with a basic read/write 184 connect/disconnect sequence. The data being transfered is 990 chars 185 in size. 186 187 Steps: 188 1. Establish a bonding between two Android devices. 189 2. Write data to RFCOMM from the client droid. 190 3. Read data from RFCOMM from the server droid. 191 4. Verify data written matches data read. 192 5. Repeat steps 2-4 5000 times. 193 6. Disconnect RFCOMM connection. 194 7. Repeat steps 1-6 1000 times. 195 196 Expected Result: 197 Each iteration should read and write to the RFCOMM connection 198 successfully. Each connect and disconnect should be successful. 199 200 Returns: 201 Pass if True 202 Fail if False 203 204 TAGS: Classic, Longevity, RFCOMM 205 Priority: 2 206 """ 207 message = "x" * 990 # largest message size till sl4a fixed 208 for i in range(self.longev_iterations): 209 self.log.info("iteration {} connection".format(i + 1)) 210 if not orchestrate_rfcomm_connection(self.client_ad, 211 self.server_ad): 212 return False 213 for n in range(self.write_iterations): 214 self.log.info("iteration {} data".format( 215 ((n + 1) + (i * self.write_iterations)))) 216 if not write_read_verify_data(self.client_ad, self.server_ad, 217 message, False): 218 return False 219 self.log.info("Iteration {} completed".format(n)) 220 self.client_ad.droid.bluetoothRfcommStop() 221 self.server_ad.droid.bluetoothRfcommStop() 222 return True 223 224 @test_tracker_info(uuid='950924b7-d893-4a33-ba09-d80d53dc7d13') 225 def test_rfcomm_longev_connection_interuption(self): 226 """Longevity test an RFCOMM connection's with socket interuptions 227 228 Test the longevity of RFCOMM with a basic read/write 229 connect/disconnect sequence. Randomly in the sequence of reads and 230 writes the socket on the client side will close. There should be 231 an exception thrown for writing the next set of data and the 232 test should start up a new connection and continue. 233 234 Steps: 235 1. Establish a bonding between two Android devices. 236 2. Write data to RFCOMM from the client droid. 237 3. Read data from RFCOMM from the server droid. 238 4. Verify data written matches data read. 239 5. Repeat steps 2-4 5000 times or until the random interupt occurs. 240 6. Re-establish an RFCOMM connection. 241 7. Repeat steps 1-6 1000 times. 242 243 Expected Result: 244 Each iteration should read and write to the RFCOMM connection 245 successfully. Each connect and disconnect should be successful. 246 Devices should recover a new connection after each interruption. 247 248 Returns: 249 Pass if True 250 Fail if False 251 252 TAGS: Classic, Longevity, RFCOMM 253 Priority: 2 254 """ 255 for i in range(self.longev_iterations): 256 try: 257 self.log.info("iteration {} connection".format(i + 1)) 258 if not orchestrate_rfcomm_connection(self.client_ad, 259 self.server_ad): 260 return False 261 random_interup_iteration = randint(0, self.write_iterations) 262 for n in range(self.write_iterations): 263 self.log.info("iteration {} data".format( 264 ((n + 1) + (i * self.write_iterations)))) 265 if not write_read_verify_data(self.client_ad, 266 self.server_ad, 267 self.generic_message, False): 268 return False 269 self.log.info("Iteration {} completed".format(n)) 270 if n > random_interup_iteration: 271 self.client_ad.droid.bluetoothRfcommCloseSocket() 272 self.client_ad.droid.bluetoothRfcommStop() 273 self.server_ad.droid.bluetoothRfcommStop() 274 except Exception: 275 self.log.info("Exception found as expected. Continuing...") 276 try: 277 self.client_ad.droid.bluetoothRfcommStop() 278 except Exception as err: 279 self.log.error( 280 "Error closing client connection: {}".format(err)) 281 return False 282 try: 283 self.server_ad.droid.bluetoothRfcommStop() 284 except Exception as err: 285 self.log.error( 286 "Error closing server connection: {}".format(err)) 287 return False 288 return True 289 290 @test_tracker_info(uuid='155a25be-3e6c-4462-a78f-f6a161b90953') 291 def test_rfcomm_longev_data_elasticity(self): 292 """Longevity test an RFCOMM connection's I/O with changing data size 293 294 Test the longevity of RFCOMM with a basic read/write 295 connect/disconnect sequence. The data being transfered changes 296 in size after each write/read sequence to increase up to 990 297 chars in size and decrease down to 1 in size. This repeats through 298 the entire test in order to exercise different size values being 299 written. 300 301 Steps: 302 1. Establish a bonding between two Android devices. 303 2. Write data to RFCOMM from the client droid. 304 3. Read data from RFCOMM from the server droid. 305 4. Verify data written matches data read. 306 5. Change data size according to above description. 307 6. Repeat steps 2-5 5000 times. 308 7. Disconnect RFCOMM connection. 309 8. Repeat steps 1-6 1000 times. 310 311 Expected Result: 312 Each iteration should read and write to the RFCOMM connection 313 successfully. Each connect and disconnect should be successful. 314 315 Returns: 316 Pass if True 317 Fail if False 318 319 TAGS: Classic, Longevity, RFCOMM 320 Priority: 2 321 """ 322 message = "x" 323 resize_toggle = 1 324 for i in range(self.longev_iterations): 325 try: 326 self.log.info("iteration {} connection".format(i + 1)) 327 if not orchestrate_rfcomm_connection(self.client_ad, 328 self.server_ad): 329 return False 330 for n in range(self.write_iterations): 331 self.log.info("iteration {} data".format( 332 ((n + 1) + (i * self.write_iterations)))) 333 if not write_read_verify_data( 334 self.client_ad, self.server_ad, message, False): 335 return False 336 self.log.info("Iteration {} completed".format(n)) 337 size_of_message = len(message) 338 #max size is 990 due to a bug in sl4a. 339 if size_of_message >= 990: 340 resize_toggle = 0 341 elif size_of_message <= 1: 342 resize_toggle = 1 343 if resize_toggle == 0: 344 message = "x" * (size_of_message - 1) 345 else: 346 message = "x" * (size_of_message + 1) 347 self.client_ad.droid.bluetoothRfcommStop() 348 self.server_ad.droid.bluetoothRfcommStop() 349 except Exception as err: 350 self.log.info("Error in longevity test: {}".format(err)) 351 return False 352 return True 353