interpolation_test.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import pytest
  4. from compose.config.environment import Environment
  5. from compose.config.interpolation import interpolate_environment_variables
  6. from compose.config.interpolation import Interpolator
  7. from compose.config.interpolation import InvalidInterpolation
  8. from compose.config.interpolation import TemplateWithDefaults
  9. from compose.const import COMPOSEFILE_V2_0 as V2_0
  10. from compose.const import COMPOSEFILE_V3_1 as V3_1
  11. @pytest.fixture
  12. def mock_env():
  13. return Environment({'USER': 'jenny', 'FOO': 'bar'})
  14. @pytest.fixture
  15. def variable_mapping():
  16. return Environment({'FOO': 'first', 'BAR': ''})
  17. @pytest.fixture
  18. def defaults_interpolator(variable_mapping):
  19. return Interpolator(TemplateWithDefaults, variable_mapping).interpolate
  20. def test_interpolate_environment_variables_in_services(mock_env):
  21. services = {
  22. 'servicea': {
  23. 'image': 'example:${USER}',
  24. 'volumes': ['$FOO:/target'],
  25. 'logging': {
  26. 'driver': '${FOO}',
  27. 'options': {
  28. 'user': '$USER',
  29. }
  30. }
  31. }
  32. }
  33. expected = {
  34. 'servicea': {
  35. 'image': 'example:jenny',
  36. 'volumes': ['bar:/target'],
  37. 'logging': {
  38. 'driver': 'bar',
  39. 'options': {
  40. 'user': 'jenny',
  41. }
  42. }
  43. }
  44. }
  45. value = interpolate_environment_variables(V2_0, services, 'service', mock_env)
  46. assert value == expected
  47. def test_interpolate_environment_variables_in_volumes(mock_env):
  48. volumes = {
  49. 'data': {
  50. 'driver': '$FOO',
  51. 'driver_opts': {
  52. 'max': 2,
  53. 'user': '${USER}'
  54. }
  55. },
  56. 'other': None,
  57. }
  58. expected = {
  59. 'data': {
  60. 'driver': 'bar',
  61. 'driver_opts': {
  62. 'max': 2,
  63. 'user': 'jenny'
  64. }
  65. },
  66. 'other': {},
  67. }
  68. value = interpolate_environment_variables(V2_0, volumes, 'volume', mock_env)
  69. assert value == expected
  70. def test_interpolate_environment_variables_in_secrets(mock_env):
  71. secrets = {
  72. 'secretservice': {
  73. 'file': '$FOO',
  74. 'labels': {
  75. 'max': 2,
  76. 'user': '${USER}'
  77. }
  78. },
  79. 'other': None,
  80. }
  81. expected = {
  82. 'secretservice': {
  83. 'file': 'bar',
  84. 'labels': {
  85. 'max': 2,
  86. 'user': 'jenny'
  87. }
  88. },
  89. 'other': {},
  90. }
  91. value = interpolate_environment_variables(V3_1, secrets, 'volume', mock_env)
  92. assert value == expected
  93. def test_escaped_interpolation(defaults_interpolator):
  94. assert defaults_interpolator('$${foo}') == '${foo}'
  95. def test_invalid_interpolation(defaults_interpolator):
  96. with pytest.raises(InvalidInterpolation):
  97. defaults_interpolator('${')
  98. with pytest.raises(InvalidInterpolation):
  99. defaults_interpolator('$}')
  100. with pytest.raises(InvalidInterpolation):
  101. defaults_interpolator('${}')
  102. with pytest.raises(InvalidInterpolation):
  103. defaults_interpolator('${ }')
  104. with pytest.raises(InvalidInterpolation):
  105. defaults_interpolator('${ foo}')
  106. with pytest.raises(InvalidInterpolation):
  107. defaults_interpolator('${foo }')
  108. with pytest.raises(InvalidInterpolation):
  109. defaults_interpolator('${foo!}')
  110. def test_interpolate_missing_no_default(defaults_interpolator):
  111. assert defaults_interpolator("This ${missing} var") == "This var"
  112. assert defaults_interpolator("This ${BAR} var") == "This var"
  113. def test_interpolate_with_value(defaults_interpolator):
  114. assert defaults_interpolator("This $FOO var") == "This first var"
  115. assert defaults_interpolator("This ${FOO} var") == "This first var"
  116. def test_interpolate_missing_with_default(defaults_interpolator):
  117. assert defaults_interpolator("ok ${missing:-def}") == "ok def"
  118. assert defaults_interpolator("ok ${missing-def}") == "ok def"
  119. assert defaults_interpolator("ok ${BAR:-/non:-alphanumeric}") == "ok /non:-alphanumeric"
  120. def test_interpolate_with_empty_and_default_value(defaults_interpolator):
  121. assert defaults_interpolator("ok ${BAR:-def}") == "ok def"
  122. assert defaults_interpolator("ok ${BAR-def}") == "ok "