66 "fmt"
77 "net/http"
88 "os/exec"
9+ "slices"
910 "strings"
1011 "time"
1112
@@ -28,7 +29,7 @@ const (
2829 ngfContainerName = "nginx-gateway"
2930)
3031
31- // Since checkContainerLogsForErrors may experience interference from previous tests (as explained in the function
32+ // Since checkNGFContainerLogsForErrors may experience interference from previous tests (as explained in the function
3233// documentation), this test is recommended to be run separate from other tests.
3334var _ = Describe ("Graceful Recovery test" , Ordered , Label ("graceful-recovery" ), func () {
3435 files := []string {
@@ -189,6 +190,9 @@ func runRestartNodeTest(teaURL, coffeeURL string, files []string, ns *core.Names
189190 }
190191
191192 checkNGFFunctionality (teaURL , coffeeURL , ngfPodName , "" , files , ns )
193+ if errorLogs := getUnexpectedNginxErrorLogs (ngfPodName ); errorLogs != "" {
194+ Skip (fmt .Sprintf ("NGINX has unexpected error logs: \n %s" , errorLogs ))
195+ }
192196}
193197
194198func runRecoveryTest (teaURL , coffeeURL , ngfPodName , containerName string , files []string , ns * core.Namespace ) {
@@ -219,6 +223,9 @@ func runRecoveryTest(teaURL, coffeeURL, ngfPodName, containerName string, files
219223 }
220224
221225 checkNGFFunctionality (teaURL , coffeeURL , ngfPodName , containerName , files , ns )
226+ if errorLogs := getUnexpectedNginxErrorLogs (ngfPodName ); errorLogs != "" {
227+ Skip (fmt .Sprintf ("NGINX has unexpected error logs: \n %s" , errorLogs ))
228+ }
222229}
223230
224231func restartContainer (ngfPodName , containerName string ) {
@@ -347,52 +354,80 @@ func checkNGFFunctionality(teaURL, coffeeURL, ngfPodName, containerName string,
347354 WithPolling (500 * time .Millisecond ).
348355 Should (Succeed ())
349356
350- checkContainerLogsForErrors (ngfPodName , containerName == nginxContainerName )
357+ // When the NGINX process is killed, some errors are expected in the NGF logs while we wait for the
358+ // NGINX container to be restarted. Therefore, we don't want to check the NGF logs for errors when the container
359+ // we restarted was NGINX.
360+ if containerName != nginxContainerName {
361+ checkNGFContainerLogsForErrors (ngfPodName )
362+ }
351363}
352364
353- // checkContainerLogsForErrors checks both nginx and NGF container's logs for any possible errors.
354- // When the NGINX process is killed, some errors are expected in the NGF logs while we wait for the
355- // NGINX container to be restarted.
356- func checkContainerLogsForErrors (ngfPodName string , checkNginxLogsOnly bool ) {
365+ func getNginxErrorLogs (ngfPodName string ) string {
357366 nginxLogs , err := resourceManager .GetPodLogs (
358367 ngfNamespace ,
359368 ngfPodName ,
360369 & core.PodLogOptions {Container : nginxContainerName },
361370 )
362371 Expect (err ).ToNot (HaveOccurred ())
363372
373+ errPrefixes := []string {
374+ framework .CritNGINXLog ,
375+ framework .ErrorNGINXLog ,
376+ framework .WarnNGINXLog ,
377+ framework .AlertNGINXLog ,
378+ framework .EmergNGINXLog ,
379+ }
380+ errorLogs := ""
381+
364382 for _ , line := range strings .Split (nginxLogs , "\n " ) {
365- Expect (line ).ToNot (ContainSubstring ("[crit]" ), line )
366- Expect (line ).ToNot (ContainSubstring ("[alert]" ), line )
367- Expect (line ).ToNot (ContainSubstring ("[emerg]" ), line )
368- if strings .Contains (line , "[error]" ) {
369- expectedError1 := "connect() failed (111: Connection refused)"
370- expectedError2 := "could not be resolved (host not found) during usage report"
371- expectedError3 := "server returned 429"
372- // FIXME(salonichf5) remove this error message check
373- // when https://github.com/nginxinc/nginx-gateway-fabric/issues/2090 is completed.
374- expectedError4 := "no live upstreams while connecting to upstream"
375- Expect (line ).To (Or (
376- ContainSubstring (expectedError1 ),
377- ContainSubstring (expectedError2 ),
378- ContainSubstring (expectedError3 ),
379- ContainSubstring (expectedError4 ),
380- ))
383+ for _ , prefix := range errPrefixes {
384+ if strings .Contains (line , prefix ) {
385+ errorLogs += line + "\n "
386+ break
387+ }
381388 }
382389 }
383390
384- if ! checkNginxLogsOnly {
385- ngfLogs , err := resourceManager .GetPodLogs (
386- ngfNamespace ,
387- ngfPodName ,
388- & core.PodLogOptions {Container : ngfContainerName },
389- )
390- Expect (err ).ToNot (HaveOccurred ())
391+ return errorLogs
392+ }
393+
394+ func getUnexpectedNginxErrorLogs (ngfPodName string ) string {
395+ expectedErrStrings := []string {
396+ "connect() failed (111: Connection refused)" ,
397+ "could not be resolved (host not found) during usage report" ,
398+ "server returned 429" ,
399+ // FIXME(salonichf5) remove this error message check
400+ // when https://github.com/nginxinc/nginx-gateway-fabric/issues/2090 is completed.
401+ "no live upstreams while connecting to upstream" ,
402+ }
391403
392- for _ , line := range strings .Split (ngfLogs , "\n " ) {
393- Expect (line ).ToNot (ContainSubstring ("\" level\" :\" error\" " ), line )
404+ unexpectedErrors := ""
405+
406+ errorLogs := getNginxErrorLogs (ngfPodName )
407+
408+ for _ , line := range strings .Split (errorLogs , "\n " ) {
409+ if ! slices .ContainsFunc (expectedErrStrings , func (s string ) bool {
410+ return strings .Contains (line , s )
411+ }) {
412+ unexpectedErrors += line
394413 }
395414 }
415+
416+ return unexpectedErrors
417+ }
418+
419+ // checkNGFContainerLogsForErrors checks NGF container's logs for any possible errors.
420+ func checkNGFContainerLogsForErrors (ngfPodName string ) {
421+ ngfLogs , err := resourceManager .GetPodLogs (
422+ ngfNamespace ,
423+ ngfPodName ,
424+ & core.PodLogOptions {Container : ngfContainerName },
425+ )
426+ Expect (err ).ToNot (HaveOccurred ())
427+
428+ for _ , line := range strings .Split (ngfLogs , "\n " ) {
429+ Expect (line ).ToNot (ContainSubstring ("\" level\" :\" error\" " ), line )
430+ }
396431}
397432
398433func checkLeaderLeaseChange (originalLeaseName string ) error {
0 commit comments