OLD | NEW |
1 // launchpad.net/juju/go/state | 1 // launchpad.net/juju/go/state |
2 // | 2 // |
3 // Copyright (c) 2011-2012 Canonical Ltd. | 3 // Copyright (c) 2011-2012 Canonical Ltd. |
4 package state | 4 package state |
5 | 5 |
6 import ( | 6 import ( |
7 . "launchpad.net/gocheck" | 7 . "launchpad.net/gocheck" |
8 "launchpad.net/goyaml" | 8 "launchpad.net/goyaml" |
9 "launchpad.net/gozk/zookeeper" | 9 "launchpad.net/gozk/zookeeper" |
10 ) | 10 ) |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 c.Assert(relation.Services[RolePeer], Equals, "s-p") | 469 c.Assert(relation.Services[RolePeer], Equals, "s-p") |
470 } | 470 } |
471 | 471 |
472 func (s *TopologySuite) TestAddRelation(c *C) { | 472 func (s *TopologySuite) TestAddRelation(c *C) { |
473 // Check that adding a relation works and can only be done once and with········ | 473 // Check that adding a relation works and can only be done once and with········ |
474 // valid services. | 474 // valid services. |
475 relation, err := s.t.Relation("r-1") | 475 relation, err := s.t.Relation("r-1") |
476 c.Assert(relation, IsNil) | 476 c.Assert(relation, IsNil) |
477 c.Assert(err, ErrorMatches, `relation "r-1" does not exist`) | 477 c.Assert(err, ErrorMatches, `relation "r-1" does not exist`) |
478 s.t.AddService("s-p", "mysql") | 478 s.t.AddService("s-p", "mysql") |
479 » s.t.AddService("s-c", "wordpress") | 479 » s.t.AddService("s-r", "wordpress") |
480 err = s.t.AddRelation("r-1", &zkRelation{ | 480 err = s.t.AddRelation("r-1", &zkRelation{ |
481 Interface: "ifce", | 481 Interface: "ifce", |
482 Scope: ScopeGlobal, | 482 Scope: ScopeGlobal, |
483 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-c"}, | 483 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
484 }) | 484 }) |
485 c.Assert(err, IsNil) | 485 c.Assert(err, IsNil) |
486 relation, err = s.t.Relation("r-1") | 486 relation, err = s.t.Relation("r-1") |
487 c.Assert(err, IsNil) | 487 c.Assert(err, IsNil) |
488 c.Assert(relation, NotNil) | 488 c.Assert(relation, NotNil) |
489 c.Assert(relation.Services[RoleProvider], Equals, "s-p") | 489 c.Assert(relation.Services[RoleProvider], Equals, "s-p") |
490 » c.Assert(relation.Services[RoleRequirer], Equals, "s-c") | 490 » c.Assert(relation.Services[RoleRequirer], Equals, "s-r") |
491 | 491 |
492 err = s.t.AddRelation("r-2", &zkRelation{ | 492 err = s.t.AddRelation("r-2", &zkRelation{ |
493 Interface: "", | 493 Interface: "", |
494 Scope: ScopeGlobal, | 494 Scope: ScopeGlobal, |
495 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-c"}, | 495 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
496 }) | 496 }) |
497 c.Assert(err, ErrorMatches, `relation interface is empty`) | 497 c.Assert(err, ErrorMatches, `relation interface is empty`) |
498 | 498 |
499 err = s.t.AddRelation("r-2", &zkRelation{ | 499 err = s.t.AddRelation("r-2", &zkRelation{ |
500 Interface: "ifce", | 500 Interface: "ifce", |
501 Scope: ScopeGlobal, | 501 Scope: ScopeGlobal, |
502 Services: map[RelationRole]string{}, | 502 Services: map[RelationRole]string{}, |
503 }) | 503 }) |
504 c.Assert(err, ErrorMatches, `no service defined`) | 504 c.Assert(err, ErrorMatches, `no service defined`) |
505 | 505 |
506 err = s.t.AddRelation("r-2", &zkRelation{ | 506 err = s.t.AddRelation("r-2", &zkRelation{ |
507 Interface: "ifce", | 507 Interface: "ifce", |
508 Scope: ScopeGlobal, | 508 Scope: ScopeGlobal, |
509 Services: map[RelationRole]string{RoleProvider: "s-p"}, | 509 Services: map[RelationRole]string{RoleProvider: "s-p"}, |
510 }) | 510 }) |
511 c.Assert(err, ErrorMatches, `provider or consumer service missing`) | 511 c.Assert(err, ErrorMatches, `provider or consumer service missing`) |
512 | 512 |
513 err = s.t.AddRelation("r-2", &zkRelation{ | 513 err = s.t.AddRelation("r-2", &zkRelation{ |
514 Interface: "ifce", | 514 Interface: "ifce", |
515 Scope: ScopeGlobal, | 515 Scope: ScopeGlobal, |
516 » » Services: map[RelationRole]string{RoleProvider: "s-p", RolePeer
: "s-c"}, | 516 » » Services: map[RelationRole]string{RoleProvider: "s-p", RolePeer
: "s-r"}, |
517 }) | 517 }) |
518 c.Assert(err, ErrorMatches, `mixed peer with provider or consumer servic
e`) | 518 c.Assert(err, ErrorMatches, `mixed peer with provider or consumer servic
e`) |
519 | 519 |
520 err = s.t.AddRelation("r-2", &zkRelation{ | 520 err = s.t.AddRelation("r-2", &zkRelation{ |
521 Interface: "ifce", | 521 Interface: "ifce", |
522 Scope: ScopeGlobal, | 522 Scope: ScopeGlobal, |
523 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-c", RolePeer: "s-c"}, | 523 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r", RolePeer: "s-r"}, |
524 }) | 524 }) |
525 c.Assert(err, ErrorMatches, `too many services defined`) | 525 c.Assert(err, ErrorMatches, `too many services defined`) |
526 | 526 |
527 err = s.t.AddRelation("r-2", &zkRelation{ | 527 err = s.t.AddRelation("r-2", &zkRelation{ |
528 Interface: "ifce", | 528 Interface: "ifce", |
529 Scope: ScopeGlobal, | 529 Scope: ScopeGlobal, |
530 Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "illegal"}, | 530 Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "illegal"}, |
531 }) | 531 }) |
532 c.Assert(err, ErrorMatches, `service with key "illegal" not found`) | 532 c.Assert(err, ErrorMatches, `service with key "illegal" not found`) |
533 | 533 |
534 err = s.t.AddRelation("r-1", &zkRelation{ | 534 err = s.t.AddRelation("r-1", &zkRelation{ |
535 Interface: "ifce", | 535 Interface: "ifce", |
536 Scope: ScopeGlobal, | 536 Scope: ScopeGlobal, |
537 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-c"}, | 537 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
538 }) | 538 }) |
539 c.Assert(err, ErrorMatches, `relation key "r-1" already in use`) | 539 c.Assert(err, ErrorMatches, `relation key "r-1" already in use`) |
540 } | 540 } |
541 | 541 |
542 func (s *TopologySuite) TestRelationKeys(c *C) { | 542 func (s *TopologySuite) TestRelationKeys(c *C) { |
543 // Check that fetching the relation keys works. | 543 // Check that fetching the relation keys works. |
544 keys := s.t.RelationKeys() | 544 keys := s.t.RelationKeys() |
545 c.Assert(keys, DeepEquals, []string{}) | 545 c.Assert(keys, DeepEquals, []string{}) |
546 | 546 |
547 s.t.AddService("s-p", "riak") | 547 s.t.AddService("s-p", "riak") |
548 s.t.AddRelation("r-1", &zkRelation{ | 548 s.t.AddRelation("r-1", &zkRelation{ |
549 Interface: "ifce", | 549 Interface: "ifce", |
550 Scope: ScopeGlobal, | 550 Scope: ScopeGlobal, |
551 Services: map[RelationRole]string{RolePeer: "s-p"}, | 551 Services: map[RelationRole]string{RolePeer: "s-p"}, |
552 }) | 552 }) |
553 keys = s.t.RelationKeys() | 553 keys = s.t.RelationKeys() |
554 c.Assert(keys, DeepEquals, []string{"r-1"}) | 554 c.Assert(keys, DeepEquals, []string{"r-1"}) |
555 | 555 |
556 s.t.AddRelation("r-2", &zkRelation{ | 556 s.t.AddRelation("r-2", &zkRelation{ |
557 Interface: "ifce", | 557 Interface: "ifce", |
558 Scope: ScopeGlobal, | 558 Scope: ScopeGlobal, |
559 Services: map[RelationRole]string{RolePeer: "s-p"}, | 559 Services: map[RelationRole]string{RolePeer: "s-p"}, |
560 }) | 560 }) |
561 keys = s.t.RelationKeys() | 561 keys = s.t.RelationKeys() |
562 c.Assert(keys, DeepEquals, []string{"r-1", "r-2"}) | 562 c.Assert(keys, DeepEquals, []string{"r-1", "r-2"}) |
563 } | 563 } |
564 | 564 |
565 func (s *TopologySuite) TestRemoveRelation(c *C) { | 565 func (s *TopologySuite) TestRemoveRelation(c *C) { |
566 // Check that removing of a relation works. | 566 // Check that removing of a relation works. |
567 » s.t.AddService("s-c", "wordpress") | 567 » s.t.AddService("s-r", "wordpress") |
568 s.t.AddService("s-p", "mysql") | 568 s.t.AddService("s-p", "mysql") |
569 | 569 |
570 err := s.t.AddRelation("r-1", &zkRelation{ | 570 err := s.t.AddRelation("r-1", &zkRelation{ |
571 Interface: "ifce", | 571 Interface: "ifce", |
572 Scope: ScopeGlobal, | 572 Scope: ScopeGlobal, |
573 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-c"}, | 573 » » Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
574 }) | 574 }) |
575 c.Assert(err, IsNil) | 575 c.Assert(err, IsNil) |
576 | 576 |
577 relation, err := s.t.Relation("r-1") | 577 relation, err := s.t.Relation("r-1") |
578 c.Assert(err, IsNil) | 578 c.Assert(err, IsNil) |
579 c.Assert(relation, NotNil) | 579 c.Assert(relation, NotNil) |
580 c.Assert(relation.Services[RoleProvider], Equals, "s-p") | 580 c.Assert(relation.Services[RoleProvider], Equals, "s-p") |
581 » c.Assert(relation.Services[RoleRequirer], Equals, "s-c") | 581 » c.Assert(relation.Services[RoleRequirer], Equals, "s-r") |
582 | 582 |
583 s.t.RemoveRelation("r-1") | 583 s.t.RemoveRelation("r-1") |
584 | 584 |
585 relation, err = s.t.Relation("r-1") | 585 relation, err = s.t.Relation("r-1") |
586 c.Assert(relation, IsNil) | 586 c.Assert(relation, IsNil) |
587 c.Assert(err, ErrorMatches, `relation "r-1" does not exist`) | 587 c.Assert(err, ErrorMatches, `relation "r-1" does not exist`) |
588 } | 588 } |
589 | 589 |
590 func (s *TopologySuite) TestRemoveServiceWithRelations(c *C) { | 590 func (s *TopologySuite) TestRemoveServiceWithRelations(c *C) { |
591 // Check that the removing of a service with | 591 // Check that the removing of a service with |
592 // associated relations leads to an error. | 592 // associated relations leads to an error. |
593 s.t.AddService("s-p", "riak") | 593 s.t.AddService("s-p", "riak") |
594 s.t.AddRelation("r-1", &zkRelation{ | 594 s.t.AddRelation("r-1", &zkRelation{ |
595 Interface: "ifce", | 595 Interface: "ifce", |
596 Scope: ScopeGlobal, | 596 Scope: ScopeGlobal, |
597 Services: map[RelationRole]string{RolePeer: "s-p"}, | 597 Services: map[RelationRole]string{RolePeer: "s-p"}, |
598 }) | 598 }) |
599 | 599 |
600 err := s.t.RemoveService("s-p") | 600 err := s.t.RemoveService("s-p") |
601 c.Assert(err, ErrorMatches, `cannot remove service "s-p" with active rel
ations`) | 601 c.Assert(err, ErrorMatches, `cannot remove service "s-p" with active rel
ations`) |
602 } | 602 } |
603 | 603 |
| 604 func (s *TopologySuite) TestRelationKeyEndpoints(c *C) { |
| 605 mysqlep1 := RelationEndpoint{"mysql", "ifce1", "blog1", RoleProvider, Sc
opeGlobal} |
| 606 blogep1 := RelationEndpoint{"wordpress", "ifce1", "blog1", RoleRequirer,
ScopeGlobal} |
| 607 mysqlep2 := RelationEndpoint{"mysql", "ifce2", "blog2", RoleProvider, Sc
opeGlobal} |
| 608 blogep2 := RelationEndpoint{"wordpress", "ifce2", "blog2", RoleRequirer,
ScopeGlobal} |
| 609 mysqlep3 := RelationEndpoint{"mysql", "ifce3", "blog3", RoleProvider, Sc
opeGlobal} |
| 610 blogep3 := RelationEndpoint{"wordpress", "ifce3", "blog3", RoleRequirer,
ScopeGlobal} |
| 611 s.t.AddService("s-r", "wordpress") |
| 612 s.t.AddService("s-p", "mysql") |
| 613 s.t.AddRelation("r-0", &zkRelation{ |
| 614 Interface: "ifce1", |
| 615 Scope: ScopeGlobal, |
| 616 Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
| 617 }) |
| 618 s.t.AddRelation("r-1", &zkRelation{ |
| 619 Interface: "ifce2", |
| 620 Scope: ScopeGlobal, |
| 621 Services: map[RelationRole]string{RoleProvider: "s-p", RoleRequ
irer: "s-r"}, |
| 622 }) |
| 623 |
| 624 // Valid relations. |
| 625 key, err := s.t.RelationKey(mysqlep1, blogep1) |
| 626 c.Assert(err, IsNil) |
| 627 c.Assert(key, Equals, "r-0") |
| 628 key, err = s.t.RelationKey(blogep1, mysqlep1) |
| 629 c.Assert(err, IsNil) |
| 630 c.Assert(key, Equals, "r-0") |
| 631 key, err = s.t.RelationKey(mysqlep2, blogep2) |
| 632 c.Assert(err, IsNil) |
| 633 c.Assert(key, Equals, "r-1") |
| 634 key, err = s.t.RelationKey(blogep2, mysqlep2) |
| 635 c.Assert(err, IsNil) |
| 636 c.Assert(key, Equals, "r-1") |
| 637 |
| 638 // Endpoints without relation. |
| 639 _, err = s.t.RelationKey(mysqlep3, blogep3) |
| 640 c.Assert(err, ErrorMatches, `state: no relation between "provider:blog3:
mysql:ifce3" and "requirer:blog3:wordpress:ifce3"`) |
| 641 |
| 642 // Mix of endpoints of two relations. |
| 643 _, err = s.t.RelationKey(mysqlep1, blogep2) |
| 644 c.Assert(err, ErrorMatches, `state: no relation between "provider:blog1:
mysql:ifce1" and "requirer:blog2:wordpress:ifce2"`) |
| 645 } |
| 646 |
| 647 func (s *TopologySuite) TestRelationKeyIllegalEndpoints(c *C) { |
| 648 mysqlep1 := RelationEndpoint{"mysql", "ifce", "blog", RoleProvider, Scop
eGlobal} |
| 649 blogep1 := RelationEndpoint{"wordpress", "ifce", "blog", RoleRequirer, S
copeGlobal} |
| 650 mysqlep2 := RelationEndpoint{"illegal-mysql", "ifce", "blog", RoleProvid
er, ScopeGlobal} |
| 651 blogep2 := RelationEndpoint{"illegal-wordpress", "ifce", "blog", RoleReq
uirer, ScopeGlobal} |
| 652 riakep3 := RelationEndpoint{"riak", "ifce", "ring", RolePeer, ScopeGloba
l} |
| 653 s.t.AddService("s-r", "wordpress") |
| 654 s.t.AddService("s-p1", "mysql") |
| 655 s.t.AddService("s-p2", "riak") |
| 656 s.t.AddRelation("r-0", &zkRelation{ |
| 657 Interface: "ifce1", |
| 658 Scope: ScopeGlobal, |
| 659 Services: map[RelationRole]string{RoleProvider: "s-p1", RoleReq
uirer: "s-r"}, |
| 660 }) |
| 661 |
| 662 key, err := s.t.RelationKey(mysqlep1, blogep2) |
| 663 c.Assert(key, Equals, "") |
| 664 c.Assert(err, ErrorMatches, `service with name "illegal-wordpress" not f
ound`) |
| 665 key, err = s.t.RelationKey(mysqlep2, blogep1) |
| 666 c.Assert(key, Equals, "") |
| 667 c.Assert(err, ErrorMatches, `service with name "illegal-mysql" not found
`) |
| 668 key, err = s.t.RelationKey(mysqlep1, riakep3) |
| 669 c.Assert(key, Equals, "") |
| 670 c.Assert(err, ErrorMatches, `state: no relation between "provider:blog:m
ysql:ifce" and "peer:ring:riak:ifce"`) |
| 671 } |
| 672 |
| 673 func (s *TopologySuite) TestPeerRelationKeyEndpoints(c *C) { |
| 674 riakep1 := RelationEndpoint{"riak", "ifce1", "ring", RolePeer, ScopeGlob
al} |
| 675 riakep2 := RelationEndpoint{"riak", "ifce2", "ring", RolePeer, ScopeGlob
al} |
| 676 riakep3 := RelationEndpoint{"riak", "ifce3", "ring", RolePeer, ScopeGlob
al} |
| 677 s.t.AddService("s-p", "riak") |
| 678 s.t.AddRelation("r-0", &zkRelation{ |
| 679 Interface: "ifce1", |
| 680 Scope: ScopeGlobal, |
| 681 Services: map[RelationRole]string{RolePeer: "s-p"}, |
| 682 }) |
| 683 s.t.AddRelation("r-1", &zkRelation{ |
| 684 Interface: "ifce2", |
| 685 Scope: ScopeGlobal, |
| 686 Services: map[RelationRole]string{RolePeer: "s-p"}, |
| 687 }) |
| 688 |
| 689 // Valid relations. |
| 690 key, err := s.t.PeerRelationKey(riakep1) |
| 691 c.Assert(err, IsNil) |
| 692 c.Assert(key, Equals, "r-0") |
| 693 key, err = s.t.PeerRelationKey(riakep2) |
| 694 c.Assert(err, IsNil) |
| 695 c.Assert(key, Equals, "r-1") |
| 696 |
| 697 // Endpoint without relation. |
| 698 key, err = s.t.PeerRelationKey(riakep3) |
| 699 c.Assert(err, ErrorMatches, `state: no peer relation for "peer:ring:riak
:ifce3"`) |
| 700 } |
| 701 |
| 702 func (s *TopologySuite) TestPeerRelationKeyIllegalEndpoints(c *C) { |
| 703 riakep1 := RelationEndpoint{"illegal-riak", "ifce", "ring", RolePeer, Sc
opeGlobal} |
| 704 s.t.AddService("s-p", "riak") |
| 705 s.t.AddRelation("r-0", &zkRelation{ |
| 706 Interface: "ifce", |
| 707 Scope: ScopeGlobal, |
| 708 Services: map[RelationRole]string{RolePeer: "s-p"}, |
| 709 }) |
| 710 |
| 711 key, err := s.t.PeerRelationKey(riakep1) |
| 712 c.Assert(key, Equals, "") |
| 713 c.Assert(err, ErrorMatches, `service with name "illegal-riak" not found`
) |
| 714 } |
| 715 |
604 type ConfigNodeSuite struct { | 716 type ConfigNodeSuite struct { |
605 zkServer *zookeeper.Server | 717 zkServer *zookeeper.Server |
606 zkTestRoot string | 718 zkTestRoot string |
607 zkTestPort int | 719 zkTestPort int |
608 zkAddr string | 720 zkAddr string |
609 zkConn *zookeeper.Conn | 721 zkConn *zookeeper.Conn |
610 path string | 722 path string |
611 } | 723 } |
612 | 724 |
613 var _ = Suite(&ConfigNodeSuite{}) | 725 var _ = Suite(&ConfigNodeSuite{}) |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 out := Quote(in) | 1062 out := Quote(in) |
951 c.Assert(out, Equals, in) | 1063 c.Assert(out, Equals, in) |
952 } | 1064 } |
953 | 1065 |
954 func (s *QuoteSuite) TestQuote(c *C) { | 1066 func (s *QuoteSuite) TestQuote(c *C) { |
955 // Check that invalid chars are translated correctly. | 1067 // Check that invalid chars are translated correctly. |
956 in := "hello_there/how'are~you-today.sir" | 1068 in := "hello_there/how'are~you-today.sir" |
957 out := Quote(in) | 1069 out := Quote(in) |
958 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir") | 1070 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir") |
959 } | 1071 } |
OLD | NEW |