mirror of
https://github.com/nestriness/cdc-file-transfer.git
synced 2026-01-30 12:25:35 +02:00
[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.
132 lines
4.5 KiB
Python
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()
|