1package disk_test
2
3import (
4	"errors"
5	. "github.com/onsi/ginkgo"
6	. "github.com/onsi/gomega"
7
8	bicloud "github.com/cloudfoundry/bosh-cli/cloud"
9	biconfig "github.com/cloudfoundry/bosh-cli/config"
10	boshlog "github.com/cloudfoundry/bosh-utils/logger"
11	biproperty "github.com/cloudfoundry/bosh-utils/property"
12	fakesys "github.com/cloudfoundry/bosh-utils/system/fakes"
13	fakeuuid "github.com/cloudfoundry/bosh-utils/uuid/fakes"
14
15	fakebicloud "github.com/cloudfoundry/bosh-cli/cloud/fakes"
16
17	. "github.com/cloudfoundry/bosh-cli/deployment/disk"
18)
19
20var _ = Describe("Disk", func() {
21	var (
22		disk                Disk
23		diskCloudProperties biproperty.Map
24		fakeCloud           *fakebicloud.FakeCloud
25		diskRepo            biconfig.DiskRepo
26		fakeUUIDGenerator   *fakeuuid.FakeGenerator
27	)
28
29	BeforeEach(func() {
30		diskCloudProperties = biproperty.Map{
31			"fake-cloud-property-key": "fake-cloud-property-value",
32		}
33		fakeCloud = fakebicloud.NewFakeCloud()
34
35		diskRecord := biconfig.DiskRecord{
36			CID:             "fake-disk-cid",
37			Size:            1024,
38			CloudProperties: diskCloudProperties,
39		}
40
41		fs := fakesys.NewFakeFileSystem()
42		logger := boshlog.NewLogger(boshlog.LevelNone)
43		fakeUUIDGenerator = &fakeuuid.FakeGenerator{}
44		//		todo: come back to this?
45		deploymentStateService := biconfig.NewFileSystemDeploymentStateService(fs, fakeUUIDGenerator, logger, "/fake/path")
46		diskRepo = biconfig.NewDiskRepo(deploymentStateService, fakeUUIDGenerator)
47
48		disk = NewDisk(diskRecord, fakeCloud, diskRepo)
49	})
50
51	Describe("NeedsMigration", func() {
52		Context("when size is different", func() {
53			It("returns true", func() {
54				needsMigration := disk.NeedsMigration(2048, diskCloudProperties)
55				Expect(needsMigration).To(BeTrue())
56			})
57		})
58
59		Context("when cloud properties are different", func() {
60			It("returns true", func() {
61				newDiskCloudProperties := biproperty.Map{
62					"fake-cloud-property-key": "new-fake-cloud-property-value",
63				}
64
65				needsMigration := disk.NeedsMigration(1024, newDiskCloudProperties)
66				Expect(needsMigration).To(BeTrue())
67			})
68		})
69
70		Context("when cloud properties are nil", func() {
71			It("returns true", func() {
72				needsMigration := disk.NeedsMigration(1024, nil)
73				Expect(needsMigration).To(BeTrue())
74			})
75		})
76
77		Context("when size and cloud properties are the same", func() {
78			It("returns false", func() {
79				needsMigration := disk.NeedsMigration(1024, diskCloudProperties)
80				Expect(needsMigration).To(BeFalse())
81			})
82		})
83	})
84
85	Describe("Delete", func() {
86		It("deletes disk from cloud", func() {
87			err := disk.Delete()
88			Expect(err).ToNot(HaveOccurred())
89			Expect(fakeCloud.DeleteDiskInputs).To(Equal([]fakebicloud.DeleteDiskInput{
90				{
91					DiskCID: "fake-disk-cid",
92				},
93			}))
94		})
95
96		It("deletes disk from repo", func() {
97			_, err := diskRepo.Save("fake-disk-cid", 1024, diskCloudProperties)
98			Expect(err).ToNot(HaveOccurred())
99
100			err = disk.Delete()
101			Expect(err).ToNot(HaveOccurred())
102			diskRecords, err := diskRepo.All()
103			Expect(diskRecords).To(BeEmpty())
104		})
105
106		Context("when deleted disk is the current disk", func() {
107			BeforeEach(func() {
108				diskRecord, err := diskRepo.Save("fake-disk-cid", 1024, diskCloudProperties)
109				Expect(err).ToNot(HaveOccurred())
110
111				err = diskRepo.UpdateCurrent(diskRecord.ID)
112				Expect(err).ToNot(HaveOccurred())
113			})
114
115			It("clears current disk in the disk repo", func() {
116				err := disk.Delete()
117				Expect(err).ToNot(HaveOccurred())
118
119				_, found, err := diskRepo.FindCurrent()
120				Expect(err).ToNot(HaveOccurred())
121				Expect(found).To(BeFalse())
122			})
123		})
124
125		Context("when deleting disk in the cloud fails", func() {
126			BeforeEach(func() {
127				fakeCloud.DeleteDiskErr = errors.New("fake-delete-disk-error")
128			})
129
130			It("returns an error", func() {
131				err := disk.Delete()
132				Expect(err).To(HaveOccurred())
133				Expect(err.Error()).To(ContainSubstring("fake-delete-disk-error"))
134			})
135		})
136
137		Context("when deleting disk in the cloud fails with DiskNotFoundError", func() {
138			var deleteErr = bicloud.NewCPIError("delete_vm", bicloud.CmdError{
139				Type:    bicloud.DiskNotFoundError,
140				Message: "fake-disk-not-found-message",
141			})
142
143			BeforeEach(func() {
144				diskRecord, err := diskRepo.Save("fake-disk-cid", 1024, diskCloudProperties)
145				Expect(err).ToNot(HaveOccurred())
146
147				err = diskRepo.UpdateCurrent(diskRecord.ID)
148				Expect(err).ToNot(HaveOccurred())
149
150				fakeCloud.DeleteDiskErr = deleteErr
151			})
152
153			It("deletes disk in the cloud", func() {
154				err := disk.Delete()
155				Expect(err).To(HaveOccurred())
156				Expect(err).To(Equal(deleteErr))
157
158				Expect(fakeCloud.DeleteDiskInputs).To(Equal([]fakebicloud.DeleteDiskInput{
159					{
160						DiskCID: "fake-disk-cid",
161					},
162				}))
163			})
164
165			It("deletes disk in the disk repo", func() {
166				err := disk.Delete()
167				Expect(err).To(HaveOccurred())
168				Expect(err).To(Equal(deleteErr))
169
170				diskRecords, err := diskRepo.All()
171				Expect(diskRecords).To(BeEmpty())
172			})
173
174			It("clears current disk in the disk repo", func() {
175				err := disk.Delete()
176				Expect(err).To(HaveOccurred())
177				Expect(err).To(Equal(deleteErr))
178
179				_, found, err := diskRepo.FindCurrent()
180				Expect(err).ToNot(HaveOccurred())
181				Expect(found).To(BeFalse())
182			})
183		})
184	})
185})
186