MuranoCLI 3.0.7 → 3.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.ignore +1 -1
  4. data/.rubocop.yml +10 -5
  5. data/.trustme.sh +272 -106
  6. data/.trustme.vim +20 -1
  7. data/Gemfile +7 -5
  8. data/LICENSE.txt +14 -15
  9. data/MuranoCLI.gemspec +7 -5
  10. data/Rakefile +5 -5
  11. data/bin/murano +4 -4
  12. data/lib/MrMurano/Account.rb +13 -8
  13. data/lib/MrMurano/Business.rb +6 -7
  14. data/lib/MrMurano/Commander-Entry.rb +5 -5
  15. data/lib/MrMurano/Config-Migrate.rb +4 -4
  16. data/lib/MrMurano/Config.rb +27 -6
  17. data/lib/MrMurano/Content.rb +5 -5
  18. data/lib/MrMurano/Exchange-Element.rb +4 -4
  19. data/lib/MrMurano/Exchange.rb +4 -4
  20. data/lib/MrMurano/Gateway.rb +22 -11
  21. data/lib/MrMurano/Keystore.rb +4 -4
  22. data/lib/MrMurano/Logs.rb +87 -0
  23. data/lib/MrMurano/Mock.rb +5 -4
  24. data/lib/MrMurano/Passwords.rb +4 -5
  25. data/lib/MrMurano/ProjectFile.rb +4 -4
  26. data/lib/MrMurano/ReCommander.rb +4 -4
  27. data/lib/MrMurano/Setting.rb +5 -5
  28. data/lib/MrMurano/Settings-HttpService.rb +9 -6
  29. data/lib/MrMurano/Solution-ServiceConfig.rb +5 -5
  30. data/lib/MrMurano/Solution-Services.rb +76 -50
  31. data/lib/MrMurano/Solution-Users.rb +5 -4
  32. data/lib/MrMurano/Solution.rb +6 -6
  33. data/lib/MrMurano/SolutionId.rb +4 -4
  34. data/lib/MrMurano/SubCmdGroupContext.rb +4 -4
  35. data/lib/MrMurano/SyncAllowed.rb +4 -4
  36. data/lib/MrMurano/SyncRoot.rb +5 -5
  37. data/lib/MrMurano/SyncUpDown-Core.rb +515 -0
  38. data/lib/MrMurano/SyncUpDown-Item.rb +159 -0
  39. data/lib/MrMurano/SyncUpDown.rb +120 -688
  40. data/lib/MrMurano/Webservice-Cors.rb +4 -4
  41. data/lib/MrMurano/Webservice-Endpoint.rb +9 -6
  42. data/lib/MrMurano/Webservice-File.rb +5 -4
  43. data/lib/MrMurano/Webservice.rb +5 -5
  44. data/lib/MrMurano/commands/business.rb +4 -4
  45. data/lib/MrMurano/commands/completion.rb +6 -6
  46. data/lib/MrMurano/commands/config.rb +7 -5
  47. data/lib/MrMurano/commands/content.rb +5 -4
  48. data/lib/MrMurano/commands/cors.rb +4 -4
  49. data/lib/MrMurano/commands/devices.rb +6 -6
  50. data/lib/MrMurano/commands/domain.rb +4 -4
  51. data/lib/MrMurano/commands/exchange.rb +4 -4
  52. data/lib/MrMurano/commands/gb.rb +4 -4
  53. data/lib/MrMurano/commands/globals.rb +12 -4
  54. data/lib/MrMurano/commands/init.rb +5 -4
  55. data/lib/MrMurano/commands/keystore.rb +4 -4
  56. data/lib/MrMurano/commands/link.rb +4 -4
  57. data/lib/MrMurano/commands/login.rb +4 -4
  58. data/lib/MrMurano/commands/logs.rb +229 -76
  59. data/lib/MrMurano/commands/mock.rb +4 -4
  60. data/lib/MrMurano/commands/password.rb +4 -4
  61. data/lib/MrMurano/commands/postgresql.rb +4 -4
  62. data/lib/MrMurano/commands/settings.rb +4 -4
  63. data/lib/MrMurano/commands/show.rb +4 -4
  64. data/lib/MrMurano/commands/solution.rb +4 -4
  65. data/lib/MrMurano/commands/solution_picker.rb +4 -4
  66. data/lib/MrMurano/commands/status.rb +12 -4
  67. data/lib/MrMurano/commands/sync.rb +4 -4
  68. data/lib/MrMurano/commands/timeseries.rb +4 -4
  69. data/lib/MrMurano/commands/tsdb.rb +6 -7
  70. data/lib/MrMurano/commands/usage.rb +4 -4
  71. data/lib/MrMurano/commands.rb +4 -4
  72. data/lib/MrMurano/hash.rb +5 -5
  73. data/lib/MrMurano/http.rb +26 -22
  74. data/lib/MrMurano/makePretty.rb +194 -10
  75. data/lib/MrMurano/optparse.rb +1 -1
  76. data/lib/MrMurano/orderedhash.rb +1 -1
  77. data/lib/MrMurano/progress.rb +4 -4
  78. data/lib/MrMurano/verbosing.rb +6 -6
  79. data/lib/MrMurano/version.rb +5 -5
  80. data/lib/MrMurano.rb +7 -4
  81. data/spec/Account-Passwords_spec.rb +4 -4
  82. data/spec/Account_spec.rb +4 -4
  83. data/spec/Business_spec.rb +4 -4
  84. data/spec/ConfigFile_spec.rb +4 -4
  85. data/spec/ConfigMigrate_spec.rb +5 -4
  86. data/spec/Config_spec.rb +5 -4
  87. data/spec/Content_spec.rb +5 -4
  88. data/spec/GatewayBase_spec.rb +4 -4
  89. data/spec/GatewayDevice_spec.rb +4 -4
  90. data/spec/GatewayResource_spec.rb +5 -4
  91. data/spec/GatewaySettings_spec.rb +4 -4
  92. data/spec/Http_spec.rb +4 -4
  93. data/spec/MakePretties_spec.rb +20 -20
  94. data/spec/Mock_spec.rb +4 -4
  95. data/spec/ProjectFile_spec.rb +4 -4
  96. data/spec/Setting_spec.rb +4 -4
  97. data/spec/Solution-ServiceConfig_spec.rb +4 -4
  98. data/spec/Solution-ServiceEventHandler_spec.rb +5 -4
  99. data/spec/Solution-ServiceModules_spec.rb +5 -4
  100. data/spec/Solution-UsersRoles_spec.rb +5 -4
  101. data/spec/Solution_spec.rb +4 -4
  102. data/spec/SyncRoot_spec.rb +4 -4
  103. data/spec/SyncUpDown_spec.rb +67 -21
  104. data/spec/Verbosing_spec.rb +12 -10
  105. data/spec/Webservice-Cors_spec.rb +4 -4
  106. data/spec/Webservice-Endpoint_spec.rb +5 -4
  107. data/spec/Webservice-File_spec.rb +5 -4
  108. data/spec/Webservice-Setting_spec.rb +4 -4
  109. data/spec/_workspace.rb +4 -4
  110. data/spec/cmd_business_spec.rb +4 -5
  111. data/spec/cmd_common.rb +51 -20
  112. data/spec/cmd_config_spec.rb +4 -5
  113. data/spec/cmd_content_spec.rb +4 -5
  114. data/spec/cmd_cors_spec.rb +4 -5
  115. data/spec/cmd_device_spec.rb +5 -6
  116. data/spec/cmd_domain_spec.rb +4 -5
  117. data/spec/cmd_exchange_spec.rb +4 -5
  118. data/spec/cmd_help_spec.rb +4 -5
  119. data/spec/cmd_init_spec.rb +16 -35
  120. data/spec/cmd_keystore_spec.rb +4 -5
  121. data/spec/cmd_link_spec.rb +11 -12
  122. data/spec/cmd_logs_spec.rb +162 -0
  123. data/spec/cmd_password_spec.rb +4 -5
  124. data/spec/cmd_setting_application_spec.rb +4 -5
  125. data/spec/cmd_setting_product_spec.rb +4 -5
  126. data/spec/cmd_status_spec.rb +44 -81
  127. data/spec/cmd_syncdown_application_spec.rb +7 -10
  128. data/spec/cmd_syncdown_both_spec.rb +10 -25
  129. data/spec/cmd_syncup_spec.rb +31 -37
  130. data/spec/cmd_usage_spec.rb +4 -5
  131. data/spec/fixtures/dumped_config +1 -0
  132. data/spec/fixtures/websocket/logs_blather.rb +27 -0
  133. data/spec/fixtures/websocket/logs_faker.rb +153 -0
  134. data/spec/fixtures/websocket/simple_connection.rb +45 -0
  135. data/spec/fixtures/websocket/simple_options.rb +77 -0
  136. data/spec/fixtures/websocket/simple_server.rb +69 -0
  137. data/spec/fixtures/websocket/wss-echo.rb +48 -0
  138. data/spec/fixtures/websocket/wss-fake-logs.rb +20 -0
  139. metadata +55 -2
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'cmd_common'
12
11
 
13
12
  RSpec.describe 'murano config', :cmd do
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'yaml'
12
11
  require 'cmd_common'
13
12
 
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'json'
12
11
  require 'cmd_common'
13
12
 
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'cmd_common'
12
11
 
13
12
  RSpec.describe 'murano device', :cmd, :needs_password do
@@ -93,7 +92,7 @@ RSpec.describe 'murano device', :cmd, :needs_password do
93
92
  )
94
93
 
95
94
  out, err, status = Open3.capture3(capcmd('murano', 'syncup', '--resources'))
96
- expect(out).to eq("Adding item state\nAdding item temperature\nAdding item uptime\nAdding item humidity\nUpdating product resources\n")
95
+ expect(out).to eq("Adding item state\nAdding item temperature\nAdding item uptime\nAdding item humidity\nUpdating remote product resources\n")
97
96
  expect(err).to eq('')
98
97
  expect(status.exitstatus).to eq(0)
99
98
 
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'cmd_common'
12
11
 
13
12
  RSpec.describe 'murano domain', :cmd, :needs_password do
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
 
12
11
  require 'cmd_common'
13
12
  require 'MrMurano/Config'
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.08.31 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
 
12
11
  require 'highline/import'
13
12
 
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'cmd_common'
12
11
 
13
12
  RSpec.describe 'murano init', :cmd do
@@ -52,7 +51,6 @@ RSpec.describe 'murano init', :cmd do
52
51
  "\n", # 10
53
52
  ]
54
53
  elsif has_no_solutions
55
- # 2017-07-05: line numbers are for: context "without", :needs_password do / it "existing project" do
56
54
  expecting += [
57
55
  "This business does not have any applications. Let's create one\n", # 7
58
56
  "\n", # 8
@@ -109,20 +107,15 @@ RSpec.describe 'murano init', :cmd do
109
107
  "\n",
110
108
  ]
111
109
  end
112
- #expecting += [
113
- # t.a_string_matching(%r{Adding item \w+_event\n}),
114
- # # Order not consistent...
115
- # #"Adding item tsdb_exportJob\n",
116
- # #"Adding item timer_timer\n",
117
- # #"Adding item user_account\n",
118
- # t.a_string_starting_with('Adding item '),
119
- # t.a_string_starting_with('Adding item '),
120
- # t.a_string_starting_with('Adding item '),
121
- # "Synced 4 items\n",
122
- # "\n",
123
- #]
124
110
  expecting += [
125
- "Items already synced\n",
111
+ # 2017-12-15: Currently:
112
+ # services{product.id}_event.lua
113
+ # services/user_account.lua
114
+ # specs/resources.yaml
115
+ "Updating local product resources\n",
116
+ t.a_string_starting_with('Adding item '),
117
+ t.a_string_starting_with('Adding item '),
118
+ "Synced 3 items\n",
126
119
  "\n",
127
120
  ]
128
121
  expecting += [
@@ -227,10 +220,10 @@ RSpec.describe 'murano init', :cmd do
227
220
  # It will ask to create an application and product.
228
221
  # MAGIC_NUMBER: !!!! the 8 is hardcoded indention here !!!!
229
222
  # (removes the leading whitespace from the <<-EOT heredoc)
230
- data = <<-EOT.gsub(/^ {8}/, '')
223
+ data = <<-DATA.gsub(/^ {8}/, '')
231
224
  #{@applctn_name}
232
225
  #{@product_name}
233
- EOT
226
+ DATA
234
227
  # 2017-07-05: [lb] added line numbers to use debugger to help maintain this test.
235
228
  out, err, status = Open3.capture3(capcmd('murano', 'init'), stdin_data: data)
236
229
  expecting = expected_response_when_ids_found_in_config(
@@ -332,9 +325,6 @@ RSpec.describe 'murano init', :cmd do
332
325
  self,
333
326
  expect_rebasing: true,
334
327
  creates_some_default_directories: true,
335
- # Because the /tmp/murcli-test/services directory is empty,
336
- # murano init *will* download all the event handlers.
337
- #local_files_found: true,
338
328
  )
339
329
  out_lines = out.lines.map { |line| strip_fancy(line) }
340
330
  expect(out_lines).to match_array(the_expected)
@@ -360,9 +350,6 @@ RSpec.describe 'murano init', :cmd do
360
350
  expect_rebasing: true,
361
351
  expect_proj_file_write: false,
362
352
  creates_some_default_directories: true,
363
- # Because the /tmp/murcli-test/services directory is empty,
364
- # murano init *will* download all the event handlers.
365
- #local_files_found: true,
366
353
  )
367
354
  out_lines = out.lines.map { |line| strip_fancy(line) }
368
355
  expect(out_lines).to match_array(expected)
@@ -396,15 +383,13 @@ RSpec.describe 'murano init', :cmd do
396
383
  end
397
384
  # The test account will have one business, one product, and one application.
398
385
  # So it won't ask any questions.
386
+ # NOTE: This tests uses an old Solutionfile.json, config v0.2.0, and it
387
+ # downloads Lua scripts to the root of the project directory. Just FYI.
399
388
  out, err, status = Open3.capture3(capcmd('murano', 'init'))
400
389
  expected = expected_response_when_ids_found_in_config(
401
390
  self,
402
391
  expect_rebasing: true,
403
392
  creates_some_default_directories: true,
404
- # Because the /tmp/murcli-test/services directory is empty,
405
- # murano init *will* download all the event handlers.
406
- ##local_files_found_application: true,
407
- #local_files_found_product: true,
408
393
  )
409
394
  out_lines = out.lines.map { |line| strip_fancy(line) }
410
395
  expect(out_lines).to match_array(expected)
@@ -444,10 +429,6 @@ RSpec.describe 'murano init', :cmd do
444
429
  self,
445
430
  expect_rebasing: true,
446
431
  creates_some_default_directories: true,
447
- # Because the /tmp/murcli-test/services directory is empty,
448
- # murano init *will* download all the event handlers.
449
- ##local_files_found_application: true,
450
- #local_files_found_product: true,
451
432
  )
452
433
  out_lines = out.lines.map { |line| strip_fancy(line) }
453
434
  expect(out_lines).to match_array(expected)
@@ -1,13 +1,12 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
  require 'json'
12
11
  require 'cmd_common'
13
12
 
@@ -1,16 +1,16 @@
1
- # Last Modified: 2017.09.12 /coding: utf-8
1
+ # Copyright © 2016-2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
2
3
  # frozen_string_literal: true
3
4
 
4
- # Copyright © 2016-2017 Exosite LLC.
5
- # License: MIT. See LICENSE.txt.
6
- # vim:tw=0:ts=2:sw=2:et:ai
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
8
  require 'fileutils'
9
9
  require 'open3'
10
- require 'pathname'
11
10
 
12
11
  require 'cmd_common'
13
12
  require 'MrMurano/Config'
13
+ require 'MrMurano/commands/link'
14
14
 
15
15
  RSpec.describe 'murano link', :cmd, :needs_password do
16
16
  include_context 'CI_CMD'
@@ -36,11 +36,10 @@ RSpec.describe 'murano link', :cmd, :needs_password do
36
36
 
37
37
  context 'using commander' do
38
38
  it 'will not list' do
39
- stdout, stderr = murano_command_run('link list')
40
- expect(stdout).to eq(MrMurano::Config::INVALID_PROJECT_HINT + "\n")
41
- expect(stderr).to eq(
42
- %(The "link list" command only works in a Murano project.\n)
43
- )
39
+ # Because we run from the context of the rspec command, the :env
40
+ # config file will have loaded, so business.id will be set.
41
+ expect { murano_command_run('link list') }.to raise_error(SystemExit)
42
+ $exited_abnormally = false
44
43
  end
45
44
  end
46
45
  end
@@ -52,7 +51,6 @@ RSpec.describe 'murano link', :cmd, :needs_password do
52
51
 
53
52
  it 'links and lists' do
54
53
  out, err, status = Open3.capture3(capcmd('murano', 'assign', 'set'))
55
- #expect(out).to a_string_starting_with("Linked product #{@solz_name}")
56
54
  olines = out.lines
57
55
 
58
56
  expect(strip_fancy(olines[0])).to eq(
@@ -88,7 +86,8 @@ RSpec.describe 'murano link', :cmd, :needs_password do
88
86
  #expect(out).to a_string_starting_with("Unlinked #{@solz_name}")
89
87
  # E.g.,
90
88
  # Unlinked ‘linktest3e7def1b86a1d680’ from ‘linktest3e7def1b86a1d680’\n
91
- # Removed ‘h2thqll2z9sqoooc0_w4w3vxla11ngg4cok_event’ from ‘linktest3e7def1b86a1d680\n
89
+ # Removed ‘h2thqll2z9sqoooc0_w4w3vxla11ngg4cok_event’
90
+ # from ‘linktest3e7def1b86a1d680\n
92
91
  olines = out.lines
93
92
  expect(strip_fancy(olines[0])).to eq(
94
93
  "Unlinked '#{@proj_name_prod}' from '#{@proj_name_appy}'\n"
@@ -0,0 +1,162 @@
1
+ # Copyright © 2017 Exosite LLC. All Rights Reserved
2
+ # License: PROPRIETARY. See LICENSE.txt.
3
+ # frozen_string_literal: true
4
+
5
+ # vim:tw=0:ts=2:sw=2:et:ai
6
+ # Unauthorized copying of this file is strictly prohibited.
7
+
8
+ require 'json'
9
+ require 'open3'
10
+ require 'socket'
11
+ require 'timeout'
12
+ require 'uri'
13
+
14
+ require 'MrMurano/Config'
15
+ require 'cmd_common'
16
+ require 'fixtures/websocket/simple_server'
17
+ require 'fixtures/websocket/logs_faker'
18
+
19
+ RSpec.describe 'murano logs', :cmd, :needs_password do
20
+ include_context 'CI_CMD'
21
+
22
+ before(:example) do
23
+ @port = SimpleWebSocket::Server::DEFAULT_WS_PORT
24
+ @port_s = @port && ":#{@port}" || ''
25
+
26
+ # CI_CMD's before() creates a new Config and calls load().
27
+ # We just need to add a few things.
28
+ $cfg.set('net.host', "127.0.0.1#{@port_s}", :project)
29
+ $cfg.set('net.protocol', 'http', :project)
30
+ $cfg.set('application.id', 'XYZ', :project)
31
+
32
+ @acc = MrMurano::Account.instance
33
+ allow(@acc).to receive(:login_info).and_return(email: 'bob', password: 'v')
34
+ end
35
+
36
+ # FIXME: (landonb): MUR-3081: Remove old http code for v3.1.0. Search: LOGS_USE_HTTP.
37
+ def supports_ws?
38
+ runner = ::Commander::Runner.instance
39
+ logs_cmd = runner.command(:logs)
40
+ logs_cmd.options.any? do |opt|
41
+ opt[:args].include? '--http'
42
+ end
43
+ end
44
+
45
+ def test_tail_log
46
+ stub_request_token
47
+ spawn_websocket_server
48
+ spawn_logs_stream_test_simple
49
+ run_logs_tail
50
+ wait_websocket_server
51
+ expect_output
52
+ end
53
+
54
+ def stub_request_token
55
+ stub_request(:post, "http://127.0.0.1#{@port_s}/api:1/token/")
56
+ .with(
57
+ body: '{"email":"bob","password":"v"}',
58
+ headers: {
59
+ 'Accept' => '*/*',
60
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
61
+ 'Content-Type' => 'application/json',
62
+ # 'Host'=>'ABC',
63
+ 'Host' => "127.0.0.1#{@port_s}",
64
+ 'User-Agent' => 'MrMurano/3.0.7',
65
+ }
66
+ )
67
+ .to_return(
68
+ status: 200, body: { token: 'ABCDEFGHIJKLMNOP' }.to_json, headers: {}
69
+ )
70
+ end
71
+
72
+ def spawn_websocket_server
73
+ ws_svr = "#{File.dirname(__FILE__)}/fixtures/websocket/wss-echo.rb"
74
+ @wss_in, @wss_out, @wss_err, @wss_thr = Open3.popen3(ws_svr.to_s)
75
+ @wss_out.close
76
+ @wss_err.close
77
+ await_websocket_server!
78
+ end
79
+
80
+ def await_websocket_server!
81
+ # Wait for the server to start, or the logs command will fail to connect.
82
+ ready = false
83
+ 5.times do
84
+ begin
85
+ s = TCPSocket.new('127.0.0.1', @port)
86
+ s.close
87
+ ready = true
88
+ break
89
+ # rubocop:disable Lint/HandleExceptions: Do not suppress exceptions.
90
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
91
+ # pass
92
+ end
93
+ sleep 0.2
94
+ end
95
+ raise 'Server never started!' unless ready
96
+ end
97
+
98
+ def spawn_logs_stream_test_simple
99
+ Thread.abort_on_exception = true
100
+ @svr_thd = Thread.new { logs_stream_test_simple }
101
+ end
102
+
103
+ def logs_stream_test_simple
104
+ sleep 0.1 until EM.reactor_running?
105
+ @blatherer = LogsFaker.new
106
+ sleep 0.1
107
+ @wss_in.puts JSON.generate(@blatherer.example_type_script)
108
+ sleep 0.1
109
+ @wss_in.puts JSON.generate(@blatherer.example_type_call)
110
+ sleep 0.1
111
+ @wss_in.puts JSON.generate(@blatherer.example_type_event)
112
+ sleep 0.1
113
+ @wss_in.puts JSON.generate(@blatherer.example_type_config_device_v1)
114
+ sleep 0.1
115
+ @wss_in.puts JSON.generate(@blatherer.example_type_config_null)
116
+ sleep 0.1
117
+ @wss_in.puts JSON.generate(@blatherer.example_type_config_newservice)
118
+ sleep 0.1
119
+ @wss_in.puts 'EXIT'
120
+ @wss_in.close
121
+ end
122
+
123
+ def run_logs_tail
124
+ # For coverage, we have to call the command directly.
125
+ #
126
+ # DEVs: Run this is you want stdout to flow to the terminal
127
+ # (to make developing easier):
128
+ #
129
+ # runner = ::Commander::Runner.instance
130
+ # logs_cmd = runner.command(:logs)
131
+ # mrcmd = logs_cmd.run('-f')
132
+ #
133
+ # Normally, we instead capture stdout so we can expect() it.
134
+ @cmd_out, @cmd_err = murano_command_run('logs', '-f')
135
+ end
136
+
137
+ def wait_websocket_server
138
+ # Block 'til subprocess exits. Receives a Process::Status.
139
+ _proc_status = @wss_thr.value
140
+ end
141
+
142
+ def expect_output
143
+ expect(@cmd_err).to eq(%(WebSocket closed [1006]\n))
144
+ expect(@cmd_out).to eq(
145
+ %(
146
+ message: #{JSON.generate(@blatherer.example_type_script)}
147
+ message: #{JSON.generate(@blatherer.example_type_call)}
148
+ message: #{JSON.generate(@blatherer.example_type_event)}
149
+ message: #{JSON.generate(@blatherer.example_type_config_device_v1)}
150
+ message: #{JSON.generate(@blatherer.example_type_config_null)}
151
+ message: #{JSON.generate(@blatherer.example_type_config_newservice)}
152
+ ).strip + "\n"
153
+ )
154
+ end
155
+
156
+ context 'when project is setup' do
157
+ it 'tail log' do
158
+ test_tail_log if supports_ws?
159
+ end
160
+ end
161
+ end
162
+