Coverage for tests\__init__.py: 100%

125 statements  

« prev     ^ index     » next       coverage.py v7.3.0, created at 2023-08-27 21:50 -0700

1#! /usr/bin/python3 

2# -*- coding: utf-8 -*- 

3 

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""" 

22 

23import os 

24import atexit 

25import shutil 

26import string 

27from datetime import datetime 

28from pathlib import Path 

29 

30import pytest 

31 

32from torrentfile.torrent import ( 

33 TorrentAssembler, TorrentFile, TorrentFileHybrid, TorrentFileV2) 

34 

35 

36def tempfile(path=None, exp=18): 

37 """Create temporary file. 

38 

39 Creates a temporary file for unittesting purposes.py 

40 

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 

47 

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 

78 

79 

80def rmpath(*args): 

81 """Remove file or directory path. 

82 

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 

101 

102 

103def tempdir(ext="1"): 

104 """Create temporary directory. 

105 

106 Parameters 

107 ---------- 

108 ext : str, optional 

109 extension to file names, by default "1" 

110 

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) 

139 

140 

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) 

152 

153 

154def torrents(): 

155 """ 

156 Return seq of torrentfile objects. 

157 """ 

158 return [TorrentFile, TorrentFileV2, TorrentFileHybrid, TorrentAssembler] 

159 

160 

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 

168 

169 

170@pytest.fixture() 

171def dir1(): 

172 """Create a specific temporary structured directory. 

173 

174 Yields 

175 ------ 

176 str 

177 path to root of temporary directory 

178 """ 

179 root = tempdir() 

180 yield root 

181 rmpath(root) 

182 

183 

184@pytest.fixture() 

185def dir2(): 

186 """Create a specific temporary structured directory. 

187 

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) 

196 

197 

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) 

219 

220 

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 

240 

241 

242@pytest.fixture() 

243def file1(): 

244 """ 

245 Return the path to a temporary file package scope. 

246 """ 

247 path = tempfile() 

248 yield path 

249 

250 

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) 

272 

273 

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) 

295 

296 

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) 

305 

306 

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)