Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Elasticsearch 8.x #232

Merged
merged 2 commits into from Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 45 additions & 2 deletions testcontainers/elasticsearch.py
Expand Up @@ -10,10 +10,50 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import re
import urllib
from typing import Dict

from deprecation import deprecated

from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_container_is_ready
import urllib

_FALLBACK_VERSION = 8
"""This version is used when no version could be detected from the image name."""


def _major_version_from_image_name(image_name: str) -> int:
"""Returns the major version from a container name like 'elasticsearch:8.1.0'
If the major version could not be determined, it will use the most recent
one (8 at the time of writing 2022-08-11).
"""
version_string = image_name.split(":")[-1]
regex_match = re.compile(r"(\d+)\.\d+\.\d+").match(version_string)
if not regex_match:
logging.warning("Could not determine major version from image name '%s'. Will use %s",
image_name, _FALLBACK_VERSION)
return _FALLBACK_VERSION
else:
return int(regex_match.group(1))


def _environment_by_version(version: int) -> Dict[str, str]:
"""Returns environment variables required for each major version to work."""
if version == 6:
lippertto marked this conversation as resolved.
Show resolved Hide resolved
# This setting is needed to avoid the check for the kernel parameter
# vm.max_map_count in the BootstrapChecks
return {"discovery.zen.minimum_master_nodes": "1"}
elif version == 7:
return {}
elif version == 8:
# Elasticsearch uses https now by default. However, our readiness
# check uses http, which does not work. Hence we disable security
# which should not be an issue for our context
return {"xpack.security.enabled": "false"}
else:
raise ValueError(f"Unknown elasticsearch version given: {version}")


class ElasticSearchContainer(DockerContainer):
Expand All @@ -33,7 +73,10 @@ def __init__(self, image="elasticsearch", port_to_expose=9200, **kwargs):
self.with_exposed_ports(self.port_to_expose)
self.with_env('transport.host', '127.0.0.1')
self.with_env('http.host', '0.0.0.0')
self.with_env('discovery.zen.minimum_master_nodes', '1')

major_version = _major_version_from_image_name(image)
for key, value in _environment_by_version(major_version).items():
self.with_env(key, value)

@wait_container_is_ready()
def _connect(self):
Expand Down
6 changes: 4 additions & 2 deletions tests/test_elasticsearch.py
@@ -1,11 +1,13 @@
import json
import urllib
import pytest

from testcontainers.elasticsearch import ElasticSearchContainer


def test_docker_run_elasticsearch():
version = '7.16.1'
# The versions below were the current supported versions at time of writing (2022-08-11)
@pytest.mark.parametrize('version', ['6.8.23', '7.17.5', '8.3.3'])
def test_docker_run_elasticsearch(version):
with ElasticSearchContainer(f'elasticsearch:{version}') as es:
resp = urllib.request.urlopen(es.get_url())
assert json.loads(resp.read().decode())['version']['number'] == version