]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - test/test_journal.rb
2a522aa75b9101d4c3dceeeb287a28433ea783f7
[user/henk/code/ruby/rbot.git] / test / test_journal.rb
1 $:.unshift File.join(File.dirname(__FILE__), '../lib')
2
3 require 'test/unit'
4 require 'rbot/ircbot'
5 require 'rbot/journal'
6 require 'rbot/journal/postgres.rb'
7
8 DAY=60*60*24
9
10 class JournalMessageTest < Test::Unit::TestCase
11
12   include Irc::Bot::Journal
13
14   def test_get
15     m = JournalMessage.create('foo', {'bar': 42, 'baz': nil, 'qux': {'quxx': 23}})
16     assert_equal(42, m.get('bar'))
17     assert_raise ArgumentError do
18       m.get('nope')
19     end
20     assert_nil(m.get('nope', nil))
21     assert_nil(m.get('baz'))
22     assert_equal(23, m.get('qux.quxx'))
23   end
24
25 end
26
27 class QueryTest < Test::Unit::TestCase
28
29   include Irc::Bot::Journal
30
31   def test_define
32
33     q = Query.define do
34       id 'foo'
35       id 'bar', 'baz'
36       topic 'log.irc.*'
37       topic 'log.core', 'baz'
38       timestamp from: Time.now, to: Time.now + 60 * 10
39       payload 'action': :privmsg, 'alice': 'bob'
40       payload 'channel': '#rbot'
41       payload 'foo.bar': 'baz'
42     end
43     assert_equal(['foo', 'bar', 'baz'], q.id)
44     assert_equal(['log.irc.*', 'log.core', 'baz'], q.topic)
45     assert_equal([:from, :to], q.timestamp.keys)
46     assert_equal(Time, q.timestamp[:to].class)
47     assert_equal(Time, q.timestamp[:from].class)
48     assert_equal({
49       'action': :privmsg, 'alice': 'bob',
50       'channel': '#rbot',
51       'foo.bar': 'baz'
52     }, q.payload)
53
54   end
55
56   def test_topic_matches
57     q = Query.define do
58       topic 'foo'
59     end
60     assert_true(q.topic_matches?('foo'))
61     assert_false(q.topic_matches?('bar'))
62     assert_false(q.topic_matches?('foo.bar'))
63
64     q = Query.define do
65       topic 'foo.bar'
66     end
67     assert_false(q.topic_matches?('foo'))
68     assert_false(q.topic_matches?('bar'))
69     assert_true(q.topic_matches?('foo.bar'))
70
71     q = Query.define do
72       topic 'foo.*'
73     end
74     assert_false(q.topic_matches?('foo'))
75     assert_false(q.topic_matches?('bar'))
76     assert_true(q.topic_matches?('foo.bar'))
77     assert_true(q.topic_matches?('foo.baz'))
78
79     q = Query.define do
80       topic '*.bar'
81     end
82     assert_false(q.topic_matches?('foo'))
83     assert_false(q.topic_matches?('bar'))
84     assert_true(q.topic_matches?('foo.bar'))
85     assert_true(q.topic_matches?('bar.bar'))
86     assert_false(q.topic_matches?('foo.foo'))
87
88     q = Query.define do
89       topic '*.*'
90     end
91     assert_false(q.topic_matches?('foo'))
92     assert_true(q.topic_matches?('foo.bar'))
93
94     q = Query.define do
95       topic 'foo'
96       topic 'bar'
97       topic 'baz.alice.bob.*.foo'
98     end
99     assert_true(q.topic_matches?('foo'))
100     assert_true(q.topic_matches?('bar'))
101     assert_true(q.topic_matches?('baz.alice.bob.asdf.foo'))
102     assert_false(q.topic_matches?('baz.alice.bob..foo'))
103
104   end
105   def test_matches
106     q = Query.define do
107       #id 'foo', 'bar'
108       topic 'log.irc.*', 'log.core'
109       timestamp from: Time.now - DAY, to: Time.now + DAY
110       payload 'action': 'privmsg', 'foo.bar': 'baz'
111     end
112     assert_true(q.matches? JournalMessage.create('log.irc.raw', {'action' => 'privmsg'}))
113     assert_false(q.matches? JournalMessage.create('baz', {}))
114     assert_true(q.matches? JournalMessage.create('log.core', {foo: {bar: 'baz'}}))
115
116     # tests timestamp from/to:
117     assert_true(q.matches? JournalMessage.new(
118       id: 'foo',
119       topic: 'log.core',
120       timestamp: Time.now,
121       payload: {action: 'privmsg'}))
122     assert_false(q.matches? JournalMessage.new(
123       id: 'foo',
124       topic: 'log.core',
125       timestamp: Time.now - DAY*3,
126       payload: {action: 'privmsg'}))
127     assert_false(q.matches? JournalMessage.new(
128       id: 'foo',
129       topic: 'log.core',
130       timestamp: Time.now + DAY*3,
131       payload: {action: 'privmsg'}))
132   end
133
134 end
135
136 class JournalBrokerTest < Test::Unit::TestCase
137
138   include Irc::Bot::Journal
139
140   def test_publish
141     received = []
142     journal = JournalBroker.new(consumer: Proc.new { |message|
143       received << message
144     })
145
146     # publish some messages:
147     journal.publish 'log.irc',
148       source: 'alice', message: '<3 pg'
149     journal.publish 'log.irc',
150       source: 'bob', message: 'mysql > pg'
151     journal.publish 'log.irc',
152       source: 'alice', target: 'bob', action: :kick
153
154     # wait for messages to be consumed:
155     sleep 0.1
156     assert_equal(3, received.length)
157   end
158
159   def test_subscribe
160     received = []
161     journal = JournalBroker.new
162
163     # subscribe to messages:
164     sub = journal.subscribe(Query.define { topic 'foo' }) do |message|
165       received << message
166     end
167
168     # publish some messages:
169     journal.publish 'foo', {}
170     journal.publish 'bar', {}
171     journal.publish 'foo', {}
172
173     # wait for messages to be consumed:
174     sleep 0.1
175     assert_equal(2, received.length)
176
177     received.clear
178
179     journal.publish 'foo', {}
180     sleep 0.1
181     sub.cancel
182     journal.publish 'foo', {}
183     sleep 0.1
184     assert_equal(1, received.length)
185   end
186
187 end
188
189 class JournalStoragePostgresTest < Test::Unit::TestCase
190
191   include Irc::Bot::Journal
192
193   def setup
194     @storage = Storage::PostgresStorage.new(
195       uri: ENV['DB_URI'] || 'postgresql://localhost/rbot_journal',
196       drop: true)
197   end
198
199   def teardown
200     @storage.drop
201   end
202
203   def test_query_to_sql
204     q = Query.define do
205       id 'foo'
206       id 'bar', 'baz'
207       topic 'log.irc.*'
208       topic 'log.core', 'baz'
209       timestamp from: Time.now, to: Time.now + 60 * 10
210       payload 'action': :privmsg, 'alice': 'bob'
211       payload 'channel': '#rbot'
212       payload 'foo.bar': 'baz'
213     end
214     sql = @storage.query_to_sql(q)
215     assert_equal("(id = $1 OR id = $2 OR id = $3) AND (topic ILIKE $4 OR topic ILIKE $5 OR topic ILIKE $6) AND (timestamp >= $7 AND timestamp <= $8) AND (payload->>'action' = $9 OR payload->>'alice' = $10 OR payload->>'channel' = $11 OR payload->'foo'->>'bar' = $12)", sql[0])
216     q = Query.define do
217       id 'foo'
218     end
219     assert_equal('(id = $1)', @storage.query_to_sql(q)[0])
220     q = Query.define do
221       topic 'foo.*.bar'
222     end
223     assert_equal('(topic ILIKE $1)', @storage.query_to_sql(q)[0])
224     assert_equal(['foo.%.bar'], @storage.query_to_sql(q)[1])
225   end
226
227   def test_insert
228     # the test message to persist
229     m = JournalMessage.create('log.core', {foo: {bar: 'baz'}})
230     # insert the test message:
231     @storage.insert(m)
232
233     # find the test message by query:
234     q = Query.define do
235       topic 'log.core'
236     end
237     res = @storage.find(q)
238     _m = res.first
239     assert_equal(m, _m) # this only checks id
240     assert_equal(m.timestamp.strftime('%Y-%m-%d %H:%M:%S%z'),
241                  _m.timestamp.strftime('%Y-%m-%d %H:%M:%S%z'))
242     assert_equal('log.core', _m.topic)
243     assert_equal({'foo' => {'bar' => 'baz'}}, _m.payload)
244     assert_equal(1, @storage.count(q))
245   end
246
247   def test_query_range
248     timestamp = Time.now - DAY*7
249     m = JournalMessage.create('log.core', {foo: {bar: 'baz'}},
250                               timestamp: timestamp)
251     assert_equal(timestamp, m.timestamp)
252
253     @storage.insert(m)
254     @storage.insert(JournalMessage.create('a.foo', {}))
255     @storage.insert(JournalMessage.create('b.bar', {}))
256     @storage.insert(JournalMessage.create('b.baz', {}))
257
258     r = @storage.find(Query.define { timestamp(from: timestamp-DAY, to: timestamp+DAY) })
259
260     assert_equal(1, r.length)
261     assert_equal(m, r.first)
262
263   end
264
265 end
266