Skip to content

Commit db1404a

Browse files
authored
Merge pull request #36 from korolevpavel/feat/test-no-build
feat(test): add prepared infobase mode
2 parents d612e2d + 51ea040 commit db1404a

19 files changed

Lines changed: 642 additions & 73 deletions

File tree

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,25 @@ v8-runner syntax designer-modules --server
103103
v8-runner test yaxunit all
104104
```
105105

106+
Для уже подготовленной файловой или серверной ИБ можно явно пропустить build:
107+
108+
```bash
109+
v8-runner test --no-build yaxunit all
110+
```
111+
112+
Для файловой ИБ этот режим до запуска 1С проверяет наличие `1Cv8.1CD`.
113+
Проверка конфигурации не требует наличия project source-set: нужны только настройки ИБ,
114+
платформы и выбранного test engine. Для server connection отдельный portable preflight без
115+
запуска платформы пока недоступен, поэтому соединение проверяет сам test engine.
116+
106117
### Или тесты Vanessa Automation:
107118

108119
```bash
109120
v8-runner test va
110121
```
111122

112-
Команда сначала выполняет `build`, затем запускает настроенный профиль Vanessa Automation.
123+
По умолчанию команда сначала выполняет `build`, затем запускает настроенный профиль Vanessa
124+
Automation. Для подготовленной ИБ используйте `v8-runner test --no-build va`.
113125

114126
Для отладки и написания тестов Vanessa Automation запустите ее в режиме MCP и, если агенту нужно
115127
сразу подключаться к endpoint, дождитесь готовности:

SKILL/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ v8-runner init
7373
- Only one source-set changed: use commands that accept `--source-set <NAME>` instead of rebuilding or materializing everything.
7474
- Branch switch, rebase, large object moves, stale source-backed tool extension state, or suspicious incremental state: run `v8-runner build --full-rebuild`.
7575
- Syntax check: inspect `format` and `builder`, then choose `syntax designer-modules`, `syntax designer-config`, or `syntax edt`.
76-
- Behavior validation: run the relevant `v8-runner test ...` command; tests build first.
76+
- Behavior validation: run the relevant `v8-runner test ...` command; tests build first unless the
77+
caller explicitly requests `--no-build` for an already prepared infobase.
7778
- Missing local YAxUnit, Vanessa Automation, or onec-client-mcp-devkit setup: run
7879
`v8-runner tools download yaxunit --sources`, `v8-runner tools download vanessa`, and
7980
`v8-runner tools download client-mcp --sources` for source-backed setup. Omit

SKILL/references/testing.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Testing
22

3-
Use tests when behavior matters. Test commands build first, so do not run a separate `build` unless the user specifically asked for a build-only diagnosis.
3+
Use tests when behavior matters. Test commands build first, so do not run a separate `build` unless the user specifically asked for a build-only diagnosis. For an immutable prepared infobase clone, use `test --no-build`; never infer this mode merely because a previous build appears successful.
44

55
## YaXUnit
66

@@ -9,6 +9,7 @@ All tests:
99
```bash
1010
v8-runner test yaxunit all
1111
v8-runner test yaxunit --full all
12+
v8-runner test --no-build yaxunit all
1213
```
1314

1415
Target one module:
@@ -26,12 +27,16 @@ Run the configured Vanessa Automation profile:
2627

2728
```bash
2829
v8-runner test va
30+
v8-runner test --no-build va
2931
```
3032

3133
If the user points to a specific feature or profile, inspect `tests.va` in `v8project.yaml` before changing the command.
3234

3335
`test va` uses the configured `tests.va.profile`; do not invent ad hoc feature paths without updating config or using the repo's established wrapper.
3436

37+
`--no-build` requires an existing `1Cv8.1CD` for file infobases. Server infobases are validated by the test-engine connection because a local filesystem preflight is not possible.
38+
This mode does not require project source-set directories or build tooling to be present; runner and platform inputs are still validated.
39+
3540
When driving tests through the MCP `run_all_tests` tool, pass `runner: "vanessa"` plus optional `profile`, `feature`, `filterTag`, `ignoreTag`, or `scenarioFilter`; do not use the default YaXUnit runner for functional `.feature` acceptance scenarios.
3641

3742
`tests.va.fail_fast` defaults to `false`.

docs/CAPABILITIES.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ CLI help, доверяйте текущему коду и затем синхр
3030
| `extensions` | `format=DESIGNER` или `format=EDT` | Обновляет свойства extension `source-set` |
3131
| `build` | `format=DESIGNER` + `builder=DESIGNER|IBCMD` | Выполняет incremental/full загрузку в ИБ |
3232
| `build` | `format=EDT` + `builder=DESIGNER|IBCMD` | Экспортирует изменённые EDT `source-set`, затем грузит generated Designer output |
33-
| `test` | Та же матрица, что и у `build` | Всегда сначала запускает `build` |
33+
| `test` | Та же матрица, что и у `build` | По умолчанию запускает `build` |
34+
| `test --no-build` | Подготовленная file/server ИБ; source-set и build tooling не требуются | Запускает выбранный test engine без build |
3435
| `dump` | `format=DESIGNER` + `builder=DESIGNER` | Полная, инкрементальная или object-scoped partial выгрузка |
3536
| `dump` | `format=DESIGNER` + `builder=IBCMD` | Полная и инкрементальная выгрузка; `partial` деградирует в incremental с warning; standalone-server state изолирован в `workPath/ibcmd-data` |
3637
| `dump` | `format=EDT` + `builder=DESIGNER|IBCMD` | Reverse sync из ИБ через internal Designer snapshot и EDT import |
@@ -193,13 +194,18 @@ v8-runner build [--source-set <NAME>] [--full-rebuild]
193194
### `test`
194195

195196
```bash
196-
v8-runner test yaxunit [--full] all
197-
v8-runner test yaxunit [--full] module <NAME>
198-
v8-runner test va
199-
v8-runner test va --feature login --filter-tag @smoke
197+
v8-runner test [--full] [--no-build] yaxunit all
198+
v8-runner test [--full] [--no-build] yaxunit module <NAME>
199+
v8-runner test [--no-build] va
200+
v8-runner test [--no-build] va --feature login --filter-tag @smoke
200201
```
201202

202-
- Всегда сначала запускает `build`.
203+
- По умолчанию сначала запускает `build`. `--no-build` отмечает build-step как `skipped` и
204+
запускает тесты на подготовленной ИБ; для file connection до запуска платформы требуется
205+
`<infobase>/1Cv8.1CD`, для server connection доступность подтверждается запуском test engine.
206+
- В `--no-build` source-set и build tooling не проходят filesystem/layout validation: исходники
207+
configuration могут отсутствовать. Валидация ИБ, платформы и настроек test engine сохраняется.
208+
- `--no-build` является CLI-only контрактом; MCP `run_all_tests` сохраняет build-first поведение.
203209
- `test yaxunit module <NAME>` требует непустое имя модуля.
204210
- `test va` использует профиль из `tests.va.profile`; `--feature`, `--filter-tag`,
205211
`--ignore-tag` и `--scenario-filter` переопределяют соответствующие списки выбранного профиля
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Test Without Build Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Add an opt-in CLI test mode that runs against an already prepared infobase without building it.
6+
7+
**Architecture:** Map the CLI flag into a typed transport-neutral build policy. Branch in the test coordinator before artifact creation: validate a file infobase and emit a skipped build step, or execute the existing build-first path.
8+
9+
**Tech Stack:** Rust, clap, serde, existing execution-step and test-result models.
10+
11+
## Global Constraints
12+
13+
- Default test behavior remains build-first.
14+
- MCP remains build-first.
15+
- Skip mode must not invoke build/load/update operations.
16+
- File infobases require an existing `1Cv8.1CD` marker.
17+
- Use Result-based errors and exhaustive enum matches.
18+
19+
---
20+
21+
### Task 1: CLI and typed request policy
22+
23+
**Files:**
24+
- Modify: `src/cli/args.rs`
25+
- Modify: `src/cli/execute.rs`
26+
- Modify: `src/use_cases/request.rs`
27+
- Test: `tests/cli_help.rs`
28+
29+
**Interfaces:**
30+
- Produces: `TestBuildPolicy::{BuildFirst, Skip}` and `TestRequest.build_policy`.
31+
32+
- [ ] Add a failing help test for `test --no-build`.
33+
- [ ] Run the focused help test and confirm it fails because the flag is absent.
34+
- [ ] Add `--no-build`, the enum, and mapping with build-first defaults for non-CLI callers.
35+
- [ ] Run the focused help test and request-mapping tests.
36+
37+
### Task 2: Skip behavior and file-infobase preflight
38+
39+
**Files:**
40+
- Modify: `src/use_cases/run_tests/coordinator.rs`
41+
- Modify: `src/use_cases/run_tests/helpers.rs`
42+
- Modify: `src/domain/test.rs`
43+
- Test: `tests/cli_test.rs`
44+
45+
**Interfaces:**
46+
- Consumes: `TestRequest.build_policy`.
47+
- Produces: skipped `build` step or typed `infobase_unavailable` failure.
48+
49+
- [ ] Add failing YaXUnit tests for skipped build and missing `1Cv8.1CD`.
50+
- [ ] Run them and confirm the missing option/behavior failures.
51+
- [ ] Implement preflight, skipped step, and exhaustive test error mapping.
52+
- [ ] Run the focused YaXUnit tests.
53+
- [ ] Add a failing Vanessa no-build test, then implement only any missing shared behavior.
54+
- [ ] Run the focused Vanessa test.
55+
56+
### Task 3: Documentation and verification
57+
58+
**Files:**
59+
- Modify: `README.md`
60+
- Modify: `docs/CAPABILITIES.md`
61+
- Modify: `SKILL/SKILL.md`
62+
- Modify: `SKILL/references/testing.md`
63+
64+
**Interfaces:**
65+
- Documents the CLI-only prepared-infobase workflow and file/server distinction.
66+
67+
- [ ] Update user and agent guidance.
68+
- [ ] Run formatter, focused suites, check, and diff-check.
69+
- [ ] Run independent Rust and contract reviews; fix or explicitly waive every finding.
70+
- [ ] Commit, push, and create the upstream PR.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Test Without Build Design
2+
3+
## Goal
4+
5+
Allow CLI users to run YaXUnit or Vanessa Automation against a prepared infobase without invoking the build pipeline.
6+
7+
## Contract
8+
9+
`v8-runner test --no-build yaxunit all` and `v8-runner test --no-build va` select a typed `TestBuildPolicy::Skip`. The default remains `TestBuildPolicy::BuildFirst`. MCP requests keep the default and do not expose the new CLI-only option.
10+
11+
The result keeps a `build` execution step. In skip mode that step has status `skipped` and a stable message stating that the caller explicitly skipped the prerequisite.
12+
13+
## Infobase preflight
14+
15+
For file connections, skip mode requires the configured infobase directory to contain `1Cv8.1CD`. Failure is returned before test artifacts or a platform process are created, using typed test error code `infobase_unavailable`.
16+
17+
Prepared-test config loading deliberately skips source-set and build-tool filesystem validation, while retaining base/work path, connection, platform, timeout, and test configuration validation. This lets immutable CI clones run after their configuration sources have been removed.
18+
19+
Accepted portability waiver: the current public server connection contract does not carry cluster-administration credentials or a portable non-1C management adapter, so existence of a named server infobase cannot be proven before starting 1C without introducing a false-positive TCP check or a new external dependency. Server availability therefore remains established by the test-engine connection and its typed process errors; file infobases receive the strict preflight required by this change.
20+
21+
Server connections cannot be proven available without contacting the server through a platform process. Skip mode therefore validates their configuration using the existing loader and lets the selected test engine establish connectivity; it does not introduce a hidden probe command.
22+
23+
## Components
24+
25+
- CLI maps `--no-build` to the typed build policy.
26+
- The transport-neutral request owns the policy.
27+
- The test coordinator performs file-infobase preflight or the existing build prerequisite.
28+
- Existing step serialization reports the explicit skip.
29+
- CLI integration tests cover YaXUnit, Vanessa, and a missing file infobase.
30+
- README, capabilities, and repo-local skill guidance describe the workflow.
31+
32+
## Error handling and compatibility
33+
34+
Default behavior is unchanged. Skip mode never invokes build, load, or update-database operations. Missing file state returns the existing runtime CLI error class plus the new typed test error. Credentials and launch options continue through existing code paths.
35+
36+
## Testing
37+
38+
Tests first demonstrate that the option is absent. After implementation they assert no build script invocation, a skipped build step in JSON, successful YaXUnit and Vanessa execution, and failure before platform launch when `1Cv8.1CD` is missing.

src/app.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use crate::cli::execute;
1010
use crate::cli::output::{failure_envelope, print_command_error};
1111
use crate::command_envelope::Envelope;
1212
use crate::config::loader::{
13-
load_config, load_config_for_tools_download, resolve_primary_config_path,
13+
load_config, load_config_for_prepared_test, load_config_for_tools_download,
14+
resolve_primary_config_path,
1415
};
1516
use crate::output::presenter::Presenter;
1617
use crate::output::text::{TimelineItem, TimelineStatus};
@@ -148,6 +149,8 @@ fn load_cli_config(
148149
})
149150
) {
150151
load_config_for_tools_download(cli.config.as_deref(), cli.workdir.as_deref())
152+
} else if matches!(&cli.command, Command::Test(args) if args.no_build) {
153+
load_config_for_prepared_test(cli.config.as_deref(), cli.workdir.as_deref())
151154
} else {
152155
load_config(cli.config.as_deref(), cli.workdir.as_deref())
153156
}

src/cli/args.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub enum Command {
6060
Build(BuildArgs),
6161
/// Apply built release artifacts to the infobase
6262
Load(LoadArgs),
63-
/// Build first, then run YaXUnit or Vanessa Automation tests
63+
/// Run YaXUnit or Vanessa Automation tests, building first by default
6464
Test(TestArgs),
6565
/// Dump infobase state back to project files
6666
Dump(DumpArgs),
@@ -246,6 +246,10 @@ pub struct TestArgs {
246246
#[arg(long, global = true)]
247247
pub full: bool,
248248

249+
/// Run tests against the configured prepared infobase without building sources first
250+
#[arg(long, global = true)]
251+
pub no_build: bool,
252+
249253
/// Client mode used for enterprise launch during test execution
250254
#[arg(long = "client-mode", value_parser = ["designer", "thin", "thick", "ordinary"])]
251255
pub client_mode: Option<String>,

src/cli/execute.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,18 +869,25 @@ fn map_tools_download_force(args: &ToolsDownloadArgs) -> bool {
869869

870870
fn map_test_request(config: &AppConfig, args: &TestArgs) -> Result<TestRequest, UseCaseError> {
871871
let client_mode = map_test_client_mode(args.client_mode.as_deref())?;
872+
let build_policy = if args.no_build {
873+
crate::use_cases::request::TestBuildPolicy::Skip
874+
} else {
875+
crate::use_cases::request::TestBuildPolicy::BuildFirst
876+
};
872877
match &args.runner {
873878
TestRunner::Yaxunit(TestYaxunitArgs { scope }) => {
874879
let scope = map_yaxunit_scope(scope)?;
875880
Ok(TestRequest {
876881
execution: build_yaxunit_execution(config, &args.launch, client_mode)?,
877882
full: args.full,
883+
build_policy,
878884
scope,
879885
})
880886
}
881887
TestRunner::Va(_) => Ok(TestRequest {
882888
execution: build_vanessa_execution(config, &args.launch, client_mode)?,
883889
full: args.full,
890+
build_policy,
884891
scope: TestScopeRequest::All,
885892
}),
886893
}
@@ -2484,7 +2491,7 @@ mod tests {
24842491
use crate::use_cases::request::{
24852492
ArtifactsModeRequest, ClientMcpAddonRequest, ClientMcpMode, ClientMcpOptionsRequest,
24862493
DesignerClientScope, DesignerConfigCheck, DumpModeRequest, LaunchRequest,
2487-
LaunchTargetRequest, SyntaxTargetRequest, TestScopeRequest,
2494+
LaunchTargetRequest, SyntaxTargetRequest, TestBuildPolicy, TestScopeRequest,
24882495
};
24892496
use crate::use_cases::result::{UseCaseError, UseCaseErrorKind};
24902497
use crate::use_cases::workspace_lock::workspace_lock_path;
@@ -2500,6 +2507,7 @@ mod tests {
25002507
&config,
25012508
&TestArgs {
25022509
full: true,
2510+
no_build: false,
25032511
client_mode: None,
25042512
launch: TestLaunchOptionsArgs::default(),
25052513
runner: TestRunner::Yaxunit(TestYaxunitArgs {
@@ -2512,6 +2520,7 @@ mod tests {
25122520
.expect("request");
25132521

25142522
assert!(request.full);
2523+
assert_eq!(request.build_policy, TestBuildPolicy::BuildFirst);
25152524
assert_eq!(
25162525
request.scope,
25172526
TestScopeRequest::Module {
@@ -2520,6 +2529,27 @@ mod tests {
25202529
);
25212530
}
25222531

2532+
#[test]
2533+
fn maps_no_build_yaxunit_request() {
2534+
let work = tempdir().expect("tempdir");
2535+
let config = sample_config(work.path());
2536+
let request = map_test_request(
2537+
&config,
2538+
&TestArgs {
2539+
full: false,
2540+
no_build: true,
2541+
client_mode: None,
2542+
launch: TestLaunchOptionsArgs::default(),
2543+
runner: TestRunner::Yaxunit(TestYaxunitArgs {
2544+
scope: TestScope::All,
2545+
}),
2546+
},
2547+
)
2548+
.expect("request");
2549+
2550+
assert_eq!(request.build_policy, TestBuildPolicy::Skip);
2551+
}
2552+
25232553
#[test]
25242554
fn rejects_blank_test_module_request() {
25252555
let work = tempdir().expect("tempdir");
@@ -2528,6 +2558,7 @@ mod tests {
25282558
&config,
25292559
&TestArgs {
25302560
full: false,
2561+
no_build: false,
25312562
client_mode: None,
25322563
launch: TestLaunchOptionsArgs::default(),
25332564
runner: TestRunner::Yaxunit(TestYaxunitArgs {
@@ -2575,6 +2606,7 @@ mod tests {
25752606
&config,
25762607
&TestArgs {
25772608
full: false,
2609+
no_build: false,
25782610
client_mode: None,
25792611
launch: TestLaunchOptionsArgs::default(),
25802612
runner: TestRunner::Va(TestVaArgs::default()),
@@ -2584,8 +2616,23 @@ mod tests {
25842616

25852617
assert_eq!(request.execution.profile.kind, RunnerKind::Vanessa);
25862618
assert_eq!(request.execution.profile.id, "smoke");
2619+
assert_eq!(request.build_policy, TestBuildPolicy::BuildFirst);
25872620
assert_eq!(request.scope, TestScopeRequest::All);
25882621
assert_eq!(request.execution.timeouts.total_ms, Some(300_000));
2622+
2623+
let no_build_request = map_test_request(
2624+
&config,
2625+
&TestArgs {
2626+
full: false,
2627+
no_build: true,
2628+
client_mode: None,
2629+
launch: TestLaunchOptionsArgs::default(),
2630+
runner: TestRunner::Va(TestVaArgs::default()),
2631+
},
2632+
)
2633+
.expect("no-build request");
2634+
2635+
assert_eq!(no_build_request.build_policy, TestBuildPolicy::Skip);
25892636
}
25902637

25912638
#[test]
@@ -3011,6 +3058,7 @@ mod tests {
30113058
&config,
30123059
&Command::Test(TestArgs {
30133060
full: false,
3061+
no_build: false,
30143062
client_mode: None,
30153063
launch: TestLaunchOptionsArgs::default(),
30163064
runner: TestRunner::Yaxunit(TestYaxunitArgs {
@@ -3075,6 +3123,7 @@ mod tests {
30753123
&config,
30763124
&Command::Test(TestArgs {
30773125
full: false,
3126+
no_build: false,
30783127
client_mode: None,
30793128
launch: TestLaunchOptionsArgs::default(),
30803129
runner: TestRunner::Yaxunit(TestYaxunitArgs {

0 commit comments

Comments
 (0)