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
7 changes: 7 additions & 0 deletions case-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>

<!--不同版本用例间 diff 及 patch 用-->
<dependency>
<groupId>com.flipkart.zjsonpatch</groupId>
<artifactId>zjsonpatch</artifactId>
<version>0.4.11</version>
</dependency>
</dependencies>

<build>
Expand Down
5 changes: 5 additions & 0 deletions case-server/sql/case-server.sql
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,8 @@ INSERT INTO `authority` (id,authority_name,authority_desc,authority_content) VAL
INSERT INTO `authority` (id,authority_name,authority_desc,authority_content) VALUES (2, 'ROLE_ADMIN', '管理员', '/api/dir/list,/api/backup/**,/api/record/**,/api/file/**,/api/user/**,/api/case/**');
INSERT INTO `authority` (id,authority_name,authority_desc,authority_content) VALUES (3, 'ROLE_SA', '超级管理员','/api/**');

# 添加2个字段,记录每次保存的增量修改内容

ALTER TABLE `case_manager`.`case_backup`
ADD COLUMN `json_patch` longtext NULL COMMENT '本次修改内容的 json-patch 。如果是冲突,保存的是存在冲突无法应用的 patch ',
ADD COLUMN `is_conflict` tinyint(1) NULL COMMENT '是否为冲突保存的副本';
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.xiaoju.framework.constants.enums;

public enum ApplyPatchFlagEnum {

/**
* 忽略对 order replace 操作时出现的冲突
* 在测试任务编辑时,因为展示的脑图是完整脑图的子集,各个字段的 order 值和完整版会不一样
* 所以一旦改动节点顺序,replace 原始的 order 值基本都会是错的,引起冲突
*/
IGNORE_REPLACE_ORDER_CONFLICT,

/**
* 忽略对节点展开属性变更导致的冲突。这个冲突不影响实际用例数据,只影响展示效果
*/
IGNORE_EXPAND_STATE_CONFLICT
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public enum StatusCode implements Status {
WS_UNKNOWN_ERROR(100010, "websocket访问异常"),
AUTHORITY_ERROR(100011, "权限认证错误"),
ASPECT_ERROR(100012, "权限内部处理错误"),
SAVE_CONFLICT(20002, "本次修改内容和数据库最新版本存在冲突"),

// 内部异常
INTERNAL_ERROR(10400, "内部参数校验或逻辑出错"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ public Response<List<CaseBackup>> getBackupByCaseId(@RequestParam @NotNull(messa
return Response.success(caseBackupService.getBackupByCaseId(caseId, beginTime, endTime));
}

/**
* 获取单个备份记录
* @param backupId 备份记录对应的 id
* @return
*/
@GetMapping(value = "/getBackupById")
public Response<CaseBackup> getBackupById(@RequestParam @NotNull(message = "备份记录id为空") Long backupId) {
CaseBackup caseBackup = caseBackupService.getBackupById(backupId);
if (caseBackup == null) {
return Response.build(StatusCode.NOT_FOUND_ENTITY, String.format("未找到备份记录id为 %d 的备份记录", backupId));
}
return Response.success(caseBackup);
}

/**
* 删除某个用例所有的备份记录
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ public Response<?> updateWsCase(@RequestBody WsSaveReq req) {
caseService.wsSave(req);
return Response.success();
} catch (CaseServerException e) {
throw new CaseServerException(e.getLocalizedMessage(), e.getStatus());
LOGGER.error("[Case Update]Update test case failed. params={}.", req.toString(), e);
return Response.build(e.getStatus().getStatus(), e.getMessage());
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("[Case Update]Update test case failed. params={} e={} ", req.toString(), e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.xiaoju.framework.entity.dto;

import lombok.Data;

import java.util.List;

@Data
public class ApplyPatchResultDto {

/**
* 应用了不冲突patch后的json
*/
String jsonAfterPatch;

/**
* 存在冲突无法应用的 patch
*/
List<String> conflictPatch;

/**
* 无冲突已应用的 patch
*/
List<String> applyPatch;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,13 @@ public class CaseBackup {
private String recordContent;
private String extra;
private Integer isDelete;
/**
* 本次变更应用的 patch 内容。如果是冲突副本,则此处记录的是冲突无法应用的 patch 内容
*/
private String jsonPatch;

/**
* 是否为保存冲突时记录的副本
*/
private Boolean isConflict;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public class WsSaveReq implements ParamValidate {
*/
private String caseContent;

/**
* 改动前的内容。可能是 record 的,也可能是 testcase 的。若提供,会进行增量保存。若不提供,进行全量保存
*/
private String baseCaseContent;

private Long id;

private String modifier;
Expand All @@ -29,6 +34,11 @@ public class WsSaveReq implements ParamValidate {
*/
private Long recordId;

/**
* 保存理由。若不为空,会作为历史记录的 title
*/
private String saveReason;

@Override
public void validate() {
if (StringUtils.isEmpty(caseContent)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
public interface CaseBackupMapper {

/**
* 获取一份用例下所有的用例备份记录
* 获取一份用例下所有的用例备份记录
*
* @param caseId 用例id
* @param beginTime 开始时间
* @param endTime 结束时间
* @return 所有备份记录
*/
List<CaseBackup> selectByCaseId(@Param("caseId") Long caseId,
@Param("beginTime") Date beginTime,
@Param("endTime") Date endTime);
@Param("beginTime") Date beginTime,
@Param("endTime") Date endTime);

/**
* 删除一批备份记录
Expand All @@ -46,4 +46,11 @@ List<CaseBackup> selectByCaseId(@Param("caseId") Long caseId,
* @return int
*/
int insert(CaseBackup caseBackup);

/**
* 根据备份记录id获取单条备份记录
* @param id 备份记录id
* @return
*/
CaseBackup selectOne(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ public interface CaseBackupService {
* @return int
*/
int deleteBackup(Long caseId);

/**
* 根据 id 获取备份记录
* @param backupId 备份记录id
* @return
*/
CaseBackup getBackupById(Long backupId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,5 @@ public interface CaseService {
*
* @param req 请求体
*/
void wsSave(WsSaveReq req);
String wsSave(WsSaveReq req);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package com.xiaoju.framework.service.impl;

import com.xiaoju.framework.constants.enums.StatusCode;
import com.xiaoju.framework.entity.exception.CaseServerException;
import com.xiaoju.framework.entity.persistent.CaseBackup;
import com.xiaoju.framework.mapper.CaseBackupMapper;
import com.xiaoju.framework.service.CaseBackupService;
import com.xiaoju.framework.util.MinderJsonPatchUtil;
import com.xiaoju.framework.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;

Expand Down Expand Up @@ -70,4 +76,28 @@ private Date transferTime(String time) {
}
return TimeUtil.transferStrToDateInSecond(time);
}

@Override
public CaseBackup getBackupById(Long backupId) {
CaseBackup caseBackup = caseBackupMapper.selectOne(backupId);

if (StringUtils.isEmpty(caseBackup.getJsonPatch())) {
// 老的数据没有 json-patch 记录,直接返回即可
return caseBackup;
}

try {
LOGGER.info("patch 内容: " + caseBackup.getJsonPatch());
caseBackup.setCaseContent(MinderJsonPatchUtil.markJsonPatchOnMinderContent(
caseBackup.getJsonPatch(),
caseBackup.getCaseContent()));
} catch (IOException | IllegalArgumentException e) {
throw new CaseServerException("添加标记出错,存储的 json-patch 的格式不正确", e, StatusCode.DATA_FORMAT_ERROR);
} catch (Exception e) {
// 其他异常,一般是标记失败造成。先记录一个 warning 即可,然后返回的内容就不做标记直接返回
LOGGER.warn("patch标记失败,backupId 为 {} ", caseBackup.getId(), e);
}

return caseBackup;
}
}
Loading