github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/worker/firewaller/firewaller_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package firewaller_test
     5  
     6  import (
     7  	"reflect"
     8  	stdtesting "testing"
     9  	"time"
    10  
    11  	"github.com/juju/utils"
    12  	gc "launchpad.net/gocheck"
    13  
    14  	"github.com/juju/juju/environs/config"
    15  	"github.com/juju/juju/instance"
    16  	"github.com/juju/juju/juju"
    17  	"github.com/juju/juju/juju/testing"
    18  	"github.com/juju/juju/provider/dummy"
    19  	"github.com/juju/juju/state"
    20  	"github.com/juju/juju/state/api"
    21  	apifirewaller "github.com/juju/juju/state/api/firewaller"
    22  	coretesting "github.com/juju/juju/testing"
    23  	"github.com/juju/juju/worker"
    24  	"github.com/juju/juju/worker/firewaller"
    25  )
    26  
    27  func TestPackage(t *stdtesting.T) {
    28  	coretesting.MgoTestPackage(t)
    29  }
    30  
    31  type FirewallerSuite struct {
    32  	testing.JujuConnSuite
    33  	op    <-chan dummy.Operation
    34  	charm *state.Charm
    35  
    36  	st         *api.State
    37  	firewaller *apifirewaller.State
    38  }
    39  
    40  type FirewallerGlobalModeSuite struct {
    41  	FirewallerSuite
    42  }
    43  
    44  var _ worker.Worker = (*firewaller.Firewaller)(nil)
    45  
    46  // assertPorts retrieves the open ports of the instance and compares them
    47  // to the expected.
    48  func (s *FirewallerSuite) assertPorts(c *gc.C, inst instance.Instance, machineId string, expected []instance.Port) {
    49  	s.BackingState.StartSync()
    50  	start := time.Now()
    51  	for {
    52  		got, err := inst.Ports(machineId)
    53  		if err != nil {
    54  			c.Fatal(err)
    55  			return
    56  		}
    57  		instance.SortPorts(got)
    58  		instance.SortPorts(expected)
    59  		if reflect.DeepEqual(got, expected) {
    60  			c.Succeed()
    61  			return
    62  		}
    63  		if time.Since(start) > coretesting.LongWait {
    64  			c.Fatalf("timed out: expected %q; got %q", expected, got)
    65  			return
    66  		}
    67  		time.Sleep(coretesting.ShortWait)
    68  	}
    69  }
    70  
    71  // assertEnvironPorts retrieves the open ports of environment and compares them
    72  // to the expected.
    73  func (s *FirewallerSuite) assertEnvironPorts(c *gc.C, expected []instance.Port) {
    74  	s.BackingState.StartSync()
    75  	start := time.Now()
    76  	for {
    77  		got, err := s.Conn.Environ.Ports()
    78  		if err != nil {
    79  			c.Fatal(err)
    80  			return
    81  		}
    82  		instance.SortPorts(got)
    83  		instance.SortPorts(expected)
    84  		if reflect.DeepEqual(got, expected) {
    85  			c.Succeed()
    86  			return
    87  		}
    88  		if time.Since(start) > coretesting.LongWait {
    89  			c.Fatalf("timed out: expected %q; got %q", expected, got)
    90  			return
    91  		}
    92  		time.Sleep(coretesting.ShortWait)
    93  	}
    94  }
    95  
    96  var _ = gc.Suite(&FirewallerSuite{})
    97  
    98  func (s FirewallerGlobalModeSuite) SetUpTest(c *gc.C) {
    99  	add := map[string]interface{}{"firewall-mode": config.FwGlobal}
   100  	s.DummyConfig = dummy.SampleConfig().Merge(add).Delete("admin-secret", "ca-private-key")
   101  
   102  	s.FirewallerSuite.SetUpTest(c)
   103  }
   104  
   105  func (s *FirewallerSuite) SetUpTest(c *gc.C) {
   106  	s.JujuConnSuite.SetUpTest(c)
   107  	s.charm = s.AddTestingCharm(c, "dummy")
   108  
   109  	// Create a manager machine and login to the API.
   110  	machine, err := s.State.AddMachine("quantal", state.JobManageEnviron)
   111  	c.Assert(err, gc.IsNil)
   112  	password, err := utils.RandomPassword()
   113  	c.Assert(err, gc.IsNil)
   114  	err = machine.SetPassword(password)
   115  	c.Assert(err, gc.IsNil)
   116  	err = machine.SetProvisioned("i-manager", "fake_nonce", nil)
   117  	c.Assert(err, gc.IsNil)
   118  	s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce")
   119  	c.Assert(s.st, gc.NotNil)
   120  
   121  	// Create the firewaller API facade.
   122  	s.firewaller = s.st.Firewaller()
   123  	c.Assert(s.firewaller, gc.NotNil)
   124  }
   125  
   126  func (s *FirewallerSuite) TestStartStop(c *gc.C) {
   127  	fw, err := firewaller.NewFirewaller(s.firewaller)
   128  	c.Assert(err, gc.IsNil)
   129  	c.Assert(fw.Stop(), gc.IsNil)
   130  }
   131  
   132  func (s *FirewallerSuite) addUnit(c *gc.C, svc *state.Service) (*state.Unit, *state.Machine) {
   133  	units, err := juju.AddUnits(s.State, svc, 1, "")
   134  	c.Assert(err, gc.IsNil)
   135  	u := units[0]
   136  	id, err := u.AssignedMachineId()
   137  	c.Assert(err, gc.IsNil)
   138  	m, err := s.State.Machine(id)
   139  	c.Assert(err, gc.IsNil)
   140  	return u, m
   141  }
   142  
   143  // startInstance starts a new instance for the given machine.
   144  func (s *FirewallerSuite) startInstance(c *gc.C, m *state.Machine) instance.Instance {
   145  	inst, hc := testing.AssertStartInstance(c, s.Conn.Environ, m.Id())
   146  	err := m.SetProvisioned(inst.Id(), "fake_nonce", hc)
   147  	c.Assert(err, gc.IsNil)
   148  	return inst
   149  }
   150  
   151  func (s *FirewallerSuite) TestNotExposedService(c *gc.C) {
   152  	fw, err := firewaller.NewFirewaller(s.firewaller)
   153  	c.Assert(err, gc.IsNil)
   154  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   155  
   156  	svc := s.AddTestingService(c, "wordpress", s.charm)
   157  	u, m := s.addUnit(c, svc)
   158  	inst := s.startInstance(c, m)
   159  
   160  	err = u.OpenPort("tcp", 80)
   161  	c.Assert(err, gc.IsNil)
   162  	err = u.OpenPort("tcp", 8080)
   163  	c.Assert(err, gc.IsNil)
   164  
   165  	s.assertPorts(c, inst, m.Id(), nil)
   166  
   167  	err = u.ClosePort("tcp", 80)
   168  	c.Assert(err, gc.IsNil)
   169  
   170  	s.assertPorts(c, inst, m.Id(), nil)
   171  }
   172  
   173  func (s *FirewallerSuite) TestExposedService(c *gc.C) {
   174  	fw, err := firewaller.NewFirewaller(s.firewaller)
   175  	c.Assert(err, gc.IsNil)
   176  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   177  
   178  	svc := s.AddTestingService(c, "wordpress", s.charm)
   179  
   180  	err = svc.SetExposed()
   181  	c.Assert(err, gc.IsNil)
   182  	u, m := s.addUnit(c, svc)
   183  	inst := s.startInstance(c, m)
   184  
   185  	err = u.OpenPort("tcp", 80)
   186  	c.Assert(err, gc.IsNil)
   187  	err = u.OpenPort("tcp", 8080)
   188  	c.Assert(err, gc.IsNil)
   189  
   190  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   191  
   192  	err = u.ClosePort("tcp", 80)
   193  	c.Assert(err, gc.IsNil)
   194  
   195  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 8080}})
   196  }
   197  
   198  func (s *FirewallerSuite) TestMultipleExposedServices(c *gc.C) {
   199  	fw, err := firewaller.NewFirewaller(s.firewaller)
   200  	c.Assert(err, gc.IsNil)
   201  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   202  
   203  	svc1 := s.AddTestingService(c, "wordpress", s.charm)
   204  	err = svc1.SetExposed()
   205  	c.Assert(err, gc.IsNil)
   206  
   207  	u1, m1 := s.addUnit(c, svc1)
   208  	inst1 := s.startInstance(c, m1)
   209  	err = u1.OpenPort("tcp", 80)
   210  	c.Assert(err, gc.IsNil)
   211  	err = u1.OpenPort("tcp", 8080)
   212  	c.Assert(err, gc.IsNil)
   213  
   214  	svc2 := s.AddTestingService(c, "mysql", s.charm)
   215  	c.Assert(err, gc.IsNil)
   216  	err = svc2.SetExposed()
   217  	c.Assert(err, gc.IsNil)
   218  
   219  	u2, m2 := s.addUnit(c, svc2)
   220  	inst2 := s.startInstance(c, m2)
   221  	err = u2.OpenPort("tcp", 3306)
   222  	c.Assert(err, gc.IsNil)
   223  
   224  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   225  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 3306}})
   226  
   227  	err = u1.ClosePort("tcp", 80)
   228  	c.Assert(err, gc.IsNil)
   229  	err = u2.ClosePort("tcp", 3306)
   230  	c.Assert(err, gc.IsNil)
   231  
   232  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 8080}})
   233  	s.assertPorts(c, inst2, m2.Id(), nil)
   234  }
   235  
   236  func (s *FirewallerSuite) TestMachineWithoutInstanceId(c *gc.C) {
   237  	fw, err := firewaller.NewFirewaller(s.firewaller)
   238  	c.Assert(err, gc.IsNil)
   239  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   240  
   241  	svc := s.AddTestingService(c, "wordpress", s.charm)
   242  	err = svc.SetExposed()
   243  	c.Assert(err, gc.IsNil)
   244  	// add a unit but don't start its instance yet.
   245  	u1, m1 := s.addUnit(c, svc)
   246  
   247  	// add another unit and start its instance, so that
   248  	// we're sure the firewaller has seen the first instance.
   249  	u2, m2 := s.addUnit(c, svc)
   250  	inst2 := s.startInstance(c, m2)
   251  	err = u2.OpenPort("tcp", 80)
   252  	c.Assert(err, gc.IsNil)
   253  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 80}})
   254  
   255  	inst1 := s.startInstance(c, m1)
   256  	err = u1.OpenPort("tcp", 8080)
   257  	c.Assert(err, gc.IsNil)
   258  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 8080}})
   259  }
   260  
   261  func (s *FirewallerSuite) TestMultipleUnits(c *gc.C) {
   262  	fw, err := firewaller.NewFirewaller(s.firewaller)
   263  	c.Assert(err, gc.IsNil)
   264  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   265  
   266  	svc := s.AddTestingService(c, "wordpress", s.charm)
   267  	err = svc.SetExposed()
   268  	c.Assert(err, gc.IsNil)
   269  
   270  	u1, m1 := s.addUnit(c, svc)
   271  	inst1 := s.startInstance(c, m1)
   272  	err = u1.OpenPort("tcp", 80)
   273  	c.Assert(err, gc.IsNil)
   274  
   275  	u2, m2 := s.addUnit(c, svc)
   276  	inst2 := s.startInstance(c, m2)
   277  	err = u2.OpenPort("tcp", 80)
   278  	c.Assert(err, gc.IsNil)
   279  
   280  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 80}})
   281  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 80}})
   282  
   283  	err = u1.ClosePort("tcp", 80)
   284  	c.Assert(err, gc.IsNil)
   285  	err = u2.ClosePort("tcp", 80)
   286  	c.Assert(err, gc.IsNil)
   287  
   288  	s.assertPorts(c, inst1, m1.Id(), nil)
   289  	s.assertPorts(c, inst2, m2.Id(), nil)
   290  }
   291  
   292  func (s *FirewallerSuite) TestStartWithState(c *gc.C) {
   293  	svc := s.AddTestingService(c, "wordpress", s.charm)
   294  	err := svc.SetExposed()
   295  	c.Assert(err, gc.IsNil)
   296  	u, m := s.addUnit(c, svc)
   297  	inst := s.startInstance(c, m)
   298  
   299  	err = u.OpenPort("tcp", 80)
   300  	c.Assert(err, gc.IsNil)
   301  	err = u.OpenPort("tcp", 8080)
   302  	c.Assert(err, gc.IsNil)
   303  
   304  	// Nothing open without firewaller.
   305  	s.assertPorts(c, inst, m.Id(), nil)
   306  
   307  	// Starting the firewaller opens the ports.
   308  	fw, err := firewaller.NewFirewaller(s.firewaller)
   309  	c.Assert(err, gc.IsNil)
   310  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   311  
   312  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   313  
   314  	err = svc.SetExposed()
   315  	c.Assert(err, gc.IsNil)
   316  }
   317  
   318  func (s *FirewallerSuite) TestStartWithPartialState(c *gc.C) {
   319  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
   320  	c.Assert(err, gc.IsNil)
   321  	inst := s.startInstance(c, m)
   322  
   323  	svc := s.AddTestingService(c, "wordpress", s.charm)
   324  	err = svc.SetExposed()
   325  	c.Assert(err, gc.IsNil)
   326  
   327  	// Starting the firewaller, no open ports.
   328  	fw, err := firewaller.NewFirewaller(s.firewaller)
   329  	c.Assert(err, gc.IsNil)
   330  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   331  
   332  	s.assertPorts(c, inst, m.Id(), nil)
   333  
   334  	// Complete steps to open port.
   335  	u, err := svc.AddUnit()
   336  	c.Assert(err, gc.IsNil)
   337  	err = u.AssignToMachine(m)
   338  	c.Assert(err, gc.IsNil)
   339  	err = u.OpenPort("tcp", 80)
   340  	c.Assert(err, gc.IsNil)
   341  
   342  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}})
   343  }
   344  
   345  func (s *FirewallerSuite) TestStartWithUnexposedService(c *gc.C) {
   346  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
   347  	c.Assert(err, gc.IsNil)
   348  	inst := s.startInstance(c, m)
   349  
   350  	svc := s.AddTestingService(c, "wordpress", s.charm)
   351  	u, err := svc.AddUnit()
   352  	c.Assert(err, gc.IsNil)
   353  	err = u.AssignToMachine(m)
   354  	c.Assert(err, gc.IsNil)
   355  	err = u.OpenPort("tcp", 80)
   356  	c.Assert(err, gc.IsNil)
   357  
   358  	// Starting the firewaller, no open ports.
   359  	fw, err := firewaller.NewFirewaller(s.firewaller)
   360  	c.Assert(err, gc.IsNil)
   361  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   362  
   363  	s.assertPorts(c, inst, m.Id(), nil)
   364  
   365  	// Expose service.
   366  	err = svc.SetExposed()
   367  	c.Assert(err, gc.IsNil)
   368  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}})
   369  }
   370  
   371  func (s *FirewallerSuite) TestSetClearExposedService(c *gc.C) {
   372  	fw, err := firewaller.NewFirewaller(s.firewaller)
   373  	c.Assert(err, gc.IsNil)
   374  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   375  
   376  	svc := s.AddTestingService(c, "wordpress", s.charm)
   377  
   378  	u, m := s.addUnit(c, svc)
   379  	inst := s.startInstance(c, m)
   380  	err = u.OpenPort("tcp", 80)
   381  	c.Assert(err, gc.IsNil)
   382  	err = u.OpenPort("tcp", 8080)
   383  	c.Assert(err, gc.IsNil)
   384  
   385  	// Not exposed service, so no open port.
   386  	s.assertPorts(c, inst, m.Id(), nil)
   387  
   388  	// SeExposed opens the ports.
   389  	err = svc.SetExposed()
   390  	c.Assert(err, gc.IsNil)
   391  
   392  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   393  
   394  	// ClearExposed closes the ports again.
   395  	err = svc.ClearExposed()
   396  	c.Assert(err, gc.IsNil)
   397  
   398  	s.assertPorts(c, inst, m.Id(), nil)
   399  }
   400  
   401  func (s *FirewallerSuite) TestRemoveUnit(c *gc.C) {
   402  	fw, err := firewaller.NewFirewaller(s.firewaller)
   403  	c.Assert(err, gc.IsNil)
   404  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   405  
   406  	svc := s.AddTestingService(c, "wordpress", s.charm)
   407  	err = svc.SetExposed()
   408  	c.Assert(err, gc.IsNil)
   409  
   410  	u1, m1 := s.addUnit(c, svc)
   411  	inst1 := s.startInstance(c, m1)
   412  	err = u1.OpenPort("tcp", 80)
   413  	c.Assert(err, gc.IsNil)
   414  
   415  	u2, m2 := s.addUnit(c, svc)
   416  	inst2 := s.startInstance(c, m2)
   417  	err = u2.OpenPort("tcp", 80)
   418  	c.Assert(err, gc.IsNil)
   419  
   420  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 80}})
   421  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 80}})
   422  
   423  	// Remove unit.
   424  	err = u1.EnsureDead()
   425  	c.Assert(err, gc.IsNil)
   426  	err = u1.Remove()
   427  	c.Assert(err, gc.IsNil)
   428  
   429  	s.assertPorts(c, inst1, m1.Id(), nil)
   430  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 80}})
   431  }
   432  
   433  func (s *FirewallerSuite) TestRemoveService(c *gc.C) {
   434  	fw, err := firewaller.NewFirewaller(s.firewaller)
   435  	c.Assert(err, gc.IsNil)
   436  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   437  
   438  	svc := s.AddTestingService(c, "wordpress", s.charm)
   439  	err = svc.SetExposed()
   440  	c.Assert(err, gc.IsNil)
   441  
   442  	u, m := s.addUnit(c, svc)
   443  	inst := s.startInstance(c, m)
   444  	err = u.OpenPort("tcp", 80)
   445  	c.Assert(err, gc.IsNil)
   446  
   447  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}})
   448  
   449  	// Remove service.
   450  	err = u.EnsureDead()
   451  	c.Assert(err, gc.IsNil)
   452  	err = u.Remove()
   453  	c.Assert(err, gc.IsNil)
   454  	err = svc.Destroy()
   455  	c.Assert(err, gc.IsNil)
   456  	s.assertPorts(c, inst, m.Id(), nil)
   457  }
   458  
   459  func (s *FirewallerSuite) TestRemoveMultipleServices(c *gc.C) {
   460  	fw, err := firewaller.NewFirewaller(s.firewaller)
   461  	c.Assert(err, gc.IsNil)
   462  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   463  
   464  	svc1 := s.AddTestingService(c, "wordpress", s.charm)
   465  	err = svc1.SetExposed()
   466  	c.Assert(err, gc.IsNil)
   467  
   468  	u1, m1 := s.addUnit(c, svc1)
   469  	inst1 := s.startInstance(c, m1)
   470  	err = u1.OpenPort("tcp", 80)
   471  	c.Assert(err, gc.IsNil)
   472  
   473  	svc2 := s.AddTestingService(c, "mysql", s.charm)
   474  	err = svc2.SetExposed()
   475  	c.Assert(err, gc.IsNil)
   476  
   477  	u2, m2 := s.addUnit(c, svc2)
   478  	inst2 := s.startInstance(c, m2)
   479  	err = u2.OpenPort("tcp", 3306)
   480  	c.Assert(err, gc.IsNil)
   481  
   482  	s.assertPorts(c, inst1, m1.Id(), []instance.Port{{"tcp", 80}})
   483  	s.assertPorts(c, inst2, m2.Id(), []instance.Port{{"tcp", 3306}})
   484  
   485  	// Remove services.
   486  	err = u2.EnsureDead()
   487  	c.Assert(err, gc.IsNil)
   488  	err = u2.Remove()
   489  	c.Assert(err, gc.IsNil)
   490  	err = svc2.Destroy()
   491  	c.Assert(err, gc.IsNil)
   492  
   493  	err = u1.EnsureDead()
   494  	c.Assert(err, gc.IsNil)
   495  	err = u1.Remove()
   496  	c.Assert(err, gc.IsNil)
   497  	err = svc1.Destroy()
   498  	c.Assert(err, gc.IsNil)
   499  
   500  	s.assertPorts(c, inst1, m1.Id(), nil)
   501  	s.assertPorts(c, inst2, m2.Id(), nil)
   502  }
   503  
   504  func (s *FirewallerSuite) TestDeadMachine(c *gc.C) {
   505  	fw, err := firewaller.NewFirewaller(s.firewaller)
   506  	c.Assert(err, gc.IsNil)
   507  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   508  
   509  	svc := s.AddTestingService(c, "wordpress", s.charm)
   510  	err = svc.SetExposed()
   511  	c.Assert(err, gc.IsNil)
   512  
   513  	u, m := s.addUnit(c, svc)
   514  	inst := s.startInstance(c, m)
   515  	err = u.OpenPort("tcp", 80)
   516  	c.Assert(err, gc.IsNil)
   517  
   518  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}})
   519  
   520  	// Remove unit and service, also tested without. Has no effect.
   521  	err = u.EnsureDead()
   522  	c.Assert(err, gc.IsNil)
   523  	err = u.Remove()
   524  	c.Assert(err, gc.IsNil)
   525  	err = svc.Destroy()
   526  	c.Assert(err, gc.IsNil)
   527  
   528  	// Kill machine.
   529  	err = m.Refresh()
   530  	c.Assert(err, gc.IsNil)
   531  	err = m.EnsureDead()
   532  	c.Assert(err, gc.IsNil)
   533  
   534  	s.assertPorts(c, inst, m.Id(), nil)
   535  }
   536  
   537  func (s *FirewallerSuite) TestRemoveMachine(c *gc.C) {
   538  	fw, err := firewaller.NewFirewaller(s.firewaller)
   539  	c.Assert(err, gc.IsNil)
   540  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   541  
   542  	svc := s.AddTestingService(c, "wordpress", s.charm)
   543  	err = svc.SetExposed()
   544  	c.Assert(err, gc.IsNil)
   545  
   546  	u, m := s.addUnit(c, svc)
   547  	inst := s.startInstance(c, m)
   548  	err = u.OpenPort("tcp", 80)
   549  	c.Assert(err, gc.IsNil)
   550  
   551  	s.assertPorts(c, inst, m.Id(), []instance.Port{{"tcp", 80}})
   552  
   553  	// Remove unit.
   554  	err = u.EnsureDead()
   555  	c.Assert(err, gc.IsNil)
   556  	err = u.Remove()
   557  	c.Assert(err, gc.IsNil)
   558  
   559  	// Remove machine. Nothing bad should happen, but can't
   560  	// assert port state since the machine must have been
   561  	// destroyed and we lost its reference.
   562  	err = m.Refresh()
   563  	c.Assert(err, gc.IsNil)
   564  	err = m.EnsureDead()
   565  	c.Assert(err, gc.IsNil)
   566  	err = m.Remove()
   567  	c.Assert(err, gc.IsNil)
   568  }
   569  
   570  func (s *FirewallerGlobalModeSuite) TestGlobalMode(c *gc.C) {
   571  	// Start firewaller and open ports.
   572  	fw, err := firewaller.NewFirewaller(s.firewaller)
   573  	c.Assert(err, gc.IsNil)
   574  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   575  
   576  	svc1 := s.AddTestingService(c, "wordpress", s.charm)
   577  	err = svc1.SetExposed()
   578  	c.Assert(err, gc.IsNil)
   579  
   580  	u1, m1 := s.addUnit(c, svc1)
   581  	s.startInstance(c, m1)
   582  	err = u1.OpenPort("tcp", 80)
   583  	c.Assert(err, gc.IsNil)
   584  	err = u1.OpenPort("tcp", 8080)
   585  	c.Assert(err, gc.IsNil)
   586  
   587  	svc2 := s.AddTestingService(c, "moinmoin", s.charm)
   588  	c.Assert(err, gc.IsNil)
   589  	err = svc2.SetExposed()
   590  	c.Assert(err, gc.IsNil)
   591  
   592  	u2, m2 := s.addUnit(c, svc2)
   593  	s.startInstance(c, m2)
   594  	err = u2.OpenPort("tcp", 80)
   595  	c.Assert(err, gc.IsNil)
   596  
   597  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   598  
   599  	// Closing a port opened by a different unit won't touch the environment.
   600  	err = u1.ClosePort("tcp", 80)
   601  	c.Assert(err, gc.IsNil)
   602  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   603  
   604  	// Closing a port used just once changes the environment.
   605  	err = u1.ClosePort("tcp", 8080)
   606  	c.Assert(err, gc.IsNil)
   607  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}})
   608  
   609  	// Closing the last port also modifies the environment.
   610  	err = u2.ClosePort("tcp", 80)
   611  	c.Assert(err, gc.IsNil)
   612  	s.assertEnvironPorts(c, nil)
   613  }
   614  
   615  func (s *FirewallerGlobalModeSuite) TestGlobalModeStartWithUnexposedService(c *gc.C) {
   616  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
   617  	c.Assert(err, gc.IsNil)
   618  	s.startInstance(c, m)
   619  
   620  	svc := s.AddTestingService(c, "wordpress", s.charm)
   621  	u, err := svc.AddUnit()
   622  	c.Assert(err, gc.IsNil)
   623  	err = u.AssignToMachine(m)
   624  	c.Assert(err, gc.IsNil)
   625  	err = u.OpenPort("tcp", 80)
   626  	c.Assert(err, gc.IsNil)
   627  
   628  	// Starting the firewaller, no open ports.
   629  	fw, err := firewaller.NewFirewaller(s.firewaller)
   630  	c.Assert(err, gc.IsNil)
   631  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   632  
   633  	s.assertEnvironPorts(c, nil)
   634  
   635  	// Expose service.
   636  	err = svc.SetExposed()
   637  	c.Assert(err, gc.IsNil)
   638  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}})
   639  }
   640  
   641  func (s *FirewallerGlobalModeSuite) TestGlobalModeRestart(c *gc.C) {
   642  	// Start firewaller and open ports.
   643  	fw, err := firewaller.NewFirewaller(s.firewaller)
   644  	c.Assert(err, gc.IsNil)
   645  
   646  	svc := s.AddTestingService(c, "wordpress", s.charm)
   647  	err = svc.SetExposed()
   648  	c.Assert(err, gc.IsNil)
   649  
   650  	u, m := s.addUnit(c, svc)
   651  	s.startInstance(c, m)
   652  	err = u.OpenPort("tcp", 80)
   653  	c.Assert(err, gc.IsNil)
   654  	err = u.OpenPort("tcp", 8080)
   655  	c.Assert(err, gc.IsNil)
   656  
   657  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   658  
   659  	// Stop firewaller and close one and open a different port.
   660  	err = fw.Stop()
   661  	c.Assert(err, gc.IsNil)
   662  
   663  	err = u.ClosePort("tcp", 8080)
   664  	c.Assert(err, gc.IsNil)
   665  	err = u.OpenPort("tcp", 8888)
   666  	c.Assert(err, gc.IsNil)
   667  
   668  	// Start firewaller and check port.
   669  	fw, err = firewaller.NewFirewaller(s.firewaller)
   670  	c.Assert(err, gc.IsNil)
   671  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   672  
   673  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8888}})
   674  }
   675  
   676  func (s *FirewallerGlobalModeSuite) TestGlobalModeRestartUnexposedService(c *gc.C) {
   677  	// Start firewaller and open ports.
   678  	fw, err := firewaller.NewFirewaller(s.firewaller)
   679  	c.Assert(err, gc.IsNil)
   680  
   681  	svc := s.AddTestingService(c, "wordpress", s.charm)
   682  	err = svc.SetExposed()
   683  	c.Assert(err, gc.IsNil)
   684  
   685  	u, m := s.addUnit(c, svc)
   686  	s.startInstance(c, m)
   687  	err = u.OpenPort("tcp", 80)
   688  	c.Assert(err, gc.IsNil)
   689  	err = u.OpenPort("tcp", 8080)
   690  	c.Assert(err, gc.IsNil)
   691  
   692  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   693  
   694  	// Stop firewaller and clear exposed flag on service.
   695  	err = fw.Stop()
   696  	c.Assert(err, gc.IsNil)
   697  
   698  	err = svc.ClearExposed()
   699  	c.Assert(err, gc.IsNil)
   700  
   701  	// Start firewaller and check port.
   702  	fw, err = firewaller.NewFirewaller(s.firewaller)
   703  	c.Assert(err, gc.IsNil)
   704  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   705  
   706  	s.assertEnvironPorts(c, nil)
   707  }
   708  
   709  func (s *FirewallerGlobalModeSuite) TestGlobalModeRestartPortCount(c *gc.C) {
   710  	// Start firewaller and open ports.
   711  	fw, err := firewaller.NewFirewaller(s.firewaller)
   712  	c.Assert(err, gc.IsNil)
   713  
   714  	svc1 := s.AddTestingService(c, "wordpress", s.charm)
   715  	err = svc1.SetExposed()
   716  	c.Assert(err, gc.IsNil)
   717  
   718  	u1, m1 := s.addUnit(c, svc1)
   719  	s.startInstance(c, m1)
   720  	err = u1.OpenPort("tcp", 80)
   721  	c.Assert(err, gc.IsNil)
   722  	err = u1.OpenPort("tcp", 8080)
   723  	c.Assert(err, gc.IsNil)
   724  
   725  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   726  
   727  	// Stop firewaller and add another service using the port.
   728  	err = fw.Stop()
   729  	c.Assert(err, gc.IsNil)
   730  
   731  	svc2 := s.AddTestingService(c, "moinmoin", s.charm)
   732  	err = svc2.SetExposed()
   733  	c.Assert(err, gc.IsNil)
   734  
   735  	u2, m2 := s.addUnit(c, svc2)
   736  	s.startInstance(c, m2)
   737  	err = u2.OpenPort("tcp", 80)
   738  	c.Assert(err, gc.IsNil)
   739  
   740  	// Start firewaller and check port.
   741  	fw, err = firewaller.NewFirewaller(s.firewaller)
   742  	c.Assert(err, gc.IsNil)
   743  	defer func() { c.Assert(fw.Stop(), gc.IsNil) }()
   744  
   745  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   746  
   747  	// Closing a port opened by a different unit won't touch the environment.
   748  	err = u1.ClosePort("tcp", 80)
   749  	c.Assert(err, gc.IsNil)
   750  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}, {"tcp", 8080}})
   751  
   752  	// Closing a port used just once changes the environment.
   753  	err = u1.ClosePort("tcp", 8080)
   754  	c.Assert(err, gc.IsNil)
   755  	s.assertEnvironPorts(c, []instance.Port{{"tcp", 80}})
   756  
   757  	// Closing the last port also modifies the environment.
   758  	err = u2.ClosePort("tcp", 80)
   759  	c.Assert(err, gc.IsNil)
   760  	s.assertEnvironPorts(c, nil)
   761  }