github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/integration/lifecycle/destroy_test.go (about)

     1  package lifecycle_test
     2  
     3  import (
     4  	"compress/gzip"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  
    11  	"github.com/cloudfoundry-incubator/garden"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("Destroying a container", func() {
    17  	Context("when wshd goes away", func() {
    18  		Context("the container destruction", func() {
    19  			It("succeeds", func() {
    20  				client = startGarden()
    21  
    22  				container, err := client.Create(garden.ContainerSpec{})
    23  				Expect(err).ToNot(HaveOccurred())
    24  
    25  				info, err := container.Info()
    26  				Expect(err).ToNot(HaveOccurred())
    27  				pidFilePath := filepath.Join(info.ContainerPath, "run", "wshd.pid")
    28  
    29  				fileContents, err := ioutil.ReadFile(pidFilePath)
    30  				Expect(err).ToNot(HaveOccurred())
    31  				Expect(fileContents).ToNot(BeEmpty())
    32  
    33  				var pid int
    34  				n, err := fmt.Sscanf(string(fileContents), "%d", &pid)
    35  				Expect(err).ToNot(HaveOccurred())
    36  				Expect(n).To(Equal(1))
    37  
    38  				cmd := exec.Command("kill", "-9", fmt.Sprintf("%d", pid))
    39  				cmd.Stdout = GinkgoWriter
    40  				cmd.Stderr = GinkgoWriter
    41  				Expect(cmd.Run()).To(Succeed())
    42  
    43  				Expect(client.Destroy(container.Handle())).To(Succeed())
    44  			})
    45  		})
    46  	})
    47  
    48  	Context("when destroying a container with a disk limit", func() {
    49  		var tgzPath string
    50  
    51  		createContainer := func() (garden.Container, error) {
    52  			container, err := client.Create(garden.ContainerSpec{
    53  				Limits: garden.Limits{
    54  					Disk: garden.DiskLimits{
    55  						ByteHard: 100 * 1024 * 1024,
    56  						Scope:    garden.DiskLimitScopeExclusive,
    57  					},
    58  				},
    59  			})
    60  
    61  			return container, err
    62  		}
    63  
    64  		streamInDora := func(container garden.Container) error {
    65  			tgz, err := os.Open(tgzPath)
    66  			if err != nil {
    67  				return err
    68  			}
    69  
    70  			tarStream, err := gzip.NewReader(tgz)
    71  			if err != nil {
    72  				return err
    73  			}
    74  
    75  			err = container.StreamIn(garden.StreamInSpec{
    76  				User:      "root",
    77  				Path:      "/root/dora",
    78  				TarStream: tarStream,
    79  			})
    80  
    81  			return err
    82  		}
    83  
    84  		destroy := func(handle string) error {
    85  			err := client.Destroy(handle)
    86  			return err
    87  		}
    88  
    89  		entriesAmt := func(path string) int {
    90  			entries, err := ioutil.ReadDir(path)
    91  			Expect(err).NotTo(HaveOccurred())
    92  
    93  			return len(entries)
    94  		}
    95  
    96  		preloadRootfsInToGraph := func() {
    97  			container, err := createContainer()
    98  			Expect(err).NotTo(HaveOccurred())
    99  			Expect(destroy(container.Handle())).To(Succeed())
   100  		}
   101  
   102  		BeforeEach(func() {
   103  			tgzPath = os.Getenv("GARDEN_DORA_PATH")
   104  			if tgzPath == "" {
   105  				Skip("`GARDEN_DORA_PATH` is not set")
   106  			}
   107  		})
   108  
   109  		It("should remove the backing store for the container", func() {
   110  			client = startGarden()
   111  
   112  			preloadRootfsInToGraph()
   113  
   114  			beforeBsAmt := entriesAmt(filepath.Join(client.GraphPath, "backing_stores"))
   115  			beforeDiffAmt := entriesAmt(filepath.Join(client.GraphPath, "aufs", "diff"))
   116  			beforeMntAmt := entriesAmt(filepath.Join(client.GraphPath, "aufs", "mnt"))
   117  
   118  			containersAmt := 5
   119  
   120  			h := make(chan string, containersAmt)
   121  			createErrs := make(chan error, containersAmt)
   122  			destroyErrs := make(chan error, containersAmt)
   123  			for i := 0; i < containersAmt; i++ {
   124  				go func() {
   125  					defer GinkgoRecover()
   126  
   127  					container, err := createContainer()
   128  					if err != nil {
   129  						createErrs <- err
   130  						return
   131  					}
   132  
   133  					if err := streamInDora(container); err != nil {
   134  						createErrs <- err
   135  						return
   136  					}
   137  
   138  					h <- container.Handle()
   139  				}()
   140  			}
   141  
   142  			for i := 0; i < containersAmt; i++ {
   143  				select {
   144  				case handle := <-h:
   145  					go func() {
   146  						defer GinkgoRecover()
   147  
   148  						destroyErrs <- destroy(handle)
   149  					}()
   150  				case err := <-createErrs:
   151  					Fail(err.Error())
   152  				}
   153  			}
   154  
   155  			for i := 0; i < containersAmt; i++ {
   156  				e := <-destroyErrs
   157  				Expect(e).NotTo(HaveOccurred())
   158  			}
   159  
   160  			afterBsAmt := entriesAmt(filepath.Join(client.GraphPath, "backing_stores"))
   161  			Expect(afterBsAmt).To(Equal(beforeBsAmt))
   162  			afterDiffAmt := entriesAmt(filepath.Join(client.GraphPath, "aufs", "diff"))
   163  			Expect(afterDiffAmt).To(Equal(beforeDiffAmt))
   164  			afterMntAmt := entriesAmt(filepath.Join(client.GraphPath, "aufs", "mnt"))
   165  			Expect(afterMntAmt).To(Equal(beforeMntAmt))
   166  		})
   167  	})
   168  })