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

     1  package packagers_test
     2  
     3  import (
     4  	"archive/tar"
     5  	"bytes"
     6  	"compress/gzip"
     7  	"crypto/sha1"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"os"
    13  	"path"
    14  	"path/filepath"
    15  
    16  	. "github.com/cloudfoundry-incubator/stembuild/package_stemcell/packagers"
    17  
    18  	"github.com/cloudfoundry-incubator/stembuild/filesystem"
    19  	"github.com/cloudfoundry-incubator/stembuild/package_stemcell/packagers/packagersfakes"
    20  
    21  	"github.com/cloudfoundry-incubator/stembuild/package_stemcell/config"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("VcenterPackager", func() {
    27  
    28  	var outputDir string
    29  	var sourceConfig config.SourceConfig
    30  	var outputConfig config.OutputConfig
    31  	var fakeVcenterClient *packagersfakes.FakeIaasClient
    32  
    33  	BeforeEach(func() {
    34  		outputDir, _ = ioutil.TempDir(os.TempDir(), "vcenter-test-output-dir")
    35  		sourceConfig = config.SourceConfig{Password: "password", URL: "url", Username: "username", VmInventoryPath: "path/valid-vm-name"}
    36  		outputConfig = config.OutputConfig{Os: "2012R2", StemcellVersion: "1200.2", OutputDir: outputDir}
    37  		fakeVcenterClient = &packagersfakes.FakeIaasClient{}
    38  	})
    39  
    40  	AfterEach(func() {
    41  		_ = os.RemoveAll(outputDir)
    42  	})
    43  
    44  	Context("ValidateSourceParameters", func() {
    45  		It("returns an error if the vCenter url is invalid", func() {
    46  			fakeVcenterClient.ValidateUrlReturns(errors.New("vcenter client url error"))
    47  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
    48  
    49  			err := packager.ValidateSourceParameters()
    50  
    51  			Expect(err).To(HaveOccurred())
    52  			Expect(fakeVcenterClient.ValidateUrlCallCount()).To(Equal(1))
    53  			Expect(err.Error()).To(Equal("vcenter client url error"))
    54  
    55  		})
    56  		It("returns an error if the vCenter credentials are not valid", func() {
    57  			fakeVcenterClient.ValidateCredentialsReturns(errors.New("vcenter client credential error"))
    58  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
    59  
    60  			err := packager.ValidateSourceParameters()
    61  
    62  			Expect(err).To(HaveOccurred())
    63  			Expect(fakeVcenterClient.ValidateCredentialsCallCount()).To(Equal(1))
    64  			Expect(err.Error()).To(ContainSubstring("vcenter client credential error"))
    65  		})
    66  
    67  		It("returns an error if VM given does not exist ", func() {
    68  			fakeVcenterClient.FindVMReturns(errors.New("vcenter client vm error"))
    69  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
    70  
    71  			err := packager.ValidateSourceParameters()
    72  
    73  			Expect(err).To(HaveOccurred())
    74  			Expect(fakeVcenterClient.FindVMCallCount()).To(Equal(1))
    75  			Expect(err.Error()).To(Equal("vcenter client vm error"))
    76  		})
    77  		It("returns no error if all source parameters are valid", func() {
    78  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
    79  
    80  			err := packager.ValidateSourceParameters()
    81  
    82  			Expect(err).NotTo(HaveOccurred())
    83  		})
    84  	})
    85  	Context("ValidateFreeSpace", func() {
    86  		It("is a NOOP", func() {
    87  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
    88  			err := packager.ValidateFreeSpaceForPackage(&filesystem.OSFileSystem{})
    89  
    90  			Expect(err).To(Not(HaveOccurred()))
    91  		})
    92  	})
    93  
    94  	Describe("Package", func() {
    95  		var packager *VCenterPackager
    96  
    97  		AfterEach(func() {
    98  			_ = os.RemoveAll("./valid-vm-name")
    99  			_ = os.RemoveAll("image")
   100  		})
   101  
   102  		BeforeEach(func() {
   103  			packager = &VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
   104  
   105  			fakeVcenterClient.ExportVMStub = func(vmInventoryPath string, destination string) error {
   106  				vmName := path.Base(vmInventoryPath)
   107  				os.Mkdir(filepath.Join(destination, vmName), 0777)
   108  
   109  				testOvfName := "valid-vm-name.content"
   110  				err := ioutil.WriteFile(filepath.Join(filepath.Join(destination, vmName), testOvfName), []byte(""), 0777)
   111  				Expect(err).NotTo(HaveOccurred())
   112  				return nil
   113  			}
   114  		})
   115  
   116  		It("creates a valid stemcell in the output directory", func() {
   117  			err := packager.Package()
   118  
   119  			Expect(err).To(Not(HaveOccurred()))
   120  			stemcellFilename := StemcellFilename(packager.OutputConfig.StemcellVersion, packager.OutputConfig.Os)
   121  			stemcellFile := filepath.Join(packager.OutputConfig.OutputDir, stemcellFilename)
   122  			_, err = os.Stat(stemcellFile)
   123  
   124  			Expect(err).NotTo(HaveOccurred())
   125  			var actualStemcellManifestContent string
   126  			expectedManifestContent := `---
   127  name: bosh-vsphere-esxi-windows2012R2-go_agent
   128  version: '1200.2'
   129  api_version: 3
   130  sha1: %x
   131  operating_system: windows2012R2
   132  cloud_properties:
   133    infrastructure: vsphere
   134    hypervisor: esxi
   135  stemcell_formats:
   136  - vsphere-ovf
   137  - vsphere-ova
   138  `
   139  			var fileReader, _ = os.OpenFile(stemcellFile, os.O_RDONLY, 0777)
   140  			gzr, err := gzip.NewReader(fileReader)
   141  			Expect(err).ToNot(HaveOccurred())
   142  			defer gzr.Close()
   143  			tarfileReader := tar.NewReader(gzr)
   144  			count := 0
   145  
   146  			for {
   147  				header, err := tarfileReader.Next()
   148  				if err == io.EOF {
   149  					break
   150  				}
   151  
   152  				Expect(err).NotTo(HaveOccurred())
   153  
   154  				switch filepath.Base(header.Name) {
   155  				case "stemcell.MF":
   156  					buf := new(bytes.Buffer)
   157  					_, err = buf.ReadFrom(tarfileReader)
   158  					Expect(err).NotTo(HaveOccurred())
   159  					count++
   160  
   161  					actualStemcellManifestContent = buf.String()
   162  
   163  				case "image":
   164  					count++
   165  					actualSha1 := sha1.New()
   166  					io.Copy(actualSha1, tarfileReader)
   167  
   168  					expectedManifestContent = fmt.Sprintf(expectedManifestContent, actualSha1.Sum(nil))
   169  
   170  				default:
   171  
   172  					Fail(fmt.Sprintf("Found unknown file: %s", filepath.Base(header.Name)))
   173  				}
   174  			}
   175  			Expect(count).To(Equal(2))
   176  			Expect(actualStemcellManifestContent).To(Equal(expectedManifestContent))
   177  		})
   178  
   179  		It("removes all ethernet and floppy devices", func() {
   180  			fullDeviceList := []string{"video-674", "cdrom-12", "ps2-450", "ethernet-1", "floppy-8000", "floppy-9000", "video-500"}
   181  			expectedDeviceList := []string{"ethernet-1", "floppy-8000", "floppy-9000"}
   182  			fakeVcenterClient.ListDevicesReturns(fullDeviceList, nil)
   183  
   184  			err := packager.Package()
   185  
   186  			Expect(err).NotTo(HaveOccurred())
   187  
   188  			for i, device := range expectedDeviceList {
   189  				vmPath, deviceName := fakeVcenterClient.RemoveDeviceArgsForCall(i)
   190  				Expect(vmPath).To(Equal(sourceConfig.VmInventoryPath))
   191  				Expect(deviceName).To(Equal(device))
   192  			}
   193  		})
   194  
   195  		It("ejects all CD ROM devices", func() {
   196  			fullDeviceList := []string{"video-674", "cdrom-12", "ps2-450", "ethernet-1", "cdrom-123"}
   197  			expectedDeviceList := []string{"cdrom-12", "cdrom-123"}
   198  			fakeVcenterClient.ListDevicesReturns(fullDeviceList, nil)
   199  
   200  			err := packager.Package()
   201  
   202  			Expect(err).NotTo(HaveOccurred())
   203  
   204  			for i, device := range expectedDeviceList {
   205  				vmPath, deviceName := fakeVcenterClient.EjectCDRomArgsForCall(i)
   206  				Expect(vmPath).To(Equal(sourceConfig.VmInventoryPath))
   207  				Expect(deviceName).To(Equal(device))
   208  			}
   209  		})
   210  
   211  		It("Throws an error if the VCenter client fails to list devices", func() {
   212  			fakeVcenterClient.ListDevicesReturns([]string{}, errors.New("some client error"))
   213  
   214  			err := packager.Package()
   215  			Expect(err).To(MatchError("some client error"))
   216  		})
   217  
   218  		It("Throws an error if the VCenter client fails to remove a device", func() {
   219  			fakeVcenterClient.ListDevicesReturns([]string{"floppy-8000"}, nil)
   220  			fakeVcenterClient.RemoveDeviceReturns(errors.New("some client error"))
   221  
   222  			err := packager.Package()
   223  			Expect(err).To(MatchError("some client error"))
   224  		})
   225  
   226  		It("Returns a error message if exporting the VM fails", func() {
   227  			packager := VCenterPackager{SourceConfig: sourceConfig, OutputConfig: outputConfig, Client: fakeVcenterClient}
   228  			fakeVcenterClient.ExportVMReturns(errors.New("some client error"))
   229  			err := packager.Package()
   230  
   231  			Expect(fakeVcenterClient.ExportVMCallCount()).To(Equal(1))
   232  			vmPath, _ := fakeVcenterClient.ExportVMArgsForCall(0)
   233  			Expect(vmPath).To(Equal(sourceConfig.VmInventoryPath))
   234  			Expect(err.Error()).To(Equal("failed to export the prepared VM"))
   235  		})
   236  	})
   237  })