flying-sphinx 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +4 -6
  3. data/Appraisals +14 -10
  4. data/HISTORY +8 -0
  5. data/README.textile +4 -6
  6. data/flying-sphinx.gemspec +1 -2
  7. data/lib/flying_sphinx.rb +5 -15
  8. data/lib/flying_sphinx/cli.rb +17 -80
  9. data/lib/flying_sphinx/commands.rb +35 -0
  10. data/lib/flying_sphinx/commands/base.rb +86 -0
  11. data/lib/flying_sphinx/commands/clear.rb +7 -0
  12. data/lib/flying_sphinx/commands/configure.rb +7 -0
  13. data/lib/flying_sphinx/commands/index_sql.rb +33 -0
  14. data/lib/flying_sphinx/commands/merge.rb +17 -0
  15. data/lib/flying_sphinx/commands/prepare.rb +7 -0
  16. data/lib/flying_sphinx/commands/rebuild.rb +7 -0
  17. data/lib/flying_sphinx/commands/reset.rb +7 -0
  18. data/lib/flying_sphinx/commands/restart.rb +7 -0
  19. data/lib/flying_sphinx/commands/rotate.rb +7 -0
  20. data/lib/flying_sphinx/commands/running.rb +7 -0
  21. data/lib/flying_sphinx/commands/start.rb +7 -0
  22. data/lib/flying_sphinx/commands/start_attached.rb +10 -0
  23. data/lib/flying_sphinx/commands/stop.rb +7 -0
  24. data/lib/flying_sphinx/configuration_options.rb +11 -5
  25. data/lib/flying_sphinx/configurer.rb +7 -2
  26. data/lib/flying_sphinx/railtie.rb +7 -5
  27. data/lib/flying_sphinx/rake_interface.rb +25 -0
  28. data/lib/flying_sphinx/response/invalid.rb +1 -1
  29. data/lib/flying_sphinx/setting_files.rb +2 -2
  30. data/lib/flying_sphinx/tasks.rb +31 -24
  31. data/lib/flying_sphinx/tasks/deprecated.rb +31 -0
  32. data/lib/flying_sphinx/tasks/replaced.rb +27 -0
  33. data/lib/flying_sphinx/version.rb +1 -1
  34. data/spec/acceptance/configuring_spec.rb +7 -7
  35. data/spec/acceptance/start_or_stop_sphinx_spec.rb +7 -4
  36. data/spec/flying_sphinx/action_spec.rb +1 -1
  37. data/spec/flying_sphinx/commands/clear_spec.rb +22 -0
  38. data/spec/flying_sphinx/commands/configure_spec.rb +38 -0
  39. data/spec/flying_sphinx/commands/index_sql_spec.rb +69 -0
  40. data/spec/flying_sphinx/commands/merge_spec.rb +30 -0
  41. data/spec/flying_sphinx/commands/rebuild_spec.rb +26 -0
  42. data/spec/flying_sphinx/commands/reset_spec.rb +26 -0
  43. data/spec/flying_sphinx/commands/restart_spec.rb +23 -0
  44. data/spec/flying_sphinx/commands/rotate_spec.rb +22 -0
  45. data/spec/flying_sphinx/commands/running_spec.rb +24 -0
  46. data/spec/flying_sphinx/commands/start_attached_spec.rb +14 -0
  47. data/spec/flying_sphinx/commands/start_spec.rb +23 -0
  48. data/spec/flying_sphinx/commands/stop_spec.rb +23 -0
  49. data/spec/flying_sphinx/configurer_spec.rb +147 -0
  50. data/spec/support/command_helpers.rb +11 -0
  51. data/spec/support/multipart.rb +10 -6
  52. metadata +51 -27
  53. data/lib/flying_sphinx/binary.rb +0 -7
  54. data/lib/flying_sphinx/binary/translator.rb +0 -48
  55. data/lib/flying_sphinx/controller.rb +0 -104
  56. data/lib/flying_sphinx/rails.rb +0 -7
  57. data/lib/flying_sphinx/sphinxql.rb +0 -7
  58. data/lib/flying_sphinx/sphinxql/translator.rb +0 -26
  59. data/spec/flying_sphinx/controller_spec.rb +0 -71
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Configure do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Configure.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+
16
+ stub_const 'FlyingSphinx::Configurer', double(:call => "/foo")
17
+ end
18
+
19
+ it "sends through gzipped configuration archive" do
20
+ expect(api).to receive(:post).with "/perform",
21
+ :action => "configure",
22
+ :path => "/foo"
23
+
24
+ subject.call
25
+ end
26
+
27
+ it "raises an exception if an invalid path error is returned" do
28
+ allow(api).to receive(:post).and_return('status' => 'INVALID PATH')
29
+
30
+ expect { subject.call }.to raise_error(FlyingSphinx::Error)
31
+ end
32
+
33
+ it "raises an exception if an unknown error is returned" do
34
+ allow(api).to receive(:post).and_return('status' => nil)
35
+
36
+ expect { subject.call }.to raise_error(FlyingSphinx::Error)
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::IndexSQL do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::IndexSQL.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+ end
16
+
17
+ context "synchronous" do
18
+ it "sends the action" do
19
+ expect(api).to receive(:post).with "/perform",
20
+ :action => "index",
21
+ :indices => ""
22
+
23
+ subject.call
24
+ end
25
+
26
+ it "waits for the action to finish" do
27
+ expect(action_class).to receive(:perform) do |identifier, &block|
28
+ block.call
29
+ end
30
+
31
+ subject.call
32
+ end
33
+ end
34
+
35
+ context "asynchronous" do
36
+ let(:subject) do
37
+ FlyingSphinx::Commands::IndexSQL.new(
38
+ double, :api => api, :indices => ["foo_delta"]
39
+ )
40
+ end
41
+
42
+ it "sends the action" do
43
+ expect(api).to receive(:post).with "/perform",
44
+ :action => "index",
45
+ :indices => "foo_delta",
46
+ :unique => "true"
47
+
48
+ subject.call
49
+ end
50
+
51
+ it "does not wait for the action to finish" do
52
+ expect(action_class).not_to receive(:perform)
53
+
54
+ subject.call
55
+ end
56
+
57
+ it "raises an exception if a blocked error is returned" do
58
+ allow(api).to receive(:post).and_return('status' => 'BLOCKED')
59
+
60
+ expect { subject.call }.to raise_error(FlyingSphinx::Error)
61
+ end
62
+
63
+ it "raises an exception if an unconfigured error is returned" do
64
+ allow(api).to receive(:post).and_return('status' => 'UNCONFIGURED')
65
+
66
+ expect { subject.call }.to raise_error(FlyingSphinx::Error)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Merge do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Merge.new configuration_double, :api => api,
6
+ :core_index => core_index, :delta_index => delta_index,
7
+ :filters => {:deleted => 0}
8
+ end
9
+ let(:api) do
10
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
11
+ end
12
+ let(:core_index) { double "index", :name => "core" }
13
+ let(:delta_index) { double "index", :name => "delta" }
14
+ let(:action_class) { double }
15
+
16
+ before :each do
17
+ stub_const 'FlyingSphinx::Action', action_class
18
+ action_class.stub(:perform) { |identifier, &block| block.call }
19
+ end
20
+
21
+ it "sends through action" do
22
+ expect(api).to receive(:post).with "/perform",
23
+ :action => "merge",
24
+ :core_index => "core",
25
+ :delta_index => "delta",
26
+ :filters => '{"deleted":0}'
27
+
28
+ subject.call
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Rebuild do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Rebuild.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+
16
+ stub_const 'FlyingSphinx::Configurer', double(:call => "/foo")
17
+ end
18
+
19
+ it "sends through gzipped configuration archive" do
20
+ expect(api).to receive(:post).with "/perform",
21
+ :action => "rebuild",
22
+ :path => "/foo"
23
+
24
+ subject.call
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Reset do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Reset.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+
16
+ stub_const 'FlyingSphinx::Configurer', double(:call => "/foo")
17
+ end
18
+
19
+ it "sends through gzipped configuration archive" do
20
+ expect(api).to receive(:post).with "/perform",
21
+ :action => "reset",
22
+ :path => "/foo"
23
+
24
+ subject.call
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Restart do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Restart.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+ end
16
+
17
+ it "sends through action" do
18
+ expect(api).to receive(:post).with "/perform",
19
+ :action => "restart"
20
+
21
+ subject.call
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Rotate do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Rotate.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+ end
16
+
17
+ it "sends through action" do
18
+ expect(api).to receive(:post).with "/perform", :action => "rotate"
19
+
20
+ subject.call
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Running do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Running.new configuration_double, :api => api
6
+ end
7
+ let(:api) { double 'API', :identifier => 'foo', :get => {"running" => true} }
8
+
9
+ it "sends through the API request" do
10
+ expect(api).to receive(:get).with("/running").and_return("running" => true)
11
+
12
+ subject.call
13
+ end
14
+
15
+ it "returns true when the API does" do
16
+ expect(subject.call).to eq(true)
17
+ end
18
+
19
+ it "returns false when the API does" do
20
+ allow(api).to receive(:get).with("/running").and_return("running" => false)
21
+
22
+ expect(subject.call).to eq(false)
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::StartAttached do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::StartAttached.new(configuration_double, {}, stream)
6
+ end
7
+ let(:stream) { double 'Stream', :puts => nil }
8
+
9
+ it "prints a warning" do
10
+ expect(stream).to receive(:puts)
11
+
12
+ subject.call
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Start do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Start.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+ end
16
+
17
+ it "sends through action" do
18
+ expect(api).to receive(:post).with "/perform",
19
+ :action => "start"
20
+
21
+ subject.call
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Commands::Stop do
4
+ let(:subject) do
5
+ FlyingSphinx::Commands::Stop.new configuration_double, :api => api
6
+ end
7
+ let(:api) do
8
+ double 'API', :identifier => 'foo', :post => {'status' => 'OK'}
9
+ end
10
+ let(:action_class) { double }
11
+
12
+ before :each do
13
+ stub_const 'FlyingSphinx::Action', action_class
14
+ action_class.stub(:perform) { |identifier, &block| block.call }
15
+ end
16
+
17
+ it "sends through action" do
18
+ expect(api).to receive(:post).with "/perform",
19
+ :action => "stop"
20
+
21
+ subject.call
22
+ end
23
+ end
@@ -0,0 +1,147 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe FlyingSphinx::Configurer do
4
+ let(:subject) { FlyingSphinx::Configurer.new api }
5
+ let(:api) { double :get => presignature }
6
+ let(:presignature) { {
7
+ "status" => "OK",
8
+ "path" => "a/path/of/my/own",
9
+ "url" => "https://confserver",
10
+ "fields" => {"message" => "something"}
11
+ } }
12
+ let(:configuration_options) { double "conf options", :version => "2.2.3",
13
+ :raw => "indexer ...", :settings => settings, :engine => "manticore" }
14
+ let(:settings) { {
15
+ "extra" => "wordforms/txt.txt",
16
+ "wordforms/txt.txt" => "something"
17
+ } }
18
+
19
+ before :each do
20
+ stub_request(:post, "https://confserver").to_return(:status => 200)
21
+
22
+ allow(FlyingSphinx::ConfigurationOptions).to receive(:new).
23
+ and_return(configuration_options)
24
+ end
25
+
26
+ it "requests a presignature path" do
27
+ expect(api).to receive(:get).with("/presignature").and_return(presignature)
28
+
29
+ subject.call
30
+ end
31
+
32
+ it "uploads a file to the presignature path" do
33
+ subject.call
34
+
35
+ expect(
36
+ a_multipart_request(:post, 'https://confserver')
37
+ ).to have_been_made
38
+ end
39
+
40
+ it "includes the configuration in the file" do
41
+ subject.call
42
+
43
+ expect(
44
+ a_multipart_request(:post, "https://confserver").
45
+ with_file { |contents|
46
+ reader = GZippedTar::Reader.new contents
47
+ reader.read("sphinx/raw.conf") == "indexer ..."
48
+ }
49
+ ).to have_been_made
50
+ end
51
+
52
+ it "includes the Sphinx version in the file" do
53
+ subject.call
54
+
55
+ expect(
56
+ a_multipart_request(:post, "https://confserver").
57
+ with_file { |contents|
58
+ reader = GZippedTar::Reader.new contents
59
+ reader.read("sphinx/version.txt") == "2.2.3"
60
+ }
61
+ ).to have_been_made
62
+ end
63
+
64
+ it "includes the Sphinx engine in the file" do
65
+ subject.call
66
+
67
+ expect(
68
+ a_multipart_request(:post, "https://confserver").
69
+ with_file { |contents|
70
+ reader = GZippedTar::Reader.new contents
71
+ reader.read("sphinx/engine.txt") == "manticore"
72
+ }
73
+ ).to have_been_made
74
+ end
75
+
76
+ it "includes the extra settings in the file" do
77
+ subject.call
78
+
79
+ expect(
80
+ a_multipart_request(:post, "https://confserver").
81
+ with_file { |contents|
82
+ reader = GZippedTar::Reader.new contents
83
+ reader.read("wordforms/txt.txt") == "something"
84
+ }
85
+ ).to have_been_made
86
+ end
87
+
88
+ it "includes the extra summary in the file" do
89
+ subject.call
90
+
91
+ expect(
92
+ a_multipart_request(:post, "https://confserver").
93
+ with_file { |contents|
94
+ reader = GZippedTar::Reader.new contents
95
+ reader.read("sphinx/extra.txt") == "wordforms/txt.txt"
96
+ }
97
+ ).to have_been_made
98
+ end
99
+
100
+ it "includes the provided fields in the request" do
101
+ subject.call
102
+
103
+ expect(
104
+ a_multipart_request(:post, "https://confserver").
105
+ with_params { |params| params["message"] == "something" }
106
+ ).to have_been_made
107
+ end
108
+
109
+ it "returns the presignature path" do
110
+ expect(subject.call).to eq("a/path/of/my/own")
111
+ end
112
+
113
+ context "presignature failure" do
114
+ before :each do
115
+ presignature["status"] = "failure"
116
+ end
117
+
118
+ it "raises a PresignatureError exception" do
119
+ expect { subject.call }.to raise_error(
120
+ FlyingSphinx::Configurer::PresignatureError
121
+ )
122
+ end
123
+
124
+ it "does not attempt to upload" do
125
+ begin
126
+ subject.call
127
+ rescue FlyingSphinx::Configurer::PresignatureError
128
+ end
129
+
130
+ expect(
131
+ a_multipart_request(:post, "https://confserver")
132
+ ).not_to have_been_made
133
+ end
134
+ end
135
+
136
+ context "upload failure" do
137
+ before :each do
138
+ stub_request(:post, "https://confserver").to_return(:status => 400)
139
+ end
140
+
141
+ it "raises an UploadError exception" do
142
+ expect { subject.call }.to raise_error(
143
+ FlyingSphinx::Configurer::UploadError
144
+ )
145
+ end
146
+ end
147
+ end