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 }