github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/network/debinterfaces/activate_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package debinterfaces_test
     5  
     6  // These tests verify the commands that would be executed, but using a
     7  // dryrun option to the script that is executed.
     8  
     9  import (
    10  	"fmt"
    11  	"time"
    12  
    13  	"github.com/juju/clock"
    14  	"github.com/juju/clock/testclock"
    15  	"github.com/juju/testing"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/network/debinterfaces"
    19  )
    20  
    21  type ActivationSuite struct {
    22  	testing.IsolationSuite
    23  }
    24  
    25  var _ = gc.Suite(&ActivationSuite{})
    26  
    27  func (s *ActivationSuite) SetUpSuite(c *gc.C) {
    28  	s.IsolationSuite.SetUpSuite(c)
    29  }
    30  
    31  func (*BridgeSuite) TestActivateNonExistentDevice(c *gc.C) {
    32  	params := debinterfaces.ActivationParams{
    33  		DryRun:           true,
    34  		Clock:            clock.WallClock,
    35  		Devices:          map[string]string{"non-existent": "non-existent"},
    36  		Filename:         "testdata/TestInputSourceStanza/interfaces",
    37  		ReconfigureDelay: 10,
    38  		Timeout:          5 * time.Minute,
    39  	}
    40  
    41  	result, err := debinterfaces.BridgeAndActivate(params)
    42  	c.Assert(err, gc.IsNil)
    43  	c.Check(result, gc.IsNil)
    44  }
    45  
    46  func (s *BridgeSuite) TestActivateEth0(c *gc.C) {
    47  	filename := "testdata/TestInputSourceStanza/interfaces"
    48  
    49  	params := debinterfaces.ActivationParams{
    50  		Clock:            testclock.NewClock(time.Now()),
    51  		Devices:          map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
    52  		DryRun:           true,
    53  		Filename:         filename,
    54  		ReconfigureDelay: 10,
    55  		Timeout:          5 * time.Minute,
    56  	}
    57  	result, err := debinterfaces.BridgeAndActivate(params)
    58  	c.Assert(err, gc.IsNil)
    59  	c.Check(result, gc.NotNil)
    60  	c.Check(result.Code, gc.Equals, 0)
    61  
    62  	expected := fmt.Sprintf(`
    63  write_backup testdata/TestInputSourceStanza/interfaces.backup-%d
    64  write_content testdata/TestInputSourceStanza/interfaces.new
    65  ifdown --interfaces=testdata/TestInputSourceStanza/interfaces eth0 eth1
    66  sleep 10
    67  cp testdata/TestInputSourceStanza/interfaces.new testdata/TestInputSourceStanza/interfaces
    68  ifup --interfaces=testdata/TestInputSourceStanza/interfaces -a
    69  `, params.Clock.Now().Unix())
    70  	c.Check(string(result.Stdout), gc.Equals, expected[1:])
    71  }
    72  
    73  func (s *BridgeSuite) TestActivateEth0WithoutBackup(c *gc.C) {
    74  	filename := "testdata/TestInputSourceStanza/interfaces"
    75  
    76  	params := debinterfaces.ActivationParams{
    77  		Clock:            testclock.NewClock(time.Now()),
    78  		Devices:          map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
    79  		DryRun:           true,
    80  		Filename:         filename,
    81  		ReconfigureDelay: 100,
    82  		Timeout:          5 * time.Minute,
    83  	}
    84  
    85  	result, err := debinterfaces.BridgeAndActivate(params)
    86  	c.Assert(err, gc.IsNil)
    87  	c.Check(result, gc.NotNil)
    88  	c.Check(result.Code, gc.Equals, 0)
    89  
    90  	expected := fmt.Sprintf(`
    91  write_backup testdata/TestInputSourceStanza/interfaces.backup-%d
    92  write_content testdata/TestInputSourceStanza/interfaces.new
    93  ifdown --interfaces=testdata/TestInputSourceStanza/interfaces eth0 eth1
    94  sleep 100
    95  cp testdata/TestInputSourceStanza/interfaces.new testdata/TestInputSourceStanza/interfaces
    96  ifup --interfaces=testdata/TestInputSourceStanza/interfaces -a
    97  `, params.Clock.Now().Unix())
    98  	c.Check(string(result.Stdout), gc.Equals, expected[1:])
    99  }
   100  
   101  func (s *BridgeSuite) TestActivateWithNegativeReconfigureDelay(c *gc.C) {
   102  	filename := "testdata/TestInputSourceStanza/interfaces"
   103  
   104  	params := debinterfaces.ActivationParams{
   105  		Clock:            testclock.NewClock(time.Now()),
   106  		Devices:          map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
   107  		DryRun:           true,
   108  		Filename:         filename,
   109  		ReconfigureDelay: -3,
   110  		Timeout:          5 * time.Minute,
   111  	}
   112  
   113  	result, err := debinterfaces.BridgeAndActivate(params)
   114  	c.Assert(err, gc.IsNil)
   115  	c.Check(result, gc.NotNil)
   116  	c.Check(result.Code, gc.Equals, 0)
   117  
   118  	expected := fmt.Sprintf(`
   119  write_backup testdata/TestInputSourceStanza/interfaces.backup-%d
   120  write_content testdata/TestInputSourceStanza/interfaces.new
   121  ifdown --interfaces=testdata/TestInputSourceStanza/interfaces eth0 eth1
   122  sleep 0
   123  cp testdata/TestInputSourceStanza/interfaces.new testdata/TestInputSourceStanza/interfaces
   124  ifup --interfaces=testdata/TestInputSourceStanza/interfaces -a
   125  `, params.Clock.Now().Unix())
   126  	c.Check(string(result.Stdout), gc.Equals, expected[1:])
   127  }
   128  
   129  func (*BridgeSuite) TestActivateWithNoDevicesSpecified(c *gc.C) {
   130  	filename := "testdata/TestInputSourceStanza/interfaces"
   131  
   132  	params := debinterfaces.ActivationParams{
   133  		Clock:    clock.WallClock,
   134  		Devices:  map[string]string{},
   135  		DryRun:   true,
   136  		Filename: filename,
   137  	}
   138  
   139  	_, err := debinterfaces.BridgeAndActivate(params)
   140  	c.Assert(err, gc.NotNil)
   141  	c.Check(err, gc.ErrorMatches, "no devices specified")
   142  }
   143  
   144  func (*BridgeSuite) TestActivateWithParsingError(c *gc.C) {
   145  	filename := "testdata/TestInputSourceStanzaWithErrors/interfaces"
   146  
   147  	params := debinterfaces.ActivationParams{
   148  		Clock:    clock.WallClock,
   149  		Devices:  map[string]string{"eth0": "br-eth0"},
   150  		DryRun:   true,
   151  		Filename: filename,
   152  	}
   153  
   154  	_, err := debinterfaces.BridgeAndActivate(params)
   155  	c.Assert(err, gc.NotNil)
   156  	c.Assert(err, gc.FitsTypeOf, &debinterfaces.ParseError{})
   157  	parseError := err.(*debinterfaces.ParseError)
   158  	c.Check(parseError, gc.DeepEquals, &debinterfaces.ParseError{
   159  		Filename: "testdata/TestInputSourceStanzaWithErrors/interfaces.d/eth1.cfg",
   160  		Line:     "iface",
   161  		LineNum:  2,
   162  		Message:  "missing device name",
   163  	})
   164  }
   165  
   166  func (*BridgeSuite) TestActivateWithTimeout(c *gc.C) {
   167  	filename := "testdata/TestInputSourceStanza/interfaces"
   168  
   169  	params := debinterfaces.ActivationParams{
   170  		Clock:    clock.WallClock,
   171  		Devices:  map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
   172  		DryRun:   true,
   173  		Filename: filename,
   174  		// magic value causing the bash script to sleep
   175  		ReconfigureDelay: 25694,
   176  		Timeout:          10,
   177  	}
   178  
   179  	_, err := debinterfaces.BridgeAndActivate(params)
   180  	c.Assert(err, gc.NotNil)
   181  	c.Check(err, gc.ErrorMatches, "bridge activation error: command cancelled")
   182  }
   183  
   184  func (*BridgeSuite) TestActivateFailure(c *gc.C) {
   185  	filename := "testdata/TestInputSourceStanza/interfaces"
   186  
   187  	params := debinterfaces.ActivationParams{
   188  		Clock:    clock.WallClock,
   189  		Devices:  map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
   190  		DryRun:   true,
   191  		Filename: filename,
   192  		// magic value causing the bash script to fail
   193  		ReconfigureDelay: 25695,
   194  		Timeout:          5 * time.Minute,
   195  	}
   196  
   197  	result, err := debinterfaces.BridgeAndActivate(params)
   198  	c.Assert(err, gc.NotNil)
   199  	c.Check(err, gc.ErrorMatches, "bridge activation failed: artificial failure\n")
   200  	c.Check(result.Code, gc.Equals, 1)
   201  }
   202  
   203  func (*BridgeSuite) TestActivateFailureShortMessage(c *gc.C) {
   204  	filename := "testdata/TestInputSourceStanza/interfaces"
   205  
   206  	params := debinterfaces.ActivationParams{
   207  		Clock:    clock.WallClock,
   208  		Devices:  map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"},
   209  		DryRun:   true,
   210  		Filename: filename,
   211  		// magic value causing the bash script to fail
   212  		ReconfigureDelay: 25696,
   213  		Timeout:          5 * time.Minute,
   214  	}
   215  
   216  	result, err := debinterfaces.BridgeAndActivate(params)
   217  	c.Assert(err, gc.NotNil)
   218  	c.Check(err, gc.ErrorMatches, "bridge activation failed, see logs for details")
   219  	c.Check(result.Code, gc.Equals, 1)
   220  }