ruby_yacht 0.5.0 → 0.6.0

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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rdoc_options +8 -2
  4. data/.rspec +1 -0
  5. data/.travis.yml +17 -1
  6. data/Gemfile.lock +18 -2
  7. data/README.md +28 -10
  8. data/bin/ruby_yacht +5 -0
  9. data/doc/TODO.md +1 -20
  10. data/doc/configuration.md +104 -21
  11. data/doc/configuration_sample.rb +19 -8
  12. data/doc/contributing.md +28 -5
  13. data/doc/plugins.md +105 -45
  14. data/lib/ruby_yacht/dsl/app.rb +14 -18
  15. data/lib/ruby_yacht/dsl/configuration.rb +51 -32
  16. data/lib/ruby_yacht/dsl/database.rb +24 -8
  17. data/lib/ruby_yacht/dsl/dsl.rb +32 -4
  18. data/lib/ruby_yacht/dsl/hook.rb +182 -48
  19. data/lib/ruby_yacht/dsl/project.rb +20 -14
  20. data/lib/ruby_yacht/dsl/server_type.rb +14 -31
  21. data/lib/ruby_yacht/dsl/web_server.rb +87 -0
  22. data/lib/ruby_yacht/dsl.rb +1 -0
  23. data/lib/ruby_yacht/images/app/Dockerfile.erb +17 -6
  24. data/lib/ruby_yacht/images/app/before_startup.bash.erb +5 -3
  25. data/lib/ruby_yacht/images/app/startup.bash.erb +5 -2
  26. data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +7 -11
  27. data/lib/ruby_yacht/images/database/Dockerfile.erb +7 -18
  28. data/lib/ruby_yacht/images/database/startup.bash.erb +1 -1
  29. data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -19
  30. data/lib/ruby_yacht/plugins/mysql.rb +18 -8
  31. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_app.rb +5 -5
  32. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_project.rb +3 -3
  33. data/lib/ruby_yacht/plugins/nginx.rb +28 -0
  34. data/lib/ruby_yacht/plugins/rails/scripts/build_new_app.rb +10 -0
  35. data/lib/ruby_yacht/plugins/rails/scripts/update_rails_config.rb +6 -1
  36. data/lib/ruby_yacht/plugins/rails.rb +34 -19
  37. data/lib/ruby_yacht/plugins.rb +2 -1
  38. data/lib/ruby_yacht/runner/build_images.rb +87 -73
  39. data/lib/ruby_yacht/runner/checkout.rb +1 -1
  40. data/lib/ruby_yacht/runner/command.rb +13 -1
  41. data/lib/ruby_yacht/runner/create_new_project.rb +91 -0
  42. data/lib/ruby_yacht/runner/help.rb +1 -1
  43. data/lib/ruby_yacht/runner/run_containers.rb +17 -21
  44. data/lib/ruby_yacht/runner/runner.rb +27 -2
  45. data/lib/ruby_yacht/runner/services.rb +15 -10
  46. data/lib/ruby_yacht/runner/shell.rb +1 -1
  47. data/lib/ruby_yacht/runner/update_hosts.rb +16 -11
  48. data/lib/ruby_yacht/runner.rb +1 -0
  49. data/log/.gitkeep +0 -0
  50. data/ruby_yacht.gemspec +4 -2
  51. data/spec/docker/Dockerfile +19 -3
  52. data/spec/docker/install_gems.bash +5 -0
  53. data/spec/docker/run.bash +44 -0
  54. data/spec/docker/startup.bash +10 -0
  55. data/spec/dsl/app_spec.rb +66 -38
  56. data/spec/dsl/configuration_spec.rb +236 -30
  57. data/spec/dsl/database_spec.rb +103 -4
  58. data/spec/dsl/dsl_spec.rb +46 -3
  59. data/spec/dsl/hook_spec.rb +278 -57
  60. data/spec/dsl/project_spec.rb +75 -45
  61. data/spec/dsl/server_type_spec.rb +52 -12
  62. data/spec/dsl/web_server_spec.rb +160 -0
  63. data/spec/fixtures/apollo-new-project-config +20 -0
  64. data/spec/fixtures/app-dependencies-dockerfile-generic +4 -7
  65. data/spec/fixtures/app-dependencies-dockerfile-generic-with-library-install +6 -10
  66. data/spec/fixtures/app-dependencies-dockerfile-rails +9 -11
  67. data/spec/fixtures/app-dependencies-dockerfile-with-no-repository +20 -0
  68. data/spec/fixtures/database-dockerfile +1 -1
  69. data/spec/fixtures/database-dockerfile-mysql +3 -3
  70. data/spec/fixtures/database-dockerfile-rails +5 -4
  71. data/spec/fixtures/database-dockerfile-rails-with-no-repository +27 -0
  72. data/spec/fixtures/database-dockerfile-with-seed-hooks +3 -3
  73. data/spec/fixtures/database-startup-mysql +2 -1
  74. data/spec/fixtures/mars-before-startup +2 -2
  75. data/spec/fixtures/mars-before-startup-rails +5 -4
  76. data/spec/fixtures/mars-before-startup-with-before-startup-hooks +5 -4
  77. data/spec/fixtures/mars-before-startup-with-custom-file-copy +3 -3
  78. data/spec/fixtures/mars-before-startup-with-no-repository +3 -0
  79. data/spec/fixtures/mars-dockerfile +3 -2
  80. data/spec/fixtures/mars-dockerfile-rails +6 -5
  81. data/spec/fixtures/mars-dockerfile-rails-with-no-repository +32 -0
  82. data/spec/fixtures/mars-dockerfile-with-after-checkout-hooks +5 -4
  83. data/spec/fixtures/mars-dockerfile-with-before-startup-hooks +5 -4
  84. data/spec/fixtures/mars-dockerfile-with-custom-file-copy +4 -3
  85. data/spec/fixtures/mars-dockerfile-with-local-database +4 -2
  86. data/spec/fixtures/mars-dockerfile-with-no-repository +22 -0
  87. data/spec/fixtures/mars-dockerfile-with-remote-database +4 -2
  88. data/spec/fixtures/mars-startup +2 -2
  89. data/spec/fixtures/mars-startup-rails +2 -2
  90. data/spec/fixtures/mars-startup-rails-with-no-repository +5 -0
  91. data/spec/fixtures/mars-startup-with-no-repository +4 -0
  92. data/spec/fixtures/web-dockerfile +18 -11
  93. data/spec/fixtures/web-dockerfile-jupiter +28 -0
  94. data/spec/fixtures/web-dockerfile-nginx +38 -0
  95. data/spec/fixtures/web-dockerfile-with-eponymous-app +16 -10
  96. data/spec/fixtures/web-dockerfile-with-primary-app +16 -10
  97. data/spec/integration/build_images_spec.rb +210 -0
  98. data/spec/integration/build_spec.rb +23 -0
  99. data/spec/integration/checkout_spec.rb +94 -0
  100. data/spec/integration/create_new_project_spec.rb +50 -0
  101. data/spec/integration/implode_spec.rb +20 -0
  102. data/spec/integration/run.rb +93 -0
  103. data/spec/integration/run_containers_spec.rb +279 -0
  104. data/spec/integration/services_spec.rb +99 -0
  105. data/spec/integration/shell_spec.rb +31 -0
  106. data/spec/integration/update_hosts_spec.rb +35 -0
  107. data/spec/plugins/mysql_spec.rb +18 -1
  108. data/spec/plugins/nginx_spec.rb +66 -0
  109. data/spec/plugins/rails_spec.rb +61 -89
  110. data/spec/runner/build_images_spec.rb +111 -58
  111. data/spec/runner/command_spec.rb +55 -3
  112. data/spec/runner/create_new_project_spec.rb +93 -0
  113. data/spec/runner/help_spec.rb +5 -1
  114. data/spec/runner/run_containers_spec.rb +22 -10
  115. data/spec/runner/runner_spec.rb +31 -4
  116. data/spec/runner/services_spec.rb +32 -4
  117. data/spec/runner/update_hosts_spec.rb +2 -1
  118. data/spec/spec_helper.rb +16 -1
  119. data/spec/support/integration_helpers.rb +76 -0
  120. data/spec/support/test_project.rb +15 -3
  121. metadata +97 -14
  122. data/spec/docker/build.bash +0 -10
  123. data/spec/fixtures/deploy-dockerfile +0 -2
  124. data/spec/fixtures/multi-project-web-dockerfile +0 -25
  125. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/app_config.erb +0 -0
  126. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index.html.erb +0 -0
  127. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index_config.erb +0 -0
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Checkout, :integration do
4
+ include IntegrationHelpers
5
+
6
+ before :all do
7
+ configure_project
8
+ run_command 'build_images'
9
+ run_command 'run_containers'
10
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost', contains: '200 OK'
11
+ end
12
+
13
+ after :all do
14
+ IntegrationHelpers.clear_docker_containers
15
+ end
16
+
17
+ context 'with a valid command' do
18
+ before :all do
19
+ @result = run_command 'checkout mars checkout-test-branch'
20
+ wait_on_command_result 'curl -H Host:mars.apollo.johnbrownlee.com localhost/posts -d ""', contains: '"tag":null'
21
+ end
22
+
23
+ it 'returns true' do
24
+ expect(@result).to be_truthy
25
+ end
26
+
27
+ it "updates the code from the server" do
28
+ results = `docker exec apollo-mars ls app/controllers`.split("\n")
29
+ expect(results).to include 'users_controller.rb'
30
+ expect(results).to include 'posts_controller.rb'
31
+ end
32
+
33
+ it "runs new database migrations" do
34
+ results = run_command_in_docker(:mars, 'mysql -uapollo -ptestpass -hapollo-database -e "show fields from apollo.posts"').split("\n")
35
+ expect(results).to include "tag\tvarchar(255)\tYES\t\tNULL\t"
36
+ end
37
+
38
+ it "starts the server with the new code base" do
39
+ results = `docker exec apollo-mars curl localhost:8080/posts -d "user_id=1&title=First%20Post&contents=Hello,%20World&tag=party" 2>&1`
40
+ expect(results).to include '"tag":"party"'
41
+ end
42
+ end
43
+
44
+ context 'with a local checkout folder' do
45
+ before :all do
46
+ run_command 'build_images', environment: { CHECK_OUT_LOCALLY: 1 }
47
+ run_command 'run_containers', environment: { CHECK_OUT_LOCALLY: 1 }
48
+ run_command 'checkout mars checkout-test-branch', environment: { CHECK_OUT_LOCALLY: 1 }
49
+ end
50
+
51
+ it "updates the code from the server" do
52
+ results = `ls ../mars/app/controllers`.split("\n")
53
+ expect(results).to include 'users_controller.rb'
54
+ expect(results).to include 'posts_controller.rb'
55
+ end
56
+
57
+ after :all do
58
+ IntegrationHelpers.clear_docker_containers
59
+ IntegrationHelpers.clear_checkout_folders
60
+ end
61
+ end
62
+
63
+ context 'with a production environment' do
64
+ before :all do
65
+ run_command 'build_images', environment: { USE_PRODUCTION_ENVIRONMENT: 1 }
66
+ run_command 'run_containers', environment: { USE_PRODUCTION_ENVIRONMENT: 1 }
67
+ run_command 'checkout mars master', environment: { USE_PRODUCTION_ENVIRONMENT: 1 }
68
+ end
69
+
70
+ it "does not install any non-production gems" do
71
+ gems = `docker exec -it apollo-mars gem list`
72
+ expect(gems).to include 'mysql2'
73
+ expect(gems).not_to include 'byebug'
74
+ end
75
+
76
+ after :all do
77
+ IntegrationHelpers.clear_docker_containers
78
+ end
79
+ end
80
+
81
+ context 'with no branch' do
82
+ it 'returns false' do
83
+ result = run_command 'checkout mars'
84
+ expect(result).to be_falsey
85
+ end
86
+ end
87
+
88
+ context 'with no app name' do
89
+ it 'returns false' do
90
+ result = run_command 'checkout'
91
+ expect(result).to be_falsey
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubyYacht::Runner::CreateNewProject, :integration do
4
+ include IntegrationHelpers
5
+
6
+ def run_command(command, environment: {}, capture_output: false)
7
+ full_command = "#{command}"
8
+ environment.each do |key, value|
9
+ full_command = "#{key}=#{value} #{full_command}"
10
+ end
11
+ folder = File.basename(FileUtils.pwd)
12
+ if capture_output
13
+ `#{full_command}`
14
+ else
15
+ system "#{full_command} 1> ../#{folder}/log/integration_stdout.txt 2> ../#{folder}/log/integration_stderr.txt"
16
+ end
17
+ end
18
+
19
+ before :all do
20
+ configure_project
21
+ run_command 'ruby_yacht new apollo ../apollo-config'
22
+ run_command 'cd ../apollo-config; ruby run.rb build'
23
+ wait_on_command_result 'curl -I -H Host:apollo.test.com localhost', contains: '200 OK'
24
+ end
25
+
26
+ after :all do
27
+ IntegrationHelpers.clear_docker_containers
28
+ restore_hosts_file
29
+ FileUtils.rm_rf '../apollo-config'
30
+ FileUtils.rm_rf '../apollo'
31
+ end
32
+
33
+ let(:containers) { `docker ps | grep "apollo\\|jupiter"`.split("\n").collect { |line| line.split(/\s+/).last }.sort }
34
+
35
+ it 'starts the containers' do
36
+ expect(containers).to eq %w(apollo apollo-web)
37
+ end
38
+
39
+ it 'brings up the app servers' do
40
+ results = `curl apollo.test.com 2>&1`
41
+ expect(results).to include 'Ruby on Rails: Welcome aboard'
42
+ end
43
+
44
+ it 'checks out the apps to a local directory' do
45
+ results = `ls ../apollo`.split("\n")
46
+ expect(results).to include "app"
47
+ expect(results).to include "Gemfile"
48
+ end
49
+ end
50
+
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Implode, :integration do
4
+ include IntegrationHelpers
5
+
6
+ before :all do
7
+ configure_project
8
+ run_command 'build'
9
+ run_command 'run_containers'
10
+ run_command 'implode'
11
+ end
12
+
13
+ it 'removes all the images and containers' do
14
+ containers = `docker ps -a | grep apollo`
15
+ expect(containers).to eq ''
16
+
17
+ images = `docker images -a | grep apollo`
18
+ expect(images).to eq ''
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ require 'ruby_yacht'
2
+
3
+ RubyYacht.configure do
4
+ project :apollo do
5
+ system_prefix :apollo
6
+ repository 'github.com'
7
+ rails_secret_key_base 'c330d739b502b4c43f4a850c592798243c5e92b1828b4e1e69de764fbdf8e733e0165241c67a76f34a9a46b10d27960fa288149ac662ea6bd9408fdb766aea39'
8
+
9
+ if ENV['CHECK_OUT_LOCALLY'] == '1'
10
+ check_out_locally
11
+ end
12
+
13
+ unless ENV['SKIP_DATABASE'] == '1'
14
+ mysql_database :apollo do
15
+ username 'apollo'
16
+ password 'testpass'
17
+ host 'localhost'
18
+
19
+ if ENV['USE_NONSTANDARD_MYSQL_PORT'] == '1'
20
+ port 3333
21
+ end
22
+ end
23
+ end
24
+
25
+ first_app_name = ENV['CREATE_TITULAR_APP'] == '1' ? :apollo : :mars
26
+ rails_app first_app_name do
27
+ repository_name 'brownleej/ruby-yacht-mars' unless ENV['NO_REPOSITORY'] == '1'
28
+ unless ENV['SKIP_DATABASE'] == '1'
29
+ database_name :apollo
30
+ end
31
+ end
32
+
33
+ rails_app :saturn do
34
+ repository_name 'brownleej/ruby-yacht-saturn' unless ENV['NO_REPOSITORY'] == '1'
35
+ unless ENV['SKIP_DATABASE'] == '1'
36
+ database_name :apollo
37
+ end
38
+ end
39
+
40
+ nginx_web_server do
41
+ domain 'apollo.johnbrownlee.com'
42
+ end
43
+
44
+ if ENV['CONFIGURE_DNS'] == '1'
45
+ dns_server do
46
+ server '4.4.4.4'
47
+ server '8.8.8.8'
48
+
49
+ search_domain 'dns1.test.com'
50
+ search_domain 'dns2.test.com'
51
+ end
52
+ end
53
+
54
+ if ENV['USE_PRODUCTION_ENVIRONMENT']
55
+ rails_environment 'production'
56
+ rails_excluded_gem_groups %w(development test)
57
+ end
58
+
59
+ if ENV['CREATE_PRIMARY_APP']
60
+ primary_app :mars
61
+ end
62
+ end
63
+
64
+ if ENV['CREATE_SECOND_PROJECT'] == '1'
65
+ project :jupiter do
66
+ system_prefix :jupiter
67
+ repository 'github.com'
68
+ rails_secret_key_base 'c330d739b502b4c43f4a850c592798243c5e92b1828b4e1e69de764fbdf8e733e0165241c67a76f34a9a46b10d27960fa288149ac662ea6bd9408fdb766aea39'
69
+
70
+ unless ENV['SKIP_DATABASE'] == '1'
71
+ mysql_database :jupiter do
72
+ username 'jupiter'
73
+ password 'testpass'
74
+ host 'localhost'
75
+ end
76
+ end
77
+
78
+ rails_app :saturn do
79
+ repository_name 'brownleej/ruby-yacht-saturn'
80
+ unless ENV['SKIP_DATABASE'] == '1'
81
+ database_name :jupiter
82
+ end
83
+ end
84
+
85
+ nginx_web_server do
86
+ domain 'jupiter.johnbrownlee.com'
87
+ port 8080
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ RubyYacht::Runner.run
@@ -0,0 +1,279 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::RunContainers, :integration do
4
+ include IntegrationHelpers
5
+
6
+ before :all do
7
+ configure_project
8
+ end
9
+
10
+ let(:containers) { `docker ps | grep "apollo\\|jupiter"`.split("\n").collect { |line| line.split(/\s+/).last }.sort }
11
+
12
+ context 'with the normal settings' do
13
+ before :all do
14
+ run_command 'build_images'
15
+ run_command 'run_containers'
16
+
17
+ wait_on_command_success 'curl localhost'
18
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost', contains: '200 OK'
19
+ wait_on_command_result 'curl -I -H Host:saturn.apollo.johnbrownlee.com localhost', contains: '200 OK'
20
+ end
21
+
22
+ after :all do
23
+ IntegrationHelpers.clear_docker_containers
24
+ end
25
+
26
+ it "starts all the containers" do
27
+ expect(containers).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
28
+ end
29
+
30
+ it "makes the app servers accessible from the web server" do
31
+ results = run_command_in_docker :web, 'bash -c "apt-get install -y curl 2>&1; curl apollo-mars:8080/users 2>&1"'
32
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
33
+ end
34
+
35
+ it "makes the web server accessible from the host machine" do
36
+ results = `curl -H Host:apollo.johnbrownlee.com localhost 2>&1`
37
+ expect(results).to include '<a href="http://mars.apollo.johnbrownlee.com/">'
38
+ end
39
+
40
+ it "makes the app servers accessible from the host machine through the web server" do
41
+ results = `curl -H Host:mars.apollo.johnbrownlee.com localhost/users 2>&1`
42
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
43
+
44
+ results = `curl -H Host:saturn.apollo.johnbrownlee.com localhost 2>&1`
45
+ expect(results).to include 'Welcome to Saturn'
46
+ end
47
+
48
+ it "does not generate static assets" do
49
+ results = `docker exec -it apollo-mars ls /var/code/public`
50
+ expect(results).not_to include 'assets'
51
+ end
52
+ end
53
+
54
+ context 'with no database server' do
55
+ before :all do
56
+ run_command 'build_images', environment: { SKIP_DATABASE: 1 }
57
+ run_command 'run_containers', environment: { SKIP_DATABASE: 1 }
58
+ end
59
+
60
+ after :all do
61
+ IntegrationHelpers.clear_docker_containers
62
+ end
63
+
64
+ it "starts all the containers except the database server" do
65
+ expect(containers).to eq %w(apollo-mars apollo-saturn apollo-web)
66
+ end
67
+
68
+ it "allows the apps to use their local sqlite databases" do
69
+ results = `docker exec -it apollo-mars rails r 'puts User.count'`
70
+ expect(results).to eq "0\r\n"
71
+ end
72
+ end
73
+
74
+ context 'with the apps checked out locally' do
75
+ before :all do
76
+ run_command 'build_images', environment: { CHECK_OUT_LOCALLY: 1 }
77
+ run_command 'run_containers', environment: { CHECK_OUT_LOCALLY: 1 }
78
+ end
79
+
80
+ after :all do
81
+ IntegrationHelpers.clear_docker_containers
82
+ IntegrationHelpers.clear_checkout_folders
83
+ end
84
+
85
+ it "starts all the containers" do
86
+ expect(containers).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
87
+ end
88
+
89
+ it "checks out the code to a local directory" do
90
+ results = `ls ..`.split("\n")
91
+ expect(results).to include "mars"
92
+ expect(results).to include "saturn"
93
+
94
+ results = `ls ../mars`.split("\n")
95
+ expect(results).to include 'app'
96
+ expect(results).to include 'Gemfile'
97
+ end
98
+ end
99
+
100
+ context 'with DNS server config' do
101
+ before :all do
102
+ run_command 'build_images', environment: { CONFIGURE_DNS: 1 }
103
+ run_command 'run_containers', environment: { CONFIGURE_DNS: 1 }
104
+ end
105
+
106
+ after :all do
107
+ IntegrationHelpers.clear_docker_containers
108
+ end
109
+
110
+ it "puts the custom config in the DNS server config" do
111
+ results = `docker exec apollo-mars cat /etc/resolv.conf`
112
+ expect(results).to include 'dns1.test.com'
113
+ end
114
+ end
115
+
116
+ context 'with a production environment' do
117
+ before :all do
118
+ run_command 'build_images', environment: { USE_PRODUCTION_ENVIRONMENT: 1 }
119
+ run_command 'run_containers', environment: { USE_PRODUCTION_ENVIRONMENT: 1 }
120
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost/users', contains: '200 OK'
121
+ end
122
+
123
+ after :all do
124
+ IntegrationHelpers.clear_docker_containers
125
+ end
126
+
127
+ it "starts all the containers" do
128
+ expect(containers).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
129
+ end
130
+
131
+ it "generates static assets" do
132
+ results = `docker exec -it apollo-mars ls /var/code/public/assets`
133
+ expect(results).to include 'application-89720f5a46589c09bfd16b3e1c7c509bba7d6a3c3dd4f3a8e13e0d05a0fbf9c1.js'
134
+ end
135
+ end
136
+
137
+ context 'with a primary app' do
138
+ before :all do
139
+ run_command 'build_images', environment: { CREATE_PRIMARY_APP: 1 }
140
+ run_command 'run_containers', environment: { CREATE_PRIMARY_APP: 1 }
141
+ wait_on_command_result 'curl -I -H Host:apollo.johnbrownlee.com localhost', contains: '200 OK'
142
+ wait_on_command_result 'curl -I -H Host:saturn.apollo.johnbrownlee.com localhost', contains: '200 OK'
143
+ end
144
+
145
+ after :all do
146
+ IntegrationHelpers.clear_docker_containers
147
+ end
148
+
149
+ it "starts all the containers" do
150
+ expect(containers).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
151
+ end
152
+
153
+ it "makes the web server accessible from the host machine" do
154
+ results = `curl -H Host:apollo.johnbrownlee.com localhost/users 2>&1`
155
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
156
+ end
157
+
158
+ it "makes the main app accessible from the host machine through the web server" do
159
+ results = `curl -H Host:mars.apollo.johnbrownlee.com localhost/users 2>&1`
160
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
161
+ end
162
+
163
+ it "makes the secondary app accessible" do
164
+ results = `curl -H Host:saturn.apollo.johnbrownlee.com localhost 2>&1`
165
+ expect(results).to include 'Welcome to Saturn'
166
+ end
167
+ end
168
+
169
+ context "with an app with the same name as the project" do
170
+ before :all do
171
+ run_command 'build_images', environment: { CREATE_TITULAR_APP: 1 }
172
+ run_command 'run_containers', environment: { CREATE_TITULAR_APP: 1 }
173
+ wait_on_command_result 'curl -I -H Host:apollo.johnbrownlee.com localhost', contains: '200 OK'
174
+ wait_on_command_result 'curl -I -H Host:saturn.apollo.johnbrownlee.com localhost', contains: '200 OK'
175
+ end
176
+
177
+ after :all do
178
+ system "docker rm -f apollo 1> /dev/null"
179
+ system "docker rmi apollo 1> /dev/null"
180
+ IntegrationHelpers.clear_docker_containers
181
+ end
182
+
183
+ it "starts all the containers" do
184
+ expect(containers).to eq %w(apollo apollo-database apollo-saturn apollo-web)
185
+ end
186
+
187
+ it "makes the web server accessible from the host machine" do
188
+ results = `curl -H Host:apollo.johnbrownlee.com localhost/users 2>&1`
189
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
190
+ end
191
+
192
+ it "makes the secondary app accessible" do
193
+ results = `curl -H Host:saturn.apollo.johnbrownlee.com localhost 2>&1`
194
+ expect(results).to include 'Welcome to Saturn'
195
+ end
196
+ end
197
+
198
+ context "with a second project" do
199
+ before :all do
200
+ run_command 'build_images', environment: { CREATE_SECOND_PROJECT: 1 }
201
+ run_command 'run_containers', environment: { CREATE_SECOND_PROJECT: 1 }
202
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost', contains: '200 OK'
203
+ wait_on_command_result 'curl -I -H Host:saturn.jupiter.johnbrownlee.com localhost:8080', contains: '200 OK'
204
+ end
205
+
206
+ after :all do
207
+ IntegrationHelpers.clear_docker_containers
208
+
209
+ IntegrationHelpers.image_names.select { |name| name =~ /jupiter/ }.each do |name|
210
+ `docker rmi #{name} 1> /dev/null`
211
+ end
212
+ end
213
+
214
+ it "starts all the containers" do
215
+ expect(containers).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web jupiter-database jupiter-saturn jupiter-web)
216
+ end
217
+
218
+ it "makes the apps for both projects accessible" do
219
+ results = `curl -H Host:mars.apollo.johnbrownlee.com localhost/users 2>&1`
220
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
221
+
222
+ results = `curl -H Host:saturn.jupiter.johnbrownlee.com localhost:8080 2>&1`
223
+ expect(results).to include 'Welcome to Saturn'
224
+ end
225
+ end
226
+
227
+ context 'with no repository name' do
228
+ before :all do
229
+ run_command 'build_images', environment: { NO_REPOSITORY: 1, CHECK_OUT_LOCALLY: 1, SKIP_DATABASE: 1 }
230
+ run_command 'run_containers', environment: { NO_REPOSITORY: 1, CHECK_OUT_LOCALLY: 1, SKIP_DATABASE: 1 }
231
+
232
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost', contains: '200 OK'
233
+ wait_on_command_result 'curl -I -H Host:saturn.jupiter.johnbrownlee.com localhost', contains: '200 OK'
234
+ end
235
+
236
+ after :all do
237
+ IntegrationHelpers.clear_docker_containers
238
+ FileUtils.rm_rf '../mars'
239
+ FileUtils.rm_rf '../saturn'
240
+ end
241
+
242
+ it 'starts all the containers' do
243
+ expect(containers).to eq %w(apollo-mars apollo-saturn apollo-web)
244
+ end
245
+
246
+ it "brings up the app servers" do
247
+ results = `curl -H Host:mars.apollo.johnbrownlee.com localhost 2>&1`
248
+ expect(results).to include 'Ruby on Rails: Welcome aboard'
249
+ end
250
+
251
+ it "checks out the code to a local directory" do
252
+ results = `ls ../mars`.split("\n")
253
+ expect(results).to include "app"
254
+ expect(results).to include "Gemfile"
255
+ end
256
+ end
257
+
258
+ context 'with a non-standard database port' do
259
+ before :all do
260
+ run_command 'build_images', environment: { USE_NONSTANDARD_MYSQL_PORT: 1 }
261
+ run_command 'run_containers', environment: { USE_NONSTANDARD_MYSQL_PORT: 1 }
262
+ wait_on_command_result 'curl -I -H Host:mars.apollo.johnbrownlee.com localhost/users', contains: '200 OK'
263
+ end
264
+
265
+ after :all do
266
+ IntegrationHelpers.clear_docker_containers
267
+ end
268
+
269
+ it 'sets up the database to listen on that port' do
270
+ results = run_command_in_docker :mars, 'mysql -uapollo -ptestpass -hapollo-database -P3333 apollo 2>&1'
271
+ expect(results).not_to include 'ERROR'
272
+ end
273
+
274
+ it 'allows the app to connect to the database on that port' do
275
+ results = `curl -H Host:mars.apollo.johnbrownlee.com localhost/users 2>&1`
276
+ expect(results).to include 'test_user@mars.apollo.johnbrownlee.com'
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Services, :integration do
4
+ include IntegrationHelpers
5
+
6
+ before :all do
7
+ configure_project
8
+ run_command 'build_images'
9
+ run_command 'run_containers'
10
+ end
11
+
12
+ after :all do
13
+ IntegrationHelpers.clear_docker_containers
14
+ end
15
+
16
+ context "with the start command" do
17
+ before do
18
+ IntegrationHelpers.image_names.each do |image|
19
+ system "docker stop #{image} 1> /dev/null 2> /dev/null"
20
+ end
21
+
22
+ @result = run_command 'services start'
23
+ end
24
+
25
+ it "returns a success" do
26
+ expect(@result).to be_truthy
27
+ end
28
+
29
+ it "starts the containers" do
30
+ results = `docker ps | grep apollo`.split("\n")
31
+ results = results.collect { |line| line.split(/\s+/).last }
32
+ results.sort!
33
+
34
+ expect(results).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
35
+ end
36
+ end
37
+
38
+ context "with the stop command" do
39
+ before do
40
+ IntegrationHelpers.image_names.each do |image|
41
+ system "docker start #{image} 1> /dev/null 2> /dev/null"
42
+ end
43
+
44
+ @result = run_command 'services stop'
45
+ end
46
+
47
+ it "returns a success" do
48
+ expect(@result).to be_truthy
49
+ end
50
+
51
+ it "stops the containers" do
52
+ results = `docker ps | grep apollo`
53
+ expect(results).to eq ''
54
+
55
+ results = `docker ps -a | grep apollo`.split("\n")
56
+ results = results.collect { |line| line.split(/\s+/).last }
57
+ results.sort!
58
+
59
+ expect(results).to eq %w(apollo-database apollo-mars apollo-saturn apollo-web)
60
+ end
61
+ end
62
+
63
+ context 'with no database' do
64
+ before do
65
+ IntegrationHelpers.image_names.each do |image|
66
+ system "docker stop #{image} 1> /dev/null 2> /dev/null"
67
+ end
68
+
69
+ @result = run_command 'services start', environment: { SKIP_DATABASE: 1 }
70
+ end
71
+
72
+ it 'does not start the database image' do
73
+ results = `docker ps | grep apollo`.split("\n")
74
+ results = results.collect { |line| line.split(/\s+/).last }
75
+ results.sort!
76
+ expect(results).to eq %w(apollo-mars apollo-saturn apollo-web)
77
+ end
78
+ end
79
+
80
+ context "with an invalid command" do
81
+ before do
82
+ @result = run_command 'services crash'
83
+ end
84
+
85
+ it "returns a failure" do
86
+ expect(@result).to be_falsey
87
+ end
88
+ end
89
+
90
+ context "with no command" do
91
+ before do
92
+ @result = run_command 'services'
93
+ end
94
+
95
+ it "returns a failure" do
96
+ expect(@result).to be_falsey
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe RubyYacht::Runner::Shell, :integration do
4
+ include IntegrationHelpers
5
+
6
+ before :all do
7
+ configure_project
8
+ run_command 'build_images'
9
+ run_command 'run_containers'
10
+ end
11
+
12
+ after :all do
13
+ system "cat /etc/hosts*.backup > /etc/hosts"
14
+ end
15
+
16
+ context 'with a normal command' do
17
+ it "returns the results of running that command" do
18
+ results = run_command 'shell mars ls', capture_output: true
19
+ results = results.split(/\s+/)
20
+ expect(results).to include "app"
21
+ expect(results).to include "db"
22
+ end
23
+ end
24
+
25
+ context 'with no app name' do
26
+ it 'returns a failure' do
27
+ results = run_command 'shell'
28
+ expect(results).to be_falsey
29
+ end
30
+ end
31
+ end