pantry 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,41 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Commands::RegisterClient do
4
+
5
+ it "builds a client and notifies server of the new client" do
6
+ message = Pantry::Message.new("RegisterClient")
7
+ message.from = "client 427"
8
+ message << {
9
+ :environment => "test", :application => "pantry", :roles => %w(app db)
10
+ }
11
+
12
+ server = Pantry::Server.new
13
+
14
+ command = Pantry::Commands::RegisterClient.new
15
+ command.server_or_client = server
16
+ command.perform(message)
17
+
18
+ clients = server.client_registry.all
19
+
20
+ assert_equal 1, clients.length
21
+ assert_equal "client 427", clients[0].identity
22
+ assert_equal "pantry", clients[0].application
23
+ assert_equal "test", clients[0].environment
24
+ assert_equal %w(app db), clients[0].roles
25
+ end
26
+
27
+ it "builds message including the Client's information for registration" do
28
+ command = Pantry::Commands::RegisterClient.new(Pantry::ClientInfo.new(
29
+ identity: "Test123", application: "pantry", environment: "test",
30
+ roles: %w(app db)
31
+ ))
32
+
33
+ message = command.to_message
34
+
35
+ assert_equal(
36
+ {:application => "pantry", :environment => "test", :roles => %w(app db)},
37
+ message.body[0]
38
+ )
39
+ end
40
+
41
+ end
@@ -0,0 +1,81 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Commands::Status do
4
+
5
+ mock_ui!
6
+
7
+ describe "#prepare_message" do
8
+ it "generates a message with the given client filter" do
9
+ command = Pantry::Commands::Status.new
10
+ message = command.prepare_message({
11
+ application: "pantry"
12
+ })
13
+
14
+ assert_equal "Status", message.type
15
+ assert_equal({application: "pantry", environment: nil, roles: [], identity: nil},
16
+ message.body[0])
17
+ end
18
+ end
19
+
20
+ describe "#perform" do
21
+ it "asks server for known clients and returns the info as a list" do
22
+ server = Pantry::Server.new
23
+ server.register_client(Pantry::ClientInfo.new(identity: "client1"))
24
+ server.register_client(Pantry::ClientInfo.new(identity: "client2"))
25
+ server.register_client(Pantry::ClientInfo.new(identity: "client3"))
26
+
27
+ message = Pantry::Message.new("Status")
28
+
29
+ command = Pantry::Commands::Status.new
30
+ command.server_or_client = server
31
+
32
+ response = command.perform(message)
33
+
34
+ assert_equal ["client1", "client2", "client3"], response.map {|entry| entry[:identity] }
35
+ end
36
+
37
+ it "only counts clients that match the given filters" do
38
+ server = Pantry::Server.new
39
+ server.register_client(Pantry::ClientInfo.new(identity: "client1", application: "pantry"))
40
+ server.register_client(Pantry::ClientInfo.new(identity: "client2", application: "pantry", environment: "testing"))
41
+ server.register_client(Pantry::ClientInfo.new(identity: "client3"))
42
+
43
+ message = Pantry::Message.new("Status")
44
+ message << Pantry::Communication::ClientFilter.new(application: "pantry").to_hash
45
+
46
+ command = Pantry::Commands::Status.new
47
+ command.server_or_client = server
48
+
49
+ response = command.perform(message)
50
+
51
+ assert_equal ["client1", "client2"], response.map {|entry| entry[:identity] }
52
+ end
53
+ end
54
+
55
+ describe "#receive_message" do
56
+ let(:response) do
57
+ Pantry::Message.new.tap do |m|
58
+ m.from = Pantry::SERVER_IDENTITY
59
+ m << {:identity => "client1", :last_checked_in => (Time.now - 60*60).to_s }
60
+ m << {:identity => "client2", :last_checked_in => (Time.now - 60*5).to_s }
61
+ end
62
+ end
63
+
64
+ it "reports the name and last time checked in to the user" do
65
+ command = Pantry::Commands::Status.new
66
+ command.receive_response(response)
67
+
68
+ assert_match /client1/, stdout, "Did not include client1 in output"
69
+ assert_match /client2/, stdout, "Did not include client2 in output"
70
+ end
71
+
72
+ it "builds a nice message for when the clients last checked in" do
73
+ command = Pantry::Commands::Status.new
74
+ command.receive_response(response)
75
+
76
+ assert_match /5 minutes ago/, stdout
77
+ assert_match /1 hour ago/, stdout
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,75 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Commands::SyncDirectory do
4
+
5
+ fake_fs!
6
+
7
+ class MySyncTest < Pantry::Commands::SyncDirectory
8
+ def server_directory(local_root)
9
+ local_root.join("copy", "from", "dir")
10
+ end
11
+
12
+ def client_directory(local_root)
13
+ local_root.join("copy", "to")
14
+ end
15
+ end
16
+
17
+ it "asks Server for all files in a directory, returning name and contents" do
18
+ client = stub_everything
19
+
20
+ response = Pantry::Message.new
21
+ response << ["file1.txt", %|some content here|]
22
+ response << ["file2.rb", %|def main; end;|]
23
+
24
+ client.expects(:send_request).with do |message|
25
+ assert_equal "DownloadDirectory", message.type
26
+ assert_equal "copy/from/dir", message.body[0]
27
+ end.returns(mock(:value => response))
28
+
29
+ command = MySyncTest.new
30
+ command.client = client
31
+ command.perform(Pantry::Message.new)
32
+
33
+ file1 = Pantry.root.join("copy", "to", "file1.txt")
34
+ assert File.exists?(file1), "Did not write the first file"
35
+ assert_equal "some content here", File.read(file1)
36
+
37
+ file2 = Pantry.root.join("copy", "to", "file2.rb")
38
+ assert File.exists?(file2), "Did not write the second file"
39
+ assert_equal "def main; end;", File.read(file2)
40
+ end
41
+
42
+ it "ensures nested directories are created" do
43
+ client = stub_everything
44
+
45
+ response = Pantry::Message.new
46
+ response << ["nested/file1.txt", ""]
47
+
48
+ client.expects(:send_request).returns(mock(:value => response))
49
+
50
+ command = MySyncTest.new
51
+ command.client = client
52
+ command.perform(Pantry::Message.new)
53
+
54
+ file1 = Pantry.root.join("copy", "to", "nested", "file1.txt")
55
+ assert File.exists?(file1), "Did not write the nested file"
56
+ end
57
+
58
+ it "doesn't allow path injection attacks" do
59
+ client = stub_everything
60
+
61
+ response = Pantry::Message.new
62
+ response << ["../../../../file1.txt", %|some content here|]
63
+
64
+ client.stubs(:send_request).returns(mock(:value => response))
65
+
66
+ command = MySyncTest.new
67
+ command.client = client
68
+ command.perform(Pantry::Message.new)
69
+
70
+ file1 = Pantry.root.join("copy", "to", "file1.txt")
71
+ assert_false File.exists?(file1), "Still wrote out the bad file?"
72
+ assert_false File.exists?(Pantry.root.join("../../../../file1.txt")), "Still wrote out the bad file?"
73
+ end
74
+
75
+ end
@@ -0,0 +1,35 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Commands::UpdateApplication do
4
+ let(:command) { Pantry::Commands::UpdateApplication.new }
5
+
6
+ fake_fs!
7
+
8
+ describe "#perform" do
9
+ it "takes contents of the message and writes out a new config file for the application" do
10
+ message = Pantry::Message.new
11
+ message << "pantry"
12
+ message << {name: "pantry", enviornment: "test"}.to_yaml
13
+
14
+ assert command.perform(message)
15
+
16
+ assert File.exists?(Pantry.root.join("applications", "pantry", "config.yml")),
17
+ "Did not write out the new config file"
18
+ end
19
+
20
+ it "ignores file content that's not valid YAML" do
21
+ message = Pantry::Message.new
22
+ message << "pantry"
23
+ message << "---\nthis: that\n<> { not valid yaml zomg }"
24
+
25
+ response = command.perform(message)
26
+
27
+ assert_false response[0]
28
+ assert_false File.exists?(Pantry.root.join("applications", "pantry", "config.yml")),
29
+ "Wrote out an invalid config file"
30
+ end
31
+
32
+ it "creates a backup of the file being overwritten"
33
+ end
34
+
35
+ end
@@ -0,0 +1,51 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Commands::UploadFile do
4
+
5
+ class MyUploader < Pantry::Commands::UploadFile
6
+ def required_options
7
+ %i(application)
8
+ end
9
+
10
+ def upload_directory(options)
11
+ Pantry.root.join("upload", options[:application])
12
+ end
13
+ end
14
+
15
+ describe "#prepare_message" do
16
+ it "requires an application we're uploading for" do
17
+ command = MyUploader.new(fixture_path("file_to_upload"))
18
+ assert_raises Pantry::MissingOption do
19
+ command.prepare_message({})
20
+ end
21
+ end
22
+
23
+ it "sets the file name and contents in the message to the Server" do
24
+ command = MyUploader.new(fixture_path("file_to_upload"))
25
+ message = command.prepare_message({application: "pantry"})
26
+
27
+ assert_equal({application: "pantry"}, message.body[0])
28
+ assert_equal "file_to_upload", message.body[1]
29
+ assert_equal %|Hello\nPantry\n!\n|, message.body[2]
30
+ end
31
+ end
32
+
33
+ describe "#perform" do
34
+ fake_fs!
35
+
36
+ it "writes out the file data to the appropriate location" do
37
+ message = Pantry::Message.new
38
+ message << {application: "pantry"}
39
+ message << "filename.rb"
40
+ message << "This is the content"
41
+
42
+ command = MyUploader.new
43
+ command.perform(message)
44
+
45
+ uploaded_file = Pantry.root.join("upload", "pantry", "filename.rb")
46
+ assert File.exists?(uploaded_file), "Did not write out the file"
47
+ assert_equal "This is the content", File.read(uploaded_file)
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,262 @@
1
+ require 'unit/test_helper'
2
+
3
+ describe Pantry::Communication::ClientFilter do
4
+
5
+ it "ensures roles is always an array" do
6
+ filter = Pantry::Communication::ClientFilter.new(roles: nil)
7
+ assert_equal [], filter.roles
8
+ end
9
+
10
+ describe "#streams" do
11
+ it "returns empty string if no filters given" do
12
+ filter = Pantry::Communication::ClientFilter.new({})
13
+ assert_equal [""], filter.streams
14
+ end
15
+
16
+ it "takes a hash of filters and builds streams from them" do
17
+ filter = Pantry::Communication::ClientFilter.new(
18
+ identity: "my_test_ident",
19
+ application: "pantry",
20
+ environment: "test",
21
+ roles: %w(db app)
22
+ )
23
+
24
+ expected_streams = [
25
+ "my_test_ident",
26
+ "pantry",
27
+ "pantry.test",
28
+ "pantry.test.db",
29
+ "pantry.test.app",
30
+ ]
31
+
32
+ assert_equal expected_streams, filter.streams
33
+ end
34
+
35
+ it "handles environment and roles, no application" do
36
+ filter = Pantry::Communication::ClientFilter.new(
37
+ environment: "test",
38
+ roles: %w(db app)
39
+ )
40
+
41
+ expected_streams = [
42
+ "test",
43
+ "test.db",
44
+ "test.app",
45
+ ]
46
+
47
+ assert_equal expected_streams, filter.streams
48
+ end
49
+
50
+ it "handles application and roles, no environment, properly" do
51
+ filter = Pantry::Communication::ClientFilter.new(
52
+ application: "pantry",
53
+ roles: %w(db app)
54
+ )
55
+
56
+ expected_streams = [
57
+ "pantry",
58
+ "pantry.db",
59
+ "pantry.app",
60
+ ]
61
+
62
+ assert_equal expected_streams, filter.streams
63
+ end
64
+
65
+ it "handles just roles" do
66
+ filter = Pantry::Communication::ClientFilter.new(
67
+ roles: %w(db app)
68
+ )
69
+
70
+ assert_equal ["db", "app"], filter.streams
71
+ end
72
+
73
+ it "uses the identity of no other values set" do
74
+ filter = Pantry::Communication::ClientFilter.new(
75
+ identity: "tester.client"
76
+ )
77
+
78
+ assert_equal ["tester.client"], filter.streams
79
+ end
80
+ end
81
+
82
+ describe "#stream" do
83
+ it "returns the most explicit stream matching filters given" do
84
+ filter = Pantry::Communication::ClientFilter.new(
85
+ application: "pantry",
86
+ environment: "test",
87
+ roles: %w(db)
88
+ )
89
+
90
+ assert_equal "pantry.test.db", filter.stream
91
+ end
92
+
93
+ it "ignores environment if left out" do
94
+ filter = Pantry::Communication::ClientFilter.new(
95
+ application: "pantry",
96
+ roles: %w(db)
97
+ )
98
+
99
+ assert_equal "pantry.db", filter.stream
100
+ end
101
+
102
+ it "ignores application if left out" do
103
+ filter = Pantry::Communication::ClientFilter.new(
104
+ roles: %w(db)
105
+ )
106
+
107
+ assert_equal "db", filter.stream
108
+ end
109
+
110
+ it "uses the client identity if given" do
111
+ filter = Pantry::Communication::ClientFilter.new(
112
+ identity: "12345.client",
113
+ roles: %w(app db)
114
+ )
115
+
116
+ assert_equal "12345.client", filter.stream
117
+ end
118
+ end
119
+
120
+ describe "#equality" do
121
+ it "return true on empty filters" do
122
+ assert_equal(
123
+ Pantry::Communication::ClientFilter.new,
124
+ Pantry::Communication::ClientFilter.new
125
+ )
126
+ end
127
+
128
+ it "returns true on matching all options" do
129
+ assert_equal(
130
+ Pantry::Communication::ClientFilter.new(
131
+ application: "app", environment: "test", roles: %w(db)),
132
+ Pantry::Communication::ClientFilter.new(
133
+ application: "app", environment: "test", roles: %w(db))
134
+ )
135
+ end
136
+
137
+ it "returns false if other is nil" do
138
+ refute_equal(
139
+ Pantry::Communication::ClientFilter.new,
140
+ nil
141
+ )
142
+ end
143
+ end
144
+
145
+ describe "#matches" do
146
+ it "returns true if the stream is matched by any part of the filter" do
147
+ filter = Pantry::Communication::ClientFilter.new(
148
+ application: "app", environment: "test", roles: %w(db))
149
+
150
+ assert filter.matches?("")
151
+ assert filter.matches?("app")
152
+ assert filter.matches?("app.test")
153
+ assert filter.matches?("app.test.db")
154
+
155
+ assert_false filter.matches?("app2")
156
+ assert_false filter.matches?("db")
157
+ assert_false filter.matches?("test")
158
+ end
159
+
160
+ it "tries to match against an identity filter" do
161
+ filter = Pantry::Communication::ClientFilter.new(identity: "test-client")
162
+
163
+ assert filter.matches?("")
164
+ assert filter.matches?("test-client")
165
+
166
+ assert_false filter.matches?("app")
167
+ assert_false filter.matches?("pantry.test")
168
+ end
169
+ end
170
+
171
+ describe "#includes?" do
172
+ it "returns true if the two filters are equal" do
173
+ f1 = Pantry::Communication::ClientFilter.new(
174
+ application: "app", environment: "test", roles: %w(db))
175
+ f2 = Pantry::Communication::ClientFilter.new(
176
+ application: "app", environment: "test", roles: %w(db))
177
+
178
+ assert f2.includes?(f1), "f1's match set was not included in f2's match set"
179
+ end
180
+
181
+ it "returns true if the most specific stream" do
182
+ f1 = Pantry::Communication::ClientFilter.new(
183
+ application: "app", environment: "test", roles: %w(db))
184
+ f2 = Pantry::Communication::ClientFilter.new(application: "app")
185
+
186
+ assert f2.includes?(f1), "app should have included app.test.db"
187
+ end
188
+
189
+ it "handles multiple roles" do
190
+ f1 = Pantry::Communication::ClientFilter.new(
191
+ application: "app", roles: %w(db web))
192
+ f2 = Pantry::Communication::ClientFilter.new(application: "app", roles: %w(web))
193
+
194
+ assert f2.includes?(f1), "app.web should have included app.test.web / app.test.db"
195
+ end
196
+
197
+ it "returns false if application doesn't match" do
198
+ f1 = Pantry::Communication::ClientFilter.new(
199
+ application: "app", environment: "test", roles: %w(db))
200
+ f2 = Pantry::Communication::ClientFilter.new(
201
+ application: "app2", environment: "test", roles: %w(db))
202
+
203
+ assert_false f2.includes?(f1), "f1's match set was included in f2's match set"
204
+ end
205
+
206
+ it "returns false if environment doesn't match" do
207
+ f1 = Pantry::Communication::ClientFilter.new(
208
+ application: "app", environment: "test", roles: %w(db))
209
+ f2 = Pantry::Communication::ClientFilter.new(
210
+ application: "app", environment: "dev", roles: %w(db))
211
+
212
+ assert_false f2.includes?(f1), "f1's match set was included in f2's match set"
213
+ end
214
+
215
+ it "returns false if roles doesn't match" do
216
+ f1 = Pantry::Communication::ClientFilter.new(
217
+ application: "app", environment: "test", roles: %w(app))
218
+ f2 = Pantry::Communication::ClientFilter.new(
219
+ application: "app", environment: "test", roles: %w(db))
220
+
221
+ assert_false f2.includes?(f1), "f1's match set was included in f2's match set"
222
+ end
223
+
224
+ it "returns false if environments are given in one but not the other" do
225
+ f1 = Pantry::Communication::ClientFilter.new(
226
+ application: "app", environment: "test", roles: %w(db))
227
+ f2 = Pantry::Communication::ClientFilter.new(
228
+ application: "app", roles: %w(db))
229
+
230
+ assert_false f2.includes?(f1), "f1's match set was included in f2's match set"
231
+ end
232
+
233
+ it "returns true if we are the empty set (match all)" do
234
+ f1 = Pantry::Communication::ClientFilter.new(
235
+ application: "app", environment: "test", roles: %w(db))
236
+ f2 = Pantry::Communication::ClientFilter.new()
237
+
238
+ assert f2.includes?(f1), "f1 was not included in f2's all client match"
239
+ end
240
+
241
+ it "returns false if identity is the only value set and doesn't match" do
242
+ f1 = Pantry::Communication::ClientFilter.new(identity: "test-client")
243
+ f2 = Pantry::Communication::ClientFilter.new(application: "pantry")
244
+
245
+ assert_false f2.includes?(f1), "f1 was not included in f2's all client match"
246
+ end
247
+ end
248
+
249
+ describe "#to_hash" do
250
+ it "returns a hash representation of the filter" do
251
+ filter = Pantry::Communication::ClientFilter.new(
252
+ application: "app", environment: "test", roles: %w(db), identity: "test"
253
+ )
254
+
255
+ assert_equal(
256
+ {application: "app", environment: "test", roles: %w(db), identity: "test"},
257
+ filter.to_hash
258
+ )
259
+ end
260
+ end
261
+
262
+ end