IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
8.5KB

  1. import pytest
  2. from focker.image import validate_spec, \
  3. build_squeeze, \
  4. build, \
  5. command_image_build, \
  6. command_image_tag, \
  7. command_image_untag, \
  8. command_image_list, \
  9. command_image_prune
  10. import subprocess
  11. from tempfile import TemporaryDirectory
  12. import focker.image
  13. import os
  14. from focker.zfs import zfs_find, \
  15. zfs_mountpoint, \
  16. zfs_exists_snapshot_sha256, \
  17. zfs_parse_output
  18. from focker.misc import focker_unlock
  19. import yaml
  20. def test_validate_spec_01():
  21. spec = { 'base': 'base', 'steps': 'steps' }
  22. validate_spec(spec)
  23. def test_validate_spec_02():
  24. spec = { 'steps': 'steps' }
  25. with pytest.raises(ValueError):
  26. validate_spec(spec)
  27. def test_validate_spec_03():
  28. spec = { 'base': 'base' }
  29. with pytest.raises(ValueError):
  30. validate_spec(spec)
  31. def test_validate_spec_04():
  32. spec = {}
  33. with pytest.raises(ValueError):
  34. validate_spec(spec)
  35. def test_build_squeeze(monkeypatch):
  36. focker_unlock()
  37. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-build-squeeze-base'])
  38. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-build-squeeze-base'])
  39. spec = dict(base='test-build-squeeze-base', steps=[
  40. dict(copy=['/etc/localtime', '/etc/localtime']),
  41. dict(copy=['/etc/hosts', '/etc/hosts'])
  42. ])
  43. _, base_sha256 = zfs_find('test-build-squeeze-base', focker_type='image')
  44. def fail(sha256, *args, **kwargs):
  45. if sha256 != base_sha256:
  46. raise RuntimeError('No pre-existing layers expected apart from base')
  47. monkeypatch.setattr(focker.image, 'zfs_snapshot_by_sha256', fail)
  48. with TemporaryDirectory() as d:
  49. args = lambda: 0
  50. args.focker_dir = d
  51. name, _ = build_squeeze(spec, args)
  52. focker_unlock()
  53. mountpoint = zfs_mountpoint(name.split('@')[0])
  54. print('name:', name, 'mountpoint:', mountpoint)
  55. assert os.path.exists(os.path.join(mountpoint, 'etc/localtime'))
  56. assert os.path.exists(os.path.join(mountpoint, 'etc/hosts'))
  57. subprocess.check_output(['focker', 'image', 'remove', '-R', 'test-build-squeeze-base'])
  58. assert not os.path.exists(mountpoint)
  59. def test_build(monkeypatch):
  60. focker_unlock()
  61. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-build-squeeze-base'])
  62. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-build-squeeze-base'])
  63. spec = dict(base='test-build-squeeze-base', steps=[
  64. dict(copy=['/etc/localtime', '/etc/localtime']),
  65. dict(copy=['/etc/hosts', '/etc/hosts'])
  66. ])
  67. _, base_sha256 = zfs_find('test-build-squeeze-base', focker_type='image')
  68. counter = 0
  69. def count_calls(*args, **kwargs):
  70. nonlocal counter
  71. counter += 1
  72. return zfs_exists_snapshot_sha256(*args, **kwargs)
  73. monkeypatch.setattr(focker.image, 'zfs_exists_snapshot_sha256', count_calls)
  74. with TemporaryDirectory() as d:
  75. args = lambda: 0
  76. args.focker_dir = d
  77. name, _ = build(spec, args)
  78. assert counter == 2
  79. focker_unlock()
  80. mountpoint = zfs_mountpoint(name.split('@')[0])
  81. print('name:', name, 'mountpoint:', mountpoint)
  82. assert os.path.exists(os.path.join(mountpoint, 'etc/localtime'))
  83. assert os.path.exists(os.path.join(mountpoint, 'etc/hosts'))
  84. subprocess.check_output(['focker', 'image', 'remove', '-R', 'test-build-squeeze-base'])
  85. assert not os.path.exists(mountpoint)
  86. def test_command_image_build():
  87. focker_unlock()
  88. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-command-image-build-base'])
  89. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-command-image-build-base'])
  90. with TemporaryDirectory() as d:
  91. args = lambda: 0
  92. with open(os.path.join(d, 'Fockerfile'), 'w') as f:
  93. yaml.dump(dict(base='test-command-image-build-base', steps=[
  94. dict(copy=['/etc/localtime', '/etc/localtime']),
  95. dict(copy=['/etc/hosts', '/etc/hosts'])
  96. ]), f)
  97. args.focker_dir = d
  98. args.squeeze = False
  99. args.tags = [ 'test-command-image-build' ]
  100. command_image_build(args)
  101. focker_unlock()
  102. name, _ = zfs_find('test-command-image-build', focker_type='image')
  103. mountpoint = zfs_mountpoint(name)
  104. assert os.path.exists(os.path.join(mountpoint, 'etc/localtime'))
  105. assert os.path.exists(os.path.join(mountpoint, 'etc/hosts'))
  106. subprocess.check_output(['focker', 'image', 'remove', '-R', 'test-command-image-build-base'])
  107. assert not os.path.exists(mountpoint)
  108. def test_command_image_tag():
  109. focker_unlock()
  110. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-command-image-tag'])
  111. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-command-image-tag'])
  112. name_1, sha256_1 = zfs_find('test-command-image-tag', focker_type='image')
  113. args = lambda: 0
  114. args.reference = sha256_1
  115. args.tags = ['test-a', 'test-b', 'test-c']
  116. command_image_tag(args)
  117. for t in args.tags:
  118. name_2, sha256_2 = zfs_find(t, focker_type='image')
  119. assert name_2 == name_1
  120. assert sha256_2 == sha256_1
  121. subprocess.check_output(['focker', 'image', 'remove', '-R', 'test-command-image-tag'])
  122. for t in args.tags:
  123. with pytest.raises(ValueError):
  124. zfs_find(t, focker_type='image')
  125. with pytest.raises(ValueError):
  126. zfs_find('test-command-image-tag', focker_type='image')
  127. def test_command_image_untag():
  128. focker_unlock()
  129. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-command-image-untag'])
  130. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-command-image-untag', 'test-command-image-untag-1', 'test-command-image-untag-2'])
  131. name, sha256 = zfs_find('test-command-image-untag', focker_type='image')
  132. args = lambda: 0
  133. args.tags = ['test-command-image-untag-1', 'test-command-image-untag-2']
  134. command_image_untag(args)
  135. tags = zfs_parse_output(['zfs', 'get', '-H', 'focker:tags', name])
  136. tags = tags[0][2].split(',')
  137. assert tags == ['test-command-image-untag']
  138. with pytest.raises(ValueError):
  139. zfs_find('test-command-image-untag-1', focker_type='image')
  140. with pytest.raises(ValueError):
  141. zfs_find('test-command-image-untag-2', focker_type='image')
  142. subprocess.check_output(['focker', 'image', 'remove', 'test-command-image-untag'])
  143. def test_command_image_list(monkeypatch):
  144. focker_unlock()
  145. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-command-image-list'])
  146. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-command-image-list', 'test-command-image-list-1', 'test-command-image-list-2'])
  147. name, sha256 = zfs_find('test-command-image-list', focker_type='image')
  148. args = lambda: 0
  149. args.tagged_only = True
  150. args.full_sha256 = True
  151. lst = None
  152. headers = None
  153. def fake_tabulate(*args, **kwargs):
  154. nonlocal lst
  155. nonlocal headers
  156. lst = args[0]
  157. headers = kwargs['headers']
  158. monkeypatch.setattr(focker.image, 'tabulate', fake_tabulate)
  159. command_image_list(args)
  160. assert lst is not None
  161. assert headers == ['Tags', 'Size', 'SHA256', 'Base']
  162. assert len(lst) >= 3
  163. match = list(filter(lambda a: sorted(a[0].split(' ')) == ['test-command-image-list', 'test-command-image-list-1', 'test-command-image-list-2'], lst))
  164. assert len(match) == 1
  165. match = match[0]
  166. assert match[2] == sha256
  167. assert match[3] == '-'
  168. subprocess.check_output(['focker', 'image', 'remove', 'test-command-image-list'])
  169. def test_command_image_prune():
  170. focker_unlock()
  171. subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-command-image-prune'])
  172. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '-t', 'test-command-image-prune'])
  173. name, sha256 = zfs_find('test-command-image-prune', focker_type='image')
  174. mountpoint = zfs_mountpoint(name)
  175. subprocess.check_output(['focker', 'image', 'untag', 'test-command-image-prune'])
  176. args = lambda: 0
  177. command_image_prune(args)
  178. with pytest.raises(ValueError):
  179. zfs_find('test-command-image-prune', focker_type='image')
  180. with pytest.raises(ValueError):
  181. zfs_find(sha256, focker_type='image')
  182. assert not os.path.exists(mountpoint)