github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/linux_container/bandwidth_manager/bandwidth_manager_test.go (about)

     1  package bandwidth_manager_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os/exec"
     7  
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/gomega"
    10  	"github.com/pivotal-golang/lager/lagertest"
    11  
    12  	"github.com/cloudfoundry-incubator/garden"
    13  	"github.com/cloudfoundry-incubator/garden-linux/linux_container/bandwidth_manager"
    14  	"github.com/cloudfoundry/gunk/command_runner/fake_command_runner"
    15  	. "github.com/cloudfoundry/gunk/command_runner/fake_command_runner/matchers"
    16  )
    17  
    18  var fakeRunner *fake_command_runner.FakeCommandRunner
    19  var logger *lagertest.TestLogger
    20  var bandwidthManager *bandwidth_manager.ContainerBandwidthManager
    21  
    22  var _ = Describe("setting rate limits", func() {
    23  	BeforeEach(func() {
    24  		fakeRunner = fake_command_runner.New()
    25  		logger = lagertest.NewTestLogger("test")
    26  		bandwidthManager = bandwidth_manager.New("/depot/some-id", "some-id", fakeRunner)
    27  	})
    28  
    29  	It("executes net_rate.sh with the appropriate environment", func() {
    30  		limits := garden.BandwidthLimits{
    31  			RateInBytesPerSecond:      128,
    32  			BurstRateInBytesPerSecond: 256,
    33  		}
    34  
    35  		err := bandwidthManager.SetLimits(logger, limits)
    36  		Expect(err).ToNot(HaveOccurred())
    37  
    38  		Expect(fakeRunner).To(HaveExecutedSerially(
    39  			fake_command_runner.CommandSpec{
    40  				Path: "/depot/some-id/net_rate.sh",
    41  				Env: []string{
    42  					"BURST=256",
    43  					fmt.Sprintf("RATE=%d", 128*8),
    44  				},
    45  			},
    46  		))
    47  	})
    48  
    49  	Context("when net_rate.sh fails", func() {
    50  		nastyError := errors.New("oh no!")
    51  
    52  		BeforeEach(func() {
    53  			fakeRunner.WhenRunning(
    54  				fake_command_runner.CommandSpec{
    55  					Path: "/depot/some-id/net_rate.sh",
    56  				}, func(*exec.Cmd) error {
    57  					return nastyError
    58  				},
    59  			)
    60  		})
    61  
    62  		It("returns the error", func() {
    63  			err := bandwidthManager.SetLimits(logger, garden.BandwidthLimits{
    64  				RateInBytesPerSecond:      128,
    65  				BurstRateInBytesPerSecond: 256,
    66  			})
    67  			Expect(err).To(Equal(nastyError))
    68  		})
    69  	})
    70  })
    71  
    72  var _ = Describe("getting bandwidth limits", func() {
    73  	BeforeEach(func() {
    74  		fakeRunner = fake_command_runner.New()
    75  		logger = lagertest.NewTestLogger("test")
    76  		bandwidthManager = bandwidth_manager.New("/depot/some-id", "some-id", fakeRunner)
    77  	})
    78  
    79  	It("executes net.sh get_egress_info and get_ingress_info", func() {
    80  		fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
    81  			Path: "/depot/some-id/net.sh",
    82  			Args: []string{"get_egress_info"},
    83  			Env:  []string{"ID=some-id"},
    84  		}, func(cmd *exec.Cmd) error {
    85  			cmd.Stdout.Write([]byte(`qdisc tbf 8010: root refcnt 2 rate 8192bit burst 64Kb lat 24.4ms
    86  qdisc ingress ffff: parent ffff:fff1 ----------------
    87  `))
    88  			return nil
    89  		})
    90  
    91  		fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
    92  			Path: "/depot/some-id/net.sh",
    93  			Args: []string{"get_ingress_info"},
    94  			Env:  []string{"ID=some-id"},
    95  		}, func(cmd *exec.Cmd) error {
    96  			cmd.Stdout.Write([]byte(`filter protocol ip pref 1 u32
    97  filter protocol ip pref 1 u32 fh 800: ht divisor 1
    98  filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1
    99    match 00000000/00000000 at 12
   100   police 0x10 rate 8192bit burst 64Kb mtu 2Kb action drop overhead 0b
   101  ref 1 bind 1
   102  `))
   103  			return nil
   104  		})
   105  
   106  		usage, err := bandwidthManager.GetLimits(logger)
   107  		Expect(err).ToNot(HaveOccurred())
   108  
   109  		Expect(usage.InRate).To(Equal(uint64(1024)))
   110  		Expect(usage.InBurst).To(Equal(uint64(65536)))
   111  
   112  		Expect(usage.OutRate).To(Equal(uint64(1024)))
   113  		Expect(usage.OutBurst).To(Equal(uint64(65536)))
   114  	})
   115  
   116  	Context("when net.sh get_egress_info fails", func() {
   117  		disaster := errors.New("oh no!")
   118  
   119  		BeforeEach(func() {
   120  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   121  				Path: "/depot/some-id/net.sh",
   122  				Args: []string{"get_egress_info"},
   123  				Env:  []string{"ID=some-id"},
   124  			}, func(*exec.Cmd) error {
   125  				return disaster
   126  			})
   127  		})
   128  
   129  		It("returns the error", func() {
   130  			_, err := bandwidthManager.GetLimits(logger)
   131  			Expect(err).To(Equal(disaster))
   132  		})
   133  	})
   134  
   135  	Context("when net.sh get_egress_info output doesn't match", func() {
   136  		It("returns 0 limits and does not error", func() {
   137  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   138  				Path: "/depot/some-id/net.sh",
   139  				Args: []string{"get_egress_info"},
   140  				Env:  []string{"ID=some-id"},
   141  			}, func(cmd *exec.Cmd) error {
   142  				cmd.Stdout.Write([]byte(`qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
   143  `))
   144  				return nil
   145  			})
   146  
   147  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   148  				Path: "/depot/some-id/net.sh",
   149  				Args: []string{"get_ingress_info"},
   150  				Env:  []string{"ID=some-id"},
   151  			}, func(cmd *exec.Cmd) error {
   152  				cmd.Stdout.Write([]byte(`filter protocol ip pref 1 u32
   153  filter protocol ip pref 1 u32 fh 800: ht divisor 1
   154  filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1
   155    match 00000000/00000000 at 12
   156   police 0x10 rate 8192bit burst 64Kb mtu 2Kb action drop overhead 0b
   157  ref 1 bind 1
   158  `))
   159  				return nil
   160  			})
   161  
   162  			usage, err := bandwidthManager.GetLimits(logger)
   163  			Expect(err).ToNot(HaveOccurred())
   164  
   165  			Expect(usage.InRate).To(Equal(uint64(0)))
   166  			Expect(usage.InBurst).To(Equal(uint64(0)))
   167  
   168  			Expect(usage.OutRate).To(Equal(uint64(1024)))
   169  			Expect(usage.OutBurst).To(Equal(uint64(65536)))
   170  		})
   171  	})
   172  
   173  	Context("when net.sh get_ingress_info fails", func() {
   174  		disaster := errors.New("oh no!")
   175  
   176  		BeforeEach(func() {
   177  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   178  				Path: "/depot/some-id/net.sh",
   179  				Args: []string{"get_ingress_info"},
   180  				Env:  []string{"ID=some-id"},
   181  			}, func(*exec.Cmd) error {
   182  				return disaster
   183  			})
   184  		})
   185  
   186  		It("returns the error", func() {
   187  			_, err := bandwidthManager.GetLimits(logger)
   188  			Expect(err).To(Equal(disaster))
   189  		})
   190  	})
   191  
   192  	Context("when net.sh get_ingress_info output doesn't match", func() {
   193  		It("returns 0 limits and does not error", func() {
   194  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   195  				Path: "/depot/some-id/net.sh",
   196  				Args: []string{"get_egress_info"},
   197  				Env:  []string{"ID=some-id"},
   198  			}, func(cmd *exec.Cmd) error {
   199  				cmd.Stdout.Write([]byte(`qdisc tbf 8010: root refcnt 2 rate 8192bit burst 64Kb lat 24.4ms
   200  qdisc ingress ffff: parent ffff:fff1 ----------------
   201  `))
   202  				return nil
   203  			})
   204  
   205  			fakeRunner.WhenRunning(fake_command_runner.CommandSpec{
   206  				Path: "/depot/some-id/net.sh",
   207  				Args: []string{"get_ingress_info"},
   208  				Env:  []string{"ID=some-id"},
   209  			}, func(cmd *exec.Cmd) error {
   210  				cmd.Stdout.Write([]byte(``))
   211  				return nil
   212  			})
   213  
   214  			usage, err := bandwidthManager.GetLimits(logger)
   215  			Expect(err).ToNot(HaveOccurred())
   216  
   217  			Expect(usage.InRate).To(Equal(uint64(1024)))
   218  			Expect(usage.InBurst).To(Equal(uint64(65536)))
   219  
   220  			Expect(usage.OutRate).To(Equal(uint64(0)))
   221  			Expect(usage.OutBurst).To(Equal(uint64(0)))
   222  		})
   223  	})
   224  })