pups 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/config_test.rb CHANGED
@@ -1,55 +1,217 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'tempfile'
3
5
 
4
6
  module Pups
5
7
  class ConfigTest < MiniTest::Test
6
-
7
8
  def test_config_from_env
8
- ENV["HELLO"] = "world"
9
+ ENV['HELLO'] = 'world'
9
10
  config = Config.new({})
10
- assert_equal("world", config.params["$ENV_HELLO"])
11
+ assert_equal('world', config.params['$ENV_HELLO'])
11
12
  end
12
13
 
13
- def test_integration
14
+ def test_env_param
15
+ ENV['FOO'] = 'BAR'
16
+ config = <<~YAML
17
+ env:
18
+ BAR: baz
19
+ hello: WORLD
20
+ one: 1
21
+ YAML
14
22
 
15
- f = Tempfile.new("test")
16
- f.close
23
+ config = Config.new(YAML.safe_load(config))
24
+ %w[BAR hello one].each { |e| ENV.delete(e) }
25
+ assert_equal('BAR', config.params['$ENV_FOO'])
26
+ assert_equal('baz', config.params['$ENV_BAR'])
27
+ assert_equal('WORLD', config.params['$ENV_hello'])
28
+ assert_equal('1', config.params['$ENV_one'])
29
+ end
30
+
31
+ def test_env_with_template
32
+ ENV['FOO'] = 'BAR'
33
+ config = <<~YAML
34
+ env:
35
+ greeting: "{{hello}}, {{planet}}!"
36
+ one: 1
37
+ other: "where are we on {{planet}}?"
38
+ env_template:
39
+ planet: pluto
40
+ hello: hola
41
+ YAML
42
+ config_hash = YAML.safe_load(config)
43
+
44
+ config = Config.new(config_hash)
45
+ %w[greeting one other].each { |e| ENV.delete(e) }
46
+ assert_equal('hola, pluto!', config.params['$ENV_greeting'])
47
+ assert_equal('1', config.params['$ENV_one'])
48
+ assert_equal('BAR', config.params['$ENV_FOO'])
49
+ assert_equal('where are we on pluto?', config.params['$ENV_other'])
50
+ end
51
+
52
+ def test_label_with_template
53
+ ENV["FOO"] = "BAR"
54
+ config = <<~YAML
55
+ env:
56
+ greeting: "{{hello}}, {{planet}}!"
57
+ one: 1
58
+ other: "where are we on {{planet}}?"
59
+ env_template:
60
+ planet: pluto
61
+ hello: hola
62
+ config: various
63
+ labels:
64
+ app_name: "{{config}}_discourse"
65
+ YAML
66
+ config_hash = YAML.load(config)
67
+
68
+ config = Config.new(config_hash)
69
+ %w[greeting one other].each { |e| ENV.delete(e) }
70
+ assert_equal("various_discourse", config.config['labels']['app_name'])
71
+ end
72
+
73
+ def test_env_with_ENV_templated_variable
74
+ ENV['env_template_config'] = 'my_application'
75
+ config = <<~YAML
76
+ env:
77
+ greeting: "{{hello}}, {{planet}}!"
78
+ one: 1
79
+ other: "building {{config}}"
80
+ env_template:
81
+ planet: pluto
82
+ hello: hola
83
+ YAML
84
+ config_hash = YAML.safe_load(config)
85
+
86
+ config = Config.new(config_hash)
87
+ %w[greeting one other].each { |e| ENV.delete(e) }
88
+ assert_equal('hola, pluto!', config.params['$ENV_greeting'])
89
+ assert_equal('1', config.params['$ENV_one'])
90
+ assert_equal('building my_application', config.params['$ENV_other'])
91
+ ENV["env_template_config"] = nil
92
+ end
17
93
 
18
- config = <<YAML
19
- params:
20
- run: #{f.path}
21
- run:
22
- - exec: echo hello world >> #{f.path}
23
- YAML
94
+ def test_integration
95
+ f = Tempfile.new('test')
96
+ f.close
24
97
 
25
- Config.new(YAML.load(config)).run
26
- assert_equal("hello world", File.read(f.path).strip)
98
+ config = <<~YAML
99
+ env:
100
+ PLANET: world
101
+ params:
102
+ run: #{f.path}
103
+ greeting: hello
104
+ run:
105
+ - exec: echo $greeting $PLANET >> #{f.path}
106
+ YAML
27
107
 
108
+ Config.new(YAML.safe_load(config)).run
109
+ ENV.delete('PLANET')
110
+ assert_equal('hello world', File.read(f.path).strip)
28
111
  ensure
29
112
  f.unlink
30
113
  end
31
114
 
32
115
  def test_hooks
33
- yaml = <<YAML
34
- run:
35
- - exec: 1
36
- - exec:
37
- hook: middle
38
- cmd: 2
39
- - exec: 3
40
- hooks:
41
- after_middle:
42
- - exec: 2.1
43
- before_middle:
44
- - exec: 1.9
45
- YAML
116
+ yaml = <<~YAML
117
+ run:
118
+ - exec: 1
119
+ - exec:
120
+ hook: middle
121
+ cmd: 2
122
+ - exec: 3
123
+ hooks:
124
+ after_middle:
125
+ - exec: 2.1
126
+ before_middle:
127
+ - exec: 1.9
128
+ YAML
46
129
 
47
130
  config = Config.load_config(yaml).config
48
- assert_equal({ "exec" => 1.9 }, config["run"][1])
49
- assert_equal({ "exec" => 2.1 }, config["run"][3])
131
+ assert_equal({ 'exec' => 1.9 }, config['run'][1])
132
+ assert_equal({ 'exec' => 2.1 }, config['run'][3])
133
+ end
134
+
135
+ def test_ignored_elements
136
+ f = Tempfile.new('test')
137
+ f.close
138
+
139
+ yaml = <<~YAML
140
+ env:
141
+ PLANET: world
142
+ params:
143
+ greeting: hello
144
+ run:
145
+ - exec: 1
146
+ - exec:
147
+ hook: middle
148
+ cmd: 2
149
+ - exec: 3
150
+ - exec: echo $greeting $PLANET >> #{f.path}
151
+ hooks:
152
+ after_middle:
153
+ - exec: 2.1
154
+ before_middle:
155
+ - exec: 1.9
156
+ YAML
50
157
 
158
+ conf = Config.load_config(yaml, %w[hooks params])
159
+ config = conf.config
160
+ assert_equal({ 'exec' => 1 }, config['run'][0])
161
+ assert_equal({ 'exec' => { 'hook' => 'middle', 'cmd' => 2 } }, config['run'][1])
162
+ assert_equal({ 'exec' => 3 }, config['run'][2])
163
+ assert_equal({ 'exec' => "echo $greeting $PLANET >> #{f.path}" }, config['run'][3])
51
164
 
165
+ # $greet from params will be an empty var as it was ignored
166
+ conf.run
167
+ ENV.delete('PLANET')
168
+ assert_equal('world', File.read(f.path).strip)
169
+ end
170
+
171
+ def test_generate_docker_run_arguments
172
+ yaml = <<~YAML
173
+ env:
174
+ foo: 1
175
+ bar: 2
176
+ baz: 'hello_{{spam}}'
177
+ env_template:
178
+ spam: 'eggs'
179
+ config: my_app
180
+ expose:
181
+ - "2222:22"
182
+ - "127.0.0.1:20080:80"
183
+ - 5555
184
+ volumes:
185
+ - volume:
186
+ host: /var/discourse/shared
187
+ guest: /shared
188
+ - volume:
189
+ host: /bar
190
+ guest: /baz
191
+ links:
192
+ - link:
193
+ name: postgres
194
+ alias: postgres
195
+ - link:
196
+ name: foo
197
+ alias: bar
198
+ labels:
199
+ monitor: "true"
200
+ app_name: "{{config}}_discourse"
201
+ YAML
202
+
203
+ config = Config.load_config(yaml)
204
+ args = config.generate_docker_run_arguments
205
+
206
+ expected = []
207
+ expected << "--env foo=1 --env bar=2 --env baz=hello_eggs"
208
+ expected << "--publish 2222:22 --publish 127.0.0.1:20080:80 --expose 5555"
209
+ expected << "--volume /var/discourse/shared:/shared --volume /bar:/baz"
210
+ expected << "--link postgres:postgres --link foo:bar"
211
+ expected << "--label monitor=true --label app_name=my_app_discourse"
212
+ expected.sort!
213
+
214
+ assert_equal(expected.join(" "), args)
52
215
  end
53
216
  end
54
217
  end
55
-
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+ require 'test_helper'
3
+ require 'tempfile'
4
+ require 'shellwords'
5
+
6
+ module Pups
7
+ class DockerTest < MiniTest::Test
8
+ def test_gen_env_arguments
9
+ yaml = <<~YAML
10
+ env:
11
+ foo: 1
12
+ bar: 2
13
+ baz: 'hello_{{spam}}'
14
+ env_template:
15
+ spam: 'eggs'
16
+ YAML
17
+
18
+ config = Config.load_config(yaml)
19
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["env"])
20
+ args = Docker.generate_env_arguments(config.config["env"])
21
+ assert_equal("--env foo=1 --env bar=2 --env baz=hello_eggs", args)
22
+ end
23
+
24
+ def test_gen_env_arguments_empty
25
+ yaml = <<~YAML
26
+ env:
27
+ foo: 1
28
+ bar: 2
29
+ baz: ''
30
+ YAML
31
+
32
+ config = Config.load_config(yaml)
33
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["env"])
34
+ args = Docker.generate_env_arguments(config.config["env"])
35
+ assert_equal("--env foo=1 --env bar=2", args)
36
+ end
37
+
38
+ def test_gen_env_arguments_escaped
39
+ yaml = <<~YAML
40
+ env:
41
+ password: "{{spam}}*`echo`@e$t| = >>$()&list;#"
42
+ env_template:
43
+ spam: 'eggs'
44
+ YAML
45
+
46
+ config = Config.load_config(yaml)
47
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["env"])
48
+ args = Docker.generate_env_arguments(config.config["env"])
49
+ assert_equal("--env password=#{Shellwords.escape('eggs*`echo`@e$t| = >>$()&list;#')}", args)
50
+ end
51
+
52
+ def test_gen_env_arguments_quoted_with_a_space
53
+ yaml = <<~YAML
54
+ env:
55
+ a_variable: here is a sentence
56
+ YAML
57
+
58
+ config = Config.load_config(yaml)
59
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["env"])
60
+ args = Docker.generate_env_arguments(config.config["env"])
61
+ assert_equal('--env a_variable=here\ is\ a\ sentence', args)
62
+ end
63
+
64
+ def test_gen_env_arguments_newline
65
+ pw = <<~PW
66
+ this password is
67
+ a weird one
68
+ PW
69
+
70
+ yaml = <<~YAML
71
+ env:
72
+ password: "#{pw}"
73
+ env_template:
74
+ spam: 'eggs'
75
+ YAML
76
+
77
+ config = Config.load_config(yaml)
78
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["env"])
79
+ args = Docker.generate_env_arguments(config.config["env"])
80
+ assert_equal('--env password=this\ password\ is\ a\ weird\ one\ ', args)
81
+ end
82
+
83
+ def test_gen_expose_arguments
84
+ yaml = <<~YAML
85
+ expose:
86
+ - "2222:22"
87
+ - "127.0.0.1:20080:80"
88
+ - 5555
89
+ YAML
90
+
91
+ config = Config.load_config(yaml)
92
+ args = Docker.generate_expose_arguments(config.config["expose"])
93
+ assert_equal("--publish 2222:22 --publish 127.0.0.1:20080:80 --expose 5555", args)
94
+ end
95
+
96
+ def test_gen_volume_arguments
97
+ yaml = <<~YAML
98
+ volumes:
99
+ - volume:
100
+ host: /var/discourse/shared
101
+ guest: /shared
102
+ - volume:
103
+ host: /bar
104
+ guest: /baz
105
+ YAML
106
+
107
+ config = Config.load_config(yaml)
108
+ args = Docker.generate_volume_arguments(config.config["volumes"])
109
+ assert_equal("--volume /var/discourse/shared:/shared --volume /bar:/baz", args)
110
+ end
111
+
112
+ def test_gen_link_arguments
113
+ yaml = <<~YAML
114
+ links:
115
+ - link:
116
+ name: postgres
117
+ alias: postgres
118
+ - link:
119
+ name: foo
120
+ alias: bar
121
+ YAML
122
+
123
+ config = Config.load_config(yaml)
124
+ args = Docker.generate_link_arguments(config.config["links"])
125
+ assert_equal("--link postgres:postgres --link foo:bar", args)
126
+ end
127
+
128
+ def test_gen_label_arguments
129
+ yaml = <<~YAML
130
+ env_template:
131
+ config: my_app
132
+ labels:
133
+ monitor: "true"
134
+ app_name: "{{config}}_discourse"
135
+ YAML
136
+
137
+ config = Config.load_config(yaml)
138
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["labels"])
139
+ args = Docker.generate_label_arguments(config.config["labels"])
140
+ assert_equal("--label monitor=true --label app_name=my_app_discourse", args)
141
+ end
142
+
143
+ def test_gen_label_arguments_escaped
144
+ yaml = <<~YAML
145
+ labels:
146
+ app_name: "{{config}}'s_di$course"
147
+ env_template:
148
+ config: my_app
149
+ YAML
150
+
151
+ config = Config.load_config(yaml)
152
+ Config.transform_config_with_templated_vars(config.config['env_template'], config.config["labels"])
153
+ args = Docker.generate_label_arguments(config.config["labels"])
154
+ assert_equal("--label app_name=#{Shellwords.escape("my_app's_di$course")}", args)
155
+ end
156
+ end
157
+ end
@@ -1,113 +1,109 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'tempfile'
3
5
 
4
6
  module Pups
5
7
  class ExecCommandTest < MiniTest::Test
6
-
7
- def from_str(str, params={})
8
+ def from_str(str, params = {})
8
9
  ExecCommand.from_str(str, params).commands
9
10
  end
10
11
 
11
- def from_hash(hash, params={})
12
+ def from_hash(hash, params = {})
12
13
  ExecCommand.from_hash(hash, params).commands
13
14
  end
14
15
 
15
16
  def test_simple_str_command
16
- assert_equal(["do_something"],
17
- from_str("do_something"))
17
+ assert_equal(['do_something'],
18
+ from_str('do_something'))
18
19
  end
19
20
 
20
21
  def test_simple_str_command_with_param
21
- assert_equal(["hello world"],
22
- from_str("hello $bob", {"bob" => "world"}))
22
+ assert_equal(['hello world'],
23
+ from_str('hello $bob', { 'bob' => 'world' }))
23
24
  end
24
25
 
25
26
  def test_nested_command
26
- assert_equal(["first"],
27
- from_hash("cmd" => "first"))
27
+ assert_equal(['first'],
28
+ from_hash('cmd' => 'first'))
28
29
  end
29
30
 
30
31
  def test_multi_commands
31
- assert_equal(["first","second"],
32
- from_hash("cmd" => ["first","second"]))
32
+ assert_equal(%w[first second],
33
+ from_hash('cmd' => %w[first second]))
33
34
  end
34
35
 
35
36
  def test_multi_commands_with_home
36
- assert_equal(["cd /home/sam && first",
37
- "cd /home/sam && second"],
38
- from_hash("cmd" => ["first","second"],
39
- "cd" => "/home/sam"))
37
+ assert_equal(['cd /home/sam && first',
38
+ 'cd /home/sam && second'],
39
+ from_hash('cmd' => %w[first second],
40
+ 'cd' => '/home/sam'))
40
41
  end
41
42
 
42
43
  def test_exec_works
43
- ExecCommand.from_str("ls",{}).run
44
+ ExecCommand.from_str('ls', {}).run
44
45
  end
45
46
 
46
47
  def test_fails_for_bad_command
47
48
  assert_raises(Errno::ENOENT) do
48
- ExecCommand.from_str("boom",{}).run
49
+ ExecCommand.from_str('boom', {}).run
49
50
  end
50
51
  end
51
52
 
52
53
  def test_backgroud_task_do_not_fail
53
54
  cmd = ExecCommand.new({})
54
55
  cmd.background = true
55
- cmd.add("sleep 10 && exit 1")
56
+ cmd.add('sleep 10 && exit 1')
56
57
  cmd.run
57
58
  end
58
59
 
59
60
  def test_raise_on_fail
60
61
  cmd = ExecCommand.new({})
61
- cmd.add("chgrp -a")
62
+ cmd.add('chgrp -a')
62
63
  cmd.raise_on_fail = false
63
64
  cmd.run
64
65
  end
65
66
 
66
67
  def test_stdin
67
-
68
68
  `touch test_file`
69
69
  cmd = ExecCommand.new({})
70
- cmd.add("read test ; echo $test > test_file")
71
- cmd.stdin = "hello"
70
+ cmd.add('read test ; echo $test > test_file')
71
+ cmd.stdin = 'hello'
72
72
  cmd.run
73
73
 
74
- assert_equal("hello\n", File.read("test_file"))
75
-
74
+ assert_equal("hello\n", File.read('test_file'))
76
75
  ensure
77
- File.delete("test_file")
76
+ File.delete('test_file')
78
77
  end
79
78
 
80
79
  def test_fails_for_non_zero_exit
81
- assert_raises(RuntimeError) do
82
- ExecCommand.from_str("chgrp -a",{}).run
80
+ assert_raises(Pups::ExecError) do
81
+ ExecCommand.from_str('chgrp -a', {}).run
83
82
  end
84
83
  end
85
84
 
86
-
87
85
  def test_can_terminate_async
88
86
  cmd = ExecCommand.new({})
89
87
  cmd.background = true
90
- pid = cmd.spawn("sleep 10 && exit 1")
88
+ pid = cmd.spawn('sleep 10 && exit 1')
91
89
  ExecCommand.terminate_async
92
90
  assert_raises(Errno::ECHILD) do
93
- Process.waitpid(pid,Process::WNOHANG)
91
+ Process.waitpid(pid, Process::WNOHANG)
94
92
  end
95
93
  end
96
94
 
97
95
  def test_can_terminate_rogues
98
96
  cmd = ExecCommand.new({})
99
97
  cmd.background = true
100
- pid = cmd.spawn("trap \"echo TERM && sleep 100\" TERM ; sleep 100")
98
+ pid = cmd.spawn('trap "echo TERM && sleep 100" TERM ; sleep 100')
101
99
  # we need to give bash enough time to trap
102
100
  sleep 0.01
103
101
 
104
102
  ExecCommand.terminate_async(wait: 0.1)
105
103
 
106
104
  assert_raises(Errno::ECHILD) do
107
- Process.waitpid(pid,Process::WNOHANG)
105
+ Process.waitpid(pid, Process::WNOHANG)
108
106
  end
109
-
110
107
  end
111
-
112
108
  end
113
109
  end