Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions conf/db/zsv/V5.1.0__schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,8 @@ CREATE TABLE IF NOT EXISTS `zstack`.`ResNotifyWebhookRefVO` (
CONSTRAINT `fk_ResNotifyWebhookRefVO_ResNotifySubscriptionVO`
FOREIGN KEY (`uuid`) REFERENCES `ResNotifySubscriptionVO`(`uuid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELETE shadow FROM ImageCacheShadowVO shadow
LEFT JOIN PrimaryStorageEO ps ON shadow.primaryStorageUuid = ps.uuid
WHERE ps.uuid IS NULL;
CALL ADD_CONSTRAINT('ImageCacheShadowVO', 'fkImageCacheShadowVOPrimaryStorageEOCascade', 'primaryStorageUuid', 'PrimaryStorageEO', 'uuid', 'CASCADE');
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package org.zstack.test.integration.storage.primary.local

import org.springframework.http.HttpEntity
import org.zstack.compute.vm.VmGlobalConfig
import org.zstack.core.db.DatabaseFacade
import org.zstack.core.db.Q
import org.zstack.header.image.ImageConstant.ImageMediaType
import org.zstack.header.network.service.NetworkServiceType
import org.zstack.header.storage.primary.ImageCacheState
import org.zstack.header.storage.primary.ImageCacheShadowVO
import org.zstack.header.storage.primary.ImageCacheShadowVO_
import org.zstack.header.storage.primary.ImageCacheVO
Expand All @@ -15,6 +18,7 @@ import org.zstack.sdk.ApplianceVmInventory
import org.zstack.sdk.ImageInventory
import org.zstack.sdk.PrimaryStorageInventory
import org.zstack.sdk.VmInstanceInventory
import org.zstack.sdk.ZoneInventory
import org.zstack.storage.primary.PrimaryStorageGlobalConfig
import org.zstack.storage.primary.local.LocalStorageKvmBackend
import org.zstack.test.integration.storage.StorageTest
Expand All @@ -24,6 +28,7 @@ import org.zstack.utils.data.SizeUnit
import org.zstack.utils.gson.JSONObjectUtil
import org.zstack.utils.path.PathUtil

import java.sql.Timestamp
import java.util.concurrent.TimeUnit

/**
Expand Down Expand Up @@ -171,6 +176,7 @@ class CleanImageCacheOnLocalPrimaryStorageCase extends SubCase{
void test() {
env.create {
testDelete()
testDeleteLocalStorageCascadesImageCacheShadow()
}
}

Expand Down Expand Up @@ -224,4 +230,40 @@ class CleanImageCacheOnLocalPrimaryStorageCase extends SubCase{
.isExists()
}
}
}

void testDeleteLocalStorageCascadesImageCacheShadow() {
ZoneInventory zone = env.inventoryByName("zone")
PrimaryStorageInventory shadowPs = addLocalPrimaryStorage {
name = "shadow-cascade-local"
url = "/local_ps_shadow"
zoneUuid = zone.uuid
}

DatabaseFacade dbf = bean(DatabaseFacade.class)
ImageCacheShadowVO shadow = new ImageCacheShadowVO()
shadow.primaryStorageUuid = shadowPs.uuid
shadow.imageUuid = "test-image-cache-shadow"
shadow.installUrl = "hostUuid://test-host//local_ps_shadow/imagecache/test-image-cache-shadow.qcow2"
shadow.mediaType = ImageMediaType.RootVolumeTemplate
shadow.size = SizeUnit.GIGABYTE.toByte(1)
shadow.state = ImageCacheState.ready
shadow.md5sum = ""
shadow.createDate = new Timestamp(System.currentTimeMillis())
shadow.lastOpDate = shadow.createDate
dbf.persist(shadow)

long beforeDelete = Q.New(ImageCacheShadowVO.class)
.eq(ImageCacheShadowVO_.primaryStorageUuid, shadowPs.uuid)
.count()
assert beforeDelete == 1 : "ImageCacheShadowVO 测试数据未创建: expected=1 actual=${beforeDelete} primaryStorageUuid=${shadowPs.uuid}"

deletePrimaryStorage {
uuid = shadowPs.uuid
}

long afterDelete = Q.New(ImageCacheShadowVO.class)
.eq(ImageCacheShadowVO_.primaryStorageUuid, shadowPs.uuid)
.count()
assert afterDelete == 0 : "删除本地存储后 ImageCacheShadowVO 未级联删除: expected=0 actual=${afterDelete} primaryStorageUuid=${shadowPs.uuid}"
}
}