Переделал тест добавления блоков в новый формат ( стло удобнее)

Дальше делать:
Описание форматов.
Запросы клиент-сервер.
Промт на клиента.

---
Потом в сервак дописать
Синхронизацию серверов.
This commit is contained in:
AidarKC 2026-01-02 16:54:13 +03:00
parent ca55bfca93
commit 771758c831
4 changed files with 46 additions and 86 deletions

View File

@ -1,37 +1,18 @@
package test.it; package test.it;
import org.junit.jupiter.api.BeforeAll; import blockchain.body.HeaderBody;
import org.junit.jupiter.api.Test; import blockchain.body.ReactionBody;
import blockchain.body.TextBody;
import test.it.addBlockUtils.AddBlockSender;
import test.it.addBlockUtils.ChainState;
import test.it.utils.ItRunContext; import test.it.utils.ItRunContext;
import test.it.utils.TestConfig; import test.it.utils.TestConfig;
import test.it.utils.TestLog; import test.it.utils.TestLog;
import test.it.addBlockUtils.AddBlockFlow;
import java.time.Duration; import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/**
* IT_03_AddBlock_NoAuth
*
* Интеграционный тест добавления блоков в персональный блокчейн без отдельной авторизации.
*
* Сценарий (как ты попросил):
* 1) AddBlock: HEADER (global=0, line=0, lineNum=0, prevGlobalHash=ZERO64) -> 200
* 2) AddBlock: TEXT#1 (global=1, line=1, lineNum=1, prevGlobalHash=hash(0)) -> 200
* 3) AddBlock: TEXT#2 (global=2, line=1, lineNum=2, prevGlobalHash=hash(1)) -> 200
* 4) AddBlock: TEXT#3 (global=3, line=1, lineNum=3, prevGlobalHash=hash(2)) -> 200
* 5) AddBlock: REACT#1 (global=4, line=2, lineNum=1, prevGlobalHash=hash(3)) -> 200
* - реакция на TEXT#1 (toBchName, toGlobal=1, toHash=hash(TEXT#1))
*
* Важно по линиям (твоя договорённость):
* - line 0: нулевой блок (HEADER) один на весь блокчейн (глобальный 0)
* - line 1 и line 2: первый блок каждой линии ссылается prevLineHash на hash(нулевого блока)
*
* В этом тесте состояние ведёт AddBlockFlow:
* - lineLastNumber[line] сколько блоков в линии (то есть последний lineNum)
* - lineLastHashHex[line] hash последнего блока линии (HEX64)
*/
public class IT_03_AddBlock_NoAuth { public class IT_03_AddBlock_NoAuth {
public static void main(String[] args) { public static void main(String[] args) {
@ -39,89 +20,64 @@ public class IT_03_AddBlock_NoAuth {
// System.exit(failed); // System.exit(failed);
} }
/** Запуск одного теста (standalone). Возвращает 0 если ок, 1 если упал. */
public static int run() { public static int run() {
return TestLog.runOne("IT_03_AddBlock_NoAuth", IT_03_AddBlock_NoAuth::testBody); return TestLog.runOne("IT_03_AddBlock_NoAuth", IT_03_AddBlock_NoAuth::testBody);
} }
@BeforeAll
static void ensureUserExists() {
ItRunContext.initIfNeeded();
// ВАЖНО:
// - requestId тут не важен, но пусть будет.
// - отдельная авторизация не нужна, но пользователь должен существовать.
//
// Если хочешь реально включить предусловие здесь просто раскомментируй блок,
// но сейчас у тебя он закомментирован.
// String reqJson = JsonBuilders.addUser("it03-adduser-beforeall");
// ничего не делаем предусловие временно отключено
}
// @Test
void addBlock_shouldAppendHeaderThenTextThenReaction() {
// JUnit-режим: как обычно
testBody();
}
private static void testBody() { private static void testBody() {
ItRunContext.initIfNeeded(); ItRunContext.initIfNeeded();
ensureUserExists();
// таймаут на каждый one-shot запрос
Duration t = Duration.ofSeconds(1); Duration t = Duration.ofSeconds(1);
if (TestConfig.DEBUG()) { if (TestConfig.DEBUG()) {
TestLog.titleBlock(""" TestLog.titleBlock("""
IT_03_AddBlock_NoAuth: сценарий AddBlock без отдельной авторизации IT_03_AddBlock_NoAuth: AddBlock без отдельной авторизации (линейный сценарий)
Используем: login = %s
login = %s blockchainName = %s
blockchainName = %s
debug=true: покажем отправку/ответ (JSON) и проверки hash
""".formatted(TestConfig.LOGIN(), TestConfig.BCH_NAME())); """.formatted(TestConfig.LOGIN(), TestConfig.BCH_NAME()));
} }
// 1) состояние + сборка + отправка ChainState st = new ChainState();
AddBlockFlow flow = new AddBlockFlow(); AddBlockSender sender = new AddBlockSender(st);
// ========================================================= // 0) HEADER
// ШАГ 0: ВАЖНО первым всегда HEADER global=0 if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 0: HEADER");
// ========================================================= sender.send(new HeaderBody(TestConfig.LOGIN()), t);
if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 0: AddBlock HEADER (global=0, line=0, lineNum=0)");
flow.sendHeader0(t);
// ========================================================= // 1) TEXT#1
// ШАГ 1..3: TEXT (line=1) if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 1: TEXT#1");
// ========================================================= sender.send(new TextBody("Hello #1 from IT_03 test"), t);
if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 1: AddBlock TEXT#1 (line=1)");
AddBlockFlow.BuiltBlock text1 = flow.sendNextText("Hello #1 from IT_03 test", t);
if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 2: AddBlock TEXT#2 (line=1)"); // Снимок hash TEXT#1 (после отправки)
flow.sendNextText("Hello #2 from IT_03 test", t); // TEXT линия = 1, первый text имеет lineNum=1 и на этом шаге он последний.
byte[] text1Hash32 = st.lineLastHash32((short) 1);
assertNotNull(text1Hash32);
assertEquals(32, text1Hash32.length);
if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 3: AddBlock TEXT#3 (line=1)"); // 2) TEXT#2
flow.sendNextText("Hello #3 from IT_03 test", t); if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 2: TEXT#2");
sender.send(new TextBody("Hello #2 from IT_03 test"), t);
// ========================================================= // 3) TEXT#3
// ШАГ 4: REACT#1 (line=2) -> на TEXT#1 (global=1, hash=text1) if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 3: TEXT#3");
// ========================================================= sender.send(new TextBody("Hello #3 from IT_03 test"), t);
if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 4: AddBlock REACT#1 (line=2) -> на TEXT#1 (global=1)");
flow.sendNextReaction( // 4) REACT#1 -> на TEXT#1 (global=1)
(short) 1, // reactionCode (пример: 1 = like) if (TestConfig.DEBUG()) TestLog.stepTitle("ШАГ 4: REACT#1 -> на TEXT#1");
TestConfig.BCH_NAME(), // toBlockchainName
1, // toBlockGlobalNumber = 1 (TEXT#1) ReactionBody like = new ReactionBody(
text1.hash32, // toBlockHash32 = hash(TEXT#1) ReactionBody.SUB_LIKE,
t TestConfig.BCH_NAME(),
1,
text1Hash32
); );
sender.send(like, t);
// Мини-контроль итогов (если захочешь красиво залогируем через твой TestLog) // Итоги (быстро)
assertEquals(4, flow.globalLastNumber(), "После 1 header + 3 text + 1 react globalLastNumber должен быть 4"); assertEquals(4, st.globalLastNumber(), "После 1 header + 3 text + 1 react globalLastNumber должен быть 4");
assertEquals(3, flow.lineLastNumber(AddBlockFlow.LINE_TEXT), "В line=1 должно быть 3 блока"); assertEquals(3, st.lineLastNumber((short) 1), "В line=1 должно быть 3 блока");
assertEquals(1, flow.lineLastNumber(AddBlockFlow.LINE_REACT), "В line=2 должен быть 1 блок"); assertEquals(1, st.lineLastNumber((short) 2), "В line=2 должен быть 1 блок");
assertNotNull(flow.globalLastHashHex());
assertEquals(64, flow.globalLastHashHex().length());
// Итог (в обычном режиме это будет единственная строка)
TestLog.pass("IT_03_AddBlock_NoAuth: OK"); TestLog.pass("IT_03_AddBlock_NoAuth: OK");
} }
} }

View File

@ -1,5 +1,5 @@
package test.it.addBlockUtils; package test.it.addBlockUtils;
// старый класс
import blockchain.BchBlockEntry; import blockchain.BchBlockEntry;
import blockchain.BchCryptoVerifier; import blockchain.BchCryptoVerifier;
import blockchain.body.HeaderBody; import blockchain.body.HeaderBody;

View File

@ -1,5 +1,7 @@
package test.it.addBlockUtils; package test.it.addBlockUtils;
// старый класс
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;

View File

@ -1,5 +1,7 @@
package test.it.addBlockUtils; package test.it.addBlockUtils;
// старый класс
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;