drntest 1.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.
- checksums.yaml +7 -0
- data/Gemfile +27 -0
- data/README.md +37 -0
- data/Rakefile +37 -0
- data/bin/drntest +20 -0
- data/drntest.gemspec +49 -0
- data/lib/drntest/executor.rb +89 -0
- data/lib/drntest/test-results.rb +42 -0
- data/lib/drntest/test-runner.rb +330 -0
- data/lib/drntest/test-suites-result.rb +36 -0
- data/lib/drntest/tester.rb +169 -0
- data/lib/drntest/version.rb +18 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eebd36d8996038d558504ce87c1fede7b37ac353
|
4
|
+
data.tar.gz: fb1a2e73e9115bfc04e8cc0cb105481dd1b78281
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9af6059cf9b7653295834f8005e4e651c4afa0241a49363c9e4461a5fbde00e9eb09e4b4ab7b071b4bef0bd1818048d7853b4627b18cb7bb36f0bf7441acbaa
|
7
|
+
data.tar.gz: ca4211497d4b62055b79259d88004be2f78e834431699f0a6b5dfa9a952aefd5f51b3a41f22b9eb2e98dcb5b5d23a1b560acd2fc9971d2ba6f08467b79b7798a
|
data/Gemfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
source "https://rubygems.org"
|
19
|
+
|
20
|
+
base_dir = File.dirname(__FILE__)
|
21
|
+
local_droonga_client_ruby_dir = File.join(base_dir, "..", "droonga-client-ruby")
|
22
|
+
local_droonga_client_ruby_dir = File.expand_path(local_droonga_client_ruby_dir)
|
23
|
+
if File.exist?(local_droonga_client_ruby_dir)
|
24
|
+
gem "droonga-client", path: local_droonga_client_ruby_dir
|
25
|
+
else
|
26
|
+
gem "droonga-client", github: "droonga/droonga-client-ruby"
|
27
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# README
|
2
|
+
|
3
|
+
## Name
|
4
|
+
|
5
|
+
drntest
|
6
|
+
|
7
|
+
## Description
|
8
|
+
|
9
|
+
Drntest is a testing framework for Droonga. You can write a test for
|
10
|
+
Droonga by writing Droonga commands and expected result.
|
11
|
+
|
12
|
+
## Install
|
13
|
+
|
14
|
+
```
|
15
|
+
% gem install drntest
|
16
|
+
```
|
17
|
+
|
18
|
+
## Basic usage
|
19
|
+
|
20
|
+
TODO
|
21
|
+
|
22
|
+
## Mailing list
|
23
|
+
|
24
|
+
* English: [groonga-talk@lists.sourceforge.net](https://lists.sourceforge.net/lists/listinfo/groonga-talk)
|
25
|
+
* Japanese: [groonga-dev@lists.sourceforge.jp](http://lists.sourceforge.jp/mailman/listinfo/groonga-dev)
|
26
|
+
|
27
|
+
## Thanks
|
28
|
+
|
29
|
+
* ...
|
30
|
+
|
31
|
+
## Copyright
|
32
|
+
|
33
|
+
Copyright (c) 2013 Droonga Project
|
34
|
+
|
35
|
+
## License
|
36
|
+
|
37
|
+
GPLv3 or later. See LICENSE.txt for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
task :default => :test
|
19
|
+
|
20
|
+
require "rubygems"
|
21
|
+
require "bundler/gem_helper"
|
22
|
+
|
23
|
+
base_dir = File.join(File.dirname(__FILE__))
|
24
|
+
|
25
|
+
helper = Bundler::GemHelper.new(base_dir)
|
26
|
+
def helper.version_tag
|
27
|
+
version
|
28
|
+
end
|
29
|
+
|
30
|
+
helper.install
|
31
|
+
spec = helper.gemspec
|
32
|
+
|
33
|
+
desc "Run tests"
|
34
|
+
task :test do
|
35
|
+
# No test
|
36
|
+
# ruby("test/run-test.rb")
|
37
|
+
end
|
data/bin/drntest
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "drntest/tester"
|
19
|
+
|
20
|
+
exit(Drntest::Tester.run)
|
data/drntest.gemspec
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
clean_white_space = lambda do |entry|
|
19
|
+
entry.gsub(/(\A\n+|\n+\z)/, '') + "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
|
23
|
+
require "drntest/version"
|
24
|
+
|
25
|
+
Gem::Specification.new do |spec|
|
26
|
+
spec.name = "drntest"
|
27
|
+
spec.version = Drntest::VERSION
|
28
|
+
spec.homepage = "https://github.com/droonga/drntest"
|
29
|
+
spec.authors = ["Droonga Project"]
|
30
|
+
spec.email = ["droonga@groonga.org"]
|
31
|
+
readme = File.read("README.md")
|
32
|
+
readme.force_encoding("UTF-8")
|
33
|
+
entries = readme.split(/^\#\#\s(.*)$/)
|
34
|
+
description = clean_white_space.call(entries[entries.index("Description") + 1])
|
35
|
+
spec.summary, spec.description, = description.split(/\n\n+/, 3)
|
36
|
+
spec.license = "GPLv3 or later"
|
37
|
+
spec.files = ["README.md", "Rakefile", "Gemfile", "#{spec.name}.gemspec"]
|
38
|
+
spec.files += Dir.glob("lib/**/*.rb")
|
39
|
+
Dir.chdir("bin") do
|
40
|
+
spec.executables = Dir.glob("*")
|
41
|
+
end
|
42
|
+
|
43
|
+
spec.add_runtime_dependency("json")
|
44
|
+
spec.add_runtime_dependency("yajl-ruby")
|
45
|
+
spec.add_runtime_dependency("droonga-client")
|
46
|
+
|
47
|
+
spec.add_development_dependency("bundler")
|
48
|
+
spec.add_development_dependency("rake")
|
49
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require "droonga/client"
|
17
|
+
|
18
|
+
module Drntest
|
19
|
+
class Executor
|
20
|
+
attr_reader :owner, :request
|
21
|
+
|
22
|
+
def initialize(owner, request)
|
23
|
+
@owner = owner
|
24
|
+
@request = request
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute
|
28
|
+
normalize_result(execute_commands)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def execute_commands
|
33
|
+
client = Droonga::Client.new(tag: owner.tag, port: owner.port)
|
34
|
+
client.connection.send(request, :response => :one)
|
35
|
+
end
|
36
|
+
|
37
|
+
def normalize_result(result)
|
38
|
+
return result if result.nil?
|
39
|
+
|
40
|
+
normalized_result = result.dup
|
41
|
+
normalize_envelope!(normalized_result)
|
42
|
+
normalize_body!(normalized_result)
|
43
|
+
normalized_result
|
44
|
+
end
|
45
|
+
|
46
|
+
def normalize_envelope!(normalized_result)
|
47
|
+
normalized_start_time = 0
|
48
|
+
normalized_result[1] = normalized_start_time
|
49
|
+
end
|
50
|
+
|
51
|
+
def normalize_body!(normalized_result)
|
52
|
+
return unless groonga_command?
|
53
|
+
begin
|
54
|
+
normalize_groonga_command_result!(normalized_result[2])
|
55
|
+
rescue StandardError => error
|
56
|
+
p error
|
57
|
+
normalized_result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
GROONGA_COMMANDS = [
|
62
|
+
"table_create",
|
63
|
+
"column_create",
|
64
|
+
"select",
|
65
|
+
]
|
66
|
+
def groonga_command?
|
67
|
+
GROONGA_COMMANDS.include?(request["type"])
|
68
|
+
end
|
69
|
+
|
70
|
+
def normalize_groonga_command_result!(result)
|
71
|
+
normalize_groonga_command_header!(result["body"][0])
|
72
|
+
end
|
73
|
+
|
74
|
+
def normalize_groonga_command_header!(header)
|
75
|
+
normalized_start_time = 0.0
|
76
|
+
normalized_elapsed = 0.0
|
77
|
+
header[1] = normalized_start_time if valid_start_time?(header[1])
|
78
|
+
header[2] = normalized_elapsed if valid_elapsed?(header[2])
|
79
|
+
end
|
80
|
+
|
81
|
+
def valid_start_time?(start_time)
|
82
|
+
start_time.is_a?(Float) and start_time > 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def valid_elapsed?(elapsed)
|
86
|
+
elapsed.is_a?(Float) and elapsed > 0
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module Drntest
|
17
|
+
class TestResults
|
18
|
+
attr_accessor :name, :actuals, :expecteds
|
19
|
+
|
20
|
+
def initialize(name)
|
21
|
+
@name = name
|
22
|
+
@actuals = []
|
23
|
+
@expecteds = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def status
|
27
|
+
unless @actuals.empty?
|
28
|
+
unless @expecteds.empty?
|
29
|
+
if @actuals == @expecteds
|
30
|
+
:success
|
31
|
+
else
|
32
|
+
:failure
|
33
|
+
end
|
34
|
+
else
|
35
|
+
:not_checked
|
36
|
+
end
|
37
|
+
else
|
38
|
+
:no_response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require "json"
|
17
|
+
require "yajl"
|
18
|
+
require "tempfile"
|
19
|
+
require "pp"
|
20
|
+
require "drntest/test-results"
|
21
|
+
require "drntest/executor"
|
22
|
+
require "fileutils"
|
23
|
+
|
24
|
+
module Drntest
|
25
|
+
class TestRunner
|
26
|
+
attr_reader :owner, :base_path, :target_path
|
27
|
+
|
28
|
+
def initialize(owner, target)
|
29
|
+
@owner = owner
|
30
|
+
@base_path = Pathname(owner.base_path)
|
31
|
+
@target_path = Pathname(target)
|
32
|
+
end
|
33
|
+
|
34
|
+
def run
|
35
|
+
print "#{@target_path}: "
|
36
|
+
prepare
|
37
|
+
setup
|
38
|
+
begin
|
39
|
+
results = process_requests
|
40
|
+
ensure
|
41
|
+
teardown
|
42
|
+
end
|
43
|
+
results
|
44
|
+
end
|
45
|
+
|
46
|
+
def config_dir
|
47
|
+
(@base_path + "config") + @owner.config
|
48
|
+
end
|
49
|
+
|
50
|
+
def config_file
|
51
|
+
config_dir + "fluentd.conf"
|
52
|
+
end
|
53
|
+
|
54
|
+
def catalog_file
|
55
|
+
config_dir + "catalog.json"
|
56
|
+
end
|
57
|
+
|
58
|
+
def port
|
59
|
+
@port || @owner.port
|
60
|
+
end
|
61
|
+
|
62
|
+
def host
|
63
|
+
@host || @owner.host
|
64
|
+
end
|
65
|
+
|
66
|
+
def tag
|
67
|
+
@tag || @owner.tag
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def resolve_relative_path(path, base)
|
72
|
+
path = path.to_s
|
73
|
+
path = path[2..-1] if path[0..1] == "./"
|
74
|
+
Pathname(path).expand_path(base)
|
75
|
+
end
|
76
|
+
|
77
|
+
def prepare
|
78
|
+
if catalog_file.exist?
|
79
|
+
catalog_json = JSON.parse(catalog_file.read, :symbolize_names => true)
|
80
|
+
zone = catalog_json[:zones].first
|
81
|
+
/\A([^:]+):(\d+)\/(.+)\z/ =~ zone
|
82
|
+
@host = "localhost" # $1
|
83
|
+
@port = $2.to_i
|
84
|
+
@tag = $3
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def setup
|
89
|
+
return unless temporary_engine?
|
90
|
+
|
91
|
+
FileUtils.rm_rf(temporary_dir)
|
92
|
+
FileUtils.mkdir_p(temporary_dir)
|
93
|
+
|
94
|
+
temporary_config = temporary_dir + "fluentd.conf"
|
95
|
+
FileUtils.cp(config_file, temporary_config)
|
96
|
+
temporary_catalog = temporary_dir + "catalog.json"
|
97
|
+
FileUtils.cp(catalog_file, temporary_catalog)
|
98
|
+
|
99
|
+
engine_command = [
|
100
|
+
@owner.fluentd,
|
101
|
+
"--config", temporary_config.to_s,
|
102
|
+
*@owner.fluentd_options,
|
103
|
+
]
|
104
|
+
engine_env = {
|
105
|
+
"RUBYOPT" => nil,
|
106
|
+
"BUNDLE_GEMFILE" => nil,
|
107
|
+
"DROONGA_CATALOG" => temporary_catalog.to_s,
|
108
|
+
}
|
109
|
+
engine_options = {
|
110
|
+
:chdir => temporary_dir.to_s,
|
111
|
+
STDERR => STDOUT,
|
112
|
+
}
|
113
|
+
arguments = [engine_env, *engine_command]
|
114
|
+
arguments << engine_options
|
115
|
+
@engine_pid = Process.spawn(*arguments)
|
116
|
+
|
117
|
+
wait_until_engine_ready
|
118
|
+
end
|
119
|
+
|
120
|
+
def teardown
|
121
|
+
return unless temporary_engine?
|
122
|
+
|
123
|
+
Process.kill(:TERM, @engine_pid)
|
124
|
+
Process.wait(@engine_pid)
|
125
|
+
|
126
|
+
FileUtils.rm_rf(temporary_dir.to_s)
|
127
|
+
end
|
128
|
+
|
129
|
+
def temporary_dir
|
130
|
+
config_dir + "tmp"
|
131
|
+
end
|
132
|
+
|
133
|
+
def temporary_engine?
|
134
|
+
@owner.fluentd && config_file.exist?
|
135
|
+
end
|
136
|
+
|
137
|
+
def process_requests
|
138
|
+
results = TestResults.new(@target_path)
|
139
|
+
|
140
|
+
logging = true
|
141
|
+
load_request_envelopes.each do |request|
|
142
|
+
if request.is_a?(Directive)
|
143
|
+
case request.type
|
144
|
+
when :enable_logging
|
145
|
+
logging = true
|
146
|
+
when :disable_logging
|
147
|
+
logging = false
|
148
|
+
end
|
149
|
+
next
|
150
|
+
end
|
151
|
+
executor = Executor.new(self, request)
|
152
|
+
response = executor.execute
|
153
|
+
results.actuals << response if logging
|
154
|
+
end
|
155
|
+
if expected_exist?
|
156
|
+
results.expecteds = load_expected_responses
|
157
|
+
end
|
158
|
+
|
159
|
+
case results.status
|
160
|
+
when :success
|
161
|
+
puts "SUCCESS"
|
162
|
+
remove_reject_file
|
163
|
+
when :no_response
|
164
|
+
puts "NO RESPONSE"
|
165
|
+
when :failure
|
166
|
+
puts "FAILURE"
|
167
|
+
output_reject_file(results.actuals)
|
168
|
+
show_diff(results.expecteds, results.actuals)
|
169
|
+
when :not_checked
|
170
|
+
puts "NOT CHECKED"
|
171
|
+
output_actual_file(results.actuals)
|
172
|
+
end
|
173
|
+
|
174
|
+
results
|
175
|
+
end
|
176
|
+
|
177
|
+
def load_request_envelopes
|
178
|
+
load_jsons(@target_path)
|
179
|
+
end
|
180
|
+
|
181
|
+
def load_expected_responses
|
182
|
+
load_jsons(expected_path)
|
183
|
+
end
|
184
|
+
|
185
|
+
class Directive
|
186
|
+
MATCHER = /\A\#\@([^\s]+)(?:\s+(.+))?\z/.freeze
|
187
|
+
|
188
|
+
class << self
|
189
|
+
def directive?(source)
|
190
|
+
MATCHER =~ source.strip
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
attr_reader :type, :value
|
195
|
+
|
196
|
+
def initialize(source)
|
197
|
+
MATCHER =~ source.strip
|
198
|
+
@value = $2
|
199
|
+
@type = $1.gsub("-", "_").to_sym
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def load_jsons(path, options={})
|
204
|
+
parser = Yajl::Parser.new
|
205
|
+
json_objects = []
|
206
|
+
parser.on_parse_complete = Proc.new do |json_object|
|
207
|
+
json_objects << json_object
|
208
|
+
end
|
209
|
+
Pathname(path).read.each_line do |line|
|
210
|
+
if line[0] == "#"
|
211
|
+
if Directive.directive?(line)
|
212
|
+
directive = Directive.new(line)
|
213
|
+
if directive.type == :include
|
214
|
+
included = resolve_relative_path(directive.value,
|
215
|
+
options[:base_path] || @base_path)
|
216
|
+
included_jsons = load_jsons(included)
|
217
|
+
json_objects += included_jsons
|
218
|
+
else
|
219
|
+
json_objects << directive
|
220
|
+
end
|
221
|
+
end
|
222
|
+
else
|
223
|
+
begin
|
224
|
+
parser << line
|
225
|
+
rescue StandardError => error
|
226
|
+
p "Failed to load JSONs file: #{path.to_s}"
|
227
|
+
raise error
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
json_objects
|
232
|
+
end
|
233
|
+
|
234
|
+
def expected_exist?
|
235
|
+
expected_path.exist?
|
236
|
+
end
|
237
|
+
|
238
|
+
def expected_path
|
239
|
+
@target_path.sub_ext(".expected")
|
240
|
+
end
|
241
|
+
|
242
|
+
def reject_path
|
243
|
+
@target_path.sub_ext(".reject")
|
244
|
+
end
|
245
|
+
|
246
|
+
def actual_path
|
247
|
+
@target_path.sub_ext(".actual")
|
248
|
+
end
|
249
|
+
|
250
|
+
def remove_reject_file
|
251
|
+
FileUtils.rm_rf(reject_path, :secure => true)
|
252
|
+
end
|
253
|
+
|
254
|
+
def output_reject_file(results)
|
255
|
+
output_results(results, reject_path)
|
256
|
+
end
|
257
|
+
|
258
|
+
def output_actual_file(results)
|
259
|
+
output_results(results, actual_path)
|
260
|
+
end
|
261
|
+
|
262
|
+
def output_results(results, output_path)
|
263
|
+
puts "Saving received results as #{output_path}"
|
264
|
+
File.open(output_path, "w") do |file|
|
265
|
+
results.each do |result|
|
266
|
+
begin
|
267
|
+
json = JSON.pretty_generate(result)
|
268
|
+
file.puts(json)
|
269
|
+
rescue JSON::GeneratorError => error
|
270
|
+
p error
|
271
|
+
p result
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def show_diff(expecteds, actuals)
|
278
|
+
expected_pretty = expecteds.collect do |expected|
|
279
|
+
begin
|
280
|
+
JSON.pretty_generate(expected)
|
281
|
+
rescue JSON::GeneratorError => error
|
282
|
+
p error
|
283
|
+
p expected
|
284
|
+
end
|
285
|
+
end.join("\n")
|
286
|
+
actual_pretty = actuals.collect do |actual|
|
287
|
+
begin
|
288
|
+
JSON.pretty_generate(actual)
|
289
|
+
rescue JSON::GeneratorError => error
|
290
|
+
p error
|
291
|
+
p actual
|
292
|
+
end
|
293
|
+
end.join("\n")
|
294
|
+
|
295
|
+
create_temporary_file("expected", expected_pretty) do |expected_file|
|
296
|
+
create_temporary_file("actual", actual_pretty) do |actual_file|
|
297
|
+
diff_options = [
|
298
|
+
"-u",
|
299
|
+
"--label", "(expected)", expected_file.path,
|
300
|
+
"--label", "(actual)", actual_file.path
|
301
|
+
]
|
302
|
+
system("diff", *diff_options)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def create_temporary_file(key, content)
|
308
|
+
file = Tempfile.new("drntest-#{key}")
|
309
|
+
file.write(content)
|
310
|
+
file.close
|
311
|
+
yield(file)
|
312
|
+
end
|
313
|
+
|
314
|
+
def engine_ready?
|
315
|
+
begin
|
316
|
+
socket = TCPSocket.new(@host, @port)
|
317
|
+
socket.close
|
318
|
+
true
|
319
|
+
rescue Errno::ECONNREFUSED
|
320
|
+
false
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def wait_until_engine_ready
|
325
|
+
until engine_ready?
|
326
|
+
sleep 1
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module Drntest
|
17
|
+
class TestSuitesResult
|
18
|
+
attr_accessor :test_results
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@test_results = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def summary
|
25
|
+
status_counts = Hash.new(0)
|
26
|
+
test_results.each do |result|
|
27
|
+
status_counts[result.status] += 1
|
28
|
+
end
|
29
|
+
status_counts
|
30
|
+
end
|
31
|
+
|
32
|
+
def success?
|
33
|
+
summary[:failure].zero? && summary[:no_response].zero?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require "shellwords"
|
17
|
+
require "optparse"
|
18
|
+
require "pathname"
|
19
|
+
require "drntest/version"
|
20
|
+
require "drntest/test-runner"
|
21
|
+
require "drntest/test-suites-result"
|
22
|
+
|
23
|
+
module Drntest
|
24
|
+
class Tester
|
25
|
+
class << self
|
26
|
+
def run(argv=nil)
|
27
|
+
argv ||= ARGV.dup
|
28
|
+
tester = new
|
29
|
+
option_parser = create_option_parser(tester)
|
30
|
+
targets = option_parser.parse!(argv)
|
31
|
+
targets << tester.base_path + "suite" if targets.empty?
|
32
|
+
tester.run(*targets)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def create_option_parser(tester)
|
37
|
+
parser = OptionParser.new
|
38
|
+
|
39
|
+
parser.banner += " TEST_FILE..."
|
40
|
+
|
41
|
+
parser.on("--port=PORT",
|
42
|
+
"Connect to fluent-plugin-droonga on PORT",
|
43
|
+
"(#{tester.port})") do |port|
|
44
|
+
tester.port = port
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.on("--host=HOST",
|
48
|
+
"Connect to fluent-plugin-droonga on HOST",
|
49
|
+
"(#{tester.host})") do |host|
|
50
|
+
tester.host = host
|
51
|
+
end
|
52
|
+
|
53
|
+
parser.on("--tag=TAG",
|
54
|
+
"Send messages to fluent-plugin-droonga with TAG",
|
55
|
+
"(#{tester.tag})") do |tag|
|
56
|
+
tester.tag = tag
|
57
|
+
end
|
58
|
+
|
59
|
+
parser.on("--base=PATH",
|
60
|
+
"Path to the base directory including test suite, config and fixture",
|
61
|
+
"(#{tester.base_path})") do |base_path|
|
62
|
+
tester.base_path = Pathname(base_path).expand_path(Dir.pwd)
|
63
|
+
end
|
64
|
+
|
65
|
+
parser.on("--config=NAME",
|
66
|
+
"Name of the configuration directory for Droonga engine",
|
67
|
+
"(#{tester.config})") do |config|
|
68
|
+
tester.config = config
|
69
|
+
end
|
70
|
+
|
71
|
+
parser.on("--fluentd=PATH",
|
72
|
+
"Path to the fluentd executable",
|
73
|
+
"(#{tester.fluentd})") do |fluentd|
|
74
|
+
tester.fluentd = fluentd
|
75
|
+
end
|
76
|
+
|
77
|
+
parser.on("--fluentd-options=OPTIONS",
|
78
|
+
"Options for fluentd",
|
79
|
+
"You can specify this option multiple times") do |options|
|
80
|
+
tester.fluentd_options.concat(Shellwords.split(options))
|
81
|
+
end
|
82
|
+
|
83
|
+
parser.on("--test=PATTERN",
|
84
|
+
"Run only tests which have a name matched to the given PATTERN") do |pattern|
|
85
|
+
if /\A\/(.+)\/\z/ =~ pattern
|
86
|
+
pattern = Regexp.new($1)
|
87
|
+
end
|
88
|
+
tester.test_pattern = pattern
|
89
|
+
end
|
90
|
+
|
91
|
+
parser.on("--test-suite=PATTERN",
|
92
|
+
"Run only test suites which have a path matched to the given PATTERN") do |pattern|
|
93
|
+
if /\A\/(.+)\/\z/ =~ pattern
|
94
|
+
pattern = Regexp.new($1)
|
95
|
+
end
|
96
|
+
tester.suite_pattern = pattern
|
97
|
+
end
|
98
|
+
|
99
|
+
parser
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
attr_accessor :port, :host, :tag, :fluentd, :fluentd_options
|
104
|
+
attr_accessor :test_pattern, :suite_pattern, :base_path, :config
|
105
|
+
|
106
|
+
def initialize
|
107
|
+
@port = 24224
|
108
|
+
@host = "localhost"
|
109
|
+
@tag = "droonga"
|
110
|
+
@base_path = Pathname(Dir.pwd)
|
111
|
+
@config = "default"
|
112
|
+
@fluentd = "fluentd"
|
113
|
+
@fluentd_options = []
|
114
|
+
@test_pattern = nil
|
115
|
+
@suite_pattern = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def run(*targets)
|
119
|
+
test_suites_result = TestSuitesResult.new
|
120
|
+
tests = load_tests(*targets)
|
121
|
+
tests.each do |test|
|
122
|
+
test_runner = TestRunner.new(self, test)
|
123
|
+
test_suites_result.test_results << test_runner.run
|
124
|
+
end
|
125
|
+
|
126
|
+
puts
|
127
|
+
puts "==== Test Results ===="
|
128
|
+
test_suites_result.test_results.each do |result|
|
129
|
+
puts "%s: %s" % [
|
130
|
+
result.name,
|
131
|
+
result.status
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
puts
|
136
|
+
puts "==== Summary ===="
|
137
|
+
p test_suites_result.summary
|
138
|
+
|
139
|
+
test_suites_result.success?
|
140
|
+
end
|
141
|
+
|
142
|
+
def load_tests(*targets)
|
143
|
+
tests = []
|
144
|
+
targets.each do |target|
|
145
|
+
target_path = Pathname(target)
|
146
|
+
next unless target_path.exist?
|
147
|
+
if target_path.directory?
|
148
|
+
tests += Pathname.glob(target_path + "**" + "*.test")
|
149
|
+
else
|
150
|
+
tests << target_path
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
unless @test_pattern.nil?
|
155
|
+
tests.select! do |test|
|
156
|
+
@test_pattern === test.basename(".test").to_s
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
unless @suite_pattern.nil?
|
161
|
+
tests.select! do |test|
|
162
|
+
@suite_pattern === test.dirname.to_s.sub(@base_path.to_s, "")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
tests
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright (C) 2013 Droonga Project
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module Drntest
|
17
|
+
VERSION = "1.0.0"
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: drntest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Droonga Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yajl-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: droonga-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: ''
|
84
|
+
email:
|
85
|
+
- droonga@groonga.org
|
86
|
+
executables:
|
87
|
+
- drntest
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- Gemfile
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- bin/drntest
|
95
|
+
- drntest.gemspec
|
96
|
+
- lib/drntest/executor.rb
|
97
|
+
- lib/drntest/test-results.rb
|
98
|
+
- lib/drntest/test-runner.rb
|
99
|
+
- lib/drntest/test-suites-result.rb
|
100
|
+
- lib/drntest/tester.rb
|
101
|
+
- lib/drntest/version.rb
|
102
|
+
homepage: https://github.com/droonga/drntest
|
103
|
+
licenses:
|
104
|
+
- GPLv3 or later
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.2.0
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Drntest is a testing framework for Droonga. You can write a test for Droonga
|
126
|
+
by writing Droonga commands and expected result.
|
127
|
+
test_files: []
|
128
|
+
has_rdoc:
|