Coverage for tests\__init__.py: 100%
125 statements
« prev ^ index » next coverage.py v7.3.0, created at 2023-08-27 21:50 -0700
« prev ^ index » next coverage.py v7.3.0, created at 2023-08-27 21:50 -0700
1#! /usr/bin/python3
2# -*- coding: utf-8 -*-
4##############################################################################
5# Copyright (C) 2021-current alexpdev
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18##############################################################################
19"""
20Unittest package init module.
21"""
23import os
24import atexit
25import shutil
26import string
27from datetime import datetime
28from pathlib import Path
30import pytest
32from torrentfile.torrent import (
33 TorrentAssembler, TorrentFile, TorrentFileHybrid, TorrentFileV2)
36def tempfile(path=None, exp=18):
37 """Create temporary file.
39 Creates a temporary file for unittesting purposes.py
41 Parameters
42 ----------
43 path : str, optional
44 relative path to temporary files, by default None
45 exp : int, optional
46 Exponent used to determine size of file., by default 18
48 Returns
49 -------
50 str
51 absolute path to file.
52 """
53 seq = (string.printable + string.whitespace).encode("utf-8")
54 root = Path(__file__).parent / "TESTDIR"
55 if not os.path.exists(root):
56 os.mkdir(root)
57 if not path:
58 path = root / (str(datetime.timestamp(datetime.now())) + ".file")
59 parts = Path(path).parts
60 partial = root
61 for i, part in enumerate(parts):
62 partial = partial / part
63 if i == len(parts) - 1:
64 with open(partial, "wb") as binfile:
65 size = 2**exp
66 while size > 0:
67 if len(seq) < size:
68 binfile.write(seq)
69 size -= len(seq)
70 seq += seq
71 else:
72 binfile.write(seq[:size])
73 size -= size
74 else:
75 if not os.path.exists(partial):
76 os.mkdir(partial)
77 return partial
80def rmpath(*args):
81 """Remove file or directory path.
83 Parameters
84 ----------
85 *args : list
86 Filesystem locations for removing.
87 """
88 for arg in args:
89 if not os.path.exists(arg):
90 continue
91 if os.path.isdir(arg):
92 try:
93 shutil.rmtree(arg)
94 except PermissionError: # pragma: nocover
95 pass
96 elif os.path.isfile(arg):
97 try:
98 os.remove(arg)
99 except PermissionError: # pragma: nocover
100 pass
103def tempdir(ext="1"):
104 """Create temporary directory.
106 Parameters
107 ----------
108 ext : str, optional
109 extension to file names, by default "1"
111 Returns
112 -------
113 str
114 path to common root for directory.
115 """
116 layouts = {
117 "1": [
118 f"dir{ext}/file1.png",
119 f"dir{ext}/file2.mp4",
120 f"dir{ext}/file3.mp3",
121 f"dir{ext}/file4.zip",
122 f"dir{ext}/file5.txt",
123 f"dir{ext}/subdir1/subdir2/file.7z",
124 f"dir{ext}/subdir/subdir/file4.rar",
125 f"dir{ext}/subdir/subdir/file4.r01",
126 ],
127 "2": [
128 f"dir{ext}/file1.png",
129 f"dir{ext}/file2.jpg",
130 f"dir{ext}/subdir/file2.mp4",
131 f"dir{ext}/subdir/file3.mp3",
132 ],
133 }
134 paths = []
135 for path in layouts[ext]:
136 temps = tempfile(path=path, exp=18)
137 paths.append(temps)
138 return os.path.commonpath(paths)
141@atexit.register
142def teardown(): # pragma: nocover
143 """
144 Remove all temporary directories and files.
145 """
146 root = Path(__file__).parent / "TESTDIR"
147 dest = Path(__file__).parent / "dest"
148 dest2 = Path(__file__).parent / "dest2"
149 for path in [root, "./torrentfile.log", dest, dest2]:
150 if os.path.exists(path):
151 rmpath(path)
154def torrents():
155 """
156 Return seq of torrentfile objects.
157 """
158 return [TorrentFile, TorrentFileV2, TorrentFileHybrid, TorrentAssembler]
161@pytest.fixture(params=[2**i for i in range(15, 20)])
162def sizes(request):
163 """
164 Generate powers of 2 for file creation package scope.
165 """
166 size = request.param
167 yield size
170@pytest.fixture()
171def dir1():
172 """Create a specific temporary structured directory.
174 Yields
175 ------
176 str
177 path to root of temporary directory
178 """
179 root = tempdir()
180 yield root
181 rmpath(root)
184@pytest.fixture()
185def dir2():
186 """Create a specific temporary structured directory.
188 Yields
189 ------
190 str
191 path to root of temporary directory
192 """
193 root = tempdir(ext="2")
194 yield Path(root)
195 rmpath(root)
198@pytest.fixture(params=torrents())
199def metafile1(dir1, request):
200 """
201 Create a standard metafile for testing.
202 """
203 versions = torrents()
204 args = {
205 "path": dir1,
206 "announce": ["url1", "url2", "url4"],
207 "url_list": ["url5", "url6", "url7"],
208 "httpseeds": ["url5", "url6", "url7"],
209 "comment": "this is a comment",
210 "source": "SomeSource",
211 "private": 1,
212 }
213 torrent_class = request.param
214 outfile = str(dir1) + str(versions.index(torrent_class)) + ".torrent"
215 torrent = torrent_class(**args)
216 outfile, _ = torrent.write(outfile=outfile)
217 yield outfile
218 rmpath(outfile)
221@pytest.fixture(params=torrents())
222def metafile2(dir2, request):
223 """
224 Create a standard metafile for testing.
225 """
226 args = {
227 "path": dir2,
228 "announce": ["url1", "url4"],
229 "url_list": ["url6", "url7"],
230 "comment": "this is a comment",
231 "httpseeds": ["url6", "url7"],
232 "source": "SomeSource",
233 "private": 1,
234 }
235 torrent_class = request.param
236 outfile = str(dir2) + ".torrent"
237 torrent = torrent_class(**args)
238 outfile, _ = torrent.write(outfile=outfile)
239 yield outfile
242@pytest.fixture()
243def file1():
244 """
245 Return the path to a temporary file package scope.
246 """
247 path = tempfile()
248 yield path
251@pytest.fixture(params=torrents())
252def filemeta1(file1, request):
253 """
254 Test fixture for generating metafile for all versions of torrents.
255 """
256 args = {
257 "path": file1,
258 "announce": ["url1", "url4"],
259 "url_list": ["url6", "url7"],
260 "httpseeds": ["url6", "url7"],
261 "comment": "this is a comment",
262 "source": "SomeSource",
263 "private": 1,
264 }
265 versions = torrents()
266 version = versions.index(request.param)
267 name = str(file1) + "file" + str(version) + ".torrent"
268 torrent = request.param(**args)
269 outfile, _ = torrent.write(outfile=name)
270 yield outfile
271 rmpath(outfile)
274@pytest.fixture(params=torrents())
275def filemeta2(file2, request):
276 """
277 Test fixture for generating a meta file no scope.
278 """
279 args = {
280 "path": file2,
281 "announce": ["url1", "url4"],
282 "url_list": ["url6", "url7"],
283 "httpseeds": ["url7", "url8"],
284 "comment": "this is a comment",
285 "source": "SomeSource",
286 "private": 1,
287 }
288 versions = torrents()
289 version = versions.index(request.param)
290 name = str(file2) + "file" + str(version) + ".torrent"
291 torrent = request.param(**args)
292 outfile, _ = torrent.write(outfile=name)
293 yield outfile
294 rmpath(outfile)
297@pytest.fixture()
298def file2():
299 """
300 Return the path to a temporary file no scope.
301 """
302 path = tempfile()
303 yield path
304 rmpath(path)
307@pytest.fixture(params=torrents())
308def sizedfiles(dir2, sizes, request):
309 """
310 Generate variable sized meta files for testing, no scope.
311 """
312 versions = torrents()
313 args = {
314 "content": dir2,
315 "announce": ["url1", "url2", "url4"],
316 "url_list": ["url5", "url6", "url7"],
317 "comment": "this is a comment",
318 "source": "SomeSource",
319 "private": 1,
320 "piece_length": sizes,
321 }
322 torrent_class = request.param
323 version = str(versions.index(torrent_class))
324 outfile = str(dir2) + version + str(sizes) + ".torrent"
325 torrent = torrent_class(**args)
326 outfile, _ = torrent.write(outfile=outfile)
327 yield outfile
328 rmpath(outfile)