test_pdiffs.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. import contextlib
  2. import os
  3. import shutil
  4. import tempfile
  5. import unittest
  6. from daklib.pdiff import PDiffIndex
  7. try:
  8. from unittest import IsolatedAsyncioTestCase
  9. except ImportError:
  10. IsolatedAsyncioTestCase = None
  11. def generate_orig(content_dir, initial_content):
  12. current_file = os.path.join(content_dir, "data-current")
  13. with open(current_file, 'wt') as fd:
  14. if isinstance(initial_content, list):
  15. fd.writelines("{}\n".format(line) for line in initial_content)
  16. else:
  17. fd.write(initial_content)
  18. async def generate_patch(index, patch_name, content_dir, new_content):
  19. new_file = os.path.join(content_dir, "data-current")
  20. orig_file = os.path.join(content_dir, "data-previous")
  21. if os.path.isfile(new_file):
  22. os.rename(new_file, orig_file)
  23. elif not os.path.isfile(orig_file):
  24. # Ensure there is an empty orig file
  25. with open(orig_file, 'w'):
  26. pass
  27. generate_orig(content_dir, new_content)
  28. await index.generate_and_add_patch_file(orig_file, new_file, patch_name)
  29. def prune_history(index, known_patch_count_before=None, known_patch_count_after=None, detected_obsolete_patches=None):
  30. if known_patch_count_before is not None:
  31. assert len(index._history) == known_patch_count_before
  32. index.prune_patch_history()
  33. if known_patch_count_after is not None:
  34. assert len(index._history) == known_patch_count_after
  35. if detected_obsolete_patches is not None:
  36. assert sorted(os.path.basename(p) for p in index.find_obsolete_patches()) == detected_obsolete_patches
  37. def delete_obsolete_patches(index):
  38. for patch_file in index.find_obsolete_patches():
  39. os.unlink(patch_file)
  40. def reload_and_compare_pdiff_indices(index):
  41. reloaded_index = PDiffIndex(index.patches_dir, index.max, index.wants_merged_pdiffs)
  42. assert index._history_order == reloaded_index._history_order
  43. assert index._history == reloaded_index._history
  44. assert index._old_merged_patches_prefix == reloaded_index._old_merged_patches_prefix
  45. assert index._unmerged_history_order == reloaded_index._unmerged_history_order
  46. # Only part of the history is carried over. Ignore the missing bits.
  47. assert [index._history[x][0] for x in index._history_order] == \
  48. [reloaded_index._history[x][0] for x in reloaded_index._history_order]
  49. assert [index._history[x][2].size for x in index._history_order] == \
  50. [reloaded_index._history[x][2].size for x in reloaded_index._history_order]
  51. assert [index._history[x][2].sha256 for x in index._history_order] == \
  52. [reloaded_index._history[x][2].sha256 for x in reloaded_index._history_order]
  53. if index.wants_merged_pdiffs:
  54. assert [index._unmerged_history[x][0] for x in index._unmerged_history_order] == \
  55. [reloaded_index._unmerged_history[x][0] for x in reloaded_index._unmerged_history_order]
  56. assert [index._unmerged_history[x][2].size for x in index._unmerged_history_order] == \
  57. [reloaded_index._unmerged_history[x][2].size for x in reloaded_index._unmerged_history_order]
  58. assert [index._unmerged_history[x][2].sha256 for x in index._unmerged_history_order] == \
  59. [reloaded_index._unmerged_history[x][2].sha256 for x in reloaded_index._unmerged_history_order]
  60. assert len(index._history_order) == len(reloaded_index._unmerged_history_order)
  61. for unmerged_patch in index._unmerged_history_order:
  62. assert unmerged_patch.startswith('patch')
  63. for merged_patch in index._history_order:
  64. assert merged_patch.startswith('T-patch')
  65. assert index.filesizehashes == reloaded_index.filesizehashes
  66. assert index.can_path == reloaded_index.can_path
  67. assert index.has_merged_pdiffs == reloaded_index.has_merged_pdiffs
  68. return reloaded_index
  69. @contextlib.contextmanager
  70. def tempdir():
  71. tmpdir = tempfile.mkdtemp()
  72. try:
  73. yield tmpdir
  74. finally:
  75. shutil.rmtree(tmpdir)
  76. MISALIGNED_HISTORY_RESTORABLE = """
  77. SHA1-Current: 2f846350bf5855230190ef1588e9ee5ddc45b7c7 13499355
  78. SHA256-Current: 17f0429f6116d47a75ac05e5598cac50b9ba511386e849628ef3b6dad0247d17 13499355
  79. SHA1-History:
  80. 05e82a87ced6a0827d38bdcc84b0a795512d48e8 13992555 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  81. 7f5c4a7946dd2fb52e51ef7103ab1ee26c210d3a 13985915 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  82. 6d2356c893e6c37a1957f3ae751af7da389ba37e 13981903 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  83. 1935ed98c30fa9eef8d4a22a70614e969a1ec7b0 13761106 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  84. e791a3eed4b51744d91d7fd3100adddab2439655 13565058 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  85. SHA256-History:
  86. 82d074d6437e4bf20d1e5e99641f2576c42257bde8acf6310cf2ea1d208c189b 13992555 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  87. beed2758c3f93c8f27d83de51e37f6686861648c2ceeae8efb0f1701340e279c 13985915 TOTALLY_WRONG
  88. 668c0bb52edec49d27b0d0e673ae955798bfbe031edb779573903be9d20c1116 13981903 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  89. c7f2ff9bd51b42cb965f7cac2691ede8029422a14f6727ad255ebcc02b7db2f8 13761106 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  90. 33ac90a88d12023ce762772c8422e65ad62528b1de8b579780729978fdf9f437 13565058 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  91. SHA1-Patches:
  92. a1799e3fa0d47f6745a90b3e10e1eae442892f02 6093771 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  93. 45a0e17714357501c0251fc2f30ac3dad98bad85 6093711 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  94. 5d8ef7b8288024666148d89d2bb4a973bc41a682 6093597 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  95. 9f4ff66bc61c67070af0b8925a8c1889eab47ebd 6093251 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  96. 3a7650a9c9656872653a8c990ac802e547eff394 584 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  97. SHA256-Patches:
  98. 52cb3df2e78f012b7eb8ee4bad8bb2cdc185ce96dc1ff449222d49f454618b76 6093771 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  99. b8e607100e642b1e3127ac4751528d8fc9ffe413953a9afcedb0473cac135cd9 6093711 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  100. eabd2eaf70c6cfcb5108f1496bf971eee18b6848f9bca77bf3599c92a21993da 6093597 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  101. 70b95b9c4dd14e34706cc9063094621b04cb187f9f29f7057dff90183b11b21b 6093251 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  102. 26ceafe212bdfb45394ebbeb0d8980af01efdd6a07a78424d6cda268c797e344 584 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  103. SHA1-Download:
  104. 4ca7db18342fca28d2b9e59fec463776fd14931e 387469 GONE_WITH_THE_WIND
  105. 3d8aeb4b658fab36ae43198102a113922ef6ad21 387406 T-2020-12-12-0800.11-F-2020-11-26-0822.42.gz
  106. 11db8148e26030f65b7d29041f805b6534329f9a 271 T-2020-12-12-0800.11-F-2020-12-12-0800.11.gz
  107. SHA256-Download:
  108. dbf9a732491fe685d209a3da8d03609b874079b6b50dd1db8990854817e168be 387492 T-2020-12-12-0800.11-F-2020-11-25-0812.03.gz
  109. 3aea0a0443f624be3b3664e037634ff74b7f59631dad797d075464b8733f4cf4 387500 T-2020-12-12-0800.11-F-2020-11-25-2013.43.gz
  110. 1b96280550272f576e22b1901b100e9b7062ae9b9957fe26088b516f73611ee3 387469 T-2020-12-12-0800.11-F-2020-11-26-0212.42.gz
  111. 05ea55afd7e30cd9556d96ab211714fec51a6c71c486ca20514e9c04d091ef30 387406 T-2020-12-12-0800.11-F-2020-11-26-0822.42.gz
  112. acf2997c8ddc7e9e935154ee9807f8777d25c81fa3eb35c53ec0d94d8fb0f21d 271 T-2020-12-12-0800.11-F-2020-12-12-0800.11.gz
  113. X-Unmerged-SHA1-History:
  114. e791a3eed4b51744d91d7fd3100adddab2439655 13565058 2020-12-12-0800.11
  115. X-Unmerged-SHA256-History:
  116. 33ac90a88d12023ce762772c8422e65ad62528b1de8b579780729978fdf9f437 13565058 2020-12-12-0800.11
  117. X-Unmerged-SHA1-Patches:
  118. a4628688d21d3cfe21a560b614f9c0909b66c98f 7158486 T-2020-12-09-0202.31-F-2020-11-22-0214.58
  119. 7c652dc66607ad7f568414fb0fe6386cbf8979f3 7103094 T-2020-12-09-0202.31-F-2020-11-22-0816.18
  120. 29b8e86a32ea4493608b45efb7a7e453fb07bc64 7102980 T-2020-12-09-0202.31-F-2020-11-22-1420.12
  121. ab93e3c10d0d557dfb097b8ff0eb0b6b7029f700 7019210 T-2020-12-09-0202.31-F-2020-11-22-2016.07
  122. 3a7650a9c9656872653a8c990ac802e547eff394 584 2020-12-12-0800.11
  123. X-Unmerged-SHA256-Patches:
  124. 3ac4c2cb60dce35ee059263ddf063379737a84b5dd7459d5b95471afa3b86a00 7158486 T-2020-12-09-0202.31-F-2020-11-22-0214.58
  125. 47949559026c2253b18cc769cac858d5ccababf9236ac26ec75cb68c90d226cd 7103094 T-2020-12-09-0202.31-F-2020-11-22-0816.18
  126. f791e377a6b3cb80c9c2b6c0cdc88c59b337f0443bfb5c4116d17126dbb8ca14 7102980 T-2020-12-09-0202.31-F-2020-11-22-1420.12
  127. 1a8045dabd177304ca32350d40cb16d1e0e1ec1998f69f20a139685c978fa263 7019210 T-2020-12-09-0202.31-F-2020-11-22-2016.07
  128. 043e62ea9c798aab6f2cfe5fa50d091ed44048396f2130272bb25f08b11351ff 6963749 T-2020-12-09-0202.31-F-2020-11-23-0221.04
  129. 26ceafe212bdfb45394ebbeb0d8980af01efdd6a07a78424d6cda268c797e344 584 2020-12-12-0800.11
  130. X-Unmerged-SHA1-Download:
  131. 11db8148e26030f65b7d29041f805b6534329f9a 271 2020-12-12-0800.11.gz
  132. X-Unmerged-SHA256-Download:
  133. acf2997c8ddc7e9e935154ee9807f8777d25c81fa3eb35c53ec0d94d8fb0f21d 271 2020-12-12-0800.11.gz
  134. X-Patch-Precedence: merged
  135. X-DAK-Older-Patches: 2020-12-11-2002.18 2020-12-12-0200.49 2020-12-12-0800.11
  136. """
  137. MISALIGNED_HISTORY_BROKEN = """
  138. SHA1-Current: 2f846350bf5855230190ef1588e9ee5ddc45b7c7 13499355
  139. SHA256-Current: 17f0429f6116d47a75ac05e5598cac50b9ba511386e849628ef3b6dad0247d17 13499355
  140. SHA1-History:
  141. 05e82a87ced6a0827d38bdcc84b0a795512d48e8 13992555 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  142. 7f5c4a7946dd2fb52e51ef7103ab1ee26c210d3a 13985915 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  143. 6d2356c893e6c37a1957f3ae751af7da389ba37e 13981903 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  144. 1935ed98c30fa9eef8d4a22a70614e969a1ec7b0 13761106 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  145. e791a3eed4b51744d91d7fd3100adddab2439655 13565058 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  146. SHA256-History:
  147. 82d074d6437e4bf20d1e5e99641f2576c42257bde8acf6310cf2ea1d208c189b 13992555 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  148. beed2758c3f93c8f27d83de51e37f6686861648c2ceeae8efb0f1701340e279c 13985915 TOTALLY_WRONG
  149. 668c0bb52edec49d27b0d0e673ae955798bfbe031edb779573903be9d20c1116 13981903 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  150. c7f2ff9bd51b42cb965f7cac2691ede8029422a14f6727ad255ebcc02b7db2f8 13761106 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  151. 33ac90a88d12023ce762772c8422e65ad62528b1de8b579780729978fdf9f437 13565058 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  152. SHA1-Patches:
  153. a1799e3fa0d47f6745a90b3e10e1eae442892f02 6093771 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  154. 45a0e17714357501c0251fc2f30ac3dad98bad85 6093711 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  155. 5d8ef7b8288024666148d89d2bb4a973bc41a682 6093597 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  156. 9f4ff66bc61c67070af0b8925a8c1889eab47ebd 6093251 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  157. 3a7650a9c9656872653a8c990ac802e547eff394 584 T-2020-12-12-0800.11-F-2020-12-12-0800.11
  158. SHA256-Patches:
  159. 52cb3df2e78f012b7eb8ee4bad8bb2cdc185ce96dc1ff449222d49f454618b76 6093771 T-2020-12-12-0800.11-F-2020-11-25-0812.03
  160. b8e607100e642b1e3127ac4751528d8fc9ffe413953a9afcedb0473cac135cd9 6093711 T-2020-12-12-0800.11-F-2020-11-25-2013.43
  161. eabd2eaf70c6cfcb5108f1496bf971eee18b6848f9bca77bf3599c92a21993da 6093597 T-2020-12-12-0800.11-F-2020-11-26-0212.42
  162. 70b95b9c4dd14e34706cc9063094621b04cb187f9f29f7057dff90183b11b21b 6093251 T-2020-12-12-0800.11-F-2020-11-26-0822.42
  163. 26ceafe212bdfb45394ebbeb0d8980af01efdd6a07a78424d6cda268c797e344 584 T_T
  164. SHA1-Download:
  165. 4ca7db18342fca28d2b9e59fec463776fd14931e 387469 GONE_WITH_THE_WIND
  166. 3d8aeb4b658fab36ae43198102a113922ef6ad21 387406 T-2020-12-12-0800.11-F-2020-11-26-0822.42.gz
  167. 11db8148e26030f65b7d29041f805b6534329f9a 271 T-2020-12-12-0800.11-F-2020-12-12-0800.11.gz
  168. SHA256-Download:
  169. dbf9a732491fe685d209a3da8d03609b874079b6b50dd1db8990854817e168be 387492 T-2020-12-12-0800.11-F-2020-11-25-0812.03.gz
  170. 3aea0a0443f624be3b3664e037634ff74b7f59631dad797d075464b8733f4cf4 387500 T-2020-12-12-0800.11-F-2020-11-25-2013.43.gz
  171. 1b96280550272f576e22b1901b100e9b7062ae9b9957fe26088b516f73611ee3 387469 T-2020-12-12-0800.11-F-2020-11-26-0212.42.gz
  172. 05ea55afd7e30cd9556d96ab211714fec51a6c71c486ca20514e9c04d091ef30 387406 O_O.gz
  173. acf2997c8ddc7e9e935154ee9807f8777d25c81fa3eb35c53ec0d94d8fb0f21d 271 T-2020-12-12-0800.11-F-2020-12-12-0800.11.gz
  174. """
  175. if IsolatedAsyncioTestCase is not None:
  176. class TestPDiffs(IsolatedAsyncioTestCase):
  177. async def test_corrupt_pdiff_index(self):
  178. with tempdir() as tmpdir:
  179. pdiff_dir = os.path.join(tmpdir, "pdiffs")
  180. index_file = os.path.join(pdiff_dir, 'Index')
  181. os.mkdir(pdiff_dir)
  182. with open(index_file, 'w') as fd:
  183. fd.write(MISALIGNED_HISTORY_RESTORABLE)
  184. index = PDiffIndex(pdiff_dir, 3, False)
  185. assert index._history_order == [
  186. "T-2020-12-12-0800.11-F-2020-11-26-0822.42",
  187. "T-2020-12-12-0800.11-F-2020-12-12-0800.11",
  188. ]
  189. assert index._unmerged_history_order == ["2020-12-12-0800.11"]
  190. with open(index_file, 'w') as fd:
  191. fd.write(MISALIGNED_HISTORY_BROKEN)
  192. index = PDiffIndex(pdiff_dir, 3, False)
  193. assert index._history_order == []
  194. assert index._unmerged_history_order == []
  195. async def test_pdiff_index_unmerged(self):
  196. with tempdir() as tmpdir:
  197. pdiff_dir = os.path.join(tmpdir, "pdiffs")
  198. index_file = os.path.join(pdiff_dir, 'Index')
  199. index = PDiffIndex(pdiff_dir, 3, False)
  200. data = [
  201. 'Version 0',
  202. 'Some',
  203. 'data',
  204. 'across',
  205. '6',
  206. 'lines',
  207. ]
  208. # The pdiff system assumes we start from a non-empty file
  209. generate_orig(tmpdir, data)
  210. data[0] = 'Version 1'
  211. # Non-existing directory => empty history
  212. prune_history(index,
  213. known_patch_count_before=0,
  214. known_patch_count_after=0,
  215. detected_obsolete_patches=[]
  216. )
  217. # Update should be possible but do nothing
  218. # (dak generate-index-diffs relies on this behaviour)
  219. index.update_index()
  220. # It should not create the directory
  221. assert not os.path.isdir(pdiff_dir)
  222. # Adding a patch should "just work(tm)"
  223. await generate_patch(index, "patch-1", tmpdir, data)
  224. assert os.path.isdir(pdiff_dir)
  225. assert index.filesizehashes is not None
  226. assert index.filesizehashes.size > 0
  227. prune_history(index,
  228. known_patch_count_before=1,
  229. known_patch_count_after=1,
  230. detected_obsolete_patches=[]
  231. )
  232. assert not os.path.isfile(index_file)
  233. index.update_index()
  234. assert os.path.isfile(index_file)
  235. reload_and_compare_pdiff_indices(index)
  236. index.can_path = "/some/where"
  237. # We should detect obsolete files that are not part of the
  238. # history.
  239. with open(os.path.join(pdiff_dir, "random-patch"), "w"):
  240. pass
  241. prune_history(index,
  242. known_patch_count_before=1,
  243. known_patch_count_after=1,
  244. detected_obsolete_patches=['random-patch']
  245. )
  246. delete_obsolete_patches(index)
  247. data[0] = 'Version 2'
  248. data[3] = 'over'
  249. await generate_patch(index, "patch-2", tmpdir, data)
  250. prune_history(index,
  251. known_patch_count_before=2,
  252. known_patch_count_after=2,
  253. detected_obsolete_patches=[]
  254. )
  255. data[2] = 'Text'
  256. await generate_patch(index, "patch-3", tmpdir, data)
  257. prune_history(index,
  258. known_patch_count_before=3,
  259. known_patch_count_after=3,
  260. detected_obsolete_patches=[]
  261. )
  262. data[0] = 'Version 3'
  263. await generate_patch(index, "patch-4", tmpdir, data)
  264. prune_history(index,
  265. known_patch_count_before=4,
  266. known_patch_count_after=3,
  267. detected_obsolete_patches=['patch-1.gz']
  268. )
  269. data[0] = 'Version 4'
  270. data[-1] = 'lines.'
  271. await generate_patch(index, "patch-5", tmpdir, data)
  272. prune_history(index,
  273. known_patch_count_before=4,
  274. known_patch_count_after=3,
  275. detected_obsolete_patches=['patch-1.gz', 'patch-2.gz']
  276. )
  277. index.update_index()
  278. reload_and_compare_pdiff_indices(index)
  279. delete_obsolete_patches(index)
  280. async def test_pdiff_index_merged(self):
  281. with tempdir() as tmpdir:
  282. pdiff_dir = os.path.join(tmpdir, "pdiffs")
  283. index_file = os.path.join(pdiff_dir, 'Index')
  284. index = PDiffIndex(pdiff_dir, 3, True)
  285. data = [
  286. 'Version 0',
  287. 'Some',
  288. 'data',
  289. 'across',
  290. '6',
  291. 'lines',
  292. ]
  293. # The pdiff system assumes we start from a non-empty file
  294. generate_orig(tmpdir, data)
  295. data[0] = 'Version 1'
  296. # Non-existing directory => empty history
  297. prune_history(index,
  298. known_patch_count_before=0,
  299. known_patch_count_after=0,
  300. detected_obsolete_patches=[]
  301. )
  302. # Update should be possible but do nothing
  303. # (dak generate-index-diffs relies on this behaviour)
  304. index.update_index()
  305. # It should not create the directory
  306. assert not os.path.isdir(pdiff_dir)
  307. # Adding a patch should "just work(tm)"
  308. await generate_patch(index, "patch-1", tmpdir, data)
  309. assert os.path.isdir(pdiff_dir)
  310. assert index.filesizehashes is not None
  311. assert index.filesizehashes.size > 0
  312. prune_history(index,
  313. known_patch_count_before=1,
  314. known_patch_count_after=1,
  315. detected_obsolete_patches=[]
  316. )
  317. assert not os.path.isfile(index_file)
  318. index.update_index()
  319. assert os.path.isfile(index_file)
  320. reload_and_compare_pdiff_indices(index)
  321. index.can_path = "/some/where"
  322. data[0] = 'Version 2'
  323. data[3] = 'over'
  324. await generate_patch(index, "patch-2", tmpdir, data)
  325. prune_history(index,
  326. known_patch_count_before=2,
  327. known_patch_count_after=2,
  328. detected_obsolete_patches=[]
  329. )
  330. data[2] = 'Text'
  331. await generate_patch(index, "patch-3", tmpdir, data)
  332. prune_history(index,
  333. known_patch_count_before=3,
  334. known_patch_count_after=3,
  335. detected_obsolete_patches=[]
  336. )
  337. data[0] = 'Version 3'
  338. await generate_patch(index, "patch-4", tmpdir, data)
  339. prune_history(index,
  340. known_patch_count_before=4,
  341. known_patch_count_after=3,
  342. detected_obsolete_patches=['T-patch-1-F-patch-1.gz', 'patch-1.gz']
  343. )
  344. data[0] = 'Version 4'
  345. data[-1] = 'lines.'
  346. await generate_patch(index, "patch-5", tmpdir, data)
  347. prune_history(index,
  348. known_patch_count_before=4,
  349. known_patch_count_after=3,
  350. detected_obsolete_patches=['T-patch-1-F-patch-1.gz',
  351. 'T-patch-2-F-patch-1.gz',
  352. 'T-patch-2-F-patch-2.gz',
  353. 'patch-1.gz',
  354. 'patch-2.gz'
  355. ]
  356. )
  357. index.update_index()
  358. # Swap to the reloaded index. Assuming everything works as intended
  359. # this should not matter.
  360. reload_and_compare_pdiff_indices(index)
  361. data[0] = 'Version 5'
  362. await generate_patch(index, "patch-6", tmpdir, data)
  363. prune_history(index,
  364. known_patch_count_before=4,
  365. known_patch_count_after=3,
  366. detected_obsolete_patches=['T-patch-1-F-patch-1.gz',
  367. 'T-patch-2-F-patch-1.gz',
  368. 'T-patch-2-F-patch-2.gz',
  369. 'T-patch-3-F-patch-1.gz',
  370. 'T-patch-3-F-patch-2.gz',
  371. 'T-patch-3-F-patch-3.gz',
  372. 'patch-1.gz',
  373. 'patch-2.gz',
  374. 'patch-3.gz',
  375. ]
  376. )
  377. delete_obsolete_patches(index)
  378. data[0] = 'Version 6'
  379. await generate_patch(index, "patch-7", tmpdir, data)
  380. prune_history(index,
  381. known_patch_count_before=4,
  382. known_patch_count_after=3,
  383. detected_obsolete_patches=[
  384. 'T-patch-4-F-patch-1.gz',
  385. 'T-patch-4-F-patch-2.gz',
  386. 'T-patch-4-F-patch-3.gz',
  387. 'T-patch-4-F-patch-4.gz',
  388. 'patch-4.gz',
  389. ]
  390. )
  391. delete_obsolete_patches(index)
  392. index.update_index()
  393. reload_and_compare_pdiff_indices(index)
  394. # CHANGING TO NON-MERGED INDEX
  395. index = PDiffIndex(pdiff_dir, 3, False)
  396. data[0] = 'Version 7'
  397. # We need to add a patch to trigger the conversion
  398. await generate_patch(index, "patch-8", tmpdir, data)
  399. prune_history(index,
  400. known_patch_count_before=4,
  401. known_patch_count_after=3,
  402. detected_obsolete_patches=[
  403. 'T-patch-5-F-patch-2.gz',
  404. 'T-patch-5-F-patch-3.gz',
  405. 'T-patch-5-F-patch-4.gz',
  406. 'T-patch-5-F-patch-5.gz',
  407. 'T-patch-6-F-patch-3.gz',
  408. 'T-patch-6-F-patch-4.gz',
  409. 'T-patch-6-F-patch-5.gz',
  410. 'T-patch-6-F-patch-6.gz',
  411. 'T-patch-7-F-patch-4.gz',
  412. 'T-patch-7-F-patch-5.gz',
  413. 'T-patch-7-F-patch-6.gz',
  414. 'T-patch-7-F-patch-7.gz',
  415. 'patch-5.gz',
  416. ]
  417. )
  418. delete_obsolete_patches(index)
  419. index.update_index()
  420. # CHANGING BACK TO MERGED
  421. index = PDiffIndex(pdiff_dir, 3, True)
  422. data[0] = 'Version 8'
  423. # We need to add a patch to trigger the conversion
  424. await generate_patch(index, "patch-9", tmpdir, data)
  425. prune_history(index,
  426. known_patch_count_before=4,
  427. known_patch_count_after=3,
  428. detected_obsolete_patches=['patch-6.gz']
  429. )
  430. delete_obsolete_patches(index)
  431. index.update_index()
  432. # CHANGING TO NON-MERGED INDEX (AGAIN)
  433. # This will trip the removal of all the merged patches, proving they
  434. # were generated in the first place.
  435. index = PDiffIndex(pdiff_dir, 3, False)
  436. data[0] = 'Version 9'
  437. # We need to add a patch to trigger the conversion
  438. await generate_patch(index, "patch-A", tmpdir, data)
  439. prune_history(index,
  440. known_patch_count_before=4,
  441. known_patch_count_after=3,
  442. detected_obsolete_patches=[
  443. 'T-patch-9-F-patch-6.gz',
  444. 'T-patch-9-F-patch-7.gz',
  445. 'T-patch-9-F-patch-8.gz',
  446. 'T-patch-9-F-patch-9.gz',
  447. 'patch-7.gz',
  448. ]
  449. )
  450. delete_obsolete_patches(index)
  451. index.update_index()
  452. else:
  453. @unittest.skip("Needs IsolatedAsyncioTestCase (python3 >= 3.8)")
  454. class TestPDiffs(unittest.TestCase):
  455. pass