@@ -5,27 +5,31 @@ package watch
55
66import (
77 "encoding/json"
8+ "fmt"
89 "io"
910 "log"
11+ "net"
12+ "net/http"
1013 "os"
1114 "os/exec"
1215 "path/filepath"
1316 "strings"
1417 "testing"
18+ "time"
1519
1620 dep "github.com/hashicorp/consul-template/dependency"
1721 "github.com/hashicorp/vault/api"
1822)
1923
2024const (
21- vaultAddr = "http://127.0.0.1:8200"
2225 vaultToken = "a_token"
2326)
2427
2528var (
2629 testVault * vaultServer
2730 testClients * dep.ClientSet
2831 tokenRoleId string
32+ vaultAddr string
2933)
3034
3135func TestMain (m * testing.M ) {
@@ -35,6 +39,14 @@ func TestMain(m *testing.M) {
3539// sub-main so I can use defer
3640func main (m * testing.M ) int {
3741 log .SetOutput (io .Discard )
42+ // Find a free port for the Vault server
43+ listener , err := net .Listen ("tcp" , "127.0.0.1:0" )
44+ if err != nil {
45+ panic (fmt .Sprintf ("failed to find free port for vault: %v" , err ))
46+ }
47+ vaultAddr = fmt .Sprintf ("http://%s" , listener .Addr ().String ())
48+ listener .Close ()
49+
3850 testVault = newTestVault ()
3951 defer func () { testVault .Stop () }()
4052
@@ -71,6 +83,7 @@ func newTestVault() *vaultServer {
7183 args := []string {
7284 "server" , "-dev" , "-dev-root-token-id" , vaultToken ,
7385 "-dev-no-store-token" ,
86+ "-dev-listen-address" , strings .TrimPrefix (vaultAddr , "http://" ),
7487 }
7588 cmd := exec .Command ("vault" , args ... )
7689 cmd .Stdout = io .Discard
@@ -79,6 +92,54 @@ func newTestVault() *vaultServer {
7992 if err := cmd .Start (); err != nil {
8093 panic ("vault failed to start: " + err .Error ())
8194 }
95+
96+ // Wait for Vault to become available
97+ client := & http.Client {Timeout : 1 * time .Second }
98+ healthURL := vaultAddr + "/v1/sys/health"
99+ startTime := time .Now ()
100+ timeout := 30 * time .Second
101+
102+ for {
103+ if time .Since (startTime ) > timeout {
104+ panic ("timed out waiting for vault dev server to start" )
105+ }
106+
107+ resp , err := client .Get (healthURL )
108+ if err != nil {
109+ time .Sleep (200 * time .Millisecond )
110+ continue
111+ }
112+
113+ if resp .StatusCode == http .StatusOK {
114+ bodyBytes , readErr := io .ReadAll (resp .Body )
115+ resp .Body .Close ()
116+
117+ if readErr != nil {
118+ time .Sleep (200 * time .Millisecond )
119+ continue
120+ }
121+
122+ var healthStatus map [string ]interface {}
123+ jsonErr := json .Unmarshal (bodyBytes , & healthStatus )
124+ if jsonErr != nil {
125+ time .Sleep (200 * time .Millisecond )
126+ continue
127+ }
128+
129+ // Check for initialized and unsealed status
130+ initialized , initOk := healthStatus ["initialized" ].(bool )
131+ sealed , sealedOk := healthStatus ["sealed" ].(bool )
132+
133+ if initOk && sealedOk && initialized && ! sealed {
134+ break
135+ }
136+ } else {
137+ resp .Body .Close ()
138+ }
139+
140+ time .Sleep (1 * time .Second )
141+ }
142+
82143 return & vaultServer {
83144 cmd : cmd ,
84145 }
0 commit comments