groonga-query-log 1.0.4 → 1.0.5
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 +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:
|