测试验收:补充一期后端业务场景测试

This commit is contained in:
wangzhibiao committed 2026-09-16 16:48:48 +08:00
1 parent 4d9601a4f1
commit 126dddfa7b
24 files changed
+2313

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
package scripts.qa;
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class CheckBindings {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
try (Connection conn = DriverManager.getConnection("jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8", "kingbase", pass)) {
System.out.println("--- TEACHERS WITH USER_ID ---");
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT t_id, t_name, user_id FROM public.train_teacher WHERE user_id IS NOT NULL")) {
while (rs.next()) {
System.out.println("Teacher t_id=" + rs.getString(1) + ", name=" + rs.getString(2) + ", user_id=" + rs.getObject(3));
}
}
System.out.println("--- STUDENTS WITH USER_ID ---");
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT s_id, s_name, user_id FROM public.train_student WHERE user_id IS NOT NULL")) {
while (rs.next()) {
System.out.println("Student s_id=" + rs.getString(1) + ", name=" + rs.getString(2) + ", user_id=" + rs.getObject(3));
}
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class CheckCr {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
try (Connection conn = DriverManager.getConnection("jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8", "kingbase", pass);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT class_room_id, room_name, room_status, del_flag FROM public.train_classroom_info")) {
while (rs.next()) {
System.out.println("CR: id=" + rs.getString(1) + ", name=" + rs.getString(2) + ", status=" + rs.getString(3) + ", delFlag=" + rs.getString(4));
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class CheckMappings {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
try (Connection conn = DriverManager.getConnection("jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8", "kingbase", pass);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT count(*) FROM public.train_external_resource_mapping")) {
if (rs.next()) {
System.out.println("DMS_MAPPINGS_COUNT=" + rs.getInt(1));
}
}
}
}
+32
View File
@@ -0,0 +1,32 @@
package scripts.qa;
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class CheckRolePermissions {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
try (Connection conn = DriverManager.getConnection("jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8", "kingbase", pass)) {
System.out.println("--- ROLE PERMISSIONS ---");
String sql = "SELECT r.role_id, r.role_name, r.role_key, m.menu_name, m.perms " +
"FROM public.sys_role r " +
"JOIN public.sys_role_menu rm ON r.role_id = rm.role_id " +
"JOIN public.sys_menu m ON rm.menu_id = m.menu_id " +
"WHERE r.role_id IN (3, 4, 5) AND m.perms IS NOT NULL AND m.perms != '' " +
"ORDER BY r.role_id, m.perms";
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql)) {
while (rs.next()) {
System.out.println(String.format("Role %d (%s, %s) -> Perm: %s (%s)",
rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(5), rs.getString(4)));
}
}
}
}
}
+103
View File
@@ -0,0 +1,103 @@
package scripts.qa;
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
import java.util.*;
public class CheckRound1State {
private static final String TARGET_DB = "railwaysystem_integrated_qa_20260916";
public static void main(String[] args) {
String dbUrl = "jdbc:kingbase8://127.0.0.1:4321/" + TARGET_DB + "?useUnicode=true&characterEncoding=utf8&currentSchema=public,sys_catalog";
String user = "kingbase";
String password = resolveDbPassword();
try {
Class.forName("com.kingbase8.Driver");
try (Connection conn = DriverManager.getConnection(dbUrl, user, password)) {
// Identity Gate
String currentDb = null;
String currentUser = null;
String srvAddr = null;
String srvPort = null;
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT current_database(), current_user, inet_server_addr(), inet_server_port()")) {
if (rs.next()) {
currentDb = rs.getString(1);
currentUser = rs.getString(2);
srvAddr = rs.getString(3);
srvPort = rs.getString(4);
}
}
System.out.println("CURRENT_DATABASE: " + currentDb);
System.out.println("CURRENT_USER: " + currentUser);
System.out.println("SERVER_ADDR: " + srvAddr);
System.out.println("SERVER_PORT: " + srvPort);
if (!TARGET_DB.equals(currentDb)) {
System.err.println("FATAL: Connected to wrong database: " + currentDb + " (Expected: " + TARGET_DB + ")");
System.exit(1);
}
System.out.println("DB_ENVIRONMENT = ISOLATED_QA");
// Check core business tables
String[] coreTables = new String[]{
"train_student",
"train_teacher",
"train_course",
"train_class_plan",
"train_plan_course",
"train_enrollment",
"train_lesson",
"train_accommodation",
"train_dorm_auth",
"train_external_resource_mapping",
"train_external_operation",
"train_student_checkin",
"train_class_report"
};
System.out.println("\n--- ROUND 1 STATE VALIDATION (ROW COUNTS) ---");
boolean allEmpty = true;
for (String t : coreTables) {
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT count(*) FROM " + t)) {
if (rs.next()) {
int cnt = rs.getInt(1);
System.out.println(String.format("%-35s : %d", t, cnt));
if (cnt > 0) allEmpty = false;
}
}
}
if (allEmpty) {
System.out.println("\nROUND 1 STATE VALIDATION: PASS (All core business tables empty)");
} else {
System.err.println("\nROUND 1 STATE VALIDATION: FAIL (Non-empty business tables found!)");
System.exit(1);
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
private static String resolveDbPassword() {
String env = System.getenv("DB_PASSWORD");
if (env != null && !env.isEmpty()) return env;
try {
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
if (yml.exists()) {
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) {
return line.trim().substring("password:".length()).trim();
}
}
}
} catch (Exception ignored) {}
return "123456";
}
}
+122
View File
@@ -0,0 +1,122 @@
package scripts.qa;
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
import java.util.*;
public class InitQaUsers {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
String dbUrl = "jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8";
try (Connection conn = DriverManager.getConnection(dbUrl, "kingbase", pass)) {
conn.setAutoCommit(false);
// 1. Get admin password hash
String adminHash = null;
Long adminDeptId = 103L;
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT password, dept_id FROM public.sys_user WHERE user_id = 1")) {
if (rs.next()) {
adminHash = rs.getString(1);
adminDeptId = rs.getLong(2);
}
}
if (adminHash == null) {
throw new IllegalStateException("admin user not found in public.sys_user!");
}
// Define QA accounts and roles
// Format: username, nick_name, roles
Object[][] qaUsers = new Object[][]{
{"qa_train_admin", "培训管理员", new Long[]{3L}},
{"qa_teacher_a", "教师A", new Long[]{4L}},
{"qa_teacher_b", "教师B", new Long[]{4L}},
{"qa_student_a", "学员A", new Long[]{5L}},
{"qa_student_b", "学员B", new Long[]{5L}},
{"qa_admin_teacher", "双重角色", new Long[]{1L, 4L}},
{"qa_role_nobody", "无业务身份", new Long[]{4L}}
};
for (Object[] u : qaUsers) {
String username = (String) u[0];
String nick = (String) u[1];
Long[] roles = (Long[]) u[2];
// Delete existing if any
Long userId = null;
try (PreparedStatement ps = conn.prepareStatement("SELECT user_id FROM public.sys_user WHERE user_name = ?")) {
ps.setString(1, username);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) userId = rs.getLong(1);
}
}
if (userId != null) {
try (PreparedStatement ps = conn.prepareStatement("DELETE FROM public.sys_user_role WHERE user_id = ?")) {
ps.setLong(1, userId);
ps.executeUpdate();
}
try (PreparedStatement ps = conn.prepareStatement("DELETE FROM public.sys_user WHERE user_id = ?")) {
ps.setLong(1, userId);
ps.executeUpdate();
}
}
// Insert user
String insertSql = "INSERT INTO public.sys_user (dept_id, user_name, nick_name, user_type, email, phonenumber, sex, avatar, password, status, del_flag, create_by, create_time, remark) " +
"VALUES (?, ?, ?, '00', ?, ?, '0', '', ?, '0', '0', 'system', now(), 'QA Acceptance User') RETURNING user_id";
try (PreparedStatement ps = conn.prepareStatement(insertSql)) {
ps.setLong(1, adminDeptId != null ? adminDeptId : 103L);
ps.setString(2, username);
ps.setString(3, nick);
ps.setString(4, username + "@qa.example.com");
ps.setString(5, "1380000" + String.format("%04d", new Random().nextInt(10000)));
ps.setString(6, adminHash);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) userId = rs.getLong(1);
}
}
// Assign roles
for (Long rId : roles) {
try (PreparedStatement ps = conn.prepareStatement("INSERT INTO public.sys_user_role (user_id, role_id) VALUES (?, ?)")) {
ps.setLong(1, userId);
ps.setLong(2, rId);
ps.executeUpdate();
}
}
System.out.println("Initialized QA User: " + username + " (userId=" + userId + ", roles=" + Arrays.toString(roles) + ")");
}
// Ensure role_menu has essential perms for train_admin, train_teacher, train_student
// role 3 (train_admin): ensure all train:* menu perms
// role 4 (train_teacher): ensure 2239 (train:me:teacher), 2202, 2215, 2223, 2171, 2182
// role 5 (train_student): ensure 2240 (train:me:student), 2215, 2223
Long[][] extraRoleMenus = new Long[][]{
{4L, 2239L}, // teacher me
{4L, 2223L}, // lesson query
{4L, 2219L}, // plan query
{5L, 2240L}, // student me
{5L, 2223L}, // lesson query
};
for (Long[] rm : extraRoleMenus) {
try (PreparedStatement ps = conn.prepareStatement("INSERT INTO public.sys_role_menu (role_id, menu_id) VALUES (?, ?) ON CONFLICT DO NOTHING")) {
ps.setLong(1, rm[0]);
ps.setLong(2, rm[1]);
ps.executeUpdate();
}
}
conn.commit();
System.out.println("QA Users & Role Mappings successfully provisioned.");
}
}
}
+45
View File
@@ -0,0 +1,45 @@
package scripts.qa;
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class InspectUsers {
public static void main(String[] args) {
String dbUrl = "jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8&currentSchema=public,sys_catalog";
String user = "kingbase";
String password = resolveDbPassword();
try {
Class.forName("com.kingbase8.Driver");
try (Connection conn = DriverManager.getConnection(dbUrl, user, password)) {
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT u.user_id, u.user_name, u.nick_name, u.status, r.role_name, r.role_key FROM sys_user u LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id LEFT JOIN sys_role r ON ur.role_id = r.role_id")) {
System.out.println("--- USERS IN QA DB ---");
while (rs.next()) {
System.out.println(String.format("ID: %d | username: %-15s | nick: %-15s | status: %s | role: %-15s | role_key: %s",
rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6)));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String resolveDbPassword() {
String env = System.getenv("DB_PASSWORD");
if (env != null && !env.isEmpty()) return env;
try {
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
if (yml.exists()) {
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) {
return line.trim().substring("password:".length()).trim();
}
}
}
} catch (Exception ignored) {}
return "";
}
}
+94
View File
@@ -0,0 +1,94 @@
package scripts.qa;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.train.integration.dms.mock.MockDmsServer;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;
import java.io.*;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executors;
public class MockDmsRunner {
private static MockDmsServer mockDmsServer;
private static HttpServer controlServer;
public static void main(String[] args) throws Exception {
int dmsPort = 18099;
int controlPort = 18098;
mockDmsServer = new MockDmsServer();
// Use reflection or custom wrapper to bind exact port
java.lang.reflect.Field serverField = MockDmsServer.class.getDeclaredField("server");
serverField.setAccessible(true);
HttpServer s = HttpServer.create(new InetSocketAddress("127.0.0.1", dmsPort), 0);
s.setExecutor(Executors.newCachedThreadPool());
serverField.set(mockDmsServer, s);
java.lang.reflect.Field portField = MockDmsServer.class.getDeclaredField("port");
portField.setAccessible(true);
portField.setInt(mockDmsServer, dmsPort);
java.lang.reflect.Method regMethod = MockDmsServer.class.getDeclaredMethod("registerEndpoints");
regMethod.setAccessible(true);
regMethod.invoke(mockDmsServer);
s.start();
System.out.println("MockDmsServer started on port: " + dmsPort);
// Control server on 18098 for test orchestration
controlServer = HttpServer.create(new InetSocketAddress("127.0.0.1", controlPort), 0);
controlServer.createContext("/mock/control/set-operation-status", exchange -> {
String body = readBody(exchange);
JSONObject req = JSON.parseObject(body);
Long opId = req.getLong("operationId");
String status = req.getString("status");
String msg = req.getString("message");
mockDmsServer.setOperationStatus(opId, status, msg);
sendResponse(exchange, 200, "{\"success\":true}");
});
controlServer.createContext("/mock/control/timeout", exchange -> {
String body = readBody(exchange);
JSONObject req = JSON.parseObject(body);
boolean sim = req.getBooleanValue("simulate");
mockDmsServer.setSimulateReadTimeout(sim);
sendResponse(exchange, 200, "{\"success\":true}");
});
controlServer.createContext("/mock/control/stats", exchange -> {
JSONObject resp = new JSONObject();
resp.put("loginCount", mockDmsServer.getLoginCounter());
resp.put("createCount", mockDmsServer.getPasswordCreatePostCounter());
resp.put("deleteCount", mockDmsServer.getPasswordDeletePostCounter());
resp.put("activeToken", mockDmsServer.getActiveToken());
sendResponse(exchange, 200, resp.toJSONString());
});
controlServer.start();
System.out.println("MockDms Control Server started on port: " + controlPort);
// Keep process alive
Thread.currentThread().join();
}
private static String readBody(HttpExchange exchange) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) sb.append(line);
return sb.toString();
}
}
private static void sendResponse(HttpExchange exchange, int code, String body) throws IOException {
byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "application/json");
exchange.sendResponseHeaders(code, bytes.length);
try (OutputStream os = exchange.getResponseBody()) {
os.write(bytes);
}
}
}
+41
View File
@@ -0,0 +1,41 @@
import java.io.File;
import java.nio.file.Files;
import java.sql.*;
public class VerifyDbIntegrity {
public static void main(String[] args) throws Exception {
Class.forName("com.kingbase8.Driver");
File yml = new File("RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml");
String pass = "";
for (String line : Files.readAllLines(yml.toPath())) {
if (line.trim().startsWith("password:")) pass = line.trim().substring("password:".length()).trim();
}
try (Connection conn = DriverManager.getConnection("jdbc:kingbase8://127.0.0.1:4321/railwaysystem_integrated_qa_20260916?useUnicode=true&characterEncoding=utf8", "kingbase", pass)) {
// 1. Check orphan enrollments
int orphanEnrollments = 0;
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT count(*) FROM public.train_enrollment e WHERE NOT EXISTS (SELECT 1 FROM public.train_class_plan p WHERE p.plan_id = e.plan_id)")) {
if (rs.next()) orphanEnrollments = rs.getInt(1);
}
// 2. Check active accommodation duplicate count
int activeDup = 0;
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT enrollment_id, count(*) FROM public.train_accommodation WHERE accommodation_status = 1 GROUP BY enrollment_id HAVING count(*) > 1")) {
while (rs.next()) activeDup++;
}
// 3. Check operation idempotency violation
int idempDup = 0;
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT door_auth_id, operation_type, count(*) FROM public.train_external_operation GROUP BY door_auth_id, operation_type HAVING count(*) > 1")) {
while (rs.next()) idempDup++;
}
System.out.println("ORPHAN_COUNT=" + orphanEnrollments);
System.out.println("ACTIVE_ACCOMMODATION_DUPLICATE_COUNT=" + activeDup);
System.out.println("DMS_OPERATION_IDEMPOTENCY_VIOLATION=" + idempDup);
}
}
}
File diff suppressed because it is too large. Load diff