elasticshell 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +119 -55
- data/VERSION +1 -1
- data/bin/es +0 -2
- data/lib/elasticshell.rb +30 -25
- data/lib/elasticshell/client.rb +34 -13
- data/lib/elasticshell/command.rb +14 -170
- data/lib/elasticshell/commands/blank.rb +14 -0
- data/lib/elasticshell/commands/cd.rb +27 -0
- data/lib/elasticshell/commands/connect.rb +31 -0
- data/lib/elasticshell/commands/df.rb +23 -0
- data/lib/elasticshell/commands/help.rb +77 -0
- data/lib/elasticshell/commands/ls.rb +66 -0
- data/lib/elasticshell/commands/pretty.rb +21 -0
- data/lib/elasticshell/commands/pwd.rb +17 -0
- data/lib/elasticshell/commands/request.rb +81 -0
- data/lib/elasticshell/commands/request_parser.rb +77 -0
- data/lib/elasticshell/commands/set_verb.rb +23 -0
- data/lib/elasticshell/commands/unknown.rb +17 -0
- data/lib/elasticshell/scopes.rb +81 -50
- data/lib/elasticshell/scopes/cluster.rb +8 -16
- data/lib/elasticshell/scopes/global.rb +22 -23
- data/lib/elasticshell/scopes/index.rb +35 -29
- data/lib/elasticshell/scopes/mapping.rb +8 -28
- data/lib/elasticshell/scopes/nodes.rb +6 -15
- data/lib/elasticshell/shell.rb +155 -93
- data/lib/elasticshell/utils.rb +10 -0
- data/lib/elasticshell/{error.rb → utils/error.rb} +1 -0
- data/lib/elasticshell/utils/has_name.rb +14 -0
- data/lib/elasticshell/utils/has_verb.rb +15 -0
- data/lib/elasticshell/{log.rb → utils/log.rb} +1 -1
- data/lib/elasticshell/utils/recognizes_verb.rb +25 -0
- data/spec/elasticshell/client_spec.rb +55 -0
- data/spec/elasticshell/commands/blank_spec.rb +14 -0
- data/spec/elasticshell/commands/cd_spec.rb +23 -0
- data/spec/elasticshell/commands/connect_spec.rb +21 -0
- data/spec/elasticshell/commands/df_spec.rb +18 -0
- data/spec/elasticshell/commands/help_spec.rb +21 -0
- data/spec/elasticshell/commands/ls_spec.rb +24 -0
- data/spec/elasticshell/commands/pretty_spec.rb +19 -0
- data/spec/elasticshell/commands/pwd_spec.rb +14 -0
- data/spec/elasticshell/commands/request_parser_spec.rb +4 -0
- data/spec/elasticshell/commands/request_spec.rb +60 -0
- data/spec/elasticshell/commands/set_verb_spec.rb +14 -0
- data/spec/elasticshell/scopes_spec.rb +79 -0
- data/spec/elasticshell/shell_spec.rb +19 -0
- data/spec/elasticshell/utils/has_name_spec.rb +15 -0
- data/spec/elasticshell/utils/has_verb_spec.rb +24 -0
- data/spec/elasticshell/utils/recognizes_verb_spec.rb +23 -0
- data/spec/spec_helper.rb +4 -5
- data/spec/support/data.yml +45 -0
- data/spec/support/fake_output.rb +27 -0
- metadata +73 -4
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Client do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@client = Client.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "before connecting" do
|
10
|
+
|
11
|
+
it "should not be connected on initialization" do
|
12
|
+
expect(@client.connected?).to be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise an error when attempting to make a request before connecting" do
|
16
|
+
expect { @client.request("GET") }.to raise_error(ClientError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "when connected" do
|
21
|
+
|
22
|
+
before do
|
23
|
+
@client.stub!(:connected?).and_return(true)
|
24
|
+
@client.stub!(:log_request)
|
25
|
+
@client.stub!(:perform_request)
|
26
|
+
@verb = "GET"
|
27
|
+
@params = {:op => "/foobar"}
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should log all requests by default" do
|
31
|
+
@client.should_receive(:log_request).with(@verb, @params, {})
|
32
|
+
@client.request(@verb, @params)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should allow skipping request logging when asked" do
|
36
|
+
@client.should_not_receive(:log_request)
|
37
|
+
@client.request(@verb, @params, {:log => false})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "wrap client library errors in its own custom error class" do
|
41
|
+
@client.stub!(:perform_request).and_raise(ElasticSearch::RequestError)
|
42
|
+
expect { @client.request(@verb, @params) }.to raise_error(ClientError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return safely from a client library error if asked" do
|
46
|
+
@client.stub!(:perform_request).and_raise(ElasticSearch::RequestError)
|
47
|
+
expect(@client.request(@verb, @params, {:safely => true, :return => 3})).to eq(3)
|
48
|
+
expect(@client.safely(@verb, @params)).to be_nil
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Cd do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new, :error => FakeOutput.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should change scope when given an argument" do
|
10
|
+
expect(@shell.eval_line("cd /foo").path).to eq("/foo")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should change to the global scope when given no argument" do
|
14
|
+
expect(@shell.eval_line("cd /foo").eval_line("cd").path).to eq("/")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should properly interpret relative path names" do
|
18
|
+
expect(@shell.eval_line("cd /foo").eval_line("cd ..").path).to eq("/")
|
19
|
+
expect(@shell.eval_line("cd /foo/bar").eval_line("cd ..").path).to eq("/foo")
|
20
|
+
expect(@shell.eval_line("cd /foo/bar").eval_line("cd ../baz").path).to eq("/foo/baz")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Connect do
|
4
|
+
|
5
|
+
|
6
|
+
before do
|
7
|
+
@shell = Shell.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should start a connection to the default servers" do
|
11
|
+
@shell.client.should_receive(:connect).with()
|
12
|
+
expect(@shell.eval_line("connect"))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should start a connection to the given comma-separated servers" do
|
16
|
+
@shell.client.should_receive(:connect).with(:servers => %w[http://123.123.123.123:9200 http://321.321.321.321:9200])
|
17
|
+
expect(@shell.eval_line("connect http://123.123.123.123:9200 http://321.321.321.321:9200"))
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Df do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should produce a summary of disk usage by index" do
|
10
|
+
@global = mock("Global scope")
|
11
|
+
@shell.stub!(:connected?).and_return(true)
|
12
|
+
@shell.stub!(:scope_from_path).with("/").and_return(@global)
|
13
|
+
@global.stub!(:status).and_return({"indices"=>{"foo"=>{"index"=>{"size"=>"986b", "size_in_bytes"=>"986"}}}})
|
14
|
+
@shell.eval_line("df")
|
15
|
+
expect(@shell.output.read).to match(/986.+986b.+foo/)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Help do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should output some help text" do
|
10
|
+
@shell.eval_line("help")
|
11
|
+
expect(@shell.line).to eq(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should output some extra help text when asked" do
|
15
|
+
@shell.eval_line("help")
|
16
|
+
help = @shell.output.read.size
|
17
|
+
@shell.eval_line("help help")
|
18
|
+
expect(@shell.output.read.size).to be > help
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Ls do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new)
|
7
|
+
@shell.stub!(:connected?).and_return(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should provide a listing of the current scope's contents" do
|
11
|
+
@shell.scope.should_receive(:refresh!)
|
12
|
+
@shell.scope.stub!(:scopes).and_return(["snap", "crackle"])
|
13
|
+
@shell.eval_line("ls")
|
14
|
+
expect(@shell.output.read).to match(/crackle.+snap/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should provide a long listing of the current scope's contents" do
|
18
|
+
@shell.scope.should_receive(:refresh!)
|
19
|
+
@shell.scope.stub!(:scopes).and_return(["snap", "crackle"])
|
20
|
+
@shell.eval_line("ll")
|
21
|
+
expect(@shell.output.read).to match(/^s.+crackle.*$\ns.+snap.*$/)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Pretty do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should set the shell to pretty when it's not pretty" do
|
10
|
+
@shell.eval_line("pretty")
|
11
|
+
expect(@shell.pretty?).to be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should set the shell to pretty when it's not pretty" do
|
15
|
+
@shell.eval_line("pretty").eval_line("pretty")
|
16
|
+
expect(@shell.pretty?).to be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Commands::Request do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new, :error => FakeOutput.new, :input => FakeOutput.new )
|
7
|
+
@shell.stub!(:connected?).and_return(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should recognize a simple request" do
|
11
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
|
12
|
+
@shell.eval_line("_simple")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should recognize a simple request with a different verb" do
|
16
|
+
@shell.client.should_receive(:request).with("POST", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
|
17
|
+
@shell.eval_line("POST _simple")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should recognize a request with an absolute path" do
|
21
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/some/thing" }, kind_of(Hash), "").and_return('{}')
|
22
|
+
@shell.eval_line("/some/thing")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should recognize a request with a query string" do
|
26
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, {"foo" => "bar", "baz" => "booz what", :log => true}, "").and_return('{}')
|
27
|
+
@shell.eval_line("_simple?foo=bar&baz=booz+what")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should recognize a request with an inline body" do
|
31
|
+
@shell.client.should_receive(:request).with("POST", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
|
32
|
+
@shell.eval_line("POST _simple {}")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should recognize a request with a body read from a local file" do
|
36
|
+
File.should_receive(:exist?).with("/some/file.json").and_return(true)
|
37
|
+
File.should_receive(:read).with("/some/file.json").and_return("{}")
|
38
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
|
39
|
+
@shell.eval_line("_simple /some/file.json")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should recognize a request with a body read from STDIN" do
|
43
|
+
@shell.input_stream.stub!(:gets).and_return("{}")
|
44
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "{}").and_return('{}')
|
45
|
+
@shell.eval_line("_simple -")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be able to pipe the output of a request to Ruby inline" do
|
49
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
|
50
|
+
@shell.eval_line("_simple | response")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to pipe the output of a request to a RIPL session" do
|
54
|
+
@shell.client.should_receive(:request).with("GET", { :op => "/_simple" }, kind_of(Hash), "").and_return('{}')
|
55
|
+
require 'ripl'
|
56
|
+
Ripl.should_receive(:start)
|
57
|
+
@shell.eval_line("_simple |")
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -18,5 +18,84 @@ describe Scopes do
|
|
18
18
|
Scopes::Mapping.should_receive(:new).with(index, 'baz', kind_of(Hash))
|
19
19
|
Scopes.from_path("/foobar/baz")
|
20
20
|
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Scope do
|
25
|
+
|
26
|
+
before do
|
27
|
+
@klass = Class.new(Scope) do
|
28
|
+
def self.requests
|
29
|
+
{
|
30
|
+
"GET" => {
|
31
|
+
'_a1' => "Request a1",
|
32
|
+
'_a2' => "Request a2",
|
33
|
+
'foo' => "Request foo"
|
34
|
+
},
|
35
|
+
"POST" => {
|
36
|
+
'_b' => "Request b",
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def initial_scopes
|
42
|
+
["joe", "mary"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_scopes
|
46
|
+
self.scopes.concat(["sue", "mark"])
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
@scope = @klass.new("/path/seg", {})
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should restrict available requests to those matching its current verb" do
|
54
|
+
expect(@scope.requests).to include("_a1", "_a2")
|
55
|
+
@scope.verb = "POST"
|
56
|
+
expect(@scope.requests).to include("_b")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should reset and fetch new scopes when refreshing, but only once" do
|
60
|
+
@scope.should_receive(:reset!)
|
61
|
+
@scope.should_receive(:fetch_scopes)
|
62
|
+
3.times { @scope.refresh }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should suggest matches against requests" do
|
66
|
+
expect(@scope.requests_matching('_a')).to eql(['_a1', '_a2'])
|
67
|
+
expect(@scope.requests_matching('f')).to eql(['foo'])
|
68
|
+
expect(@scope.requests_matching('s')).to be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should suggest matches against scopes" do
|
72
|
+
expect(@scope.scopes_matching('j')).to eql(['/path/seg/joe/'])
|
73
|
+
expect(@scope.scopes_matching('m')).to eql(['/path/seg/mary/'])
|
74
|
+
end
|
75
|
+
|
76
|
+
[
|
77
|
+
%w[ / / _ ],
|
78
|
+
%w[ /foo / foo ],
|
79
|
+
%w[ /foo/ /foo _ ],
|
80
|
+
%w[ /foo/bar /foo bar ],
|
81
|
+
%w[ /foo/bar/ /foo/bar _ ],
|
82
|
+
%w[ /foo/bar/ba /foo/bar ba ],
|
83
|
+
%w[ _ /path/seg/ _ ],
|
84
|
+
%w[ foo /path/seg/ foo ],
|
85
|
+
%w[ foo/ /path/seg/foo _ ],
|
86
|
+
%w[ foo/bar /path/seg/foo bar ],
|
87
|
+
%w[ foo/bar/ /path/seg/foo/bar _ ],
|
88
|
+
%w[ foo/bar/ba /path/seg/foo/bar ba ]
|
89
|
+
].each do |prefix, completing_scope_path, prefix_within_completing_scope|
|
90
|
+
prefix = '' if prefix == '_'
|
91
|
+
prefix_within_completing_scope = '' if prefix_within_completing_scope == '_'
|
92
|
+
it "should properly parse the cd-prefix '#{prefix}' into a completion of the scope-prefix '#{prefix_within_completing_scope}' within the scope '#{completing_scope_path}'" do
|
93
|
+
expect(@scope.completing_scope_path_and_prefix(prefix)).to eql([completing_scope_path, prefix_within_completing_scope])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
21
97
|
|
98
|
+
|
22
99
|
end
|
100
|
+
|
101
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shell do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@shell = Shell.new(:output => FakeOutput.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should cache scopes with the same path" do
|
10
|
+
Scopes.should_receive(:from_path).with("/foo", kind_of(Hash))
|
11
|
+
@shell.scope_from_path("/foo")
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "printing output" do
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HasName do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@obj = Class.new { include HasName }.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "will not allow setting a name with a space or a '/'" do
|
10
|
+
expect { @obj.name = "I have spaces" }.to raise_error(Elasticshell::ArgumentError)
|
11
|
+
expect { @obj.name = "I have /" }.to raise_error(Elasticshell::ArgumentError)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HasVerb do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@obj = Class.new { include HasVerb }.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "sets 'GET' as the default verb" do
|
10
|
+
expect(@obj.verb).to eq("GET")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "will allow setting a new verb" do
|
14
|
+
@obj.verb = "POST"
|
15
|
+
expect(@obj.verb).to eq("POST")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "will not allow setting an invalid verb" do
|
19
|
+
@obj.verb = "SUCK"
|
20
|
+
expect(@obj.verb).to eq("GET")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|