9 type TrashWorkerTestData struct {
30 /* Delete block that does not exist in any of the keep volumes.
33 func TestTrashWorkerIntegration_GetNonExistingLocator(t *testing.T) {
35 testData := TrashWorkerTestData{
36 Locator1: "5d41402abc4b2a76b9719d911017c592",
37 Block1: []byte("hello"),
39 Locator2: "5d41402abc4b2a76b9719d911017c592",
40 Block2: []byte("hello"),
44 DeleteLocator: "5d41402abc4b2a76b9719d911017c592",
46 ExpectLocator1: false,
47 ExpectLocator2: false,
49 performTrashWorkerTest(testData, t)
52 /* Delete a block that exists on volume 1 of the keep servers.
53 Expect the second locator in volume 2 to be unaffected.
55 func TestTrashWorkerIntegration_LocatorInVolume1(t *testing.T) {
57 testData := TrashWorkerTestData{
66 DeleteLocator: TestHash, // first locator
68 ExpectLocator1: false,
71 performTrashWorkerTest(testData, t)
74 /* Delete a block that exists on volume 2 of the keep servers.
75 Expect the first locator in volume 1 to be unaffected.
77 func TestTrashWorkerIntegration_LocatorInVolume2(t *testing.T) {
79 testData := TrashWorkerTestData{
88 DeleteLocator: TestHash2, // locator 2
91 ExpectLocator2: false,
93 performTrashWorkerTest(testData, t)
96 /* Delete a block with matching mtime for locator in both volumes.
97 Expect locator to be deleted from both volumes.
99 func TestTrashWorkerIntegration_LocatorInBothVolumes(t *testing.T) {
101 testData := TrashWorkerTestData{
110 DeleteLocator: TestHash,
112 ExpectLocator1: false,
113 ExpectLocator2: false,
115 performTrashWorkerTest(testData, t)
118 /* Same locator with different Mtimes exists in both volumes.
119 Delete the second and expect the first to be still around.
121 func TestTrashWorkerIntegration_MtimeMatchesForLocator1ButNotForLocator2(t *testing.T) {
123 testData := TrashWorkerTestData{
131 DifferentMtimes: true,
133 DeleteLocator: TestHash,
135 ExpectLocator1: true,
136 ExpectLocator2: false,
138 performTrashWorkerTest(testData, t)
141 /* Two different locators in volume 1.
143 Expect the other unaffected.
145 func TestTrashWorkerIntegration_TwoDifferentLocatorsInVolume1(t *testing.T) {
147 testData := TrashWorkerTestData{
155 CreateInVolume1: true,
157 DeleteLocator: TestHash, // locator 1
159 ExpectLocator1: false,
160 ExpectLocator2: true,
162 performTrashWorkerTest(testData, t)
165 /* Allow default Trash Life time to be used. Thus, the newly created block
166 will not be deleted because its Mtime is within the trash life time.
168 func TestTrashWorkerIntegration_SameLocatorInTwoVolumesWithDefaultTrashLifeTime(t *testing.T) {
170 testData := TrashWorkerTestData{
178 CreateInVolume1: true,
180 UseTrashLifeTime: true,
182 DeleteLocator: TestHash, // locator 1
184 // Since trash life time is in effect, block won't be deleted.
185 ExpectLocator1: true,
186 ExpectLocator2: true,
188 performTrashWorkerTest(testData, t)
191 /* Delete a block with matching mtime for locator in both volumes, but neverDelete is true,
192 so block won't be deleted.
194 func TestTrashWorkerIntegration_NeverDelete(t *testing.T) {
196 testData := TrashWorkerTestData{
205 DeleteLocator: TestHash,
207 ExpectLocator1: true,
208 ExpectLocator2: true,
210 performTrashWorkerTest(testData, t)
213 /* Perform the test */
214 func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
215 // Create Keep Volumes
216 KeepVM = MakeTestVolumeManager(2)
220 vols := KeepVM.AllWritable()
221 if testData.CreateData {
222 vols[0].Put(testData.Locator1, testData.Block1)
223 vols[0].Put(testData.Locator1+".meta", []byte("metadata"))
225 if testData.CreateInVolume1 {
226 vols[0].Put(testData.Locator2, testData.Block2)
227 vols[0].Put(testData.Locator2+".meta", []byte("metadata"))
229 vols[1].Put(testData.Locator2, testData.Block2)
230 vols[1].Put(testData.Locator2+".meta", []byte("metadata"))
234 oldBlockTime := time.Now().Add(-blobSignatureTTL - time.Minute)
236 // Create TrashRequest for the test
237 trashRequest := TrashRequest{
238 Locator: testData.DeleteLocator,
239 BlockMtime: oldBlockTime.UnixNano(),
242 // Run trash worker and put the trashRequest on trashq
243 trashList := list.New()
244 trashList.PushBack(trashRequest)
245 trashq = NewWorkQueue()
248 if !testData.UseTrashLifeTime {
249 // Trash worker would not delete block if its Mtime is
250 // within trash life time. Back-date the block to
251 // allow the deletion to succeed.
252 for _, v := range vols {
253 v.(*MockVolume).Timestamps[testData.DeleteLocator] = oldBlockTime
254 if testData.DifferentMtimes {
255 oldBlockTime = oldBlockTime.Add(time.Second)
259 go RunTrashWorker(trashq)
261 // Install gate so all local operations block until we say go
262 gate := make(chan struct{})
263 for _, v := range vols {
264 v.(*MockVolume).Gate = gate
267 assertStatusItem := func(k string, expect float64) {
268 if v := getStatusItem("TrashQueue", k); v != expect {
269 t.Errorf("Got %s %v, expected %v", k, v, expect)
273 assertStatusItem("InProgress", 0)
274 assertStatusItem("Queued", 0)
276 listLen := trashList.Len()
277 trashq.ReplaceQueue(trashList)
279 // Wait for worker to take request(s)
280 expectEqualWithin(t, time.Second, listLen, func() interface{} { return trashq.Status().InProgress })
282 // Ensure status.json also reports work is happening
283 assertStatusItem("InProgress", float64(1))
284 assertStatusItem("Queued", float64(listLen-1))
286 // Let worker proceed
289 // Wait for worker to finish
290 expectEqualWithin(t, time.Second, 0, func() interface{} { return trashq.Status().InProgress })
292 // Verify Locator1 to be un/deleted as expected
293 buf := make([]byte, BlockSize)
294 size, err := GetBlock(testData.Locator1, buf, nil)
295 if testData.ExpectLocator1 {
296 if size == 0 || err != nil {
297 t.Errorf("Expected Locator1 to be still present: %s", testData.Locator1)
300 if size > 0 || err == nil {
301 t.Errorf("Expected Locator1 to be deleted: %s", testData.Locator1)
305 // Verify Locator2 to be un/deleted as expected
306 if testData.Locator1 != testData.Locator2 {
307 size, err = GetBlock(testData.Locator2, buf, nil)
308 if testData.ExpectLocator2 {
309 if size == 0 || err != nil {
310 t.Errorf("Expected Locator2 to be still present: %s", testData.Locator2)
313 if size > 0 || err == nil {
314 t.Errorf("Expected Locator2 to be deleted: %s", testData.Locator2)
319 // The DifferentMtimes test puts the same locator in two
320 // different volumes, but only one copy has an Mtime matching
321 // the trash request.
322 if testData.DifferentMtimes {
324 for _, volume := range KeepVM.AllReadable() {
325 buf := make([]byte, BlockSize)
326 if _, err := volume.Get(testData.Locator1, buf); err == nil {
327 locatorFoundIn = locatorFoundIn + 1
330 if locatorFoundIn != 1 {
331 t.Errorf("Found %d copies of %s, expected 1", locatorFoundIn, testData.Locator1)