pantry 0.0.0 → 0.1.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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +19 -0
  5. data/Gemfile +15 -0
  6. data/Guardfile +16 -0
  7. data/LICENSE +20 -0
  8. data/README.md +53 -0
  9. data/Rakefile +18 -0
  10. data/Vagrantfile +86 -0
  11. data/bin/pantry +11 -0
  12. data/bin/pantry-client +38 -0
  13. data/bin/pantry-server +33 -0
  14. data/dist/client.yml +79 -0
  15. data/dist/server.yml +56 -0
  16. data/dist/upstart/pantry-client.conf +12 -0
  17. data/dist/upstart/pantry-server.conf +12 -0
  18. data/doc/message_packet.dot +19 -0
  19. data/doc/message_packet.dot.png +0 -0
  20. data/doc/network_topology.dot +42 -0
  21. data/doc/network_topology.dot.png +0 -0
  22. data/lib/celluloid_zmq_patches.rb +16 -0
  23. data/lib/opt_parse_plus.rb +184 -0
  24. data/lib/pantry.rb +197 -0
  25. data/lib/pantry/cli.rb +154 -0
  26. data/lib/pantry/client.rb +131 -0
  27. data/lib/pantry/client_info.rb +34 -0
  28. data/lib/pantry/client_registry.rb +104 -0
  29. data/lib/pantry/command.rb +194 -0
  30. data/lib/pantry/command_handler.rb +53 -0
  31. data/lib/pantry/command_line.rb +115 -0
  32. data/lib/pantry/commands/create_client.rb +30 -0
  33. data/lib/pantry/commands/download_directory.rb +35 -0
  34. data/lib/pantry/commands/echo.rb +32 -0
  35. data/lib/pantry/commands/edit_application.rb +60 -0
  36. data/lib/pantry/commands/register_client.rb +38 -0
  37. data/lib/pantry/commands/status.rb +78 -0
  38. data/lib/pantry/commands/sync_directory.rb +50 -0
  39. data/lib/pantry/commands/update_application.rb +45 -0
  40. data/lib/pantry/commands/upload_file.rb +68 -0
  41. data/lib/pantry/communication.rb +20 -0
  42. data/lib/pantry/communication/client.rb +75 -0
  43. data/lib/pantry/communication/client_filter.rb +117 -0
  44. data/lib/pantry/communication/file_service.rb +125 -0
  45. data/lib/pantry/communication/file_service/file_progress.rb +164 -0
  46. data/lib/pantry/communication/file_service/receive_file.rb +97 -0
  47. data/lib/pantry/communication/file_service/send_file.rb +74 -0
  48. data/lib/pantry/communication/publish_socket.rb +20 -0
  49. data/lib/pantry/communication/reading_socket.rb +89 -0
  50. data/lib/pantry/communication/receive_socket.rb +23 -0
  51. data/lib/pantry/communication/security.rb +44 -0
  52. data/lib/pantry/communication/security/authentication.rb +98 -0
  53. data/lib/pantry/communication/security/curve_key_store.rb +120 -0
  54. data/lib/pantry/communication/security/curve_security.rb +70 -0
  55. data/lib/pantry/communication/security/null_security.rb +32 -0
  56. data/lib/pantry/communication/send_socket.rb +19 -0
  57. data/lib/pantry/communication/serialize_message.rb +84 -0
  58. data/lib/pantry/communication/server.rb +97 -0
  59. data/lib/pantry/communication/subscribe_socket.rb +33 -0
  60. data/lib/pantry/communication/wait_list.rb +45 -0
  61. data/lib/pantry/communication/writing_socket.rb +46 -0
  62. data/lib/pantry/config.rb +182 -0
  63. data/lib/pantry/file_editor.rb +67 -0
  64. data/lib/pantry/logger.rb +78 -0
  65. data/lib/pantry/message.rb +134 -0
  66. data/lib/pantry/multi_command.rb +36 -0
  67. data/lib/pantry/server.rb +132 -0
  68. data/lib/pantry/test/acceptance.rb +83 -0
  69. data/lib/pantry/test/support/fake_fs.rb +31 -0
  70. data/lib/pantry/test/support/matchers.rb +13 -0
  71. data/lib/pantry/test/support/minitest.rb +13 -0
  72. data/lib/pantry/test/support/mock_ui.rb +23 -0
  73. data/lib/pantry/test/unit.rb +13 -0
  74. data/lib/pantry/ui.rb +68 -0
  75. data/lib/pantry/version.rb +3 -0
  76. data/pantry.gemspec +40 -0
  77. data/test/acceptance/cli/error_handling_test.rb +7 -0
  78. data/test/acceptance/cli/execute_command_on_clients_test.rb +32 -0
  79. data/test/acceptance/cli/request_info_from_server_test.rb +44 -0
  80. data/test/acceptance/communication/client_requests_info_from_server_test.rb +28 -0
  81. data/test/acceptance/communication/heartbeat_test.rb +19 -0
  82. data/test/acceptance/communication/pub_sub_communication_test.rb +53 -0
  83. data/test/acceptance/communication/security_test.rb +117 -0
  84. data/test/acceptance/communication/server_requests_info_from_client_test.rb +41 -0
  85. data/test/acceptance/test_helper.rb +25 -0
  86. data/test/fixtures/config.yml +22 -0
  87. data/test/fixtures/empty.yml +2 -0
  88. data/test/fixtures/file_to_upload +3 -0
  89. data/test/root_dir/.gitkeep +0 -0
  90. data/test/unit/cli_test.rb +173 -0
  91. data/test/unit/client_registry_test.rb +61 -0
  92. data/test/unit/client_test.rb +128 -0
  93. data/test/unit/command_handler_test.rb +79 -0
  94. data/test/unit/command_line_test.rb +5 -0
  95. data/test/unit/command_test.rb +206 -0
  96. data/test/unit/commands/create_client_test.rb +25 -0
  97. data/test/unit/commands/download_directory_test.rb +58 -0
  98. data/test/unit/commands/echo_test.rb +22 -0
  99. data/test/unit/commands/edit_application_test.rb +84 -0
  100. data/test/unit/commands/register_client_test.rb +41 -0
  101. data/test/unit/commands/status_test.rb +81 -0
  102. data/test/unit/commands/sync_directory_test.rb +75 -0
  103. data/test/unit/commands/update_application_test.rb +35 -0
  104. data/test/unit/commands/upload_file_test.rb +51 -0
  105. data/test/unit/communication/client_filter_test.rb +262 -0
  106. data/test/unit/communication/client_test.rb +99 -0
  107. data/test/unit/communication/file_service/receive_file_test.rb +214 -0
  108. data/test/unit/communication/file_service/send_file_test.rb +110 -0
  109. data/test/unit/communication/file_service_test.rb +56 -0
  110. data/test/unit/communication/publish_socket_test.rb +19 -0
  111. data/test/unit/communication/reading_socket_test.rb +110 -0
  112. data/test/unit/communication/receive_socket_test.rb +20 -0
  113. data/test/unit/communication/security/authentication_test.rb +97 -0
  114. data/test/unit/communication/security/curve_key_store_test.rb +110 -0
  115. data/test/unit/communication/security/curve_security_test.rb +44 -0
  116. data/test/unit/communication/security/null_security_test.rb +15 -0
  117. data/test/unit/communication/security_test.rb +49 -0
  118. data/test/unit/communication/send_socket_test.rb +19 -0
  119. data/test/unit/communication/serialize_message_test.rb +128 -0
  120. data/test/unit/communication/server_test.rb +106 -0
  121. data/test/unit/communication/subscribe_socket_test.rb +46 -0
  122. data/test/unit/communication/wait_list_test.rb +60 -0
  123. data/test/unit/communication/writing_socket_test.rb +46 -0
  124. data/test/unit/config_test.rb +150 -0
  125. data/test/unit/logger_test.rb +79 -0
  126. data/test/unit/message_test.rb +179 -0
  127. data/test/unit/multi_command_test.rb +45 -0
  128. data/test/unit/opt_parse_plus_test.rb +218 -0
  129. data/test/unit/pantry_test.rb +82 -0
  130. data/test/unit/server_test.rb +166 -0
  131. data/test/unit/test_helper.rb +25 -0
  132. data/test/unit/ui_test.rb +58 -0
  133. metadata +389 -13
@@ -0,0 +1,31 @@
1
+ gem 'fakefs'
2
+ require 'fakefs/safe'
3
+
4
+ # Hook up FakeFS into Minitest
5
+ class MiniTest::Test
6
+ def self.fake_fs!
7
+ before do
8
+ FakeFS.activate!
9
+ end
10
+
11
+ after do
12
+ FakeFS.deactivate!
13
+ FakeFS::FileSystem.clear
14
+ end
15
+ end
16
+ end
17
+
18
+ # Minitest uses Tempfiles for figuring out more complicated diffs
19
+ # This causes FakeFS to explode, so make sure this is run without FakeFS
20
+ # enabled.
21
+ module Minitest
22
+ module Assertions
23
+ alias :actual_diff :diff
24
+
25
+ def diff exp, act
26
+ FakeFS.without do
27
+ actual_diff exp, act
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # Some custom MiniTest matchers used throughout the system
2
+
3
+ module Minitest::Assertions
4
+
5
+ # I don't like the refute_ syntax, sorry =/
6
+
7
+ alias assert_not_nil refute_nil
8
+ alias assert_not refute
9
+ alias assert_false refute
10
+ alias assert_not_equal refute_equal
11
+ alias assert_no_match refute_match
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'minitest/autorun'
2
+
3
+ # Global helpers we're adding to Minitest
4
+ module PantryMinitestHelpers
5
+ def before_setup
6
+ Celluloid.init
7
+ Pantry.reset_config!
8
+ end
9
+ end
10
+
11
+ class Minitest::Test
12
+ include PantryMinitestHelpers
13
+ end
@@ -0,0 +1,23 @@
1
+ # For actions that print out or use the console via
2
+ # Pantry.ui, these helpers mock out stdout/stderr to make it easy
3
+ # to grab what's printed and to inject keypresses
4
+ class MiniTest::Test
5
+ def self.mock_ui!
6
+ before do
7
+ @mock_stdin = StringIO.new
8
+ @mock_stdout = StringIO.new
9
+ Pantry.reset_ui!
10
+ Pantry.ui(@mock_stdin, @mock_stdout)
11
+ end
12
+ end
13
+
14
+ # Return the strings added to stdout through the test
15
+ def stdout
16
+ @mock_stdout.string
17
+ end
18
+
19
+ # Get access to the mock of STDIN to add values
20
+ def stdin
21
+ @mock_stdin
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ #
2
+ # Require this file to grab the Pantry unit test environment.
3
+ # This environment includes setup helpers to ensure Celluloid is running,
4
+ # as well as a few mocks (ui and fakefs) as well as helpers to facilitate
5
+ # testing Pantry plugins.
6
+ #
7
+
8
+ require 'pantry'
9
+ require 'celluloid/test'
10
+ require 'pantry/test/support/minitest'
11
+ require 'pantry/test/support/matchers'
12
+ require 'pantry/test/support/mock_ui'
13
+ require 'pantry/test/support/fake_fs'
@@ -0,0 +1,68 @@
1
+ module Pantry
2
+
3
+ # Global access to Pantry's UI handler. This object offers up
4
+ # a set of methods used to interact with the User via the CLI.
5
+ def self.ui(input = $stdin, output = $stdout)
6
+ @@ui ||= Pantry::UI.new(input, output)
7
+ end
8
+
9
+ def self.reset_ui!
10
+ @@ui = nil
11
+ end
12
+
13
+ class UI
14
+
15
+ def initialize(input = $stdin, output = $stdout)
16
+ require 'highline'
17
+ @output = output
18
+ @input = input
19
+ @highline = HighLine.new(input, output)
20
+ end
21
+
22
+ # Send a message to STDOUT
23
+ def say(message)
24
+ @highline.say(message)
25
+ end
26
+
27
+ # Print out a list, attempting to make it look somewhat reasonable
28
+ def list(array)
29
+ say(array.join("\n") + "\n")
30
+ end
31
+
32
+ def color(string, color)
33
+ HighLine.color(string, color)
34
+ end
35
+
36
+ # Show the user a message and ask them to continue by hitting Enter,
37
+ # or they can cancel with "No"
38
+ def continue?(message)
39
+ @highline.agree(message) do |q|
40
+ q.default = "yes"
41
+ end
42
+ end
43
+
44
+ # Start a new progress meter with the given number of ticks
45
+ def progress_start(tick_count)
46
+ require 'ruby-progressbar'
47
+ @progress = ProgressBar.create(
48
+ total: tick_count, output: @output,
49
+ format: "Progress: %P%% |%B| %c/%C %e"
50
+ )
51
+ end
52
+
53
+ # Increment the running progress meter the given number of ticks
54
+ def progress_step(tick_count)
55
+ if @progress.progress + tick_count > @progress.total
56
+ tick_count = @progress.total - @progress.progress
57
+ end
58
+
59
+ @progress.progress += tick_count
60
+ end
61
+
62
+ # Complete and close down the current progress meter
63
+ def progress_finish
64
+ @progress.finish
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ module Pantry
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,40 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "pantry/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "pantry"
6
+ s.version = Pantry::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Collective Idea", "Jason Roelofs"]
9
+ s.email = ["code@collectiveidea.com", "jasongroelofs@gmail.com"]
10
+ s.license = "MIT"
11
+ s.homepage = "http://pantryops.org"
12
+
13
+ s.summary = "Modern DevOps Automation"
14
+ s.description = <<-EOS
15
+ Pantry is a framework that provides answers to common questions encoutered when setting up a DevOps, server configuration, or server provisioning pipeline.
16
+ EOS
17
+
18
+ s.required_ruby_version = ">= 2.0.0"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- test/*`.split("\n")
22
+ s.require_path = "lib"
23
+ s.bindir = "bin"
24
+
25
+ s.executables = %w(pantry-client pantry-server pantry)
26
+
27
+ s.requirements << "zeromq 3.x or 4.x"
28
+ s.requirements << "libsodium for Curve security"
29
+
30
+ s.add_runtime_dependency "ffi-rzmq", "~> 2.0", ">= 2.0.0"
31
+ s.add_runtime_dependency "celluloid", "~> 0.15", ">= 0.15.0"
32
+ s.add_runtime_dependency "celluloid-zmq", "~> 0.15", ">= 0.15.0"
33
+ s.add_runtime_dependency "highline", "~> 1.6", ">= 1.6.21"
34
+ s.add_runtime_dependency "json", "~> 1.8", ">= 1.8.1"
35
+ s.add_runtime_dependency "ruby-progressbar", "~> 1.4", ">= 1.4.2"
36
+ s.add_runtime_dependency "safe_yaml", "~> 1.0", ">= 1.0.1"
37
+
38
+ s.add_development_dependency "mocha", "~> 1.0", ">= 1.0.0"
39
+ s.add_development_dependency "fakefs", "~> 0.5", ">= 0.5.1"
40
+ end
@@ -0,0 +1,7 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "CLI error handling" do
4
+
5
+ it "errors when the server is unavailable"
6
+
7
+ end
@@ -0,0 +1,32 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "CLI requests information from individual clients" do
4
+
5
+ mock_ui!
6
+
7
+ it "receives responses from each client asked" do
8
+ set_up_environment(ports_start_at: 10100)
9
+
10
+ Pantry::CLI.new(
11
+ ["-a", "pantry", "echo", "This is Neat"],
12
+ identity: "cli1"
13
+ ).run
14
+
15
+ assert_match %r|Expecting response from 2 clients|, stdout
16
+ assert_match %r|#{@client1.identity} echo's "This is Neat"|, stdout
17
+ assert_match %r|#{@client2.identity} echo's "This is Neat"|, stdout
18
+ end
19
+
20
+ it "can target specific clients for the commands sent" do
21
+ set_up_environment(ports_start_at: 10110)
22
+
23
+ Pantry::CLI.new(
24
+ ["-a", "pantry", "-e", "test", "-r", "app1", "echo", "This is Neat"],
25
+ identity: "cli1"
26
+ ).run
27
+
28
+ assert_match %r|Expecting response from 1 client|, stdout
29
+ assert_match %r|#{@client1.identity} echo's \"This is Neat\"|, stdout
30
+ end
31
+
32
+ end
@@ -0,0 +1,44 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "CLI can ask Server for information" do
4
+
5
+ mock_ui!
6
+
7
+ it "can ask for all known nodes" do
8
+ set_up_environment(ports_start_at: 10200)
9
+
10
+ Pantry::CLI.new(
11
+ ["status"],
12
+ identity: "test_client"
13
+ ).run
14
+
15
+ assert_match /#{@client1.identity}/, stdout, "Did not contain line for client1"
16
+ assert_match /#{@client2.identity}/, stdout, "Did not contain line for client2"
17
+ end
18
+
19
+ it "can limit the query to a subset of clients" do
20
+ set_up_environment(ports_start_at: 10210)
21
+
22
+ cli = Pantry::CLI.new(
23
+ ["-a", "chatbot", "status"],
24
+ identity: "test_client"
25
+ )
26
+
27
+ client3 = Pantry::Client.new(application: "chatbot", identity: "client3")
28
+ client3.run
29
+
30
+ client4 = Pantry::Client.new(application: "chatbot", identity: "client4")
31
+ client4.run
32
+
33
+ cli.run
34
+
35
+ assert_equal 2, stdout.split("\n").length
36
+
37
+ assert_match /client3/, stdout, "Did not contain line for client3"
38
+ assert_match /client4/, stdout, "Did not contain line for client4"
39
+
40
+ client3.shutdown
41
+ client4.shutdown
42
+ end
43
+
44
+ end
@@ -0,0 +1,28 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "Client requests information from the Server" do
4
+
5
+ it "asks the server for information and waits for a response" do
6
+ set_up_environment(ports_start_at: 10300)
7
+
8
+ message = ServerEchoCommand.new("Hello Server").to_message
9
+ response_future = @client1.send_request(message)
10
+
11
+ assert_equal ["Hello Server"], response_future.value(2).body
12
+ end
13
+
14
+ it "handles multiple requests in the proper order" do
15
+ set_up_environment(ports_start_at: 10310)
16
+
17
+ futures = []
18
+ 10.times do |i|
19
+ message = ServerEchoCommand.new("Hello Server #{i}").to_message
20
+ futures << @client1.send_request(message)
21
+ end
22
+
23
+ futures.each_with_index do |future, idx|
24
+ assert_equal ["Hello Server #{idx}"], future.value(1).body
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,19 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "Client / Server heartbeats" do
4
+
5
+ describe "Client" do
6
+ it "re-registers with the server every interval seconds" do
7
+ set_up_environment(ports_start_at: 10500, heartbeat: 1)
8
+
9
+ # Clean out the server registry then wait for clients to re-register themselves
10
+ @server.client_registry.clear!
11
+
12
+ sleep 2
13
+
14
+ assert @server.client_registry.include?(@client1), "Client1 did not check in again"
15
+ assert @server.client_registry.include?(@client2), "Client2 did not check in again"
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,53 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "Pub/Sub Communication" do
4
+
5
+ describe "Server" do
6
+ it "can publish a message to all connected clients" do
7
+ set_up_environment(ports_start_at: 10400)
8
+
9
+ @server.publish_message(
10
+ Pantry::Message.new("test_message"),
11
+ Pantry::Communication::ClientFilter.new(application: "pantry")
12
+ )
13
+
14
+ # Give communication time to happen
15
+ sleep 1
16
+
17
+ assert_equal "test_message", @client1.last_received_message.type
18
+ assert_equal "test_message", @client2.last_received_message.type
19
+ end
20
+
21
+ it "can publish a message to a subset of all connected clients" do
22
+ set_up_environment(ports_start_at: 10410)
23
+
24
+ client3 = Pantry::Client.new(roles: %w(database), identity: "client3")
25
+ client3.run
26
+
27
+ client4 = Pantry::Client.new(roles: %w(database task), identity: "client4")
28
+ client4.run
29
+
30
+ sleep 1
31
+
32
+ @server.publish_message(Pantry::Message.new("to_databases"),
33
+ Pantry::Communication::ClientFilter.new(roles: %w(database)))
34
+
35
+ # Give communication time to happen
36
+ sleep 1
37
+
38
+ assert_equal "to_databases", client3.last_received_message.type
39
+ assert_equal "to_databases", client4.last_received_message.type
40
+
41
+ @server.publish_message(Pantry::Message.new("to_tasks"),
42
+ Pantry::Communication::ClientFilter.new(roles: %w(task)))
43
+
44
+ # Give communication time to happen
45
+ sleep 1
46
+
47
+ assert_equal "to_tasks", client4.last_received_message.type
48
+
49
+ client3.shutdown
50
+ client4.shutdown
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,117 @@
1
+ require 'acceptance/test_helper'
2
+
3
+ describe "ZMQ4 CURVE security" do
4
+
5
+ break unless Pantry::Communication::Security.curve_supported?
6
+
7
+ def set_up_encrypted(ports_start_at, options = {})
8
+ Celluloid.boot
9
+ configure_pantry(ports_start_at: ports_start_at, security: "curve")
10
+
11
+ server_public, server_private = ZMQ::Util.curve_keypair
12
+ client_public, client_private = ZMQ::Util.curve_keypair
13
+
14
+ known_clients = options[:known_clients] || [client_public]
15
+
16
+ key_dir = Pantry.root.join("security", "curve")
17
+ FileUtils.mkdir_p(key_dir)
18
+
19
+ File.open(key_dir.join("server_keys.yml"), "w+") do |f|
20
+ f.write(YAML.dump({
21
+ "private_key" => server_private,
22
+ "public_key" => options[:server_public_key] || server_public,
23
+ "client_keys" => known_clients
24
+ }))
25
+ end
26
+
27
+ File.open(key_dir.join("client_keys.yml"), "w+") do |f|
28
+ f.write(YAML.dump({
29
+ "private_key" => client_private, "public_key" => client_public,
30
+ "server_public_key" => options[:server_public_key] || server_public
31
+ }))
32
+ end
33
+ end
34
+
35
+ describe "connectivity" do
36
+ def assert_message_timeout(client)
37
+ message = ServerEchoCommand.new("Hello Server").to_message
38
+ response_future = client.send_request(message)
39
+
40
+ assert_raises(Celluloid::TimeoutError) do
41
+ response_future.value(1).body
42
+ end
43
+ end
44
+
45
+ def assert_successful_message(client)
46
+ message = ServerEchoCommand.new("Hello Server").to_message
47
+ response_future = client.send_request(message)
48
+
49
+ assert_equal ["Hello Server"], response_future.value(2).body
50
+ end
51
+
52
+ it "configures CURVE security for encrypted server/client communication" do
53
+ set_up_encrypted(15000)
54
+
55
+ server = Pantry::Server.new
56
+ server.identity = "Encrypted Server"
57
+ server.run
58
+
59
+ client = Pantry::Client.new identity: "encrypted-client"
60
+ client.run
61
+
62
+ assert_successful_message(client)
63
+ end
64
+
65
+ it "rejects clients who connect with the wrong server key" do
66
+ set_up_encrypted(15010, server_public_key: "invalid security token1234567890")
67
+
68
+ server = Pantry::Server.new
69
+ server.identity = "Encrypted Server"
70
+ server.run
71
+
72
+ client = Pantry::Client.new identity: "encrypted-client"
73
+ client.run
74
+
75
+ assert_message_timeout(client)
76
+ end
77
+
78
+ it "rejects a client whos public key is not known by the server" do
79
+ set_up_encrypted(15020, known_clients: ["some other client here1234567890"])
80
+
81
+ server = Pantry::Server.new
82
+ server.identity = "Encrypted Server"
83
+ server.run
84
+
85
+ client = Pantry::Client.new identity: "encrypted-client"
86
+ client.run
87
+
88
+ assert_message_timeout(client)
89
+ end
90
+
91
+ end
92
+
93
+ describe "requesting new client keys" do
94
+
95
+ mock_ui!
96
+
97
+ it "returns a new set of client keys as requested" do
98
+ set_up_encrypted(15030)
99
+
100
+ server = Pantry::Server.new
101
+ server.identity = "Encrypted Server"
102
+ server.run
103
+
104
+ cli = Pantry::CLI.new(
105
+ ["client:create"],
106
+ identity: "encrypted-client"
107
+ )
108
+ cli.run
109
+
110
+ assert_match /server_public_key/, stdout
111
+ assert_match /public_key/, stdout
112
+ assert_match /private_key/, stdout
113
+ end
114
+
115
+ end
116
+
117
+ end