github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/worker/uniter/runner/flush_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package runner_test 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/network" 15 ) 16 17 type FlushContextSuite struct { 18 HookContextSuite 19 } 20 21 var _ = gc.Suite(&FlushContextSuite{}) 22 23 func (s *FlushContextSuite) TestRunHookRelationFlushingError(c *gc.C) { 24 uuid, err := utils.NewUUID() 25 c.Assert(err, jc.ErrorIsNil) 26 ctx := s.getHookContext(c, uuid.String(), -1, "", noProxies) 27 28 // Mess with multiple relation settings. 29 relCtx0, ok := ctx.Relation(0) 30 c.Assert(ok, jc.IsTrue) 31 node0, err := relCtx0.Settings() 32 c.Assert(err, jc.ErrorIsNil) 33 node0.Set("foo", "1") 34 relCtx1, ok := ctx.Relation(1) 35 c.Assert(ok, jc.IsTrue) 36 node1, err := relCtx1.Settings() 37 c.Assert(err, jc.ErrorIsNil) 38 node1.Set("bar", "2") 39 40 // Flush the context with a failure. 41 err = ctx.FlushContext("some badge", errors.New("blam pow")) 42 c.Assert(err, gc.ErrorMatches, "blam pow") 43 44 // Check that the changes have not been written to state. 45 settings0, err := s.relunits[0].ReadSettings("u/0") 46 c.Assert(err, jc.ErrorIsNil) 47 c.Assert(settings0, gc.DeepEquals, map[string]interface{}{"relation-name": "db0"}) 48 settings1, err := s.relunits[1].ReadSettings("u/0") 49 c.Assert(err, jc.ErrorIsNil) 50 c.Assert(settings1, gc.DeepEquals, map[string]interface{}{"relation-name": "db1"}) 51 } 52 53 func (s *FlushContextSuite) TestRunHookRelationFlushingSuccess(c *gc.C) { 54 // Create a charm with a working hook, and mess with settings again. 55 uuid, err := utils.NewUUID() 56 c.Assert(err, jc.ErrorIsNil) 57 ctx := s.getHookContext(c, uuid.String(), -1, "", noProxies) 58 59 // Mess with multiple relation settings. 60 relCtx0, ok := ctx.Relation(0) 61 c.Assert(ok, jc.IsTrue) 62 node0, err := relCtx0.Settings() 63 c.Assert(err, jc.ErrorIsNil) 64 node0.Set("baz", "3") 65 relCtx1, ok := ctx.Relation(1) 66 c.Assert(ok, jc.IsTrue) 67 node1, err := relCtx1.Settings() 68 c.Assert(err, jc.ErrorIsNil) 69 node1.Set("qux", "4") 70 71 // Flush the context with a success. 72 err = ctx.FlushContext("some badge", nil) 73 c.Assert(err, jc.ErrorIsNil) 74 75 // Check that the changes have been written to state. 76 settings0, err := s.relunits[0].ReadSettings("u/0") 77 c.Assert(err, jc.ErrorIsNil) 78 c.Assert(settings0, gc.DeepEquals, map[string]interface{}{ 79 "relation-name": "db0", 80 "baz": "3", 81 }) 82 settings1, err := s.relunits[1].ReadSettings("u/0") 83 c.Assert(err, jc.ErrorIsNil) 84 c.Assert(settings1, gc.DeepEquals, map[string]interface{}{ 85 "relation-name": "db1", 86 "qux": "4", 87 }) 88 } 89 90 func (s *FlushContextSuite) TestRunHookMetricSendingSuccess(c *gc.C) { 91 uuid, err := utils.NewUUID() 92 c.Assert(err, jc.ErrorIsNil) 93 ctx := s.getMeteredHookContext(c, uuid.String(), -1, "", noProxies, true, s.metricsDefinition("pings")) 94 95 now := time.Now() 96 err = ctx.AddMetric("pings", "50", now) 97 c.Assert(err, jc.ErrorIsNil) 98 99 // Flush the context with a success. 100 err = ctx.FlushContext("some badge", nil) 101 c.Assert(err, jc.ErrorIsNil) 102 103 metricBatches, err := s.State.MetricBatches() 104 c.Assert(err, jc.ErrorIsNil) 105 c.Assert(metricBatches, gc.HasLen, 1) 106 metrics := metricBatches[0].Metrics() 107 c.Assert(metrics, gc.HasLen, 1) 108 c.Assert(metrics[0].Key, gc.Equals, "pings") 109 c.Assert(metrics[0].Value, gc.Equals, "50") 110 } 111 112 func (s *FlushContextSuite) TestRunHookNoMetricSendingOnFailure(c *gc.C) { 113 uuid, err := utils.NewUUID() 114 c.Assert(err, jc.ErrorIsNil) 115 ctx := s.getMeteredHookContext(c, uuid.String(), -1, "", noProxies, true, s.metricsDefinition("key")) 116 117 now := time.Now() 118 ctx.AddMetric("key", "50", now) 119 120 // Flush the context with a success. 121 err = ctx.FlushContext("some badge", errors.New("boom squelch")) 122 c.Assert(err, gc.ErrorMatches, "boom squelch") 123 124 metricBatches, err := s.State.MetricBatches() 125 c.Assert(err, jc.ErrorIsNil) 126 c.Assert(metricBatches, gc.HasLen, 0) 127 } 128 129 func (s *FlushContextSuite) TestRunHookMetricSendingDisabled(c *gc.C) { 130 uuid, err := utils.NewUUID() 131 c.Assert(err, jc.ErrorIsNil) 132 ctx := s.getMeteredHookContext(c, uuid.String(), -1, "", noProxies, false, s.metricsDefinition("key")) 133 134 now := time.Now() 135 err = ctx.AddMetric("key", "50", now) 136 c.Assert(err, gc.ErrorMatches, "metrics disabled") 137 138 // Flush the context with a success. 139 err = ctx.FlushContext("some badge", nil) 140 c.Assert(err, jc.ErrorIsNil) 141 142 metricBatches, err := s.State.MetricBatches() 143 c.Assert(err, jc.ErrorIsNil) 144 c.Assert(metricBatches, gc.HasLen, 0) 145 } 146 147 func (s *FlushContextSuite) TestRunHookMetricSendingUndeclared(c *gc.C) { 148 uuid, err := utils.NewUUID() 149 c.Assert(err, jc.ErrorIsNil) 150 ctx := s.getMeteredHookContext(c, uuid.String(), -1, "", noProxies, true, nil) 151 152 now := time.Now() 153 err = ctx.AddMetric("key", "50", now) 154 c.Assert(err, gc.ErrorMatches, "metrics disabled") 155 156 // Flush the context with a success. 157 err = ctx.FlushContext("some badge", nil) 158 c.Assert(err, jc.ErrorIsNil) 159 160 metricBatches, err := s.State.MetricBatches() 161 c.Assert(err, jc.ErrorIsNil) 162 c.Assert(metricBatches, gc.HasLen, 0) 163 } 164 165 func (s *FlushContextSuite) TestRunHookOpensAndClosesPendingPorts(c *gc.C) { 166 // Initially, no port ranges are open on the unit or its machine. 167 unitRanges, err := s.unit.OpenedPorts() 168 c.Assert(err, jc.ErrorIsNil) 169 c.Assert(unitRanges, gc.HasLen, 0) 170 machinePorts, err := s.machine.AllPorts() 171 c.Assert(err, jc.ErrorIsNil) 172 c.Assert(machinePorts, gc.HasLen, 0) 173 174 // Add another unit on the same machine. 175 otherUnit, err := s.service.AddUnit() 176 c.Assert(err, jc.ErrorIsNil) 177 err = otherUnit.AssignToMachine(s.machine) 178 c.Assert(err, jc.ErrorIsNil) 179 180 // Open some ports on both units. 181 err = s.unit.OpenPorts("tcp", 100, 200) 182 c.Assert(err, jc.ErrorIsNil) 183 err = otherUnit.OpenPorts("udp", 200, 300) 184 c.Assert(err, jc.ErrorIsNil) 185 186 unitRanges, err = s.unit.OpenedPorts() 187 c.Assert(err, jc.ErrorIsNil) 188 c.Assert(unitRanges, jc.DeepEquals, []network.PortRange{ 189 {100, 200, "tcp"}, 190 }) 191 192 // Get the context. 193 uuid, err := utils.NewUUID() 194 c.Assert(err, jc.ErrorIsNil) 195 ctx := s.getHookContext(c, uuid.String(), -1, "", noProxies) 196 197 // Try opening some ports via the context. 198 err = ctx.OpenPorts("tcp", 100, 200) 199 c.Assert(err, jc.ErrorIsNil) // duplicates are ignored 200 err = ctx.OpenPorts("udp", 200, 300) 201 c.Assert(err, gc.ErrorMatches, `cannot open 200-300/udp \(unit "u/0"\): conflicts with existing 200-300/udp \(unit "u/1"\)`) 202 err = ctx.OpenPorts("udp", 100, 200) 203 c.Assert(err, gc.ErrorMatches, `cannot open 100-200/udp \(unit "u/0"\): conflicts with existing 200-300/udp \(unit "u/1"\)`) 204 err = ctx.OpenPorts("udp", 10, 20) 205 c.Assert(err, jc.ErrorIsNil) 206 err = ctx.OpenPorts("tcp", 50, 100) 207 c.Assert(err, gc.ErrorMatches, `cannot open 50-100/tcp \(unit "u/0"\): conflicts with existing 100-200/tcp \(unit "u/0"\)`) 208 err = ctx.OpenPorts("tcp", 50, 80) 209 c.Assert(err, jc.ErrorIsNil) 210 err = ctx.OpenPorts("tcp", 40, 90) 211 c.Assert(err, gc.ErrorMatches, `cannot open 40-90/tcp \(unit "u/0"\): conflicts with 50-80/tcp requested earlier`) 212 213 // Now try closing some ports as well. 214 err = ctx.ClosePorts("udp", 8080, 8088) 215 c.Assert(err, jc.ErrorIsNil) // not existing -> ignored 216 err = ctx.ClosePorts("tcp", 100, 200) 217 c.Assert(err, jc.ErrorIsNil) 218 err = ctx.ClosePorts("tcp", 100, 200) 219 c.Assert(err, jc.ErrorIsNil) // duplicates are ignored 220 err = ctx.ClosePorts("udp", 200, 300) 221 c.Assert(err, gc.ErrorMatches, `cannot close 200-300/udp \(opened by "u/1"\) from "u/0"`) 222 err = ctx.ClosePorts("tcp", 50, 80) 223 c.Assert(err, jc.ErrorIsNil) // still pending -> no longer pending 224 225 // Ensure the ports are not actually changed on the unit yet. 226 unitRanges, err = s.unit.OpenedPorts() 227 c.Assert(err, jc.ErrorIsNil) 228 c.Assert(unitRanges, jc.DeepEquals, []network.PortRange{ 229 {100, 200, "tcp"}, 230 }) 231 232 // Flush the context with a success. 233 err = ctx.FlushContext("some badge", nil) 234 c.Assert(err, jc.ErrorIsNil) 235 236 // Verify the unit ranges are now open. 237 expectUnitRanges := []network.PortRange{ 238 {FromPort: 10, ToPort: 20, Protocol: "udp"}, 239 } 240 unitRanges, err = s.unit.OpenedPorts() 241 c.Assert(err, jc.ErrorIsNil) 242 c.Assert(unitRanges, jc.DeepEquals, expectUnitRanges) 243 }