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