Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(598)

Side by Side Diff: state/megawatcher_internal_test.go

Issue 7727045: state: add allWatcher.handle method
Patch Set: state: add allWatcher.handle method Created 11 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « state/megawatcher.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package state 1 package state
2 2
3 import ( 3 import (
4 "container/list" 4 "container/list"
5 "errors" 5 "errors"
6 "fmt" 6 "fmt"
7 "labix.org/v2/mgo" 7 "labix.org/v2/mgo"
8 . "launchpad.net/gocheck" 8 . "launchpad.net/gocheck"
9 "launchpad.net/juju-core/state/api/params" 9 "launchpad.net/juju-core/state/api/params"
10 "launchpad.net/juju-core/testing" 10 "launchpad.net/juju-core/testing"
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 aw := newAllWatcher(b) 290 aw := newAllWatcher(b)
291 for _, info := range test.add { 291 for _, info := range test.add {
292 allInfoAdd(aw.all, info) 292 allInfoAdd(aw.all, info)
293 } 293 }
294 err := aw.changed(test.change) 294 err := aw.changed(test.change)
295 c.Assert(err, IsNil) 295 c.Assert(err, IsNil)
296 assertAllInfoContents(c, aw.all, test.expectRevno, test.expectCo ntents) 296 assertAllInfoContents(c, aw.all, test.expectRevno, test.expectCo ntents)
297 } 297 }
298 } 298 }
299 299
300 func (*allWatcherSuite) TestHandle(c *C) {
301 aw := newAllWatcher(&allWatcherTestBacking{})
302
303 // Add request from first watcher.
304 w0 := &StateWatcher{}
305 req0 := &allRequest{
306 w: w0,
307 reply: make(chan bool, 1),
308 }
309 aw.handle(req0)
310 assertWaitingRequests(c, aw, map[*StateWatcher][]*allRequest{
311 w0: {req0},
312 })
313
314 // Add second request from first watcher.
315 req1 := &allRequest{
316 w: w0,
317 reply: make(chan bool, 1),
318 }
319 aw.handle(req1)
320 assertWaitingRequests(c, aw, map[*StateWatcher][]*allRequest{
321 w0: {req1, req0},
322 })
323
324 // Add request from second watcher.
325 w1 := &StateWatcher{}
326 req2 := &allRequest{
327 w: w1,
328 reply: make(chan bool, 1),
329 }
330 aw.handle(req2)
331 assertWaitingRequests(c, aw, map[*StateWatcher][]*allRequest{
332 w0: {req1, req0},
333 w1: {req2},
334 })
335
336 // Stop first watcher.
337 aw.handle(&allRequest{
338 w: w0,
339 })
340 assertWaitingRequests(c, aw, map[*StateWatcher][]*allRequest{
341 w1: {req2},
342 })
343 assertReplied(c, false, req0)
344 assertReplied(c, false, req1)
345
346 // Stop second watcher.
347 aw.handle(&allRequest{
348 w: w1,
349 })
350 assertWaitingRequests(c, aw, nil)
351 assertReplied(c, false, req2)
352 }
353
354 func assertNotReplied(c *C, req *allRequest) {
355 select {
356 case v := <-req.reply:
357 c.Fatalf("request was unexpectedly replied to (got %v)", v)
358 default:
359 }
360 }
361
362 func assertReplied(c *C, val bool, req *allRequest) {
363 select {
364 case v := <-req.reply:
365 c.Assert(v, Equals, val)
366 default:
367 c.Fatalf("request was not replied to")
368 }
369 }
370
371 func assertWaitingRequests(c *C, aw *allWatcher, waiting map[*StateWatcher][]*al lRequest) {
372 c.Assert(aw.waiting, HasLen, len(waiting))
373 for w, reqs := range waiting {
374 i := 0
375 for req := aw.waiting[w]; ; req = req.next {
376 if i >= len(reqs) {
377 c.Assert(req, IsNil)
378 break
379 }
380 c.Assert(req, Equals, reqs[i])
381 assertNotReplied(c, req)
382 i++
383 }
384 }
385 }
386
300 type entityMap map[entityId]params.EntityInfo 387 type entityMap map[entityId]params.EntityInfo
301 388
302 func (em entityMap) add(infos []params.EntityInfo) entityMap { 389 func (em entityMap) add(infos []params.EntityInfo) entityMap {
303 for _, info := range infos { 390 for _, info := range infos {
304 em[entityIdForInfo(info)] = info 391 em[entityIdForInfo(info)] = info
305 } 392 }
306 return em 393 return em
307 } 394 }
308 395
309 func fetchFromMap(em entityMap) func(entityId) (params.EntityInfo, error) { 396 func fetchFromMap(em entityMap) func(entityId) (params.EntityInfo, error) {
310 return func(id entityId) (params.EntityInfo, error) { 397 return func(id entityId) (params.EntityInfo, error) {
311 if info, ok := em[id]; ok { 398 if info, ok := em[id]; ok {
312 return info, nil 399 return info, nil
313 } 400 }
314 return nil, mgo.ErrNotFound 401 return nil, mgo.ErrNotFound
315 } 402 }
316 } 403 }
317 404
318 type allWatcherTestBacking struct { 405 type allWatcherTestBacking struct {
319 fetchFunc func(id entityId) (params.EntityInfo, error) 406 fetchFunc func(id entityId) (params.EntityInfo, error)
320 } 407 }
321 408
322 func (b *allWatcherTestBacking) fetch(id entityId) (params.EntityInfo, error) { 409 func (b *allWatcherTestBacking) fetch(id entityId) (params.EntityInfo, error) {
323 return b.fetchFunc(id) 410 return b.fetchFunc(id)
324 } 411 }
412
413 func (b *allWatcherTestBacking) entityIdForInfo(info params.EntityInfo) entityId {
414 return entityIdForInfo(info)
415 }
OLDNEW
« no previous file with comments | « state/megawatcher.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b