main_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package main
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net"
  8. "os"
  9. "testing"
  10. "time"
  11. )
  12. func TestAutomaticLoginWaitsForSuccessAndPreservesBufferedData(t *testing.T) {
  13. for _, accepted := range []bool{true, false} {
  14. t.Run(fmt.Sprint(accepted), func(t *testing.T) {
  15. client, server := net.Pipe()
  16. defer client.Close()
  17. defer server.Close()
  18. done := make(chan error, 1)
  19. go func() {
  20. r := bufio.NewReader(server)
  21. fmt.Fprint(server, "DebTik login: ")
  22. user, err := r.ReadString('\n')
  23. if err != nil {
  24. done <- err
  25. return
  26. }
  27. fmt.Fprint(server, "Password: ")
  28. password, err := r.ReadString('\n')
  29. if err != nil {
  30. done <- err
  31. return
  32. }
  33. if user != "admin\n" || password != "test-password\n" {
  34. done <- fmt.Errorf("wrong credentials sent")
  35. return
  36. }
  37. if accepted {
  38. _, err = fmt.Fprint(server, "Welcome\n[admin@router] > buffered")
  39. } else {
  40. _, err = fmt.Fprint(server, "Login failed: invalid credentials\n")
  41. }
  42. done <- err
  43. }()
  44. r := bufio.NewReader(client)
  45. err := autoLogin(client, r, "admin", "test-password", io.Discard)
  46. if (err == nil) != accepted {
  47. t.Fatalf("accepted=%v err=%v", accepted, err)
  48. }
  49. if accepted {
  50. buffered := make([]byte, 8)
  51. if _, err := r.Read(buffered); err != nil || string(buffered) != "buffered" {
  52. t.Fatal("buffered data was lost")
  53. }
  54. }
  55. if err := <-done; err != nil {
  56. t.Fatal(err)
  57. }
  58. })
  59. }
  60. }
  61. func TestOneShotReportsCommandFailure(t *testing.T) {
  62. for _, status := range []string{"0", "1", "missing"} {
  63. t.Run(status, func(t *testing.T) {
  64. client, server := net.Pipe()
  65. defer client.Close()
  66. go func() {
  67. defer server.Close()
  68. r := bufio.NewReader(server)
  69. fmt.Fprint(server, "login:")
  70. r.ReadString('\n')
  71. fmt.Fprint(server, "password:")
  72. r.ReadString('\n')
  73. fmt.Fprint(server, "[user@router] > ")
  74. r.ReadString('\n')
  75. if status != "missing" {
  76. fmt.Fprintf(server, "DEBTIK-EXEC-BEGIN\nresult\nDEBTIK-EXEC-STATUS:%s\n", status)
  77. }
  78. }()
  79. err := runOneShot(client, "user", "password", "invalid", time.Second, false)
  80. if (err == nil) != (status == "0") {
  81. t.Fatalf("status %s: %v", status, err)
  82. }
  83. })
  84. }
  85. }
  86. func TestOneShotJSONEnvelope(t *testing.T) {
  87. client, server := net.Pipe()
  88. defer client.Close()
  89. go func() {
  90. defer server.Close()
  91. r := bufio.NewReader(server)
  92. fmt.Fprint(server, "login:")
  93. r.ReadString('\n')
  94. fmt.Fprint(server, "password:")
  95. r.ReadString('\n')
  96. fmt.Fprint(server, "[user@router] > ")
  97. r.ReadString('\n')
  98. fmt.Fprint(server, "echoed command\r\nDEBTIK-EXEC-BEGIN\r\nresult\r\nDEBTIK-EXEC-STATUS:1\r\n")
  99. }()
  100. original := os.Stdout
  101. read, write, err := os.Pipe()
  102. if err != nil {
  103. t.Fatal(err)
  104. }
  105. os.Stdout = write
  106. defer func() { os.Stdout = original; read.Close() }()
  107. err = runOneShot(client, "user", "password", "invalid", time.Second, true)
  108. write.Close()
  109. if err == nil {
  110. t.Fatal("expected failure")
  111. }
  112. var got struct {
  113. Output string `json:"output"`
  114. Status int `json:"status"`
  115. OK bool `json:"ok"`
  116. }
  117. if err := json.NewDecoder(read).Decode(&got); err != nil {
  118. t.Fatal(err)
  119. }
  120. if got.OK || got.Status != 1 || got.Output != "result\r\n" {
  121. t.Fatalf("unexpected envelope: %+v", got)
  122. }
  123. }