test: verify configured receive source smoke
This commit is contained in:
@@ -57,6 +57,9 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -181,6 +184,7 @@ func main() {
|
||||
if len(messagesValue) != 0 {
|
||||
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{
|
||||
"ok": true,
|
||||
@@ -190,6 +194,7 @@ func main() {
|
||||
"tools": toolNames,
|
||||
"helper_name": helperName,
|
||||
"receive_message_count": len(messagesValue),
|
||||
"configured_receive_message_count": configuredReceiveCount,
|
||||
"packet_log_file_configured": os.Getenv("ISPHERE_PACKET_LOG_FILE") != "",
|
||||
"real_isphere_login_required": false,
|
||||
"python_runtime_required": false,
|
||||
@@ -199,6 +204,128 @@ func main() {
|
||||
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) {
|
||||
payload, _ := json.Marshal(map[string]any{"ok": false, "step": step, "error": err.Error()})
|
||||
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.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.configured_receive_message_count -eq 1) "SDK harness configured_receive_message_count mismatch: $($script:harnessJson.configured_receive_message_count)"
|
||||
|
||||
[ordered]@{
|
||||
ok = $true
|
||||
@@ -237,6 +365,7 @@ func fail(step string, err error) {
|
||||
tool_count = $script:harnessJson.tool_count
|
||||
tools = $script:harnessJson.tools
|
||||
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
|
||||
python_runtime_required = $false
|
||||
real_isphere_login_required = $false
|
||||
|
||||
Reference in New Issue
Block a user