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