flying-sphinx 1.3.1 → 2.0.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 (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