No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "net/http"
  8. "os"
  9. "os/exec"
  10. "strconv"
  11. "time"
  12. baseopencode "git.x2erp.com/qdy/go-base/sdk/opencode"
  13. )
  14. func main() {
  15. fmt.Println("=== OpenCode SDK 集成测试 ===")
  16. // 1. 获取可用端口
  17. port, err := getAvailablePort()
  18. if err != nil {
  19. fmt.Printf("获取可用端口失败: %v\n", err)
  20. os.Exit(1)
  21. }
  22. fmt.Printf("使用端口: %d\n", port)
  23. // 2. 启动 opencode 服务
  24. cmd := exec.Command("opencode", "serve",
  25. "--hostname", "127.0.0.1",
  26. "--port", strconv.Itoa(port),
  27. "--log-level", "INFO",
  28. )
  29. if err := cmd.Start(); err != nil {
  30. fmt.Printf("启动 opencode 失败: %v\n", err)
  31. os.Exit(1)
  32. }
  33. defer func() {
  34. fmt.Println("停止 opencode 服务...")
  35. if cmd.Process != nil {
  36. cmd.Process.Kill()
  37. cmd.Wait()
  38. }
  39. }()
  40. fmt.Println("启动 opencode 服务...")
  41. // 3. 等待服务就绪
  42. baseURL := fmt.Sprintf("http://127.0.0.1:%d", port)
  43. if err := waitForServiceReady(baseURL); err != nil {
  44. fmt.Printf("等待服务就绪失败: %v\n", err)
  45. os.Exit(1)
  46. }
  47. fmt.Println("服务已就绪,开始测试 SDK...")
  48. // 4. 创建 SDK 客户端
  49. client, err := baseopencode.NewClientWithResponses(baseURL)
  50. if err != nil {
  51. fmt.Printf("创建客户端失败: %v\n", err)
  52. os.Exit(1)
  53. }
  54. ctx := context.Background()
  55. // 5. 测试创建会话
  56. fmt.Println("\n1. 测试创建会话...")
  57. title := "SDK测试会话-" + time.Now().Format("150405")
  58. reqBody := baseopencode.SessionCreateJSONRequestBody{
  59. Title: &title,
  60. }
  61. resp, err := client.SessionCreateWithResponse(ctx, &baseopencode.SessionCreateParams{}, reqBody)
  62. if err != nil {
  63. fmt.Printf("创建会话请求失败: %v\n", err)
  64. os.Exit(1)
  65. }
  66. if resp.StatusCode() != http.StatusOK {
  67. fmt.Printf("创建会话失败,状态码: %d\n", resp.StatusCode())
  68. fmt.Printf("响应体: %s\n", string(resp.Body))
  69. os.Exit(1)
  70. }
  71. var session baseopencode.Session
  72. if err := json.Unmarshal(resp.Body, &session); err != nil {
  73. fmt.Printf("解析会话响应失败: %v\n", err)
  74. os.Exit(1)
  75. }
  76. fmt.Printf("创建会话成功: ID=%s, Title=%s\n", session.Id, session.Title)
  77. // 6. 测试发送消息(暂时跳过,因为Parts_Item结构复杂)
  78. fmt.Println("\n2. 测试发送消息(跳过,Parts_Item结构复杂)...")
  79. fmt.Println("注意:需要进一步研究如何正确构造Parts_Item")
  80. // 7. 测试获取会话列表
  81. fmt.Println("\n3. 测试获取会话列表...")
  82. listResp, err := client.SessionListWithResponse(ctx, &baseopencode.SessionListParams{})
  83. if err != nil {
  84. fmt.Printf("获取会话列表请求失败: %v\n", err)
  85. os.Exit(1)
  86. }
  87. if listResp.StatusCode() != http.StatusOK {
  88. fmt.Printf("获取会话列表失败,状态码: %d\n", listResp.StatusCode())
  89. os.Exit(1)
  90. }
  91. var sessions []baseopencode.Session
  92. if err := json.Unmarshal(listResp.Body, &sessions); err != nil {
  93. fmt.Printf("解析会话列表失败: %v\n", err)
  94. os.Exit(1)
  95. }
  96. fmt.Printf("获取会话列表成功: 共 %d 个会话\n", len(sessions))
  97. for i, s := range sessions {
  98. fmt.Printf(" %d. ID=%s, Title=%s\n", i+1, s.Id, s.Title)
  99. }
  100. // 8. 测试健康检查
  101. fmt.Println("\n4. 测试健康检查...")
  102. healthResp, err := http.Get(baseURL + "/global/health")
  103. if err != nil {
  104. fmt.Printf("健康检查失败: %v\n", err)
  105. os.Exit(1)
  106. }
  107. defer healthResp.Body.Close()
  108. if healthResp.StatusCode != http.StatusOK {
  109. fmt.Printf("健康检查失败,状态码: %d\n", healthResp.StatusCode)
  110. os.Exit(1)
  111. }
  112. fmt.Println("健康检查通过")
  113. fmt.Println("\n=== 所有测试通过 ===")
  114. }
  115. func getAvailablePort() (int, error) {
  116. listener, err := net.Listen("tcp", "127.0.0.1:0")
  117. if err != nil {
  118. return 0, err
  119. }
  120. defer listener.Close()
  121. addr := listener.Addr().(*net.TCPAddr)
  122. return addr.Port, nil
  123. }
  124. func waitForServiceReady(baseURL string) error {
  125. client := &http.Client{Timeout: 5 * time.Second}
  126. url := baseURL + "/global/health"
  127. for i := 0; i < 30; i++ {
  128. resp, err := client.Get(url)
  129. if err == nil && resp.StatusCode == http.StatusOK {
  130. resp.Body.Close()
  131. return nil
  132. }
  133. if resp != nil {
  134. resp.Body.Close()
  135. }
  136. time.Sleep(100 * time.Millisecond)
  137. }
  138. return fmt.Errorf("服务在3秒内未就绪")
  139. }