test: verify configured receive source smoke
This commit is contained in:
@@ -21,7 +21,7 @@ Remote base before local roadmap commits: `b2d839e Merge branch 'codex/n15-repor
|
|||||||
- `win_helper_dump_uia`
|
- `win_helper_dump_uia`
|
||||||
- `isphere_receive_messages`
|
- `isphere_receive_messages`
|
||||||
- C# `ISphereWinHelper` exists under `native/ISphereWinHelper` and uses the `isphere.helper.v1` stdin/stdout JSON contract.
|
- C# `ISphereWinHelper` exists under `native/ISphereWinHelper` and uses the `isphere.helper.v1` stdin/stdout JSON contract.
|
||||||
- `scripts/verify-win-helper.ps1` and `scripts/verify-go-mcp.ps1` provide repeatable local checks for the helper, five-tool MCP surface, and default empty-source `isphere_receive_messages` smoke call.
|
- `scripts/verify-win-helper.ps1` and `scripts/verify-go-mcp.ps1` provide repeatable local checks for the helper, five-tool MCP surface, default empty-source `isphere_receive_messages`, and synthetic configured-source receive smoke.
|
||||||
- N12-pre and N12R documents define safe offline evidence intake and internal-sandbox live UIA capture procedures.
|
- N12-pre and N12R documents define safe offline evidence intake and internal-sandbox live UIA capture procedures.
|
||||||
- N13/N14/N15 produced selector catalog/report validation infrastructure, but those are supporting validation assets only.
|
- N13/N14/N15 produced selector catalog/report validation infrastructure, but those are supporting validation assets only.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ N13/N14/N15 are pre-business validation results. They can help identify UI eleme
|
|||||||
|
|
||||||
## Current loop
|
## Current loop
|
||||||
|
|
||||||
Current loop: `Stage C / Loop C6 - fixture-backed operator smoke for configured receive source`.
|
Current loop: `Stage C / Loop C7 - log-backed contact candidate extraction`.
|
||||||
|
|
||||||
Plan file: `docs/superpowers/plans/2026-07-09-stage-c-log-backed-receive-messages-loop.md`.
|
Plan file: `docs/superpowers/plans/2026-07-09-stage-c-log-backed-receive-messages-loop.md`.
|
||||||
|
|
||||||
@@ -67,11 +67,12 @@ Current loop output so far:
|
|||||||
4. C4: repeatable operator verification and docs for the five-tool surface.
|
4. C4: repeatable operator verification and docs for the five-tool surface.
|
||||||
5. C5: safe `ISPHERE_PACKET_LOG_FILE` loader for operator-local encrypted PacketReader log lines.
|
5. C5: safe `ISPHERE_PACKET_LOG_FILE` loader for operator-local encrypted PacketReader log lines.
|
||||||
6. C6: fixture-backed operator smoke for configured receive source.
|
6. C6: fixture-backed operator smoke for configured receive source.
|
||||||
|
7. C7: log-backed contact candidate extraction from sender/receiver JIDs.
|
||||||
|
|
||||||
## Next business mainline
|
## Next business mainline
|
||||||
|
|
||||||
1. Finish Stage C Loop C6: add fixture-backed configured-source operator smoke.
|
1. Implement Stage C Loop C7: extract searchable contact candidates from log-backed messages.
|
||||||
2. Rewrite the next loop around either production-safe source configuration hardening or the next read capability, based on C6 results.
|
2. Register `isphere_search_contacts` after contact source tests pass.
|
||||||
3. Add contact/group/file read tools after their source decisions are recorded.
|
3. Add group/file read tools after their source decisions are recorded.
|
||||||
4. Add `isphere_send_message` and `isphere_send_file` after source discovery and connector selection.
|
4. Add `isphere_send_message` and `isphere_send_file` after source discovery and connector selection.
|
||||||
5. Keep UIA selector/report work as fallback support, not as the primary roadmap.
|
5. Keep UIA selector/report work as fallback support, not as the primary roadmap.
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ The verification confirms:
|
|||||||
- Exactly five tools are exposed: four WinHelper observation tools plus `isphere_receive_messages`.
|
- Exactly five tools are exposed: four WinHelper observation tools plus `isphere_receive_messages`.
|
||||||
- `win_helper_version` returns `ISphereWinHelper`.
|
- `win_helper_version` returns `ISphereWinHelper`.
|
||||||
- `isphere_receive_messages` is callable and returns an empty `messages` array from the default empty source.
|
- `isphere_receive_messages` is callable and returns an empty `messages` array from the default empty source.
|
||||||
|
- A synthetic configured-source smoke check proves `ISPHERE_PACKET_LOG_FILE` can drive `isphere_receive_messages` end-to-end with one redacted fixture message.
|
||||||
- Verification uses synthetic/local helper checks and does not load raw N12-pre evidence.
|
- Verification uses synthetic/local helper checks and does not load raw N12-pre evidence.
|
||||||
- Contact/group/file/search/send business tools remain later-stage work.
|
- Contact/group/file/search/send business tools remain later-stage work.
|
||||||
|
|
||||||
@@ -112,7 +113,7 @@ $env:ISPHERE_PACKET_LOG_FILE = "E:\coding\codex\isphere-ai-bridge\runs\offline-e
|
|||||||
|
|
||||||
The file must contain one encrypted Base64 log line per line. Blank lines are ignored. Keep this file under ignored `runs/` paths or another operator-local location; do not commit raw logs or decrypted message content.
|
The file must contain one encrypted Base64 log line per line. Blank lines are ignored. Keep this file under ignored `runs/` paths or another operator-local location; do not commit raw logs or decrypted message content.
|
||||||
|
|
||||||
Then start the MCP server normally. The command entry point uses `ISPHERE_PACKET_LOG_FILE` if it is set; the repeatable verification script clears it so the default smoke test remains deterministic.
|
Then start the MCP server normally. The command entry point uses `ISPHERE_PACKET_LOG_FILE` if it is set. The repeatable verification script checks both paths: it clears the variable for the default empty-source smoke test, then creates a temporary synthetic encrypted fixture file and proves the configured-source path returns one redacted message.
|
||||||
|
|
||||||
## 7. Configure MCP client command
|
## 7. Configure MCP client command
|
||||||
|
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ Implemented and verified in this loop:
|
|||||||
- New fixture smoke creates a temporary synthetic/redacted PacketReader plaintext, encrypts it with the known log policy inside the temporary Go harness, writes one encrypted line to a temp file, sets `ISPHERE_PACKET_LOG_FILE` to that temp file, starts `mcpserver.NewServerFromEnv()`, calls `isphere_receive_messages`, and asserts one normalized message.
|
- New fixture smoke creates a temporary synthetic/redacted PacketReader plaintext, encrypts it with the known log policy inside the temporary Go harness, writes one encrypted line to a temp file, sets `ISPHERE_PACKET_LOG_FILE` to that temp file, starts `mcpserver.NewServerFromEnv()`, calls `isphere_receive_messages`, and asserts one normalized message.
|
||||||
- No raw N12-pre evidence or decrypted user content is written to the repo.
|
- No raw N12-pre evidence or decrypted user content is written to the repo.
|
||||||
|
|
||||||
- [ ] **Step 1: Capture current fixture-smoke gap**
|
- [x] **Step 1: Capture current fixture-smoke gap**
|
||||||
|
|
||||||
Run the current verification script and note that it only proves the default empty source, not configured fixture ingestion:
|
Run the current verification script and note that it only proves the default empty source, not configured fixture ingestion:
|
||||||
|
|
||||||
@@ -874,15 +874,15 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/verify-go-mcp.ps1
|
|||||||
|
|
||||||
Expected: PASS with `receive_message_count: 0`, but no configured-source proof yet.
|
Expected: PASS with `receive_message_count: 0`, but no configured-source proof yet.
|
||||||
|
|
||||||
- [ ] **Step 2: Update the temporary Go harness**
|
- [x] **Step 2: Update the temporary Go harness**
|
||||||
|
|
||||||
Extend the generated harness with a second server session that sets `ISPHERE_PACKET_LOG_FILE` to a temp synthetic encrypted log-line file and asserts one returned message with redacted content.
|
Extend the generated harness with a second server session that sets `ISPHERE_PACKET_LOG_FILE` to a temp synthetic encrypted log-line file and asserts one returned message with redacted content.
|
||||||
|
|
||||||
- [ ] **Step 3: Update docs**
|
- [x] **Step 3: Update docs**
|
||||||
|
|
||||||
Update the runbook/status card to say verification covers both default empty source and synthetic configured-source smoke.
|
Update the runbook/status card to say verification covers both default empty source and synthetic configured-source smoke.
|
||||||
|
|
||||||
- [ ] **Step 4: Run full verification and commit**
|
- [x] **Step 4: Run full verification and commit**
|
||||||
|
|
||||||
Run:
|
Run:
|
||||||
|
|
||||||
@@ -897,6 +897,67 @@ Expected: all exit 0. Remove any generated root `isphere-mcp.exe` after build. C
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Loop C6 Result
|
||||||
|
|
||||||
|
Implemented and verified in this loop:
|
||||||
|
|
||||||
|
- `scripts/verify-go-mcp.ps1` now verifies two receive paths: default empty source (`receive_message_count: 0`) and synthetic configured source (`configured_receive_message_count: 1`).
|
||||||
|
- The configured-source smoke creates a temporary encrypted PacketReader fixture line inside the generated Go harness, sets `ISPHERE_PACKET_LOG_FILE`, starts `mcpserver.NewServerFromEnv()`, calls `isphere_receive_messages`, and asserts one normalized redacted message.
|
||||||
|
- Docs now state that operator verification covers both default empty-source and synthetic configured-source paths.
|
||||||
|
- Verification completed for C6 with `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/verify-go-mcp.ps1`; full verification is run again before commit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Loop C7: Log-backed contact candidate extraction
|
||||||
|
|
||||||
|
**Goal:** Build the next read-capability foundation by extracting searchable contact candidates from normalized log-backed messages, using sender/receiver bare JIDs as stable contact ids until richer roster/display-name evidence is available.
|
||||||
|
|
||||||
|
**Contract source:** `docs/mcp-core-tools-contract.md`, tool `isphere_search_contacts`.
|
||||||
|
|
||||||
|
**Planned files:**
|
||||||
|
- Create: `internal/isphere/contacts.go`
|
||||||
|
- Create: `internal/isphere/contacts_test.go`
|
||||||
|
- Modify: `docs/source-discovery/capability-source-matrix.md`
|
||||||
|
- Modify: `docs/superpowers/plans/2026-07-09-stage-c-log-backed-receive-messages-loop.md`
|
||||||
|
|
||||||
|
**Planned behavior:**
|
||||||
|
- Consume `[]isphere.Message` records from the existing receive source layer.
|
||||||
|
- Extract unique contacts from `SenderID` and `ReceiverID`.
|
||||||
|
- Contact fields: `ContactID`, `DisplayName`, `Account`, `Source`, `Confidence`, `RawRef`.
|
||||||
|
- For now, `DisplayName` and `Account` both use the bare JID because no richer roster evidence is validated yet.
|
||||||
|
- Search query matches bare JID/display name case-insensitively.
|
||||||
|
- `Limit <= 0` returns all matches; positive `Limit` truncates.
|
||||||
|
- This loop does not register the MCP tool yet; registration comes after source behavior passes tests.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Write failing contact extraction test**
|
||||||
|
|
||||||
|
Create `internal/isphere/contacts_test.go` and run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
go test ./internal/isphere -run TestSearchContactsFromMessagesMatchesBareJIDs -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected initial failure: contact search types/functions do not exist.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Implement contact extraction/search**
|
||||||
|
|
||||||
|
Create `internal/isphere/contacts.go` with minimal pure Go logic over normalized messages. Use synthetic/redacted fixtures only.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Run full verification and rewrite Loop C8**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git diff --check
|
||||||
|
go test ./...
|
||||||
|
go build ./cmd/isphere-mcp
|
||||||
|
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/verify-go-mcp.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: all exit 0. Remove any generated root `isphere-mcp.exe` after build. Rewrite Loop C8 around registering `isphere_search_contacts` from the C7 source behavior.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Self-Review
|
## Self-Review
|
||||||
|
|
||||||
- Spec coverage: the plan follows the user's cyclic requirement: plan first, implement one loop at a time, update the next loop after each result, and ask only on blockers.
|
- Spec coverage: the plan follows the user's cyclic requirement: plan first, implement one loop at a time, update the next loop after each result, and ask only on blockers.
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/des"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -181,6 +184,7 @@ func main() {
|
|||||||
if len(messagesValue) != 0 {
|
if len(messagesValue) != 0 {
|
||||||
fail("tools/call isphere_receive_messages", fmt.Errorf("default empty source returned %d messages, want 0", len(messagesValue)))
|
fail("tools/call isphere_receive_messages", fmt.Errorf("default empty source returned %d messages, want 0", len(messagesValue)))
|
||||||
}
|
}
|
||||||
|
configuredReceiveCount := verifyConfiguredReceiveSource(ctx)
|
||||||
|
|
||||||
result := map[string]any{
|
result := map[string]any{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
@@ -190,6 +194,7 @@ func main() {
|
|||||||
"tools": toolNames,
|
"tools": toolNames,
|
||||||
"helper_name": helperName,
|
"helper_name": helperName,
|
||||||
"receive_message_count": len(messagesValue),
|
"receive_message_count": len(messagesValue),
|
||||||
|
"configured_receive_message_count": configuredReceiveCount,
|
||||||
"packet_log_file_configured": os.Getenv("ISPHERE_PACKET_LOG_FILE") != "",
|
"packet_log_file_configured": os.Getenv("ISPHERE_PACKET_LOG_FILE") != "",
|
||||||
"real_isphere_login_required": false,
|
"real_isphere_login_required": false,
|
||||||
"python_runtime_required": false,
|
"python_runtime_required": false,
|
||||||
@@ -199,6 +204,128 @@ func main() {
|
|||||||
fmt.Println(string(encoded))
|
fmt.Println(string(encoded))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func verifyConfiguredReceiveSource(ctx context.Context) int {
|
||||||
|
plaintext := "--------------------------------------------------------------------------------------------------------------------------------------------\n" +
|
||||||
|
"2026/7/7 15:30:07\n" +
|
||||||
|
"<message id=\"msg-fixture-1\" from=\"sender@imopenfire1-lanzhou/imp_pc_4.1.2.6842\" to=\"receiver@imopenfire1-lanzhou\" type=\"chat\">\n" +
|
||||||
|
" <body>redacted fixture</body>\n" +
|
||||||
|
" <received xmlns=\"urn:xmpp:receipts\" id=\"receipt-fixture-1\" type=\"1\" stamp=\"\" />\n" +
|
||||||
|
" <subject>VERIFY_FIXTURE</subject>\n" +
|
||||||
|
" <isphere xmlns=\"isphere.im\" type=\"1001\" sendtime=\"1783423807000\" version=\"1\" />\n" +
|
||||||
|
" <readed />\n" +
|
||||||
|
"</message>"
|
||||||
|
line, err := encryptPacketLogLineForHarness(plaintext)
|
||||||
|
if err != nil {
|
||||||
|
fail("fixture/encrypt", err)
|
||||||
|
}
|
||||||
|
file, err := os.CreateTemp("", "isphere-packet-log-*.txt")
|
||||||
|
if err != nil {
|
||||||
|
fail("fixture/create", err)
|
||||||
|
}
|
||||||
|
fixturePath := file.Name()
|
||||||
|
defer os.Remove(fixturePath)
|
||||||
|
if _, err := file.WriteString("\n" + line + "\n"); err != nil {
|
||||||
|
_ = file.Close()
|
||||||
|
fail("fixture/write", err)
|
||||||
|
}
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
fail("fixture/close", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldValue, hadOldValue := os.LookupEnv("ISPHERE_PACKET_LOG_FILE")
|
||||||
|
if err := os.Setenv("ISPHERE_PACKET_LOG_FILE", fixturePath); err != nil {
|
||||||
|
fail("fixture/env", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if hadOldValue {
|
||||||
|
_ = os.Setenv("ISPHERE_PACKET_LOG_FILE", oldValue)
|
||||||
|
} else {
|
||||||
|
_ = os.Unsetenv("ISPHERE_PACKET_LOG_FILE")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
serverCtx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
serverTransport, clientTransport := mcp.NewInMemoryTransports()
|
||||||
|
server, err := mcpserver.NewServerFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
fail("fixture/server_config", err)
|
||||||
|
}
|
||||||
|
serverErr := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
serverErr <- server.Run(serverCtx, serverTransport)
|
||||||
|
}()
|
||||||
|
|
||||||
|
client := mcp.NewClient(&mcp.Implementation{Name: "verify-go-mcp-fixture", Version: "0.1.0"}, nil)
|
||||||
|
session, err := client.Connect(serverCtx, clientTransport, nil)
|
||||||
|
if err != nil {
|
||||||
|
cancel()
|
||||||
|
fail("fixture/connect", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = session.Close()
|
||||||
|
cancel()
|
||||||
|
select {
|
||||||
|
case <-serverErr:
|
||||||
|
case <-time.After(2 * time.Second):
|
||||||
|
fail("fixture/server_shutdown", fmt.Errorf("server did not stop"))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
callResult, err := session.CallTool(serverCtx, &mcp.CallToolParams{Name: "isphere_receive_messages", Arguments: map[string]any{"limit": 5}})
|
||||||
|
if err != nil {
|
||||||
|
fail("fixture/call isphere_receive_messages", err)
|
||||||
|
}
|
||||||
|
if callResult.IsError {
|
||||||
|
fail("fixture/call isphere_receive_messages", fmt.Errorf("tool returned isError=true: %#v", callResult.Content))
|
||||||
|
}
|
||||||
|
var receivePayload map[string]any
|
||||||
|
receiveEncoded, _ := json.Marshal(callResult.StructuredContent)
|
||||||
|
if err := json.Unmarshal(receiveEncoded, &receivePayload); err != nil {
|
||||||
|
fail("fixture/decode", fmt.Errorf("decode structuredContent %s: %w", receiveEncoded, err))
|
||||||
|
}
|
||||||
|
messagesValue, ok := receivePayload["messages"].([]any)
|
||||||
|
if !ok {
|
||||||
|
fail("fixture/decode", fmt.Errorf("messages missing or not array: %s", receiveEncoded))
|
||||||
|
}
|
||||||
|
if len(messagesValue) != 1 {
|
||||||
|
fail("fixture/assert", fmt.Errorf("configured source returned %d messages, want 1", len(messagesValue)))
|
||||||
|
}
|
||||||
|
message, ok := messagesValue[0].(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fail("fixture/assert", fmt.Errorf("message was not object: %#v", messagesValue[0]))
|
||||||
|
}
|
||||||
|
if message["id"] != "msg-fixture-1" || message["text"] != "redacted fixture" || message["subject"] != "VERIFY_FIXTURE" {
|
||||||
|
fail("fixture/assert", fmt.Errorf("unexpected message: %#v", message))
|
||||||
|
}
|
||||||
|
if message["conversation_id"] != "sender@imopenfire1-lanzhou|receiver@imopenfire1-lanzhou" {
|
||||||
|
fail("fixture/assert", fmt.Errorf("conversation_id = %#v", message["conversation_id"]))
|
||||||
|
}
|
||||||
|
return len(messagesValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptPacketLogLineForHarness(plaintext string) (string, error) {
|
||||||
|
block, err := des.NewCipher([]byte("hyhccdtm"))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
plain := padPKCS7ForHarness([]byte(plaintext), des.BlockSize)
|
||||||
|
ciphertext := make([]byte, len(plain))
|
||||||
|
iv := []byte{0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF}
|
||||||
|
cipher.NewCBCEncrypter(block, iv).CryptBlocks(ciphertext, plain)
|
||||||
|
return base64.StdEncoding.EncodeToString(ciphertext), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func padPKCS7ForHarness(data []byte, blockSize int) []byte {
|
||||||
|
pad := blockSize - len(data)%blockSize
|
||||||
|
out := append([]byte(nil), data...)
|
||||||
|
for i := 0; i < pad; i++ {
|
||||||
|
out = append(out, byte(pad))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func fail(step string, err error) {
|
func fail(step string, err error) {
|
||||||
payload, _ := json.Marshal(map[string]any{"ok": false, "step": step, "error": err.Error()})
|
payload, _ := json.Marshal(map[string]any{"ok": false, "step": step, "error": err.Error()})
|
||||||
fmt.Fprintln(os.Stderr, string(payload))
|
fmt.Fprintln(os.Stderr, string(payload))
|
||||||
@@ -228,6 +355,7 @@ func fail(step string, err error) {
|
|||||||
Assert-True ($script:harnessJson.helper_name -eq "ISphereWinHelper") "SDK harness helper_name mismatch: $($script:harnessJson.helper_name)"
|
Assert-True ($script:harnessJson.helper_name -eq "ISphereWinHelper") "SDK harness helper_name mismatch: $($script:harnessJson.helper_name)"
|
||||||
Assert-True ($script:harnessJson.tool_count -eq 5) "SDK harness tool_count mismatch: $($script:harnessJson.tool_count)"
|
Assert-True ($script:harnessJson.tool_count -eq 5) "SDK harness tool_count mismatch: $($script:harnessJson.tool_count)"
|
||||||
Assert-True ($script:harnessJson.receive_message_count -eq 0) "SDK harness receive_message_count mismatch: $($script:harnessJson.receive_message_count)"
|
Assert-True ($script:harnessJson.receive_message_count -eq 0) "SDK harness receive_message_count mismatch: $($script:harnessJson.receive_message_count)"
|
||||||
|
Assert-True ($script:harnessJson.configured_receive_message_count -eq 1) "SDK harness configured_receive_message_count mismatch: $($script:harnessJson.configured_receive_message_count)"
|
||||||
|
|
||||||
[ordered]@{
|
[ordered]@{
|
||||||
ok = $true
|
ok = $true
|
||||||
@@ -237,6 +365,7 @@ func fail(step string, err error) {
|
|||||||
tool_count = $script:harnessJson.tool_count
|
tool_count = $script:harnessJson.tool_count
|
||||||
tools = $script:harnessJson.tools
|
tools = $script:harnessJson.tools
|
||||||
receive_message_count = $script:harnessJson.receive_message_count
|
receive_message_count = $script:harnessJson.receive_message_count
|
||||||
|
configured_receive_message_count = $script:harnessJson.configured_receive_message_count
|
||||||
packet_log_file_configured = $script:harnessJson.packet_log_file_configured
|
packet_log_file_configured = $script:harnessJson.packet_log_file_configured
|
||||||
python_runtime_required = $false
|
python_runtime_required = $false
|
||||||
real_isphere_login_required = $false
|
real_isphere_login_required = $false
|
||||||
|
|||||||
Reference in New Issue
Block a user