github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/package_stemcell/packagers/vmdk_packager_test.go (about)

     1  package packagers_test
     2  
     3  import (
     4  	"crypto/sha1"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/golang/mock/gomock"
    13  
    14  	. "github.com/cloudfoundry-incubator/stembuild/filesystem/mock"
    15  	"github.com/cloudfoundry-incubator/stembuild/package_stemcell/package_parameters"
    16  	"github.com/cloudfoundry-incubator/stembuild/package_stemcell/packagers"
    17  	"github.com/cloudfoundry-incubator/stembuild/test/helpers"
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  )
    21  
    22  var _ = Describe("VmdkPackager", func() {
    23  	var tmpDir string
    24  	var stembuildConfig package_parameters.VmdkPackageParameters
    25  	var c packagers.VmdkPackager
    26  
    27  	BeforeEach(func() {
    28  		var err error
    29  		tmpDir, err = ioutil.TempDir("", "")
    30  		Expect(err).NotTo(HaveOccurred())
    31  
    32  		stembuildConfig = package_parameters.VmdkPackageParameters{
    33  			OSVersion: "2012R2",
    34  			Version:   "1200.1",
    35  		}
    36  
    37  		c = packagers.VmdkPackager{
    38  			Stop:         make(chan struct{}),
    39  			Debugf:       func(format string, a ...interface{}) {},
    40  			BuildOptions: stembuildConfig,
    41  		}
    42  	})
    43  
    44  	AfterEach(func() {
    45  		Expect(os.RemoveAll(tmpDir)).To(Succeed())
    46  	})
    47  
    48  	Describe("vmdk", func() {
    49  		Context("valid vmdk file specified", func() {
    50  			It("should be valid", func() {
    51  
    52  				vmdk, err := ioutil.TempFile("", "temp.vmdk")
    53  				Expect(err).ToNot(HaveOccurred())
    54  				defer os.Remove(vmdk.Name())
    55  
    56  				valid, err := packagers.IsValidVMDK(vmdk.Name())
    57  				Expect(err).To(BeNil())
    58  				Expect(valid).To(BeTrue())
    59  			})
    60  		})
    61  		Context("invalid vmdk file specified", func() {
    62  			It("should be invalid", func() {
    63  				valid, err := packagers.IsValidVMDK(filepath.Join("..", "out", "invalid"))
    64  				Expect(err).To(HaveOccurred())
    65  				Expect(valid).To(BeFalse())
    66  			})
    67  		})
    68  	})
    69  
    70  	Describe("CreateImage", func() {
    71  
    72  		It("successfully creates an image tarball", func() {
    73  			c.BuildOptions.VMDKFile = filepath.Join("..", "..", "test", "data", "expected.vmdk")
    74  			err := c.CreateImage()
    75  			Expect(err).NotTo(HaveOccurred())
    76  
    77  			// the image will be saved to the VmdkPackager's temp directory
    78  			tmpdir, err := c.TempDir()
    79  			Expect(err).NotTo(HaveOccurred())
    80  
    81  			outputImagePath := filepath.Join(tmpdir, "image")
    82  			Expect(c.Image).To(Equal(outputImagePath))
    83  
    84  			// Make sure the sha1 sum is correct
    85  			h := sha1.New()
    86  			f, err := os.Open(c.Image)
    87  			Expect(err).NotTo(HaveOccurred())
    88  
    89  			_, err = io.Copy(h, f)
    90  			Expect(err).NotTo(HaveOccurred())
    91  
    92  			actualShasum := fmt.Sprintf("%x", h.Sum(nil))
    93  			Expect(c.Sha1sum).To(Equal(actualShasum))
    94  
    95  			// expect the image ova to contain only the following file names
    96  			expectedNames := []string{
    97  				"image.ovf",
    98  				"image.mf",
    99  				"image-disk1.vmdk",
   100  			}
   101  
   102  			imageDir, err := helpers.ExtractGzipArchive(c.Image)
   103  			Expect(err).NotTo(HaveOccurred())
   104  			list, err := ioutil.ReadDir(imageDir)
   105  			Expect(err).NotTo(HaveOccurred())
   106  
   107  			var names []string
   108  			infos := make(map[string]os.FileInfo)
   109  			for _, fi := range list {
   110  				names = append(names, fi.Name())
   111  				infos[fi.Name()] = fi
   112  			}
   113  			Expect(names).To(ConsistOf(expectedNames))
   114  
   115  			// the vmx template should generate an ovf file that
   116  			// does not contain an ethernet section.
   117  			ovf := filepath.Join(imageDir, "image.ovf")
   118  			ovfFile, err := helpers.ReadFile(ovf)
   119  			Expect(err).NotTo(HaveOccurred())
   120  			Expect(ovfFile).NotTo(MatchRegexp(`(?i)ethernet`))
   121  		})
   122  	})
   123  
   124  	Describe("ValidateFreeSpaceForPackage", func() {
   125  		var (
   126  			mockCtrl       *gomock.Controller
   127  			mockFileSystem *MockFileSystem
   128  		)
   129  
   130  		Context("When VMDK file is invalid", func() {
   131  			It("returns an error", func() {
   132  				c.BuildOptions.VMDKFile = ""
   133  
   134  				mockCtrl = gomock.NewController(GinkgoT())
   135  				mockFileSystem = NewMockFileSystem(mockCtrl)
   136  
   137  				err := c.ValidateFreeSpaceForPackage(mockFileSystem)
   138  				Expect(err).To(HaveOccurred())
   139  				Expect(err.Error()).To(ContainSubstring("could not get vmdk info"))
   140  
   141  			})
   142  		})
   143  
   144  		Context("When filesystem has enough free space for stemcell (twice the size of the expected free space)", func() {
   145  			It("does not return an error", func() {
   146  				c.BuildOptions.VMDKFile = filepath.Join("..", "..", "test", "data", "expected.vmdk")
   147  
   148  				mockCtrl = gomock.NewController(GinkgoT())
   149  				mockFileSystem = NewMockFileSystem(mockCtrl)
   150  
   151  				vmdkFile, err := os.Stat(c.BuildOptions.VMDKFile)
   152  				Expect(err).ToNot(HaveOccurred())
   153  
   154  				testVmdkSize := vmdkFile.Size()
   155  				expectFreeSpace := uint64(testVmdkSize)*2 + (packagers.Gigabyte / 2)
   156  
   157  				directoryPath := filepath.Dir(c.BuildOptions.VMDKFile)
   158  				mockFileSystem.EXPECT().GetAvailableDiskSpace(directoryPath).Return(uint64(expectFreeSpace*2), nil).AnyTimes()
   159  
   160  				err = c.ValidateFreeSpaceForPackage(mockFileSystem)
   161  				Expect(err).To(Not(HaveOccurred()))
   162  
   163  			})
   164  		})
   165  		Context("When filesystem does not have enough free space for stemcell (half the size of the expected free space", func() {
   166  			It("returns error", func() {
   167  				c.BuildOptions.VMDKFile = filepath.Join("..", "..", "test", "data", "expected.vmdk")
   168  
   169  				mockCtrl = gomock.NewController(GinkgoT())
   170  				mockFileSystem = NewMockFileSystem(mockCtrl)
   171  
   172  				vmdkFile, err := os.Stat(c.BuildOptions.VMDKFile)
   173  				Expect(err).ToNot(HaveOccurred())
   174  
   175  				testVmdkSize := vmdkFile.Size()
   176  				expectFreeSpace := uint64(testVmdkSize)*2 + (packagers.Gigabyte / 2)
   177  
   178  				directoryPath := filepath.Dir(c.BuildOptions.VMDKFile)
   179  				mockFileSystem.EXPECT().GetAvailableDiskSpace(directoryPath).Return(uint64(expectFreeSpace/2), nil).AnyTimes()
   180  
   181  				err = c.ValidateFreeSpaceForPackage(mockFileSystem)
   182  
   183  				Expect(err).To(HaveOccurred())
   184  
   185  				expectedErrorMsg := fmt.Sprintf("Not enough space to create stemcell. Free up ")
   186  				Expect(err.Error()).To(ContainSubstring(expectedErrorMsg))
   187  			})
   188  		})
   189  
   190  		Context("When filesystem fails to provide free space", func() {
   191  			It("returns error specifying that given disk could not provide free space", func() {
   192  				c.BuildOptions.VMDKFile = filepath.Join("..", "..", "test", "data", "expected.vmdk")
   193  
   194  				mockCtrl = gomock.NewController(GinkgoT())
   195  				mockFileSystem = NewMockFileSystem(mockCtrl)
   196  
   197  				directoryPath := filepath.Dir(c.BuildOptions.VMDKFile)
   198  				mockFileSystem.EXPECT().GetAvailableDiskSpace(directoryPath).Return(uint64(4), errors.New("some error")).AnyTimes()
   199  
   200  				err := c.ValidateFreeSpaceForPackage(mockFileSystem)
   201  
   202  				Expect(err).To(HaveOccurred())
   203  				expectedErrorMsg := fmt.Sprintf("could not check free space on disk: ")
   204  				Expect(err.Error()).To(ContainSubstring(expectedErrorMsg))
   205  			})
   206  		})
   207  	})
   208  })