mirror of https://gitee.com/bigwinds/arangodb
253 lines
8.3 KiB
Ruby
253 lines
8.3 KiB
Ruby
# coding: utf-8
|
|
|
|
require 'rspec'
|
|
require 'arangodb.rb'
|
|
require 'json'
|
|
|
|
describe ArangoDB do
|
|
|
|
before do
|
|
@api = "/_api/query"
|
|
@prefix = "api-query"
|
|
@current = "#{@api}/current"
|
|
@slow = "#{@api}/slow"
|
|
@properties = "#{@api}/properties"
|
|
@query = "FOR x IN 1..5 LET y = SLEEP(2) RETURN x"
|
|
@queryBody = JSON.dump({query: @query})
|
|
@fastQuery = "FOR x IN 1..1 LET y = SLEEP(0.2) RETURN x"
|
|
@fastQueryBody = JSON.dump({query: @fastQuery})
|
|
@longQuery = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b LET d = c LET e = d LET f = e RETURN x"
|
|
@longQueryBody = JSON.dump({query: @longQuery})
|
|
@queryWithBind = "FOR x IN 1..5 LET y = SLEEP(@value) RETURN x"
|
|
@queryWithBindBody = JSON.dump({query: @queryWithBind, bindVars: {value: 4}})
|
|
@queryEndpoint ="/_api/cursor"
|
|
@queryPrefix = "api-cursor"
|
|
end
|
|
|
|
def send_queries (count = 1, async = "true")
|
|
count.times do
|
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @queryBody, :headers => {"X-Arango-Async" => async })
|
|
end
|
|
end
|
|
|
|
def send_fast_queries (count = 1, async = "true")
|
|
count.times do
|
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @fastQueryBody, :headers => {"X-Arango-Async" => async })
|
|
end
|
|
end
|
|
|
|
def send_queries_with_bind (count = 1, async = "true")
|
|
count.times do
|
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @queryWithBindBody, :headers => {"X-Arango-Async" => async })
|
|
end
|
|
end
|
|
|
|
def contains_query (body, testq = @query)
|
|
res = JSON.parse body
|
|
res.each do |q|
|
|
if q["query"] === testq
|
|
return q
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
def wait_for_query (query, type, maxWait)
|
|
if type == "slow"
|
|
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
|
elsif type == "current"
|
|
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
|
end
|
|
doc.code.should eq(200)
|
|
|
|
while true
|
|
found = contains_query doc.body, query
|
|
if found
|
|
return found
|
|
end
|
|
maxWait -= 1
|
|
if maxWait == 0
|
|
return false
|
|
end
|
|
sleep 1
|
|
end
|
|
end
|
|
|
|
it "should activate tracking" do
|
|
doc = ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({enable: true}))
|
|
doc.code.should eq(200)
|
|
end
|
|
|
|
describe "tracking" do
|
|
before do
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({enable: true, slowQueryThreshold: 20, trackSlowQueries: true}))
|
|
end
|
|
|
|
before(:each) do
|
|
ArangoDB.log_delete("#{@prefix}-delete", @slow)
|
|
end
|
|
|
|
after(:each) do
|
|
# Let the queries finish
|
|
count = 0
|
|
while true
|
|
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
|
res = JSON.parse doc.body
|
|
if res.length == 0
|
|
break
|
|
end
|
|
res.each do |q|
|
|
if q["query"].match(/SLEEP/)
|
|
doc = ArangoDB.log_delete(@prefix, "#{@api}/" + q["id"])
|
|
end
|
|
end
|
|
count += 1
|
|
if count == 10
|
|
break
|
|
end
|
|
sleep 1
|
|
end
|
|
end
|
|
|
|
it "should track running queries" do
|
|
send_queries
|
|
found = wait_for_query @query, "current", 10
|
|
found.should_not eq(false)
|
|
found.should have_key("id")
|
|
found["id"].should match(/^\d+$/)
|
|
found.should have_key("query")
|
|
found["query"].should eq(@query)
|
|
found.should have_key("bindVars")
|
|
found["bindVars"].should eq({})
|
|
found.should have_key("runTime")
|
|
found["runTime"].should be_kind_of(Numeric)
|
|
found.should have_key("started")
|
|
found.should have_key("state")
|
|
found["state"].should be_kind_of(String)
|
|
end
|
|
|
|
it "should track running queries, with bind parameters" do
|
|
send_queries_with_bind
|
|
found = wait_for_query @queryWithBind, "current", 10
|
|
found.should_not eq(false)
|
|
found.should have_key("id")
|
|
found["id"].should match(/^\d+$/)
|
|
found.should have_key("query")
|
|
found["query"].should eq(@queryWithBind)
|
|
found.should have_key("bindVars")
|
|
found["bindVars"].should eq({"value" => 4})
|
|
found.should have_key("runTime")
|
|
found["runTime"].should be_kind_of(Numeric)
|
|
found.should have_key("started")
|
|
found.should have_key("state")
|
|
found["state"].should be_kind_of(String)
|
|
end
|
|
|
|
it "should track slow queries by threshold" do
|
|
send_fast_queries 1, "false"
|
|
found = wait_for_query @fastQuery, "slow", 1
|
|
found.should eq(false)
|
|
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 0.1}))
|
|
|
|
send_fast_queries 1, "false"
|
|
found = wait_for_query @fastQuery, "current", 1
|
|
found.should eq(false)
|
|
found = wait_for_query @fastQuery, "slow", 1
|
|
found.should_not eq(false)
|
|
found.should have_key("query")
|
|
found["query"].should eq(@fastQuery)
|
|
found["bindVars"].should eq({})
|
|
found.should have_key("runTime")
|
|
found["runTime"].should be_kind_of(Numeric)
|
|
found.should have_key("started")
|
|
found["state"].should eq("finished")
|
|
end
|
|
|
|
it "should track at most n slow queries" do
|
|
max = 3
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 0.1, maxSlowQueries: max}))
|
|
send_fast_queries 6, "false"
|
|
|
|
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
|
doc.code.should eq(200)
|
|
res = JSON.parse doc.body
|
|
res.length.should eq(max)
|
|
end
|
|
|
|
it "should not track slow queries if turned off" do
|
|
found = wait_for_query @fastQuery, "slow", 1
|
|
found.should eq(false)
|
|
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 0.1, trackSlowQueries: false}))
|
|
send_fast_queries 1, "false"
|
|
|
|
found = wait_for_query @fastQuery, "slow", 1
|
|
found.should eq(false)
|
|
end
|
|
|
|
it "should truncate the query string to at least 64 bytes" do
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 2, maxQueryStringLength: 12}))
|
|
doc = ArangoDB.log_get("#{@prefix}-properties", @properties)
|
|
res = JSON.parse doc.body
|
|
res["maxQueryStringLength"].should eq(64)
|
|
end
|
|
|
|
it "should truncate the query string" do
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 0.1, maxQueryStringLength: 64}))
|
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => @longQueryBody)
|
|
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
|
doc.code.should eq(200)
|
|
res = JSON.parse doc.body
|
|
res.length.should eq(1)
|
|
# This string is exactly 64 bytes long
|
|
shortened = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a = y LET b = a LET c = b L"
|
|
found = contains_query doc.body, shortened + "..."
|
|
found.should_not eq(false)
|
|
found.should have_key("query")
|
|
found["query"].should eq(shortened + "...")
|
|
found["bindVars"].should eq({})
|
|
end
|
|
|
|
it "should properly truncate UTF8 symbols" do
|
|
ArangoDB.log_put("#{@prefix}-properties", @properties, :body => JSON.dump({slowQueryThreshold: 0.1, maxQueryStringLength: 64}))
|
|
ArangoDB.log_post(@queryPrefix, @queryEndpoint, :body => JSON.dump({query: 'FOR x IN 1..1 LET y = SLEEP(0.2) LET a= y LET b= a LET c= "ööööööö" RETURN c'}))
|
|
doc = ArangoDB.log_get("#{@prefix}-slow", @slow)
|
|
doc.code.should eq(200)
|
|
res = JSON.parse doc.body
|
|
res.length.should eq(1)
|
|
# This string is exactly 64 bytes long
|
|
shortened = "FOR x IN 1..1 LET y = SLEEP(0.2) LET a= y LET b= a LET c= \"öö"
|
|
found = contains_query doc.body, shortened + "..."
|
|
found.should_not eq(false)
|
|
found.should have_key("query")
|
|
found["query"].should eq(shortened + "...")
|
|
found["bindVars"].should eq({})
|
|
end
|
|
|
|
it "should be able to kill a running query" do
|
|
send_queries
|
|
sleep 3
|
|
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
|
found = false
|
|
res = JSON.parse doc.body
|
|
id = ""
|
|
res.each do |q|
|
|
if q["query"] === @query
|
|
found = true
|
|
id = q["id"]
|
|
end
|
|
end
|
|
found.should eq(true)
|
|
doc = ArangoDB.log_delete(@prefix, "#{@api}/" + id)
|
|
doc.code.should eq(200)
|
|
sleep 5
|
|
doc = ArangoDB.log_get("#{@prefix}-current", @current)
|
|
found = contains_query doc.body, @query
|
|
found.should eq(false)
|
|
end
|
|
|
|
end
|
|
|
|
end
|