mirror of
https://github.com/nestriness/cdc-file-transfer.git
synced 2026-05-02 19:13:06 +03:00
[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.
This commit is contained in:
131
integration_tests/cdc_rsync/connection_test.py
Normal file
131
integration_tests/cdc_rsync/connection_test.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# 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()
|
||||
Reference in New Issue
Block a user