1package tfe 2 3import ( 4 "context" 5 "io/ioutil" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "testing" 10) 11 12func testLogReader(t *testing.T, h http.HandlerFunc) (*httptest.Server, *LogReader) { 13 ts := httptest.NewServer(h) 14 15 cfg := &Config{ 16 Address: ts.URL, 17 Token: "dummy-token", 18 HTTPClient: ts.Client(), 19 } 20 21 client, err := NewClient(cfg) 22 if err != nil { 23 t.Fatal(err) 24 } 25 26 logURL, err := url.Parse(ts.URL) 27 if err != nil { 28 t.Fatal(err) 29 } 30 31 lr := &LogReader{ 32 client: client, 33 ctx: context.Background(), 34 logURL: logURL, 35 } 36 37 return ts, lr 38} 39 40func TestLogReader_withMarkersSingle(t *testing.T) { 41 t.Parallel() 42 43 logReads := 0 44 ts, lr := testLogReader(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 45 logReads++ 46 switch { 47 case logReads == 2: 48 w.Write([]byte("\x02Terraform run started - logs - Terraform run finished\x03")) 49 } 50 })) 51 defer ts.Close() 52 53 doneReads := 0 54 lr.done = func() (bool, error) { 55 doneReads++ 56 if logReads >= 2 { 57 return true, nil 58 } 59 return false, nil 60 } 61 62 logs, err := ioutil.ReadAll(lr) 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 expected := "Terraform run started - logs - Terraform run finished" 68 if string(logs) != expected { 69 t.Fatalf("expected %s, got: %s", expected, string(logs)) 70 } 71 if doneReads != 1 { 72 t.Fatalf("expected 1 done reads, got %d reads", doneReads) 73 } 74 if logReads != 3 { 75 t.Fatalf("expected 3 log reads, got %d reads", logReads) 76 } 77} 78 79func TestLogReader_withMarkersDouble(t *testing.T) { 80 t.Parallel() 81 82 logReads := 0 83 ts, lr := testLogReader(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 84 logReads++ 85 switch { 86 case logReads == 2: 87 w.Write([]byte("\x02Terraform run started")) 88 case logReads == 3: 89 w.Write([]byte(" - logs - Terraform run finished\x03")) 90 } 91 })) 92 defer ts.Close() 93 94 doneReads := 0 95 lr.done = func() (bool, error) { 96 doneReads++ 97 if logReads >= 3 { 98 return true, nil 99 } 100 return false, nil 101 } 102 103 logs, err := ioutil.ReadAll(lr) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 expected := "Terraform run started - logs - Terraform run finished" 109 if string(logs) != expected { 110 t.Fatalf("expected %s, got: %s", expected, string(logs)) 111 } 112 if doneReads != 1 { 113 t.Fatalf("expected 1 done reads, got %d reads", doneReads) 114 } 115 if logReads != 4 { 116 t.Fatalf("expected 4 log reads, got %d reads", logReads) 117 } 118} 119 120func TestLogReader_withMarkersMulti(t *testing.T) { 121 t.Parallel() 122 123 logReads := 0 124 ts, lr := testLogReader(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 125 logReads++ 126 switch { 127 case logReads == 2: 128 w.Write([]byte("\x02")) 129 case logReads == 3: 130 w.Write([]byte("Terraform run started")) 131 case logReads == 16: 132 w.Write([]byte(" - logs - ")) 133 case logReads == 30: 134 w.Write([]byte("Terraform run finished")) 135 case logReads == 31: 136 w.Write([]byte("\x03")) 137 } 138 })) 139 defer ts.Close() 140 141 doneReads := 0 142 lr.done = func() (bool, error) { 143 doneReads++ 144 if logReads >= 31 { 145 return true, nil 146 } 147 return false, nil 148 } 149 150 logs, err := ioutil.ReadAll(lr) 151 if err != nil { 152 t.Fatal(err) 153 } 154 155 expected := "Terraform run started - logs - Terraform run finished" 156 if string(logs) != expected { 157 t.Fatalf("expected %s, got: %s", expected, string(logs)) 158 } 159 if doneReads != 3 { 160 t.Fatalf("expected 3 done reads, got %d reads", doneReads) 161 } 162 if logReads != 31 { 163 t.Fatalf("expected 31 log reads, got %d reads", logReads) 164 } 165} 166 167func TestLogReader_withoutMarkers(t *testing.T) { 168 t.Parallel() 169 170 logReads := 0 171 ts, lr := testLogReader(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 172 logReads++ 173 switch { 174 case logReads == 2: 175 w.Write([]byte("Terraform run started")) 176 case logReads == 16: 177 w.Write([]byte(" - logs - ")) 178 case logReads == 31: 179 w.Write([]byte("Terraform run finished")) 180 } 181 })) 182 defer ts.Close() 183 184 doneReads := 0 185 lr.done = func() (bool, error) { 186 doneReads++ 187 if logReads >= 31 { 188 return true, nil 189 } 190 return false, nil 191 } 192 193 logs, err := ioutil.ReadAll(lr) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 expected := "Terraform run started - logs - Terraform run finished" 199 if string(logs) != expected { 200 t.Fatalf("expected %s, got: %s", expected, string(logs)) 201 } 202 if doneReads != 25 { 203 t.Fatalf("expected 14 done reads, got %d reads", doneReads) 204 } 205 if logReads != 32 { 206 t.Fatalf("expected 32 log reads, got %d reads", logReads) 207 } 208} 209 210func TestLogReader_withoutEndOfTextMarker(t *testing.T) { 211 t.Parallel() 212 213 logReads := 0 214 ts, lr := testLogReader(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 215 logReads++ 216 switch { 217 case logReads == 2: 218 w.Write([]byte("\x02")) 219 case logReads == 3: 220 w.Write([]byte("Terraform run started")) 221 case logReads == 16: 222 w.Write([]byte(" - logs - ")) 223 case logReads == 31: 224 w.Write([]byte("Terraform run finished")) 225 } 226 })) 227 defer ts.Close() 228 229 doneReads := 0 230 lr.done = func() (bool, error) { 231 doneReads++ 232 if logReads >= 31 { 233 return true, nil 234 } 235 return false, nil 236 } 237 238 logs, err := ioutil.ReadAll(lr) 239 if err != nil { 240 t.Fatal(err) 241 } 242 243 expected := "Terraform run started - logs - Terraform run finished" 244 if string(logs) != expected { 245 t.Fatalf("expected %s, got: %s", expected, string(logs)) 246 } 247 if doneReads != 3 { 248 t.Fatalf("expected 3 done reads, got %d reads", doneReads) 249 } 250 if logReads != 42 { 251 t.Fatalf("expected 42 log reads, got %d reads", logReads) 252 } 253} 254