OLD | NEW |
1 // Copyright 2012, 2013 Canonical Ltd. | 1 // Copyright 2012, 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package state_test | 4 package state_test |
5 | 5 |
6 import ( | 6 import ( |
7 "fmt" | 7 "fmt" |
8 "sort" | 8 "sort" |
9 | 9 |
10 "labix.org/v2/mgo" | 10 "labix.org/v2/mgo" |
11 gc "launchpad.net/gocheck" | 11 gc "launchpad.net/gocheck" |
12 | 12 |
13 "launchpad.net/juju-core/charm" | 13 "launchpad.net/juju-core/charm" |
14 "launchpad.net/juju-core/constraints" | 14 "launchpad.net/juju-core/constraints" |
15 "launchpad.net/juju-core/errors" | 15 "launchpad.net/juju-core/errors" |
16 "launchpad.net/juju-core/state" | 16 "launchpad.net/juju-core/state" |
17 "launchpad.net/juju-core/state/testing" | 17 "launchpad.net/juju-core/state/testing" |
18 » "launchpad.net/juju-core/testing/checkers" | 18 » jc "launchpad.net/juju-core/testing/checkers" |
19 ) | 19 ) |
20 | 20 |
21 type ServiceSuite struct { | 21 type ServiceSuite struct { |
22 ConnSuite | 22 ConnSuite |
23 charm *state.Charm | 23 charm *state.Charm |
24 mysql *state.Service | 24 mysql *state.Service |
25 } | 25 } |
26 | 26 |
27 var _ = gc.Suite(&ServiceSuite{}) | 27 var _ = gc.Suite(&ServiceSuite{}) |
28 | 28 |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 c.Assert(err, gc.IsNil) | 513 c.Assert(err, gc.IsNil) |
514 rels := s.assertServiceRelations(c, s.mysql, "mysql:cluster", "mysql:loa
dbalancer") | 514 rels := s.assertServiceRelations(c, s.mysql, "mysql:cluster", "mysql:loa
dbalancer") |
515 | 515 |
516 // Check state consistency by attempting to destroy the service. | 516 // Check state consistency by attempting to destroy the service. |
517 err = s.mysql.Destroy() | 517 err = s.mysql.Destroy() |
518 c.Assert(err, gc.IsNil) | 518 c.Assert(err, gc.IsNil) |
519 | 519 |
520 // Check the peer relations got destroyed as well. | 520 // Check the peer relations got destroyed as well. |
521 for _, rel := range rels { | 521 for _, rel := range rels { |
522 err = rel.Refresh() | 522 err = rel.Refresh() |
523 » » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 523 » » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 func jujuInfoEp(serviceName string) state.Endpoint { | 527 func jujuInfoEp(serviceName string) state.Endpoint { |
528 return state.Endpoint{ | 528 return state.Endpoint{ |
529 ServiceName: serviceName, | 529 ServiceName: serviceName, |
530 Relation: charm.Relation{ | 530 Relation: charm.Relation{ |
531 Interface: "juju-info", | 531 Interface: "juju-info", |
532 Name: "juju-info", | 532 Name: "juju-info", |
533 Role: charm.RoleProvider, | 533 Role: charm.RoleProvider, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 err = s1.Refresh() | 712 err = s1.Refresh() |
713 c.Assert(err, gc.IsNil) | 713 c.Assert(err, gc.IsNil) |
714 testch, force, err = s1.Charm() | 714 testch, force, err = s1.Charm() |
715 c.Assert(err, gc.IsNil) | 715 c.Assert(err, gc.IsNil) |
716 c.Assert(force, gc.Equals, true) | 716 c.Assert(force, gc.Equals, true) |
717 c.Assert(testch.URL(), gc.DeepEquals, s.charm.URL()) | 717 c.Assert(testch.URL(), gc.DeepEquals, s.charm.URL()) |
718 | 718 |
719 err = s.mysql.Destroy() | 719 err = s.mysql.Destroy() |
720 c.Assert(err, gc.IsNil) | 720 c.Assert(err, gc.IsNil) |
721 err = s.mysql.Refresh() | 721 err = s.mysql.Refresh() |
722 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 722 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
723 } | 723 } |
724 | 724 |
725 func (s *ServiceSuite) TestServiceExposed(c *gc.C) { | 725 func (s *ServiceSuite) TestServiceExposed(c *gc.C) { |
726 // Check that querying for the exposed flag works correctly. | 726 // Check that querying for the exposed flag works correctly. |
727 c.Assert(s.mysql.IsExposed(), gc.Equals, false) | 727 c.Assert(s.mysql.IsExposed(), gc.Equals, false) |
728 | 728 |
729 // Check that setting and clearing the exposed flag works correctly. | 729 // Check that setting and clearing the exposed flag works correctly. |
730 err := s.mysql.SetExposed() | 730 err := s.mysql.SetExposed() |
731 c.Assert(err, gc.IsNil) | 731 c.Assert(err, gc.IsNil) |
732 c.Assert(s.mysql.IsExposed(), gc.Equals, true) | 732 c.Assert(s.mysql.IsExposed(), gc.Equals, true) |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 removeAllUnits(c, s.mysql) | 908 removeAllUnits(c, s.mysql) |
909 _, err = s.mysql.AllUnits() | 909 _, err = s.mysql.AllUnits() |
910 c.Assert(err, gc.IsNil) | 910 c.Assert(err, gc.IsNil) |
911 } | 911 } |
912 | 912 |
913 func (s *ServiceSuite) TestDestroySimple(c *gc.C) { | 913 func (s *ServiceSuite) TestDestroySimple(c *gc.C) { |
914 err := s.mysql.Destroy() | 914 err := s.mysql.Destroy() |
915 c.Assert(err, gc.IsNil) | 915 c.Assert(err, gc.IsNil) |
916 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 916 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
917 err = s.mysql.Refresh() | 917 err = s.mysql.Refresh() |
918 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 918 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
919 } | 919 } |
920 | 920 |
921 func (s *ServiceSuite) TestDestroyStillHasUnits(c *gc.C) { | 921 func (s *ServiceSuite) TestDestroyStillHasUnits(c *gc.C) { |
922 unit, err := s.mysql.AddUnit() | 922 unit, err := s.mysql.AddUnit() |
923 c.Assert(err, gc.IsNil) | 923 c.Assert(err, gc.IsNil) |
924 err = s.mysql.Destroy() | 924 err = s.mysql.Destroy() |
925 c.Assert(err, gc.IsNil) | 925 c.Assert(err, gc.IsNil) |
926 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 926 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
927 | 927 |
928 err = unit.EnsureDead() | 928 err = unit.EnsureDead() |
929 c.Assert(err, gc.IsNil) | 929 c.Assert(err, gc.IsNil) |
930 err = s.mysql.Refresh() | 930 err = s.mysql.Refresh() |
931 c.Assert(err, gc.IsNil) | 931 c.Assert(err, gc.IsNil) |
932 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 932 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
933 | 933 |
934 err = unit.Remove() | 934 err = unit.Remove() |
935 c.Assert(err, gc.IsNil) | 935 c.Assert(err, gc.IsNil) |
936 err = s.mysql.Refresh() | 936 err = s.mysql.Refresh() |
937 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 937 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
938 } | 938 } |
939 | 939 |
940 func (s *ServiceSuite) TestDestroyOnceHadUnits(c *gc.C) { | 940 func (s *ServiceSuite) TestDestroyOnceHadUnits(c *gc.C) { |
941 unit, err := s.mysql.AddUnit() | 941 unit, err := s.mysql.AddUnit() |
942 c.Assert(err, gc.IsNil) | 942 c.Assert(err, gc.IsNil) |
943 err = unit.EnsureDead() | 943 err = unit.EnsureDead() |
944 c.Assert(err, gc.IsNil) | 944 c.Assert(err, gc.IsNil) |
945 err = unit.Remove() | 945 err = unit.Remove() |
946 c.Assert(err, gc.IsNil) | 946 c.Assert(err, gc.IsNil) |
947 | 947 |
948 err = s.mysql.Destroy() | 948 err = s.mysql.Destroy() |
949 c.Assert(err, gc.IsNil) | 949 c.Assert(err, gc.IsNil) |
950 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 950 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
951 err = s.mysql.Refresh() | 951 err = s.mysql.Refresh() |
952 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 952 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
953 } | 953 } |
954 | 954 |
955 func (s *ServiceSuite) TestDestroyStaleNonZeroUnitCount(c *gc.C) { | 955 func (s *ServiceSuite) TestDestroyStaleNonZeroUnitCount(c *gc.C) { |
956 unit, err := s.mysql.AddUnit() | 956 unit, err := s.mysql.AddUnit() |
957 c.Assert(err, gc.IsNil) | 957 c.Assert(err, gc.IsNil) |
958 err = s.mysql.Refresh() | 958 err = s.mysql.Refresh() |
959 c.Assert(err, gc.IsNil) | 959 c.Assert(err, gc.IsNil) |
960 err = unit.EnsureDead() | 960 err = unit.EnsureDead() |
961 c.Assert(err, gc.IsNil) | 961 c.Assert(err, gc.IsNil) |
962 err = unit.Remove() | 962 err = unit.Remove() |
963 c.Assert(err, gc.IsNil) | 963 c.Assert(err, gc.IsNil) |
964 | 964 |
965 err = s.mysql.Destroy() | 965 err = s.mysql.Destroy() |
966 c.Assert(err, gc.IsNil) | 966 c.Assert(err, gc.IsNil) |
967 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 967 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
968 err = s.mysql.Refresh() | 968 err = s.mysql.Refresh() |
969 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 969 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
970 } | 970 } |
971 | 971 |
972 func (s *ServiceSuite) TestDestroyStaleZeroUnitCount(c *gc.C) { | 972 func (s *ServiceSuite) TestDestroyStaleZeroUnitCount(c *gc.C) { |
973 unit, err := s.mysql.AddUnit() | 973 unit, err := s.mysql.AddUnit() |
974 c.Assert(err, gc.IsNil) | 974 c.Assert(err, gc.IsNil) |
975 | 975 |
976 err = s.mysql.Destroy() | 976 err = s.mysql.Destroy() |
977 c.Assert(err, gc.IsNil) | 977 c.Assert(err, gc.IsNil) |
978 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 978 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
979 | 979 |
980 err = s.mysql.Refresh() | 980 err = s.mysql.Refresh() |
981 c.Assert(err, gc.IsNil) | 981 c.Assert(err, gc.IsNil) |
982 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 982 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
983 | 983 |
984 err = unit.EnsureDead() | 984 err = unit.EnsureDead() |
985 c.Assert(err, gc.IsNil) | 985 c.Assert(err, gc.IsNil) |
986 err = s.mysql.Refresh() | 986 err = s.mysql.Refresh() |
987 c.Assert(err, gc.IsNil) | 987 c.Assert(err, gc.IsNil) |
988 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) | 988 c.Assert(s.mysql.Life(), gc.Equals, state.Dying) |
989 | 989 |
990 err = unit.Remove() | 990 err = unit.Remove() |
991 c.Assert(err, gc.IsNil) | 991 c.Assert(err, gc.IsNil) |
992 err = s.mysql.Refresh() | 992 err = s.mysql.Refresh() |
993 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 993 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
994 } | 994 } |
995 | 995 |
996 func (s *ServiceSuite) TestDestroyWithRemovableRelation(c *gc.C) { | 996 func (s *ServiceSuite) TestDestroyWithRemovableRelation(c *gc.C) { |
997 wordpress, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "
wordpress")) | 997 wordpress, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "
wordpress")) |
998 c.Assert(err, gc.IsNil) | 998 c.Assert(err, gc.IsNil) |
999 eps, err := s.State.InferEndpoints([]string{"wordpress", "mysql"}) | 999 eps, err := s.State.InferEndpoints([]string{"wordpress", "mysql"}) |
1000 c.Assert(err, gc.IsNil) | 1000 c.Assert(err, gc.IsNil) |
1001 rel, err := s.State.AddRelation(eps...) | 1001 rel, err := s.State.AddRelation(eps...) |
1002 c.Assert(err, gc.IsNil) | 1002 c.Assert(err, gc.IsNil) |
1003 | 1003 |
1004 // Destroy a service with no units in relation scope; check service and | 1004 // Destroy a service with no units in relation scope; check service and |
1005 // unit removed. | 1005 // unit removed. |
1006 err = wordpress.Destroy() | 1006 err = wordpress.Destroy() |
1007 c.Assert(err, gc.IsNil) | 1007 c.Assert(err, gc.IsNil) |
1008 err = wordpress.Refresh() | 1008 err = wordpress.Refresh() |
1009 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1009 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1010 err = rel.Refresh() | 1010 err = rel.Refresh() |
1011 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1011 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1012 } | 1012 } |
1013 | 1013 |
1014 func (s *ServiceSuite) TestDestroyWithReferencedRelation(c *gc.C) { | 1014 func (s *ServiceSuite) TestDestroyWithReferencedRelation(c *gc.C) { |
1015 s.assertDestroyWithReferencedRelation(c, true) | 1015 s.assertDestroyWithReferencedRelation(c, true) |
1016 } | 1016 } |
1017 | 1017 |
1018 func (s *ServiceSuite) TestDestroyWithreferencedRelationStaleCount(c *gc.C) { | 1018 func (s *ServiceSuite) TestDestroyWithreferencedRelationStaleCount(c *gc.C) { |
1019 s.assertDestroyWithReferencedRelation(c, false) | 1019 s.assertDestroyWithReferencedRelation(c, false) |
1020 } | 1020 } |
1021 | 1021 |
(...skipping 28 matching lines...) Expand all Loading... |
1050 | 1050 |
1051 // Destroy, and check that the first relation becomes Dying... | 1051 // Destroy, and check that the first relation becomes Dying... |
1052 err = s.mysql.Destroy() | 1052 err = s.mysql.Destroy() |
1053 c.Assert(err, gc.IsNil) | 1053 c.Assert(err, gc.IsNil) |
1054 err = rel0.Refresh() | 1054 err = rel0.Refresh() |
1055 c.Assert(err, gc.IsNil) | 1055 c.Assert(err, gc.IsNil) |
1056 c.Assert(rel0.Life(), gc.Equals, state.Dying) | 1056 c.Assert(rel0.Life(), gc.Equals, state.Dying) |
1057 | 1057 |
1058 // ...while the second is removed directly. | 1058 // ...while the second is removed directly. |
1059 err = rel1.Refresh() | 1059 err = rel1.Refresh() |
1060 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1060 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1061 | 1061 |
1062 // Drop the last reference to the first relation; check the relation and | 1062 // Drop the last reference to the first relation; check the relation and |
1063 // the service are are both removed. | 1063 // the service are are both removed. |
1064 err = ru.LeaveScope() | 1064 err = ru.LeaveScope() |
1065 c.Assert(err, gc.IsNil) | 1065 c.Assert(err, gc.IsNil) |
1066 err = s.mysql.Refresh() | 1066 err = s.mysql.Refresh() |
1067 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1067 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1068 err = rel0.Refresh() | 1068 err = rel0.Refresh() |
1069 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1069 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1070 } | 1070 } |
1071 | 1071 |
1072 func (s *ServiceSuite) TestDestroyQueuesUnitCleanup(c *gc.C) { | 1072 func (s *ServiceSuite) TestDestroyQueuesUnitCleanup(c *gc.C) { |
1073 // Add 5 units; block quick-remove of mysql/1 and mysql/3 | 1073 // Add 5 units; block quick-remove of mysql/1 and mysql/3 |
1074 units := make([]*state.Unit, 5) | 1074 units := make([]*state.Unit, 5) |
1075 for i := range units { | 1075 for i := range units { |
1076 unit, err := s.mysql.AddUnit() | 1076 unit, err := s.mysql.AddUnit() |
1077 c.Assert(err, gc.IsNil) | 1077 c.Assert(err, gc.IsNil) |
1078 units[i] = unit | 1078 units[i] = unit |
1079 if i%2 != 0 { | 1079 if i%2 != 0 { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 c.Assert(err, gc.IsNil) | 1114 c.Assert(err, gc.IsNil) |
1115 c.Assert(dirty, gc.Equals, false) | 1115 c.Assert(dirty, gc.Equals, false) |
1116 } | 1116 } |
1117 | 1117 |
1118 func (s *ServiceSuite) TestReadUnitWithChangingState(c *gc.C) { | 1118 func (s *ServiceSuite) TestReadUnitWithChangingState(c *gc.C) { |
1119 // Check that reading a unit after removing the service | 1119 // Check that reading a unit after removing the service |
1120 // fails nicely. | 1120 // fails nicely. |
1121 err := s.mysql.Destroy() | 1121 err := s.mysql.Destroy() |
1122 c.Assert(err, gc.IsNil) | 1122 c.Assert(err, gc.IsNil) |
1123 err = s.mysql.Refresh() | 1123 err = s.mysql.Refresh() |
1124 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1124 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1125 _, err = s.State.Unit("mysql/0") | 1125 _, err = s.State.Unit("mysql/0") |
1126 c.Assert(err, gc.ErrorMatches, `unit "mysql/0" not found`) | 1126 c.Assert(err, gc.ErrorMatches, `unit "mysql/0" not found`) |
1127 } | 1127 } |
1128 | 1128 |
1129 func uint64p(val uint64) *uint64 { | 1129 func uint64p(val uint64) *uint64 { |
1130 return &val | 1130 return &val |
1131 } | 1131 } |
1132 | 1132 |
1133 func (s *ServiceSuite) TestConstraints(c *gc.C) { | 1133 func (s *ServiceSuite) TestConstraints(c *gc.C) { |
1134 // Constraints are initially empty (for now). | 1134 // Constraints are initially empty (for now). |
(...skipping 15 matching lines...) Expand all Loading... |
1150 c.Assert(err, gc.IsNil) | 1150 c.Assert(err, gc.IsNil) |
1151 cons5, err := s.mysql.Constraints() | 1151 cons5, err := s.mysql.Constraints() |
1152 c.Assert(err, gc.IsNil) | 1152 c.Assert(err, gc.IsNil) |
1153 c.Assert(cons5, gc.DeepEquals, cons4) | 1153 c.Assert(cons5, gc.DeepEquals, cons4) |
1154 | 1154 |
1155 // Destroy the existing service; there's no way to directly assert | 1155 // Destroy the existing service; there's no way to directly assert |
1156 // that the constraints are deleted... | 1156 // that the constraints are deleted... |
1157 err = s.mysql.Destroy() | 1157 err = s.mysql.Destroy() |
1158 c.Assert(err, gc.IsNil) | 1158 c.Assert(err, gc.IsNil) |
1159 err = s.mysql.Refresh() | 1159 err = s.mysql.Refresh() |
1160 » c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) | 1160 » c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
1161 | 1161 |
1162 // ...but we can check that old constraints do not affect new services | 1162 // ...but we can check that old constraints do not affect new services |
1163 // with matching names. | 1163 // with matching names. |
1164 ch, _, err := s.mysql.Charm() | 1164 ch, _, err := s.mysql.Charm() |
1165 c.Assert(err, gc.IsNil) | 1165 c.Assert(err, gc.IsNil) |
1166 mysql, err := s.State.AddService(s.mysql.Name(), ch) | 1166 mysql, err := s.State.AddService(s.mysql.Name(), ch) |
1167 c.Assert(err, gc.IsNil) | 1167 c.Assert(err, gc.IsNil) |
1168 cons6, err := mysql.Constraints() | 1168 cons6, err := mysql.Constraints() |
1169 c.Assert(err, gc.IsNil) | 1169 c.Assert(err, gc.IsNil) |
1170 c.Assert(cons6, gc.DeepEquals, cons0) | 1170 c.Assert(cons6, gc.DeepEquals, cons0) |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 func (s *ServiceSuite) TestAnnotationRemovalForService(c *gc.C) { | 1430 func (s *ServiceSuite) TestAnnotationRemovalForService(c *gc.C) { |
1431 annotations := map[string]string{"mykey": "myvalue"} | 1431 annotations := map[string]string{"mykey": "myvalue"} |
1432 err := s.mysql.SetAnnotations(annotations) | 1432 err := s.mysql.SetAnnotations(annotations) |
1433 c.Assert(err, gc.IsNil) | 1433 c.Assert(err, gc.IsNil) |
1434 err = s.mysql.Destroy() | 1434 err = s.mysql.Destroy() |
1435 c.Assert(err, gc.IsNil) | 1435 c.Assert(err, gc.IsNil) |
1436 ann, err := s.mysql.Annotations() | 1436 ann, err := s.mysql.Annotations() |
1437 c.Assert(err, gc.IsNil) | 1437 c.Assert(err, gc.IsNil) |
1438 c.Assert(ann, gc.DeepEquals, make(map[string]string)) | 1438 c.Assert(ann, gc.DeepEquals, make(map[string]string)) |
1439 } | 1439 } |
OLD | NEW |