From: Stefan Eissing Date: Tue, 21 May 2024 10:17:33 +0000 (+0200) Subject: pytest: add ftp upload tests X-Git-Tag: curl-8_9_0~418 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a913d8dc3c3d5461bcfe8c60c995b3d42d75c56;p=thirdparty%2Fcurl.git pytest: add ftp upload tests - refs #13556 - allow anon uploads on vsftpd test server - add test_30_05 for plain upload of 1k, 100k, 1m - add test_31_05 for SSL upload of 1k, 100k, 1m - verify file size and contents Closes #13734 --- diff --git a/tests/http/test_30_vsftpd.py b/tests/http/test_30_vsftpd.py index af52e10f8d..11b8902792 100644 --- a/tests/http/test_30_vsftpd.py +++ b/tests/http/test_30_vsftpd.py @@ -67,6 +67,9 @@ class TestVsFTPD: self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-10k', fsize=10*1024) self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-1m', fsize=1024*1024) self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-10m', fsize=10*1024*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1k", fsize=1024) + env.make_data_file(indir=env.gen_dir, fname="upload-100k", fsize=100*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1m", fsize=1024*1024) def test_30_01_list_dir(self, env: Env, vsftpd: VsFTPD, repeat): curl = CurlClient(env=env) @@ -115,6 +118,24 @@ class TestVsFTPD: r.check_stats(count=count, http_status=226) self.check_downloads(curl, srcfile, count) + @pytest.mark.parametrize("docname", [ + 'upload-1k', 'upload-100k', 'upload-1m' + ]) + def test_30_05_upload_1(self, env: Env, vsftpd: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_upload(urls=[url], fupload=f'{srcfile}', with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpd, docname=docname) + + def _rmf(self, path): + if os.path.exists(path): + return os.remove(path) + def check_downloads(self, client, srcfile: str, count: int, complete: bool = True): for i in range(count): @@ -128,5 +149,15 @@ class TestVsFTPD: n=1)) assert False, f'download {dfile} differs:\n{diff}' - - + def check_upload(self, env, vsftpd: VsFTPD, docname): + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + assert os.path.exists(srcfile) + assert os.path.exists(dstfile) + if not filecmp.cmp(srcfile, dstfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dstfile).readlines(), + fromfile=srcfile, + tofile=dstfile, + n=1)) + assert False, f'upload {dstfile} differs:\n{diff}' diff --git a/tests/http/test_31_vsftpds.py b/tests/http/test_31_vsftpds.py index 7dd4b3f810..e8d8153f01 100644 --- a/tests/http/test_31_vsftpds.py +++ b/tests/http/test_31_vsftpds.py @@ -77,6 +77,9 @@ class TestVsFTPD: self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-10k', fsize=10*1024) self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-1m', fsize=1024*1024) self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-10m', fsize=10*1024*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1k", fsize=1024) + env.make_data_file(indir=env.gen_dir, fname="upload-100k", fsize=100*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1m", fsize=1024*1024) def test_31_01_list_dir(self, env: Env, vsftpds: VsFTPD, repeat): curl = CurlClient(env=env) @@ -125,6 +128,24 @@ class TestVsFTPD: r.check_stats(count=count, http_status=226) self.check_downloads(curl, srcfile, count) + @pytest.mark.parametrize("docname", [ + 'upload-1k', 'upload-100k', 'upload-1m' + ]) + def test_31_05_upload_1(self, env: Env, vsftpds: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpds.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_upload(urls=[url], fupload=f'{srcfile}', with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpds, docname=docname) + + def _rmf(self, path): + if os.path.exists(path): + return os.remove(path) + def check_downloads(self, client, srcfile: str, count: int, complete: bool = True): for i in range(count): @@ -138,5 +159,16 @@ class TestVsFTPD: n=1)) assert False, f'download {dfile} differs:\n{diff}' - + def check_upload(self, env, vsftpd: VsFTPD, docname): + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + assert os.path.exists(srcfile) + assert os.path.exists(dstfile) + if not filecmp.cmp(srcfile, dstfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dstfile).readlines(), + fromfile=srcfile, + tofile=dstfile, + n=1)) + assert False, f'upload {dstfile} differs:\n{diff}' diff --git a/tests/http/testenv/curl.py b/tests/http/testenv/curl.py index 23b70b293f..f407864643 100644 --- a/tests/http/testenv/curl.py +++ b/tests/http/testenv/curl.py @@ -579,6 +579,37 @@ class CurlClient: with_profile=with_profile, no_save=no_save, extra_args=extra_args) + def ftp_upload(self, urls: List[str], fupload, + with_stats: bool = True, + with_profile: bool = False, + extra_args: List[str] = None): + if extra_args is None: + extra_args = [] + extra_args.extend([ + '--upload-file', fupload + ]) + if with_stats: + extra_args.extend([ + '-w', '%{json}\\n' + ]) + return self._raw(urls, options=extra_args, + with_stats=with_stats, + with_headers=False, + with_profile=with_profile) + + def ftp_ssl_upload(self, urls: List[str], fupload, + with_stats: bool = True, + with_profile: bool = False, + extra_args: List[str] = None): + if extra_args is None: + extra_args = [] + extra_args.extend([ + '--ssl-reqd', + ]) + return self.ftp_upload(urls=urls, fupload=fupload, + with_stats=with_stats, with_profile=with_profile, + extra_args=extra_args) + def response_file(self, idx: int): return os.path.join(self._run_dir, f'download_{idx}.data') diff --git a/tests/http/testenv/vsftpd.py b/tests/http/testenv/vsftpd.py index 4ba0132e69..8daa7b0f66 100644 --- a/tests/http/testenv/vsftpd.py +++ b/tests/http/testenv/vsftpd.py @@ -190,16 +190,19 @@ class VsFTPD: f'anonymous_enable=YES', f'anon_root={self._docs_dir}', f'dirmessage_enable=YES', + f'write_enable=YES', + f'anon_upload_enable=YES', f'log_ftp_protocol=YES', f'xferlog_enable=YES', - f'xferlog_std_format=YES', - f'xferlog_file={self._error_log}', + f'xferlog_std_format=NO', + f'vsftpd_log_file={self._error_log}', f'\n', ] if self._with_ssl: creds = self.env.get_credentials(self.domain) conf.extend([ f'ssl_enable=YES', + f'debug_ssl=YES', f'allow_anon_ssl=YES', f'rsa_cert_file={creds.cert_file}', f'rsa_private_key_file={creds.pkey_file}',