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