Files
netris-cdc-file-transfer/integration_tests/cdc_rsync/connection_test.py
Lutz Justen 668c2ca8df [cdc_rsync] Add integration tests (#42)
[cdc_rsync] Add integration tests

This CL adds Python integration tests for cdc_rsync. To run the tests,
you need to supply a Linux host and proper configuration for cdc_rsync
to work:

  set CDC_SSH_COMMAND=C:\path\to\ssh.exe <args>
  set CDC_SCP_COMMAND=C:\path\to\scp.exe <args>
  C:\python38\python.exe -m integration_tests.cdc_rsync.all_tests --binary_path=C:\full\path\to\cdc_rsync.exe --user_host=user@host

Ran the tests and made sure they worked.
2022-12-08 08:39:43 +01:00

132 lines
4.5 KiB
Python

# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Lint as: python3
"""cdc_rsync connection test."""
from concurrent import futures
import socket
import time
from integration_tests.framework import utils
from integration_tests.cdc_rsync import test_base
RETURN_CODE_SUCCESS = 0
RETURN_CODE_GENERIC_ERROR = 1
RETURN_CODE_CONNECTION_TIMEOUT = 2
RETURN_CODE_ADDRESS_IN_USE = 4
FIRST_PORT = 44450
LAST_PORT = 44459
class ConnectionTest(test_base.CdcRsyncTest):
"""cdc_rsync connection test class."""
def test_valid_instance(self):
"""Runs rsync with --instance option for a valid id.
1) Uploads a file with --instance option instead of --ip --port.
2) Checks the file exists on the used instance.
"""
utils.create_test_file(self.local_data_path, 1024)
res = utils.run_rsync(self.local_data_path, self.remote_base_dir)
self._assert_rsync_success(res)
self.assertTrue(utils.does_file_exist_remotely(self.remote_data_path))
def test_invalid_instance(self):
"""Runs rsync with --instance option for an invalid id.
1) Uploads a file with --instance option for a non-existing id.
2) Checks the error message.
"""
bad_host = 'bad_host'
utils.create_test_file(self.local_data_path, 1024)
res = utils.run_rsync(self.local_data_path,
bad_host + ":" + self.remote_base_dir)
self.assertEqual(res.returncode, RETURN_CODE_GENERIC_ERROR)
self.assertIn('lost connection', str(res.stderr))
def test_contimeout(self):
"""Runs rsync with --contimeout option for an invalid ip.
1) Uploads a file with bad IP address.
2) Checks the error message and that it timed out after ~5 seconds.
3) Uploads a file with bad IP address and --contimeout 1.
4) Checks the error message and that it timed out after ~1 second.
"""
utils.create_test_file(self.local_data_path, 1024)
bad_host = '192.0.2.1'
start = time.time()
res = utils.run_rsync(self.local_data_path,
bad_host + ":" + self.remote_base_dir)
elapsed_time = time.time() - start
self.assertGreater(elapsed_time, 4.5)
self.assertEqual(res.returncode, RETURN_CODE_CONNECTION_TIMEOUT)
self.assertIn('Error: Server connection timed out', str(res.stderr))
start = time.time()
res = utils.run_rsync(self.local_data_path,
bad_host + ":" + self.remote_base_dir,
'--contimeout=1')
elapsed_time = time.time() - start
self.assertLess(elapsed_time, 3)
self.assertEqual(res.returncode, RETURN_CODE_CONNECTION_TIMEOUT)
self.assertIn('Error: Server connection timed out', str(res.stderr))
def test_multiple_instances(self):
"""Runs multiple instances of rsync at the same time."""
num_instances = LAST_PORT - FIRST_PORT + 1
local_data_paths = []
for n in range(num_instances):
path = self.local_base_dir + ('testdata_%i.dat' % n)
utils.create_test_file(path, 1024)
local_data_paths.append(path)
with futures.ThreadPoolExecutor(max_workers=num_instances) as executor:
res = []
for n in range(num_instances):
res.append(
executor.submit(utils.run_rsync, local_data_paths[n],
self.remote_base_dir))
for r in res:
self._assert_rsync_success(r.result())
def test_address_in_use(self):
"""Blocks all ports and checks that rsync fails with the expected error."""
sockets = []
try:
# Occupy all ports.
for port in range(FIRST_PORT, LAST_PORT + 1):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockets.append(s)
s.bind(('127.0.0.1', port))
s.listen()
# rsync shouldn't be able to find an available port now.
utils.create_test_file(self.local_data_path, 1024)
res = utils.run_rsync(self.local_data_path, self.remote_base_dir)
self.assertIn('All ports are already in use', str(res.stderr))
finally:
for s in sockets:
s.close()
if __name__ == '__main__':
test_base.test_base.main()