testcontainers-core 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/Gemfile.lock +1 -1
- data/lib/testcontainers/docker_container.rb +84 -9
- data/lib/testcontainers/version.rb +1 -1
- data/lib/testcontainers.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 584f5aabce655fd2f113af37af6ce59cc8b3e0f6aa4b276bff52378e1d3c5e9d
|
4
|
+
data.tar.gz: 0a3c73c6a6ba495c61b3ded68092d4a58a06099e1ff543d7ac2a45e9503082a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18f526847480a5cec71aa4abf2b10393fa7a08ccf5c4f70a07c18667624a8fb49ca3f0d9d241f0f5dd9e32404f3e0e06fc2cb67465059703d5e9eec143c04f4e
|
7
|
+
data.tar.gz: fcc6793d0bbdf773de7e0cb5933364f45840c034c8821dd12ab99c17d08a05c23967d2b992d4152b2c7298eae12d75d751eaff8e83e21563a060647cdcbd1b67
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## [0.1.2] - 2023-05-13
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
- DockerContainer#first_mapped_port method returns the first of the
|
6
|
+
mapped ports for convenience.
|
7
|
+
|
8
|
+
- DockerContainer#get_env(key) method to gets the value of a single
|
9
|
+
env variable in the container
|
10
|
+
|
11
|
+
- Support custom healthchecks set with the new and
|
12
|
+
DockerContainer#add_/with_healthcheck methods. Example:
|
13
|
+
|
14
|
+
redis_container.with_healthcheck(test: ["redis-cli ping"], interval: 30, timeout: 30, retries: 3)
|
15
|
+
|
16
|
+
## Changed
|
17
|
+
|
18
|
+
- DockerContainer#mapped_port(port) method now returns an Integer instead of a String.
|
19
|
+
|
20
|
+
## Fixed
|
21
|
+
|
22
|
+
- Links to the GitHub project on the README.md file are fixed.
|
23
|
+
|
24
|
+
- Healtchecks handling have been fixed
|
25
|
+
|
26
|
+
## [0.1.1] - 2023-05-04
|
27
|
+
|
28
|
+
### Added
|
29
|
+
|
30
|
+
- Add .yardopts file to set the project ready for RubyDoc.info.
|
31
|
+
|
32
|
+
## [0.1.0] - 2023-05-04
|
33
|
+
|
34
|
+
### Added
|
35
|
+
|
36
|
+
- Initial release of the project with the Testcontainer::DockerContainer working.
|
data/Gemfile.lock
CHANGED
@@ -13,11 +13,12 @@ module Testcontainers
|
|
13
13
|
# @attr env [Array<String>, nil] an array of environment variables for the container in the format KEY=VALUE
|
14
14
|
# @attr labels [Hash, nil] a hash of labels to be applied to the container
|
15
15
|
# @attr working_dir [String, nil] the working directory for the container
|
16
|
+
# @attr healthcheck [Hash, nil] a hash of healthcheck options for the container
|
16
17
|
# @attr logger [Logger] a logger instance for the container
|
17
18
|
# @attr_reader _container [Docker::Container, nil] the underlying Docker::Container object
|
18
19
|
# @attr_reader _id [String, nil] the container's ID
|
19
20
|
class DockerContainer
|
20
|
-
attr_accessor :name, :image, :command, :exposed_ports, :port_bindings, :volumes, :filesystem_binds, :env, :labels, :working_dir
|
21
|
+
attr_accessor :name, :image, :command, :exposed_ports, :port_bindings, :volumes, :filesystem_binds, :env, :labels, :working_dir, :healthcheck
|
21
22
|
attr_accessor :logger
|
22
23
|
attr_reader :_container, :_id
|
23
24
|
|
@@ -35,7 +36,7 @@ module Testcontainers
|
|
35
36
|
# @param working_dir [String, nil] the working directory for the container
|
36
37
|
# @param logger [Logger] a logger instance for the container
|
37
38
|
def initialize(image, command: nil, name: nil, exposed_ports: nil, port_bindings: nil, volumes: nil, filesystem_binds: nil, env: nil,
|
38
|
-
labels: nil, working_dir: nil, logger: Testcontainers.logger)
|
39
|
+
labels: nil, working_dir: nil, healthcheck: nil, logger: Testcontainers.logger)
|
39
40
|
|
40
41
|
@image = image
|
41
42
|
@command = command
|
@@ -47,6 +48,7 @@ module Testcontainers
|
|
47
48
|
@filesystem_binds = add_filesystem_binds(filesystem_binds) if filesystem_binds
|
48
49
|
@labels = add_labels(labels) if labels
|
49
50
|
@working_dir = working_dir
|
51
|
+
@healthcheck = add_healthcheck(healthcheck) if healthcheck
|
50
52
|
@logger = logger
|
51
53
|
@_container = nil
|
52
54
|
@_id = nil
|
@@ -206,6 +208,40 @@ module Testcontainers
|
|
206
208
|
@labels
|
207
209
|
end
|
208
210
|
|
211
|
+
# Adds a healthcheck to the container.
|
212
|
+
#
|
213
|
+
# @param options [Hash] the healthcheck options.
|
214
|
+
# @option options [Array|String] :test the command to run to check the health of the container.
|
215
|
+
# @option options [Float] :interval the time in seconds between health checks. (default: 30)
|
216
|
+
# @option options [Float] :timeout the time in seconds to wait for a health check to complete. (default: 30)
|
217
|
+
# @option options [Integer] :retries the number of times to retry a failed health check before giving up. (default: 3)
|
218
|
+
# @option options [Boolean] :shell whether or not to run the health check in a shell. (default: false)
|
219
|
+
# @return [Hash] the healthcheck options for Docker.
|
220
|
+
def add_healthcheck(options = {})
|
221
|
+
test = options[:test]
|
222
|
+
|
223
|
+
if test.nil?
|
224
|
+
@healthcheck = {"Test" => ["NONE"]}
|
225
|
+
return @healthcheck
|
226
|
+
end
|
227
|
+
|
228
|
+
interval = options[:interval]&.to_f || 30.0
|
229
|
+
timeout = options[:timeout]&.to_f || 30.0
|
230
|
+
retries = options[:retries]&.to_i || 3
|
231
|
+
shell = options[:shell] || false
|
232
|
+
|
233
|
+
test = test.split(" ") if test.is_a?(String)
|
234
|
+
test = shell ? test.unshift("CMD-SHELL") : test.unshift("CMD")
|
235
|
+
|
236
|
+
@healthcheck = {
|
237
|
+
"Test" => test,
|
238
|
+
"Interval" => (interval * 1_000_000_000).to_i,
|
239
|
+
"Timeout" => (timeout * 1_000_000_000).to_i,
|
240
|
+
"Retries" => retries,
|
241
|
+
"StartPeriod" => 0
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
209
245
|
# Set options for the container configuration using "with_" methods.
|
210
246
|
#
|
211
247
|
# @param options [Hash] A hash of options where keys correspond to "with_" methods and values are the arguments for those methods.
|
@@ -323,6 +359,20 @@ module Testcontainers
|
|
323
359
|
self
|
324
360
|
end
|
325
361
|
|
362
|
+
# Adds a healthcheck to the container.
|
363
|
+
#
|
364
|
+
# @param options [Hash] the healthcheck options.
|
365
|
+
# @option options [Array|String] :test the command to run to check the health of the container.
|
366
|
+
# @option options [Float] :interval the time in seconds between health checks. (default: 30)
|
367
|
+
# @option options [Float] :timeout the time in seconds to wait for a health check to complete. (default: 30)
|
368
|
+
# @option options [Integer] :retries the number of times to retry a failed health check before giving up. (default: 3)
|
369
|
+
# @option options [Boolean] :shell whether or not to run the health check in a shell. (default: false)
|
370
|
+
# @return [DockerContainer] The updated DockerContainer instance.
|
371
|
+
def with_healthcheck(options = {})
|
372
|
+
add_healthcheck(options)
|
373
|
+
self
|
374
|
+
end
|
375
|
+
|
326
376
|
# Starts the container, yields the container instance to the block, and stops the container.
|
327
377
|
#
|
328
378
|
# @yield [DockerContainer] The container instance.
|
@@ -492,7 +542,7 @@ module Testcontainers
|
|
492
542
|
# @raise [ConnectionError] If the connection to the Docker daemon fails.
|
493
543
|
# @raise [HealthcheckNotSupportedError] If the container does not support healthchecks.
|
494
544
|
def healthy?
|
495
|
-
if
|
545
|
+
if supports_healthcheck?
|
496
546
|
@_container&.json&.dig("State", "Health", "Status") == "healthy"
|
497
547
|
else
|
498
548
|
raise HealthcheckNotSupportedError
|
@@ -508,9 +558,9 @@ module Testcontainers
|
|
508
558
|
#
|
509
559
|
# @return [Boolean] Whether the container supports healthchecks.
|
510
560
|
# @raise [ContainerNotStartedError] If the container has not been started.
|
511
|
-
def
|
561
|
+
def supports_healthcheck?
|
512
562
|
raise ContainerNotStartedError unless @_container
|
513
|
-
@_container.json["Config"]["Healthcheck"]
|
563
|
+
@_container.json["Config"]["Healthcheck"] != nil
|
514
564
|
end
|
515
565
|
|
516
566
|
# Returns whether the container exists.
|
@@ -573,8 +623,8 @@ module Testcontainers
|
|
573
623
|
|
574
624
|
# Returns the mapped host port for the given container port.
|
575
625
|
#
|
576
|
-
# @param port [Integer] The container port.
|
577
|
-
# @return [
|
626
|
+
# @param port [Integer | String] The container port.
|
627
|
+
# @return [Integer] The mapped host port.
|
578
628
|
# @raise [ConnectionError] If the connection to the Docker daemon fails.
|
579
629
|
# @raise [ContainerNotStartedError] If the container has not been started.
|
580
630
|
def mapped_port(port)
|
@@ -585,13 +635,32 @@ module Testcontainers
|
|
585
635
|
gateway_ip = container_gateway_ip
|
586
636
|
host = docker_host
|
587
637
|
|
588
|
-
return port if gateway_ip == host
|
638
|
+
return port.to_i if gateway_ip == host
|
589
639
|
end
|
590
|
-
mapped_port
|
640
|
+
mapped_port.to_i
|
591
641
|
rescue Excon::Error::Socket => e
|
592
642
|
raise ConnectionError, e.message
|
593
643
|
end
|
594
644
|
|
645
|
+
# Returns the container's first mapped port.
|
646
|
+
#
|
647
|
+
# @return [Integer] The container's first mapped port.
|
648
|
+
# @raise [ConnectionError] If the connection to the Docker daemon fails.
|
649
|
+
def first_mapped_port
|
650
|
+
raise ContainerNotStartedError unless @_container
|
651
|
+
container_ports.map { |port| mapped_port(port) }.first
|
652
|
+
end
|
653
|
+
|
654
|
+
# Returns the value for the given environment variable.
|
655
|
+
#
|
656
|
+
# @param key [String] The environment variable's key.
|
657
|
+
# @return [String] The environment variable's value.
|
658
|
+
# @return [nil] If the environment variable does not exist.
|
659
|
+
def get_env(key)
|
660
|
+
env_entry = env.find { |entry| entry.start_with?("#{key}=") }
|
661
|
+
env_entry&.split("=")&.last
|
662
|
+
end
|
663
|
+
|
595
664
|
# Returns the container's logs.
|
596
665
|
#
|
597
666
|
# @param stdout [Boolean] Whether to return stdout.
|
@@ -830,6 +899,11 @@ module Testcontainers
|
|
830
899
|
@_container&.json&.dig("NetworkSettings", "Ports", normalize_port(port))&.first&.dig("HostPort")
|
831
900
|
end
|
832
901
|
|
902
|
+
def container_ports
|
903
|
+
ports = @_container&.json&.dig("NetworkSettings", "Ports")&.keys || []
|
904
|
+
ports&.map { |port| port.split("/").first }
|
905
|
+
end
|
906
|
+
|
833
907
|
def default_gateway_ip
|
834
908
|
cmd = "ip route | awk '/default/ { print $3 }'"
|
835
909
|
|
@@ -868,6 +942,7 @@ module Testcontainers
|
|
868
942
|
"Env" => @env,
|
869
943
|
"Labels" => @labels,
|
870
944
|
"WorkingDir" => @working_dir,
|
945
|
+
"Healthcheck" => @healthcheck,
|
871
946
|
"HostConfig" => {
|
872
947
|
"PortBindings" => @port_bindings,
|
873
948
|
"Binds" => @filesystem_binds
|
data/lib/testcontainers.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testcontainers-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillermo Iguaran
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docker-api
|
@@ -88,6 +88,7 @@ executables: []
|
|
88
88
|
extensions: []
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
|
+
- CHANGELOG.md
|
91
92
|
- Gemfile
|
92
93
|
- Gemfile.lock
|
93
94
|
- LICENSE.txt
|