groonga-query-log 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -8
- data/bin/groonga-query-log-run-regression-test +23 -0
- data/doc/text/news.md +9 -0
- data/doc/text/run-regression-test.md +189 -0
- data/lib/groonga/query-log/command/run-regression-test.rb +375 -0
- data/lib/groonga/query-log/response-comparer.rb +25 -9
- data/lib/groonga/query-log/server-verifier.rb +20 -16
- data/lib/groonga/query-log/version.rb +1 -1
- data/test/test-replayer.rb +2 -2
- data/test/test-response-comparer.rb +43 -4
- metadata +81 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7baac32f5f72c344206d735fa04ab18fad813424
|
4
|
+
data.tar.gz: b81cf03d7eac23d3b6701b2539baddb6a794bf2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a945b55c42cb1b483a178fc8e0d5f3ee87392bd16775df48599498d26cfcefcce66e7a7b4eae5ce7ed0ca4f41cb0ecc4ef74fa332fb05dbcba0b6fcc480548b8
|
7
|
+
data.tar.gz: 886297948bbe6b312cd88258498564701cfdf218124d14c68bf8313941b6e01efd7fdab9d4ee53c95e4fe2714a506cee204db0ea01fccaa5829759a300f18175
|
data/README.md
CHANGED
@@ -9,9 +9,9 @@ groonga-query-log
|
|
9
9
|
## Description
|
10
10
|
|
11
11
|
Groonga-query-log is a collection of library and tools to process
|
12
|
-
[
|
12
|
+
[Groonga](http://groonga.org/)'s query log. You can write a program to
|
13
13
|
process query log by using groonga-query-log as a library. You can
|
14
|
-
analyze your
|
14
|
+
analyze your Groonga's queries and test with your Groonga's query log
|
15
15
|
by using groonga-query-log as a tool.
|
16
16
|
|
17
17
|
## Install
|
@@ -20,28 +20,52 @@ by using groonga-query-log as a tool.
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
### groonga-query-log-analyze
|
24
|
+
|
25
|
+
TODO...
|
26
|
+
|
27
|
+
### groonga-query-log-detect-memory-leak
|
28
|
+
|
23
29
|
TODO...
|
24
30
|
|
25
|
-
|
31
|
+
### groonga-query-log-extract
|
26
32
|
|
27
33
|
TODO...
|
28
34
|
|
35
|
+
### groonga-query-log-replay
|
36
|
+
|
37
|
+
TODO...
|
38
|
+
|
39
|
+
### groonga-query-log-run-regression-test
|
40
|
+
|
41
|
+
TODO...
|
42
|
+
|
43
|
+
### groonga-query-log-verify-server
|
44
|
+
|
45
|
+
TODO...
|
46
|
+
|
47
|
+
### groonga-query-log-run-regression-test
|
48
|
+
|
49
|
+
* [doc/text/run-regression-test.md](doc/text/run-regression-test.md)
|
50
|
+
|
29
51
|
## Dependencies
|
30
52
|
|
31
|
-
* Ruby
|
53
|
+
* Ruby
|
54
|
+
* [groonga-command-parser](http://rubygems.org/gems/groonga-command-parser)
|
55
|
+
* [groonga-client](http://rubygems.org/gems/groonga-client)
|
32
56
|
|
33
57
|
## Mailing list
|
34
58
|
|
35
|
-
* English: [groonga-talk@lists.sourceforge.net](https://lists.sourceforge.net/lists/listinfo/groonga-talk)
|
36
|
-
* Japanese: [groonga-dev@lists.sourceforge.jp](http://lists.sourceforge.jp/mailman/listinfo/groonga-dev)
|
59
|
+
* English: [groonga-talk@lists.sourceforge.net](https://lists.sourceforge.net/lists/listinfo/groonga-talk)
|
60
|
+
* Japanese: [groonga-dev@lists.sourceforge.jp](http://lists.sourceforge.jp/mailman/listinfo/groonga-dev)
|
37
61
|
|
38
62
|
## Thanks
|
39
63
|
|
40
|
-
* ...
|
64
|
+
* ...
|
41
65
|
|
42
66
|
## Authors
|
43
67
|
|
44
|
-
* Kouhei Sutou \<kou@clear-code.com\>
|
68
|
+
* Kouhei Sutou \<kou@clear-code.com\>
|
45
69
|
|
46
70
|
## License
|
47
71
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License as published by the Free Software Foundation; either
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
|
20
|
+
require "groonga/query-log/command/run-regression-test"
|
21
|
+
|
22
|
+
command = Groonga::QueryLog::Command::RunRegressionTest.new
|
23
|
+
command.run(*ARGV)
|
data/doc/text/news.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 1.0.5: 2014-05-12
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* groonga-query-log-verify-server: Supported `groonga-client` 0.0.8.
|
8
|
+
* groonga-query-log-verify-server: Supported comparing errors.
|
9
|
+
* groonga-query-log-run-regression-test: Added a command that
|
10
|
+
runs regression test. It is based on groonga-query-log-verify-server.
|
11
|
+
|
3
12
|
## 1.0.4: 2014-02-09
|
4
13
|
|
5
14
|
### Improvements
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# `groonga-query-log-run-regression-test`
|
2
|
+
|
3
|
+
`groonga-query-log-run-regression-test` is a regression test tool for
|
4
|
+
Groonga. It is useful when you upgrade Groonga. You can compare search
|
5
|
+
results by old Groonga and new Groonga by
|
6
|
+
`groonga-query-log-run-regression-test`. Test queries are read from
|
7
|
+
query logs. You can use query logs on production environment as is.
|
8
|
+
|
9
|
+
## Flow
|
10
|
+
|
11
|
+
Here is a work flow to run regression test with
|
12
|
+
`groonga-query-log-run-regression-test`:
|
13
|
+
|
14
|
+
1. Prepare schema.
|
15
|
+
2. Prepare data.
|
16
|
+
3. Prepare query logs.
|
17
|
+
4. Load schema into both old Groonga and new Groonga.
|
18
|
+
5. Load data into both old Groonga and new Groonga.
|
19
|
+
6. Send a request extracted from a query log to both old Groonga and
|
20
|
+
new Groonga.
|
21
|
+
7. Compare responses from old Groonga and new Groonga.
|
22
|
+
8. Repeat 6. and 7. for all request in query logs.
|
23
|
+
|
24
|
+
If there is any regression, you can find it by the 7. step.
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
This section describe how to use
|
29
|
+
`groonga-query-log-run-regression-test`.
|
30
|
+
|
31
|
+
First, you need to prepare input data. Then you can run regression
|
32
|
+
test.
|
33
|
+
|
34
|
+
### Prepare
|
35
|
+
|
36
|
+
This section describes how to prepare to run regression test.
|
37
|
+
|
38
|
+
Create a directory that has the following structure:
|
39
|
+
|
40
|
+
.
|
41
|
+
|-- schema/
|
42
|
+
|-- indexes/
|
43
|
+
|-- data/
|
44
|
+
`-- query-logs/
|
45
|
+
|
46
|
+
The following sections describe how to prepare the directories.
|
47
|
+
|
48
|
+
#### `schema/`
|
49
|
+
|
50
|
+
Put database schema definitions to `schema/` directory. Each file must
|
51
|
+
have `.grn` extension such as `ddl.grn`.
|
52
|
+
|
53
|
+
You can generate a file to be placed into `schema/` from an existing
|
54
|
+
Groonga database by `grndump` command:
|
55
|
+
|
56
|
+
% grndump --no-dump-indexes --no-dump-tables /groonga/db > schema/ddl.grn
|
57
|
+
|
58
|
+
Note that `grndump` command is provided by Rroonga. You can install
|
59
|
+
Rroonga by the following command:
|
60
|
+
|
61
|
+
% gem install rroonga
|
62
|
+
|
63
|
+
#### `indexes/`
|
64
|
+
|
65
|
+
Put index definitions to `indexes/` directory. Each file must have
|
66
|
+
`.grn` extension such as `indexes.grn`.
|
67
|
+
|
68
|
+
You can put index definitions to `schema/` directory. But it is better
|
69
|
+
that put index definitions to `indexes/` directory rather than
|
70
|
+
`schema/` directory. Because it is faster.
|
71
|
+
|
72
|
+
If you use `indexes/` directory, you can use
|
73
|
+
[offline index construction][]. Offline index construction is 10 times
|
74
|
+
faster than [online index construction][].
|
75
|
+
|
76
|
+
You can generate a file to be placed into `indexes/` from an existing
|
77
|
+
Groonga database by `grndump` command:
|
78
|
+
|
79
|
+
% grndump --no-dump-schema --no-dump-tables /groonga/db > indexes/indexes.grn
|
80
|
+
|
81
|
+
#### `data/`
|
82
|
+
|
83
|
+
Put data to `data/` directory. Each file must have `.grn` extension
|
84
|
+
such as `data.grn`.
|
85
|
+
|
86
|
+
You can generate a file to be placed into `data/` from an existing
|
87
|
+
Groonga database by `grndump` command:
|
88
|
+
|
89
|
+
% grndump --no-dump-schema --no-dump-indexes /groonga/db > data/data.grn
|
90
|
+
|
91
|
+
#### `query-logs/`
|
92
|
+
|
93
|
+
Put query logs to `query-logs/` directory. Each file must have `.log`
|
94
|
+
extension such as `query.log`.
|
95
|
+
|
96
|
+
You can put multiple log files like the following:
|
97
|
+
|
98
|
+
query-logs/
|
99
|
+
|-- query-20140506.log
|
100
|
+
|-- query-20140507.log
|
101
|
+
`-- query-20140508.log
|
102
|
+
|
103
|
+
Here are links to documents that describe how to create a query log:
|
104
|
+
|
105
|
+
* Groonga server users: You can create a query log file by using
|
106
|
+
`--query-log-path` option. See [groonga command][] documentation
|
107
|
+
for details.
|
108
|
+
* Groonga HTTPD users: You can create a query log file by using
|
109
|
+
`groonga_query_log_path` directive. See [groonga_query_log_path][] documentation
|
110
|
+
for details.
|
111
|
+
|
112
|
+
### Run
|
113
|
+
|
114
|
+
Now, you can run regression test.
|
115
|
+
|
116
|
+
Let the followings:
|
117
|
+
|
118
|
+
* Use `~/groonga/test` as the working directory to run
|
119
|
+
regression test.
|
120
|
+
* There is the current Groonga database at `/var/lib/groonga/db`.
|
121
|
+
* There are the current query logs at `/var/log/groonga/query-*.log`.
|
122
|
+
* The current Groonga is installed at `/opt/groonga-current/bin/groonga`.
|
123
|
+
* The new Groonga is installed at `/opt/groonga-new/bin/groonga`.
|
124
|
+
|
125
|
+
Install required packages:
|
126
|
+
|
127
|
+
% gem install rroonga groonga-query-log
|
128
|
+
|
129
|
+
Prepare the working directory:
|
130
|
+
|
131
|
+
% mkdir -p ~/groonga/test/{schema,indexes,data,query-logs}
|
132
|
+
% cd ~/groonga/test/
|
133
|
+
|
134
|
+
Extract needed data from the current database:
|
135
|
+
|
136
|
+
% grndump --no-dump-indexes --no-dump-tables /var/lib/groonga/db > schema/ddl.grn
|
137
|
+
% grndump --no-dump-schema --no-dump-tables /var/lib/groonga/db > indexes/indexes.grn
|
138
|
+
% grndump --no-dump-schema --no-dump-indexes /var/lib/groonga/db > data/data.grn
|
139
|
+
% cp /var/log/groonga/query-*.log query-logs/
|
140
|
+
|
141
|
+
Run regression test:
|
142
|
+
|
143
|
+
% groonga-query-log-run-regression-test \
|
144
|
+
--old-groonga=/opt/groonga-current/bin/groonga \
|
145
|
+
--new-groonga=/opt/groonga-new/bin/groonga
|
146
|
+
|
147
|
+
It creates new two databases from input data. One is created by the
|
148
|
+
current Groonga. Another is created by the new Groonga.
|
149
|
+
|
150
|
+
It starts to send requests in a query log to both Groonga servers
|
151
|
+
after databases are created. If responses don't have difference, the
|
152
|
+
request isn't a problem. If responses have any difference, the request
|
153
|
+
may be a problem.
|
154
|
+
|
155
|
+
You can find details about requests that generate different response in test
|
156
|
+
result logs. You can find test result logs under `results/`
|
157
|
+
directory. Test result log file name is the same as input query log
|
158
|
+
file name. If query log file is `query-logs/query-20140508.log`, test
|
159
|
+
result log file is `results/query-20140508.log`.
|
160
|
+
|
161
|
+
## Advanced usage
|
162
|
+
|
163
|
+
There are some advanced usages. This section describes about them.
|
164
|
+
|
165
|
+
### `--n-clients`
|
166
|
+
|
167
|
+
If your machine has free resource, you can speed up a regression test.
|
168
|
+
|
169
|
+
Use `--n-clients` option to send multiple requests concurrently. It
|
170
|
+
will reduce execution time.
|
171
|
+
|
172
|
+
Here is a sample command line to use `--n-clients`:
|
173
|
+
|
174
|
+
% groonga-query-log-run-regression-test \
|
175
|
+
--n-clients=4 \
|
176
|
+
--old-groonga=/opt/groonga-current/bin/groonga \
|
177
|
+
--new-groonga=/opt/groonga-new/bin/groonga
|
178
|
+
|
179
|
+
## Conclusion
|
180
|
+
|
181
|
+
You can run regression test with
|
182
|
+
`groonga-query-log-run-regression-test`. It helps you to upgrade
|
183
|
+
Groonga safely by confirming a new Groonga doesn't have problem with
|
184
|
+
your data.
|
185
|
+
|
186
|
+
[online index construction]: http://groonga.org/docs/reference/indexing.html#online-index-construction
|
187
|
+
[offline index construction]: http://groonga.org/docs/reference/indexing.html#offline-index-construction
|
188
|
+
[groonga command]: http://groonga.org/docs/reference/executables/groonga.html
|
189
|
+
[groonga_query_log_path]: http://groonga.org/docs/reference/executables/groonga-httpd.html#groonga-query-log-path
|
@@ -0,0 +1,375 @@
|
|
1
|
+
# Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 2.1 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library 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 GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
|
+
|
17
|
+
require "rbconfig"
|
18
|
+
require "optparse"
|
19
|
+
require "socket"
|
20
|
+
require "fileutils"
|
21
|
+
require "pathname"
|
22
|
+
require "net/http"
|
23
|
+
|
24
|
+
require "groonga/query-log"
|
25
|
+
require "groonga/query-log/command/verify-server"
|
26
|
+
|
27
|
+
module Groonga
|
28
|
+
module QueryLog
|
29
|
+
module Command
|
30
|
+
class RunRegressionTest
|
31
|
+
def initialize
|
32
|
+
@input_directory = Pathname.new(".")
|
33
|
+
@working_directory = Pathname.new(".")
|
34
|
+
|
35
|
+
@old_groonga = "groonga"
|
36
|
+
@old_database = "db.old/db"
|
37
|
+
|
38
|
+
@new_groonga = "groonga"
|
39
|
+
@new_database = "db.new/db"
|
40
|
+
|
41
|
+
@recreate_database = false
|
42
|
+
@load_data = true
|
43
|
+
@run_queries = true
|
44
|
+
@skip_finished_queries = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(*command_line)
|
48
|
+
option_parser = create_option_parser
|
49
|
+
begin
|
50
|
+
option_parser.parse!(command_line)
|
51
|
+
rescue OptionParser::ParseError => error
|
52
|
+
$stderr.puts(error.message)
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
tester = Tester.new(old_groonga_server,
|
57
|
+
new_groonga_server,
|
58
|
+
tester_options)
|
59
|
+
tester.run
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def create_option_parser
|
64
|
+
parser = OptionParser.new
|
65
|
+
parser.version = VERSION
|
66
|
+
|
67
|
+
parser.separator("")
|
68
|
+
parser.separator("Path:")
|
69
|
+
parser.on("--input-directory=DIRECTORY",
|
70
|
+
"Load schema and data from DIRECTORY.",
|
71
|
+
"(#{@input_directory})") do |directory|
|
72
|
+
@input_directory = Pathname.new(directory)
|
73
|
+
end
|
74
|
+
parser.on("--working-directory=DIRECTORY",
|
75
|
+
"Use DIRECTORY as working directory.",
|
76
|
+
"(#{@working_directory})") do |directory|
|
77
|
+
@working_directory = Pathname.new(directory)
|
78
|
+
end
|
79
|
+
|
80
|
+
parser.separator("")
|
81
|
+
parser.separator("Throughput:")
|
82
|
+
parser.on("--n-clients=N", Integer,
|
83
|
+
"Use N clients concurrently.",
|
84
|
+
"(#{@n_clients})") do |n|
|
85
|
+
@n_clients = n
|
86
|
+
end
|
87
|
+
|
88
|
+
parser.separator("")
|
89
|
+
parser.separator("Old Groonga:")
|
90
|
+
parser.on("--old-groonga=GROONGA",
|
91
|
+
"Old groonga command",
|
92
|
+
"(#{@old_groonga})") do |groonga|
|
93
|
+
@old_groonga = groonga
|
94
|
+
end
|
95
|
+
|
96
|
+
parser.separator("")
|
97
|
+
parser.separator("New Groonga:")
|
98
|
+
parser.on("--new-groonga=GROONGA",
|
99
|
+
"New groonga command",
|
100
|
+
"(#{@new_groonga})") do |groonga|
|
101
|
+
@new_groonga = groonga
|
102
|
+
end
|
103
|
+
|
104
|
+
parser.separator("")
|
105
|
+
parser.separator("Operations:")
|
106
|
+
parser.on("--recreate-database",
|
107
|
+
"Always recreate Groonga database") do
|
108
|
+
@recreate_database = true
|
109
|
+
end
|
110
|
+
parser.on("--no-load-data",
|
111
|
+
"Don't load data. Just loads schema to Groonga database") do
|
112
|
+
@load_data = false
|
113
|
+
end
|
114
|
+
parser.on("--no-run-queries",
|
115
|
+
"Don't run queries. Just creates Groonga database") do
|
116
|
+
@run_queries = false
|
117
|
+
end
|
118
|
+
parser.on("--skip-finished-queries",
|
119
|
+
"Don't run finished query logs.") do
|
120
|
+
@skip_finished_queries = true
|
121
|
+
end
|
122
|
+
|
123
|
+
parser
|
124
|
+
end
|
125
|
+
|
126
|
+
def directory_options
|
127
|
+
{
|
128
|
+
:input_directory => @input_directory,
|
129
|
+
:working_directory => @working_directory,
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def server_options
|
134
|
+
options = {
|
135
|
+
:load_data => @load_data,
|
136
|
+
:run_queries => @run_queries,
|
137
|
+
:recreate_database => @recreate_database,
|
138
|
+
:skip_finished_queries => @skip_finished_queries,
|
139
|
+
}
|
140
|
+
directory_options.merge(options)
|
141
|
+
end
|
142
|
+
|
143
|
+
def tester_options
|
144
|
+
options = {
|
145
|
+
:n_clients => @n_clients,
|
146
|
+
}
|
147
|
+
directory_options.merge(options)
|
148
|
+
end
|
149
|
+
|
150
|
+
def old_groonga_server
|
151
|
+
GroongaServer.new(@old_groonga,
|
152
|
+
@old_database,
|
153
|
+
server_options)
|
154
|
+
end
|
155
|
+
|
156
|
+
def new_groonga_server
|
157
|
+
GroongaServer.new(@new_groonga,
|
158
|
+
@new_database,
|
159
|
+
server_options)
|
160
|
+
end
|
161
|
+
|
162
|
+
class GroongaServer
|
163
|
+
attr_reader :host, :port
|
164
|
+
def initialize(groonga, database_path, options)
|
165
|
+
@input_directory = options[:input_directory] || Pathname.new(".")
|
166
|
+
@working_directory = options[:working_directory] || Pathname.new(".")
|
167
|
+
@groonga = groonga
|
168
|
+
@database_path = @working_directory + database_path
|
169
|
+
@host = "127.0.0.1"
|
170
|
+
@port = find_unused_port
|
171
|
+
@options = options
|
172
|
+
end
|
173
|
+
|
174
|
+
def run
|
175
|
+
ensure_database
|
176
|
+
return unless @options[:run_queries]
|
177
|
+
|
178
|
+
@pid = spawn(@groonga,
|
179
|
+
"--bind-address", @host,
|
180
|
+
"--port", @port.to_s,
|
181
|
+
"--log-path", log_path.to_s,
|
182
|
+
"--query-log-path", query_log_path.to_s,
|
183
|
+
"--protocol", "http",
|
184
|
+
"-s",
|
185
|
+
@database_path.to_s)
|
186
|
+
|
187
|
+
n_retries = 10
|
188
|
+
begin
|
189
|
+
send_command("status")
|
190
|
+
rescue SystemCallError
|
191
|
+
sleep(1)
|
192
|
+
n_retries -= 1
|
193
|
+
raise if n_retries.zero?
|
194
|
+
retry
|
195
|
+
end
|
196
|
+
|
197
|
+
yield
|
198
|
+
end
|
199
|
+
|
200
|
+
def shutdown
|
201
|
+
begin
|
202
|
+
send_command("shutdown")
|
203
|
+
rescue SystemCallError
|
204
|
+
end
|
205
|
+
Process.waitpid(@pid)
|
206
|
+
end
|
207
|
+
|
208
|
+
private
|
209
|
+
def find_unused_port
|
210
|
+
server = TCPServer.new(@host, 0)
|
211
|
+
begin
|
212
|
+
server.addr[1]
|
213
|
+
ensure
|
214
|
+
server.close
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def log_path
|
219
|
+
@database_path.dirname + "groonga.log"
|
220
|
+
end
|
221
|
+
|
222
|
+
def query_log_path
|
223
|
+
@database_path.dirname + "query.log"
|
224
|
+
end
|
225
|
+
|
226
|
+
def ensure_database
|
227
|
+
if @options[:recreate_database]
|
228
|
+
FileUtils.rm_rf(@database_path.dirname.to_s)
|
229
|
+
end
|
230
|
+
|
231
|
+
return if @database_path.exist?
|
232
|
+
FileUtils.mkdir_p(@database_path.dirname.to_s)
|
233
|
+
system(@groonga, "-n", @database_path.to_s, "quit")
|
234
|
+
grn_files.each do |grn_file|
|
235
|
+
command = [@groonga, @database_path.to_s]
|
236
|
+
command_line = "#{command.join(' ')} < #{grn_file}"
|
237
|
+
puts("Running...: #{command_line}")
|
238
|
+
pid = spawn(*command, :in => grn_file.to_s)
|
239
|
+
begin
|
240
|
+
pid, status = Process.waitpid2(pid)
|
241
|
+
rescue Interrupt
|
242
|
+
Process.kill(:TERM, pid)
|
243
|
+
pid, status = Process.waitpid2(pid)
|
244
|
+
end
|
245
|
+
unless status.success?
|
246
|
+
raise "Failed to run: #{command_line}"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def send_command(name)
|
252
|
+
Net::HTTP.start(@host, @port) do |http|
|
253
|
+
response = http.get("/d/#{name}")
|
254
|
+
response.body
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def grn_files
|
259
|
+
files = schema_files
|
260
|
+
files += data_files if @options[:load_data]
|
261
|
+
files += index_files
|
262
|
+
files
|
263
|
+
end
|
264
|
+
|
265
|
+
def schema_files
|
266
|
+
Pathname.glob("#{@input_directory}/schema/**/*.grn").sort
|
267
|
+
end
|
268
|
+
|
269
|
+
def index_files
|
270
|
+
Pathname.glob("#{@input_directory}/indexes/**/*.grn").sort
|
271
|
+
end
|
272
|
+
|
273
|
+
def data_files
|
274
|
+
Pathname.glob("#{@input_directory}/data/**/*.grn").sort
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
class Tester
|
279
|
+
def initialize(old, new, options)
|
280
|
+
@old = old
|
281
|
+
@new = new
|
282
|
+
@input_directory = options[:input_directory] || Pathname.new(".")
|
283
|
+
@working_directory = options[:working_directory] || Pathname.new(".")
|
284
|
+
@n_clients = options[:n_clients] || 1
|
285
|
+
@options = options
|
286
|
+
@n_ready_waits = 2
|
287
|
+
@clone_pids = []
|
288
|
+
end
|
289
|
+
|
290
|
+
def run
|
291
|
+
old_thread = Thread.new do
|
292
|
+
@old.run do
|
293
|
+
run_test
|
294
|
+
end
|
295
|
+
end
|
296
|
+
new_thread = Thread.new do
|
297
|
+
@new.run do
|
298
|
+
run_test
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
old_thread.join
|
303
|
+
new_thread.join
|
304
|
+
end
|
305
|
+
|
306
|
+
private
|
307
|
+
def run_test
|
308
|
+
@n_ready_waits -= 1
|
309
|
+
return unless @n_ready_waits.zero?
|
310
|
+
|
311
|
+
@clone_pids.each do |pid|
|
312
|
+
Process.waitpid(pid)
|
313
|
+
end
|
314
|
+
|
315
|
+
query_log_paths.each do |query_log_path|
|
316
|
+
log_path = test_log_path(query_log_path)
|
317
|
+
if @options[:skip_finished_queries] and log_path.exist?
|
318
|
+
puts("Skip query log: #{query_log_path}")
|
319
|
+
next
|
320
|
+
else
|
321
|
+
puts("Running test against query log...: #{query_log_path}")
|
322
|
+
end
|
323
|
+
pid = fork do
|
324
|
+
verify_server(log_path, query_log_path)
|
325
|
+
exit!
|
326
|
+
end
|
327
|
+
begin
|
328
|
+
Process.waitpid(pid)
|
329
|
+
rescue Interrupt
|
330
|
+
Process.kill(:TERM, pid)
|
331
|
+
Process.waitpid(pid)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
old_thread = Thread.new do
|
336
|
+
@old.shutdown
|
337
|
+
end
|
338
|
+
new_thread = Thread.new do
|
339
|
+
@new.shutdown
|
340
|
+
end
|
341
|
+
old_thread.join
|
342
|
+
new_thread.join
|
343
|
+
|
344
|
+
true
|
345
|
+
end
|
346
|
+
|
347
|
+
def verify_server(test_log_path, query_log_path)
|
348
|
+
command_line = [
|
349
|
+
"--n-clients=#{@n_clients}",
|
350
|
+
"--groonga1-host=#{@old.host}",
|
351
|
+
"--groonga1-port=#{@old.port}",
|
352
|
+
"--groonga1-protocol=http",
|
353
|
+
"--groonga2-host=#{@new.host}",
|
354
|
+
"--groonga2-port=#{@new.port}",
|
355
|
+
"--groonga2-protocol=http",
|
356
|
+
"--target-command-name=select",
|
357
|
+
"--output", test_log_path.to_s,
|
358
|
+
query_log_path.to_s,
|
359
|
+
]
|
360
|
+
verify_serer = VerifyServer.new
|
361
|
+
verify_serer.run(*command_line)
|
362
|
+
end
|
363
|
+
|
364
|
+
def query_log_paths
|
365
|
+
Pathname.glob("#{@input_directory}/query-logs/**/*.log").sort
|
366
|
+
end
|
367
|
+
|
368
|
+
def test_log_path(query_log_path)
|
369
|
+
@working_directory + "results" + query_log_path.basename
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
#
|
3
1
|
# Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
|
4
2
|
#
|
5
3
|
# This library is free software; you can redistribute it and/or
|
@@ -26,23 +24,41 @@ module Groonga
|
|
26
24
|
end
|
27
25
|
|
28
26
|
def same?
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
if error_response?(@response1) or error_response?(@response2)
|
28
|
+
if error_response?(@response1) and error_response?(@response2)
|
29
|
+
same_error_response?
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
32
33
|
else
|
33
|
-
|
34
|
+
case @command.name
|
35
|
+
when "select"
|
36
|
+
same_select_response?
|
37
|
+
else
|
38
|
+
same_response?
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
37
43
|
private
|
44
|
+
def error_response?(response)
|
45
|
+
response.is_a?(Client::Response::Error)
|
46
|
+
end
|
47
|
+
|
48
|
+
def same_error_response?
|
49
|
+
return_code1 = @response1.header[0]
|
50
|
+
return_code2 = @response2.header[0]
|
51
|
+
return_code1 == return_code2
|
52
|
+
end
|
53
|
+
|
38
54
|
def same_response?
|
39
|
-
@response1 == @response2
|
55
|
+
@response1.body == @response2.body
|
40
56
|
end
|
41
57
|
|
42
58
|
def same_select_response?
|
43
59
|
if random_sort?
|
44
|
-
records_result1 = @response1[0] || []
|
45
|
-
records_result2 = @response2[0] || []
|
60
|
+
records_result1 = @response1.body[0] || []
|
61
|
+
records_result2 = @response2.body[0] || []
|
46
62
|
records_result1.size == records_result2.size and
|
47
63
|
records_result1[0..1] == records_result2[0..1]
|
48
64
|
else
|
@@ -60,15 +60,8 @@ module Groonga
|
|
60
60
|
def run_consumers
|
61
61
|
@options.n_clients.times.collect do
|
62
62
|
Thread.new do
|
63
|
-
|
64
|
-
|
65
|
-
break if run_consumer
|
66
|
-
end
|
67
|
-
rescue Groonga::Client::Connection::Error
|
68
|
-
# TODO: add error log mechanism
|
69
|
-
$stderr.puts(Time.now.iso8601)
|
70
|
-
$stderr.puts($!.raw_error.message)
|
71
|
-
$stderr.puts($!.raw_error.backtrace)
|
63
|
+
loop do
|
64
|
+
break if run_consumer
|
72
65
|
end
|
73
66
|
end
|
74
67
|
end
|
@@ -83,12 +76,10 @@ module Groonga
|
|
83
76
|
begin
|
84
77
|
verify_command(groonga1_client, groonga2_client,
|
85
78
|
statistic.command)
|
86
|
-
rescue Groonga::Client::
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
$stderr.puts($!.raw_error.message)
|
91
|
-
$stderr.puts($!.raw_error.backtrace)
|
79
|
+
rescue Groonga::Client::Error
|
80
|
+
log_client_error($!) do
|
81
|
+
$stderr.puts(statistic.command.original_source)
|
82
|
+
end
|
92
83
|
return false
|
93
84
|
end
|
94
85
|
end
|
@@ -116,7 +107,7 @@ module Groonga
|
|
116
107
|
command["cache"] = "no" if @options.disable_cache?
|
117
108
|
response1 = groonga1_client.execute(command)
|
118
109
|
response2 = groonga2_client.execute(command)
|
119
|
-
comparer = ResponseComparer.new(command, response1
|
110
|
+
comparer = ResponseComparer.new(command, response1, response2)
|
120
111
|
unless comparer.same?
|
121
112
|
@different_results.push([command, response1, response2])
|
122
113
|
end
|
@@ -129,6 +120,18 @@ module Groonga
|
|
129
120
|
output.puts("response2: #{response2.body}")
|
130
121
|
end
|
131
122
|
|
123
|
+
def log_client_error(error)
|
124
|
+
$stderr.puts(Time.now.iso8601)
|
125
|
+
yield if block_given?
|
126
|
+
if error.respond_to?(:raw_error)
|
127
|
+
target_error = error.raw_error
|
128
|
+
else
|
129
|
+
target_error = error
|
130
|
+
end
|
131
|
+
$stderr.puts("#{target_error.class}: #{target_error.message}")
|
132
|
+
$stderr.puts(target_error.backtrace)
|
133
|
+
end
|
134
|
+
|
132
135
|
class Options
|
133
136
|
attr_reader :groonga1
|
134
137
|
attr_reader :groonga2
|
@@ -165,6 +168,7 @@ module Groonga
|
|
165
168
|
|
166
169
|
def create_output(&block)
|
167
170
|
if @output_path
|
171
|
+
FileUtils.mkdir_p(File.dirname(@output_path))
|
168
172
|
File.open(@output_path, "w", &block)
|
169
173
|
else
|
170
174
|
yield($stdout)
|
data/test/test-replayer.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
#
|
3
1
|
# Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
|
4
2
|
#
|
5
3
|
# This library is free software; you can redistribute it and/or
|
@@ -19,6 +17,8 @@
|
|
19
17
|
class ResponseComparerTest < Test::Unit::TestCase
|
20
18
|
private
|
21
19
|
def comparer(response1, response2)
|
20
|
+
response1 = normalize_response(response1)
|
21
|
+
response2 = normalize_response(response2)
|
22
22
|
Groonga::QueryLog::ResponseComparer.new(@command, response1, response2)
|
23
23
|
end
|
24
24
|
|
@@ -26,6 +26,24 @@ class ResponseComparerTest < Test::Unit::TestCase
|
|
26
26
|
comparer(response1, response2).same?
|
27
27
|
end
|
28
28
|
|
29
|
+
def response(body)
|
30
|
+
header = [0, 0.0, 0.0]
|
31
|
+
response_class = Groonga::Client::Response.find(@command.name)
|
32
|
+
response_class.new(@command, header, body)
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_response(header)
|
36
|
+
Groonga::Client::Response::Error.new(@command, header, [])
|
37
|
+
end
|
38
|
+
|
39
|
+
def normalize_response(response_or_body)
|
40
|
+
if response_or_body.is_a?(Groonga::Client::Response::Base)
|
41
|
+
response_or_body
|
42
|
+
else
|
43
|
+
response(response_or_body)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
29
47
|
class SelectTest < self
|
30
48
|
def setup
|
31
49
|
@command = Groonga::Command::Select.new("select", {})
|
@@ -63,7 +81,7 @@ class ResponseComparerTest < Test::Unit::TestCase
|
|
63
81
|
private
|
64
82
|
def random_score?(scorer)
|
65
83
|
@command["scorer"] = scorer
|
66
|
-
comparer([], []).send(:random_score?)
|
84
|
+
comparer([[[0]]], [[[0]]]).send(:random_score?)
|
67
85
|
end
|
68
86
|
end
|
69
87
|
end
|
@@ -73,7 +91,7 @@ class ResponseComparerTest < Test::Unit::TestCase
|
|
73
91
|
private
|
74
92
|
def score_sort?(sortby)
|
75
93
|
@command["sortby"] = sortby
|
76
|
-
comparer([], []).send(:score_sort?)
|
94
|
+
comparer([[[0]]], [[[0]]]).send(:score_sort?)
|
77
95
|
end
|
78
96
|
|
79
97
|
class NoScoreTest < self
|
@@ -119,5 +137,26 @@ class ResponseComparerTest < Test::Unit::TestCase
|
|
119
137
|
end
|
120
138
|
end
|
121
139
|
end
|
140
|
+
|
141
|
+
class ErrorTest < self
|
142
|
+
def test_with_location
|
143
|
+
response1_header = [
|
144
|
+
-63,
|
145
|
+
1.0,
|
146
|
+
0.1,
|
147
|
+
"Syntax error! ()",
|
148
|
+
[
|
149
|
+
["yy_syntax_error", "ecmascript.lemon", 24],
|
150
|
+
],
|
151
|
+
]
|
152
|
+
response2_header = JSON.parse(response1_header.to_json)
|
153
|
+
response2_header[4][0][2] += 1
|
154
|
+
assert_not_equal(response1_header, response2_header)
|
155
|
+
|
156
|
+
response1 = error_response(response1_header)
|
157
|
+
response2 = error_response(response2_header)
|
158
|
+
assert_true(same?(response1, response2))
|
159
|
+
end
|
160
|
+
end
|
122
161
|
end
|
123
162
|
end
|
metadata
CHANGED
@@ -1,220 +1,224 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groonga-query-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: groonga-command-parser
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: groonga-client
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: test-unit
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: test-unit-notify
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: test-unit-rr
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: bundler
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: packnga
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: yard
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: redcarpet
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
description: ''
|
154
154
|
email:
|
155
155
|
- kou@clear-code.com
|
156
156
|
executables:
|
157
|
-
- groonga-query-log-
|
158
|
-
- groonga-query-log-verify-server
|
157
|
+
- groonga-query-log-run-regression-test
|
159
158
|
- groonga-query-log-analyze
|
159
|
+
- groonga-query-log-detect-memory-leak
|
160
160
|
- groonga-query-log-replay
|
161
161
|
- groonga-query-log-extract
|
162
|
+
- groonga-query-log-verify-server
|
162
163
|
extensions: []
|
163
164
|
extra_rdoc_files: []
|
164
165
|
files:
|
166
|
+
- ".yardopts"
|
167
|
+
- Gemfile
|
165
168
|
- README.md
|
166
169
|
- Rakefile
|
167
|
-
-
|
170
|
+
- bin/groonga-query-log-analyze
|
171
|
+
- bin/groonga-query-log-detect-memory-leak
|
172
|
+
- bin/groonga-query-log-extract
|
173
|
+
- bin/groonga-query-log-replay
|
174
|
+
- bin/groonga-query-log-run-regression-test
|
175
|
+
- bin/groonga-query-log-verify-server
|
176
|
+
- doc/text/lgpl-2.1.txt
|
177
|
+
- doc/text/news.md
|
178
|
+
- doc/text/run-regression-test.md
|
168
179
|
- groonga-query-log.gemspec
|
169
180
|
- lib/groonga/query-log.rb
|
170
|
-
- lib/groonga/query-log/
|
171
|
-
- lib/groonga/query-log/
|
172
|
-
- lib/groonga/query-log/
|
181
|
+
- lib/groonga/query-log/analyzer.rb
|
182
|
+
- lib/groonga/query-log/analyzer/reporter.rb
|
183
|
+
- lib/groonga/query-log/analyzer/reporter/console.rb
|
184
|
+
- lib/groonga/query-log/analyzer/reporter/html.rb
|
185
|
+
- lib/groonga/query-log/analyzer/reporter/json.rb
|
186
|
+
- lib/groonga/query-log/analyzer/sized-grouped-operations.rb
|
187
|
+
- lib/groonga/query-log/analyzer/sized-statistics.rb
|
188
|
+
- lib/groonga/query-log/analyzer/statistic.rb
|
189
|
+
- lib/groonga/query-log/analyzer/streamer.rb
|
190
|
+
- lib/groonga/query-log/command-line-utils.rb
|
173
191
|
- lib/groonga/query-log/command/detect-memory-leak.rb
|
174
192
|
- lib/groonga/query-log/command/replay.rb
|
193
|
+
- lib/groonga/query-log/command/run-regression-test.rb
|
194
|
+
- lib/groonga/query-log/command/verify-server.rb
|
195
|
+
- lib/groonga/query-log/extractor.rb
|
175
196
|
- lib/groonga/query-log/memory-leak-detector.rb
|
176
197
|
- lib/groonga/query-log/parser.rb
|
177
|
-
- lib/groonga/query-log/
|
198
|
+
- lib/groonga/query-log/replayer.rb
|
178
199
|
- lib/groonga/query-log/response-comparer.rb
|
179
|
-
- lib/groonga/query-log/command-line-utils.rb
|
180
200
|
- lib/groonga/query-log/server-verifier.rb
|
181
|
-
- lib/groonga/query-log/
|
182
|
-
- lib/groonga/query-log/analyzer/statistic.rb
|
183
|
-
- lib/groonga/query-log/analyzer/streamer.rb
|
184
|
-
- lib/groonga/query-log/analyzer/sized-statistics.rb
|
185
|
-
- lib/groonga/query-log/analyzer/sized-grouped-operations.rb
|
186
|
-
- lib/groonga/query-log/analyzer/reporter.rb
|
187
|
-
- lib/groonga/query-log/analyzer/reporter/console.rb
|
188
|
-
- lib/groonga/query-log/analyzer/reporter/json.rb
|
189
|
-
- lib/groonga/query-log/analyzer/reporter/html.rb
|
190
|
-
- doc/text/news.md
|
191
|
-
- doc/text/lgpl-2.1.txt
|
192
|
-
- .yardopts
|
193
|
-
- test/test-replayer.rb
|
201
|
+
- lib/groonga/query-log/version.rb
|
194
202
|
- test/command/test-select.rb
|
195
|
-
- test/test-response-comparer.rb
|
196
|
-
- test/groonga-query-log-test-utils.rb
|
197
|
-
- test/test-extractor.rb
|
198
|
-
- test/run-test.rb
|
199
|
-
- test/fixtures/n_entries.expected
|
200
|
-
- test/fixtures/other-query.log
|
201
203
|
- test/fixtures/multi.expected
|
204
|
+
- test/fixtures/n_entries.expected
|
205
|
+
- test/fixtures/no-report-summary.expected
|
206
|
+
- test/fixtures/order/-elapsed.expected
|
202
207
|
- test/fixtures/order/-start-time.expected
|
203
208
|
- test/fixtures/order/elapsed.expected
|
204
209
|
- test/fixtures/order/start-time.expected
|
205
|
-
- test/fixtures/
|
206
|
-
- test/fixtures/no-report-summary.expected
|
210
|
+
- test/fixtures/other-query.log
|
207
211
|
- test/fixtures/query.log
|
208
|
-
- test/fixtures/reporter/json.expected
|
209
|
-
- test/fixtures/reporter/html.expected
|
210
212
|
- test/fixtures/reporter/console.expected
|
213
|
+
- test/fixtures/reporter/html.expected
|
214
|
+
- test/fixtures/reporter/json.expected
|
215
|
+
- test/groonga-query-log-test-utils.rb
|
216
|
+
- test/run-test.rb
|
211
217
|
- test/test-analyzer.rb
|
218
|
+
- test/test-extractor.rb
|
212
219
|
- test/test-parser.rb
|
213
|
-
-
|
214
|
-
-
|
215
|
-
- bin/groonga-query-log-analyze
|
216
|
-
- bin/groonga-query-log-replay
|
217
|
-
- bin/groonga-query-log-extract
|
220
|
+
- test/test-replayer.rb
|
221
|
+
- test/test-response-comparer.rb
|
218
222
|
homepage: https://github.com/groonga/groonga-query-log
|
219
223
|
licenses:
|
220
224
|
- LGPLv2.1+
|
@@ -225,42 +229,42 @@ require_paths:
|
|
225
229
|
- lib
|
226
230
|
required_ruby_version: !ruby/object:Gem::Requirement
|
227
231
|
requirements:
|
228
|
-
- -
|
232
|
+
- - ">="
|
229
233
|
- !ruby/object:Gem::Version
|
230
234
|
version: '0'
|
231
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
236
|
requirements:
|
233
|
-
- -
|
237
|
+
- - ">="
|
234
238
|
- !ruby/object:Gem::Version
|
235
239
|
version: '0'
|
236
240
|
requirements: []
|
237
241
|
rubyforge_project:
|
238
|
-
rubygems_version: 2.
|
242
|
+
rubygems_version: 2.2.2
|
239
243
|
signing_key:
|
240
244
|
specification_version: 4
|
241
|
-
summary: Groonga-query-log is a collection of library and tools to process [
|
245
|
+
summary: Groonga-query-log is a collection of library and tools to process [Groonga](http://groonga.org/)'s
|
242
246
|
query log. You can write a program to process query log by using groonga-query-log
|
243
|
-
as a library. You can analyze your
|
247
|
+
as a library. You can analyze your Groonga's queries and test with your Groonga's
|
244
248
|
query log by using groonga-query-log as a tool.
|
245
249
|
test_files:
|
246
|
-
- test/test-replayer.rb
|
247
|
-
- test/command/test-select.rb
|
248
|
-
- test/test-response-comparer.rb
|
249
|
-
- test/groonga-query-log-test-utils.rb
|
250
|
-
- test/test-extractor.rb
|
251
250
|
- test/run-test.rb
|
252
|
-
- test/
|
253
|
-
- test/
|
254
|
-
- test/
|
255
|
-
- test/
|
251
|
+
- test/test-extractor.rb
|
252
|
+
- test/command/test-select.rb
|
253
|
+
- test/test-analyzer.rb
|
254
|
+
- test/test-replayer.rb
|
255
|
+
- test/test-parser.rb
|
256
|
+
- test/fixtures/no-report-summary.expected
|
256
257
|
- test/fixtures/order/elapsed.expected
|
258
|
+
- test/fixtures/order/-start-time.expected
|
257
259
|
- test/fixtures/order/start-time.expected
|
258
260
|
- test/fixtures/order/-elapsed.expected
|
259
|
-
- test/fixtures/
|
260
|
-
- test/fixtures/query.log
|
261
|
+
- test/fixtures/n_entries.expected
|
262
|
+
- test/fixtures/other-query.log
|
261
263
|
- test/fixtures/reporter/json.expected
|
262
|
-
- test/fixtures/reporter/html.expected
|
263
264
|
- test/fixtures/reporter/console.expected
|
264
|
-
- test/
|
265
|
-
- test/
|
265
|
+
- test/fixtures/reporter/html.expected
|
266
|
+
- test/fixtures/multi.expected
|
267
|
+
- test/fixtures/query.log
|
268
|
+
- test/groonga-query-log-test-utils.rb
|
269
|
+
- test/test-response-comparer.rb
|
266
270
|
has_rdoc:
|