helpers.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import functools
  4. import os
  5. from docker.errors import APIError
  6. from pytest import skip
  7. from compose.config.config import ConfigDetails
  8. from compose.config.config import ConfigFile
  9. from compose.config.config import load
  10. def build_config(contents, **kwargs):
  11. return load(build_config_details(contents, **kwargs))
  12. def build_config_details(contents, working_dir='working_dir', filename='filename.yml'):
  13. return ConfigDetails(
  14. working_dir,
  15. [ConfigFile(filename, contents)],
  16. )
  17. def create_host_file(client, filename):
  18. dirname = os.path.dirname(filename)
  19. with open(filename, 'r') as fh:
  20. content = fh.read()
  21. container = client.create_container(
  22. 'busybox:latest',
  23. ['sh', '-c', 'echo -n "{}" > {}'.format(content, filename)],
  24. volumes={dirname: {}},
  25. host_config=client.create_host_config(
  26. binds={dirname: {'bind': dirname, 'ro': False}},
  27. network_mode='none',
  28. ),
  29. )
  30. try:
  31. client.start(container)
  32. exitcode = client.wait(container)
  33. if exitcode != 0:
  34. output = client.logs(container)
  35. raise Exception(
  36. "Container exited with code {}:\n{}".format(exitcode, output))
  37. finally:
  38. client.remove_container(container, force=True)
  39. def is_cluster(client):
  40. nodes = None
  41. def get_nodes_number():
  42. try:
  43. return len(client.nodes())
  44. except APIError:
  45. # If the Engine is not part of a Swarm, the SDK will raise
  46. # an APIError
  47. return 0
  48. if nodes is None:
  49. # Only make the API call if the value hasn't been cached yet
  50. nodes = get_nodes_number()
  51. return nodes > 1
  52. def no_cluster(reason):
  53. def decorator(f):
  54. @functools.wraps(f)
  55. def wrapper(self, *args, **kwargs):
  56. if is_cluster(self.client):
  57. skip("Test will not be run in cluster mode: %s" % reason)
  58. return
  59. return f(self, *args, **kwargs)
  60. return wrapper
  61. return decorator