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!
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

201 řádky
6.8KB

  1. from focker.compose import exec_hook, \
  2. exec_prebuild, \
  3. exec_postbuild, \
  4. build_volumes, \
  5. build_images, \
  6. setup_dependencies
  7. from tempfile import TemporaryDirectory
  8. import os
  9. import pytest
  10. import fcntl
  11. from focker.misc import focker_lock, \
  12. focker_unlock
  13. import inspect
  14. import ast
  15. import stat
  16. from focker.zfs import zfs_find, \
  17. zfs_mountpoint, \
  18. zfs_parse_output
  19. import subprocess
  20. import yaml
  21. import jailconf
  22. def test_exec_hook_01():
  23. spec = [
  24. 'touch test-exec-hook-01',
  25. 'touch test-exec-hook-02'
  26. ]
  27. with TemporaryDirectory() as d:
  28. exec_hook(spec, d, 'test-exec-hook')
  29. assert os.path.exists(os.path.join(d, 'test-exec-hook-01'))
  30. assert os.path.exists(os.path.join(d, 'test-exec-hook-02'))
  31. assert not os.path.exists(d)
  32. def test_exec_hook_02():
  33. spec = 'touch test-exec-hook-01 && touch test-exec-hook-02'
  34. with TemporaryDirectory() as d:
  35. exec_hook(spec, d, 'test-exec-hook')
  36. assert os.path.exists(os.path.join(d, 'test-exec-hook-01'))
  37. assert os.path.exists(os.path.join(d, 'test-exec-hook-02'))
  38. assert not os.path.exists(d)
  39. @pytest.mark.xfail(raises=ValueError, strict=True)
  40. def test_exec_hook_03a():
  41. spec = 1
  42. with TemporaryDirectory() as d:
  43. exec_hook(spec, d, 'test-exec-hook')
  44. @pytest.mark.xfail(raises=TypeError, strict=True)
  45. def test_exec_hook_03b():
  46. spec = [1]
  47. with TemporaryDirectory() as d:
  48. exec_hook(spec, d, 'test-exec-hook')
  49. @pytest.mark.xfail(raises=FileNotFoundError, strict=True)
  50. def test_exec_hook_04():
  51. spec = 'ls'
  52. exec_hook(spec, '/non-existent-directory/wcj20fy103', 'test-exec-hook')
  53. def test_exec_hook_05():
  54. spec = 'ls'
  55. oldwd = os.getcwd()
  56. with TemporaryDirectory() as d:
  57. exec_hook(spec, d, 'test-exec-hook')
  58. assert os.getcwd() == oldwd
  59. @pytest.mark.xfail(raises=RuntimeError, strict=True)
  60. def test_exec_hook_06():
  61. spec = '/non-existent-command/hf249h'
  62. with TemporaryDirectory() as d:
  63. exec_hook(spec, d, 'test-exec-hook')
  64. def test_exec_hook_07():
  65. os.chdir('/')
  66. spec = 'flock --nonblock /var/lock/focker.lock -c ls'
  67. focker_lock()
  68. assert fcntl.flock(focker_lock.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) != 0
  69. with TemporaryDirectory() as d:
  70. exec_hook(spec, d, 'test-exec-hook')
  71. assert fcntl.flock(focker_lock.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) != 0
  72. focker_unlock()
  73. def _test_simple_forward(fun, fwd_fun_name='exec_hook'):
  74. src = inspect.getsource(fun)
  75. mod = ast.parse(src)
  76. assert isinstance(mod.body[0], ast.FunctionDef)
  77. assert isinstance(mod.body[0].body[0], ast.Return)
  78. assert isinstance(mod.body[0].body[0].value, ast.Call)
  79. assert mod.body[0].body[0].value.func.id == fwd_fun_name
  80. def test_exec_prebuild():
  81. _test_simple_forward(exec_prebuild)
  82. def test_exec_postbuild():
  83. _test_simple_forward(exec_postbuild)
  84. def test_build_volumes():
  85. subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-build-volumes'])
  86. err = False
  87. try:
  88. name, _ = zfs_find('test-build-volumes', focker_type='volume')
  89. except:
  90. err = True
  91. assert err
  92. spec = {
  93. 'test-build-volumes': {
  94. 'chown': '65534:65534',
  95. 'chmod': 0o123,
  96. 'zfs': {
  97. 'quota': '1G',
  98. 'readonly': 'on'
  99. }
  100. }
  101. }
  102. build_volumes(spec)
  103. name, _ = zfs_find('test-build-volumes', focker_type='volume')
  104. st = os.stat(zfs_mountpoint(name))
  105. assert st.st_uid == 65534
  106. assert st.st_gid == 65534
  107. assert ('%o' % st.st_mode)[-3:] == '123'
  108. zst = zfs_parse_output(['zfs', 'get', '-H', 'quota,readonly', name])
  109. assert zst[0][2] == '1G'
  110. assert zst[1][2] == 'on'
  111. subprocess.check_output(['zfs', 'destroy', '-r', '-f', name])
  112. def test_build_images():
  113. subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap'])
  114. subprocess.check_output(['focker', 'bootstrap', '--dry-run', '--tags', 'test-focker-bootstrap'])
  115. subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-build-images'])
  116. with TemporaryDirectory() as d:
  117. with open(os.path.join(d, 'Fockerfile'), 'w') as f:
  118. yaml.dump({
  119. 'base': 'test-focker-bootstrap',
  120. 'steps': [
  121. { 'copy': [
  122. [ '/bin/sh', '/bin/sh', { 'chmod': 0o777 } ],
  123. [ '/lib/libedit.so.7', '/lib/libedit.so.7' ],
  124. [ '/lib/libncursesw.so.8', '/lib/libncursesw.so.8' ],
  125. [ '/lib/libc.so.7', '/lib/libc.so.7' ],
  126. [ '/usr/bin/touch', '/usr/bin/touch', { 'chmod': 0o777 } ],
  127. [ '/libexec/ld-elf.so.1', '/libexec/ld-elf.so.1', { 'chmod': 0o555 } ]
  128. ] },
  129. { 'run': 'touch /test-build-images' }
  130. ]
  131. }, f)
  132. args = lambda: 0
  133. args.squeeze = False
  134. build_images({
  135. 'test-build-images': '.'
  136. }, d, args)
  137. focker_unlock()
  138. name, _ = zfs_find('test-build-images', focker_type='image')
  139. assert os.path.exists(os.path.join(zfs_mountpoint(name), 'test-build-images'))
  140. subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-build-images'])
  141. subprocess.check_output(['focker', 'image', 'prune'])
  142. subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap'])
  143. def test_setup_dependencies():
  144. conf = jailconf.load('/etc/jail.conf')
  145. jail = jailconf.JailBlock()
  146. conf['test-setup-dependencies-A'] = jail
  147. conf['test-setup-dependencies-B'] = jail
  148. conf['test-setup-dependencies-C'] = jail
  149. conf.write('/etc/jail.conf')
  150. setup_dependencies({
  151. 'test-setup-dependencies-A': {},
  152. 'test-setup-dependencies-B': { 'depend': 'test-setup-dependencies-A' },
  153. 'test-setup-dependencies-C': { 'depend': [
  154. 'test-setup-dependencies-A',
  155. 'test-setup-dependencies-B'
  156. ] }
  157. }, {
  158. 'test-setup-dependencies-A': 'test-setup-dependencies-A',
  159. 'test-setup-dependencies-B': 'test-setup-dependencies-B',
  160. 'test-setup-dependencies-C': 'test-setup-dependencies-C'
  161. })
  162. conf = jailconf.load('/etc/jail.conf')
  163. assert 'depend' not in conf['test-setup-dependencies-A']
  164. assert conf['test-setup-dependencies-B']['depend'] == 'test-setup-dependencies-A'
  165. assert conf['test-setup-dependencies-C']['depend'] == [
  166. 'test-setup-dependencies-A',
  167. 'test-setup-dependencies-B'
  168. ]
  169. del conf['test-setup-dependencies-A']
  170. del conf['test-setup-dependencies-B']
  171. del conf['test-setup-dependencies-C']
  172. conf.write('/etc/jail.conf')