github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/internal_integration/synchronized_suite_nodes_test.go (about)

     1  package internal_integration_test
     2  
     3  import (
     4  	. "github.com/onsi/ginkgo"
     5  	. "github.com/onsi/ginkgo/internal/test_helpers"
     6  	"github.com/onsi/ginkgo/types"
     7  	. "github.com/onsi/gomega"
     8  	"github.com/onsi/gomega/gbytes"
     9  )
    10  
    11  var _ = Describe("Synchronized Suite Nodes", func() {
    12  	var failInBeforeSuiteProc1, failInBeforeSuiteAllProcs, failInAfterSuiteAllProcs, failInAfterSuiteProc1 bool
    13  	var fixture func()
    14  
    15  	BeforeEach(func() {
    16  		failInBeforeSuiteProc1, failInBeforeSuiteAllProcs, failInAfterSuiteAllProcs, failInAfterSuiteProc1 = false, false, false, false
    17  		fixture = func() {
    18  			SynchronizedBeforeSuite(func() []byte {
    19  				outputInterceptor.AppendInterceptedOutput("before-suite-proc-1")
    20  				rt.Run("before-suite-proc-1")
    21  				if failInBeforeSuiteProc1 {
    22  					F("fail-in-before-suite-proc-1", cl)
    23  				}
    24  				return []byte("hey there")
    25  			}, func(data []byte) {
    26  				outputInterceptor.AppendInterceptedOutput("before-suite-all-procs")
    27  				rt.RunWithData("before-suite-all-procs", "data", string(data))
    28  				if failInBeforeSuiteAllProcs {
    29  					F("fail-in-before-suite-all-procs", cl)
    30  				}
    31  			})
    32  			It("test", rt.T("test"))
    33  			SynchronizedAfterSuite(func() {
    34  				outputInterceptor.AppendInterceptedOutput("after-suite-all-procs")
    35  				rt.Run("after-suite-all-procs")
    36  				if failInAfterSuiteAllProcs {
    37  					F("fail-in-after-suite-all-procs", cl)
    38  				}
    39  			}, func() {
    40  				outputInterceptor.AppendInterceptedOutput("after-suite-proc-1")
    41  				rt.Run("after-suite-proc-1")
    42  				if failInAfterSuiteProc1 {
    43  					F("fail-in-after-suite-proc-1", cl)
    44  				}
    45  			})
    46  		}
    47  	})
    48  
    49  	Describe("when running in series", func() {
    50  		BeforeEach(func() {
    51  			conf.ParallelTotal = 1
    52  			conf.ParallelProcess = 1
    53  		})
    54  
    55  		Describe("happy path", func() {
    56  			BeforeEach(func() {
    57  				success, _ := RunFixture("happy-path", fixture)
    58  				Ω(success).Should(BeTrue())
    59  			})
    60  
    61  			It("runs all the functions", func() {
    62  				Ω(rt).Should(HaveTracked(
    63  					"before-suite-proc-1", "before-suite-all-procs",
    64  					"test",
    65  					"after-suite-all-procs", "after-suite-proc-1",
    66  				))
    67  			})
    68  
    69  			It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() {
    70  				befReports := reporter.Did.WithLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)
    71  				Ω(befReports).Should(HaveLen(1))
    72  				Ω(befReports[0]).Should(HavePassed())
    73  
    74  				aftReports := reporter.Did.WithLeafNodeType(types.NodeTypeSynchronizedAfterSuite)
    75  				Ω(aftReports).Should(HaveLen(1))
    76  				Ω(aftReports[0]).Should(HavePassed())
    77  			})
    78  
    79  			It("passes data between the two SynchronizedBeforeSuite functions", func() {
    80  				Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there"))
    81  			})
    82  		})
    83  
    84  		Describe("when the SynchronizedBeforeSuite proc1 function fails", func() {
    85  			BeforeEach(func() {
    86  				failInBeforeSuiteProc1 = true
    87  				success, _ := RunFixture("fail in SynchronizedBeforeSuite proc1", fixture)
    88  				Ω(success).Should(BeFalse())
    89  			})
    90  
    91  			It("doens't run the allProcs function or any of the tests", func() {
    92  				Ω(rt).Should(HaveTracked(
    93  					"before-suite-proc-1",
    94  					"after-suite-all-procs", "after-suite-proc-1",
    95  				))
    96  			})
    97  
    98  			It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() {
    99  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed("fail-in-before-suite-proc-1"))
   100  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed())
   101  			})
   102  		})
   103  
   104  		Describe("when the SynchronizedBeforeSuite allProcs function fails", func() {
   105  			BeforeEach(func() {
   106  				failInBeforeSuiteAllProcs = true
   107  				success, _ := RunFixture("fail in SynchronizedBeforeSuite allProcs", fixture)
   108  				Ω(success).Should(BeFalse())
   109  			})
   110  
   111  			It("doesn't run the tests", func() {
   112  				Ω(rt).Should(HaveTracked(
   113  					"before-suite-proc-1", "before-suite-all-procs",
   114  					"after-suite-all-procs", "after-suite-proc-1",
   115  				))
   116  				Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there"))
   117  			})
   118  
   119  			It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() {
   120  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed("fail-in-before-suite-all-procs"))
   121  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed())
   122  			})
   123  		})
   124  
   125  		Describe("when the SynchronizedAfterSuite allProcs function fails", func() {
   126  			BeforeEach(func() {
   127  				failInAfterSuiteAllProcs = true
   128  				success, _ := RunFixture("fail in SynchronizedAfterSuite allProcs", fixture)
   129  				Ω(success).Should(BeFalse())
   130  			})
   131  
   132  			It("nonetheless runs the proc-1 function", func() {
   133  				Ω(rt).Should(HaveTracked(
   134  					"before-suite-proc-1", "before-suite-all-procs",
   135  					"test",
   136  					"after-suite-all-procs", "after-suite-proc-1",
   137  				))
   138  				Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there"))
   139  			})
   140  
   141  			It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() {
   142  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed())
   143  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HaveFailed("fail-in-after-suite-all-procs"))
   144  			})
   145  		})
   146  
   147  		Describe("when the SynchronizedAfterSuite proc1 function fails", func() {
   148  			BeforeEach(func() {
   149  				failInAfterSuiteProc1 = true
   150  				success, _ := RunFixture("fail in SynchronizedAfterSuite proc1", fixture)
   151  				Ω(success).Should(BeFalse())
   152  			})
   153  
   154  			It("will have run everything", func() {
   155  				Ω(rt).Should(HaveTracked(
   156  					"before-suite-proc-1", "before-suite-all-procs",
   157  					"test",
   158  					"after-suite-all-procs", "after-suite-proc-1",
   159  				))
   160  				Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there"))
   161  			})
   162  
   163  			It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() {
   164  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed())
   165  				Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HaveFailed("fail-in-after-suite-proc-1"))
   166  			})
   167  		})
   168  	})
   169  
   170  	Describe("when running in parallel", func() {
   171  		var serverOutputBuffer *gbytes.Buffer
   172  
   173  		BeforeEach(func() {
   174  			SetUpForParallel(2)
   175  			serverOutputBuffer = gbytes.NewBuffer()
   176  			server.SetOutputDestination(serverOutputBuffer)
   177  		})
   178  
   179  		Describe("when running as proc 1", func() {
   180  			BeforeEach(func() {
   181  				conf.ParallelProcess = 1
   182  			})
   183  
   184  			Describe("happy path", func() {
   185  				BeforeEach(func() {
   186  					close(exitChannels[2]) //trigger proc 2 exiting so the proc1 after suite runs
   187  					success, _ := RunFixture("happy-path", fixture)
   188  					Ω(success).Should(BeTrue())
   189  				})
   190  
   191  				It("runs all the functions", func() {
   192  					Ω(rt).Should(HaveTracked(
   193  						"before-suite-proc-1", "before-suite-all-procs",
   194  						"test",
   195  						"after-suite-all-procs", "after-suite-proc-1",
   196  					))
   197  				})
   198  
   199  				It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() {
   200  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed())
   201  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed())
   202  				})
   203  
   204  				It("passes data between the two SynchronizedBeforeSuite functions and up to the server", func() {
   205  					Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there"))
   206  					state, data, err := client.BlockUntilSynchronizedBeforeSuiteData()
   207  					Ω(state).Should(Equal(types.SpecStatePassed))
   208  					Ω(data).Should(Equal([]byte("hey there")))
   209  					Ω(err).ShouldNot(HaveOccurred())
   210  				})
   211  
   212  				It("emits the output of the proc-1 BeforeSuite function and the proc-1 AfterSuite fnction", func() {
   213  					Ω(string(serverOutputBuffer.Contents())).Should(Equal("before-suite-proc-1after-suite-proc-1"))
   214  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed(CapturedStdOutput("before-suite-proc-1before-suite-all-procs")))
   215  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed(CapturedStdOutput("after-suite-all-procsafter-suite-proc-1")))
   216  				})
   217  			})
   218  
   219  			Describe("when the BeforeSuite proc1 function fails", func() {
   220  				BeforeEach(func() {
   221  					close(exitChannels[2]) //trigger proc 2 exiting so the proc1 after suite runs
   222  					failInBeforeSuiteProc1 = true
   223  					success, _ := RunFixture("happy-path", fixture)
   224  					Ω(success).Should(BeFalse())
   225  				})
   226  
   227  				It("tells the server", func() {
   228  					state, data, err := client.BlockUntilSynchronizedBeforeSuiteData()
   229  					Ω(state).Should(Equal(types.SpecStateFailed))
   230  					Ω(data).Should(BeNil())
   231  					Ω(err).ShouldNot(HaveOccurred())
   232  				})
   233  			})
   234  
   235  			Describe("waiting for all procs to finish before running the AfterSuite proc 1 function", func() {
   236  				It("waits for the server to give it the all clear", func() {
   237  					done := make(chan interface{})
   238  					go func() {
   239  						defer GinkgoRecover()
   240  						success, _ := RunFixture("happy-path", fixture)
   241  						Ω(success).Should(BeTrue())
   242  						close(done)
   243  					}()
   244  					Consistently(done).ShouldNot(BeClosed())
   245  					close(exitChannels[2])
   246  					Eventually(done).Should(BeClosed())
   247  				})
   248  			})
   249  		})
   250  
   251  		Describe("when running as another proc", func() {
   252  			BeforeEach(func() {
   253  				conf.ParallelProcess = 2
   254  			})
   255  
   256  			Describe("happy path", func() {
   257  				BeforeEach(func() {
   258  					client.PostSynchronizedBeforeSuiteCompleted(types.SpecStatePassed, []byte("hola hola"))
   259  					success, _ := RunFixture("happy-path", fixture)
   260  					Ω(success).Should(BeTrue())
   261  				})
   262  
   263  				It("runs all the all-procs functions", func() {
   264  					Ω(rt).Should(HaveTracked(
   265  						"before-suite-all-procs",
   266  						"test",
   267  						"after-suite-all-procs",
   268  					))
   269  				})
   270  
   271  				It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() {
   272  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed())
   273  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed())
   274  				})
   275  
   276  				It("gets data for the SynchronizedBeforeSuite all procs function from the server", func() {
   277  					Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hola hola"))
   278  				})
   279  			})
   280  
   281  			Describe("waiting for the data from proc 1", func() {
   282  				It("waits for the server to give it the data", func() {
   283  					done := make(chan interface{})
   284  					go func() {
   285  						defer GinkgoRecover()
   286  						success, _ := RunFixture("happy-path", fixture)
   287  						Ω(success).Should(BeTrue())
   288  						close(done)
   289  					}()
   290  					Consistently(done).ShouldNot(BeClosed())
   291  					client.PostSynchronizedBeforeSuiteCompleted(types.SpecStatePassed, []byte("hola hola"))
   292  					Eventually(done).Should(BeClosed())
   293  					Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hola hola"))
   294  				})
   295  			})
   296  
   297  			Describe("when proc 1 fails the SynchronizedBeforeSuite proc1 function", func() {
   298  				It("fails and only runs the after suite", func() {
   299  					done := make(chan interface{})
   300  					go func() {
   301  						defer GinkgoRecover()
   302  						success, _ := RunFixture("happy-path", fixture)
   303  						Ω(success).Should(BeFalse())
   304  						close(done)
   305  					}()
   306  					Consistently(done).ShouldNot(BeClosed())
   307  					client.PostSynchronizedBeforeSuiteCompleted(types.SpecStateFailed, nil)
   308  					Eventually(done).Should(BeClosed())
   309  
   310  					Ω(rt).Should(HaveTracked("after-suite-all-procs"))
   311  
   312  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed(types.GinkgoErrors.SynchronizedBeforeSuiteFailedOnProc1().Error()))
   313  				})
   314  			})
   315  
   316  			Describe("when the proc1 SynchronizedBeforeSuite function Skips()", func() {
   317  				It("fails and only runs the after suite", func() {
   318  					done := make(chan interface{})
   319  					go func() {
   320  						defer GinkgoRecover()
   321  						success, _ := RunFixture("happy-path", fixture)
   322  						Ω(success).Should(BeTrue())
   323  						close(done)
   324  					}()
   325  					Consistently(done).ShouldNot(BeClosed())
   326  					client.PostSynchronizedBeforeSuiteCompleted(types.SpecStateSkipped, nil)
   327  					Eventually(done).Should(BeClosed())
   328  
   329  					Ω(rt).Should(HaveTracked("after-suite-all-procs"))
   330  
   331  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveBeenSkipped())
   332  				})
   333  			})
   334  
   335  			Describe("when proc 1 disappears before the proc 1 function returns", func() {
   336  				It("fails and only runs the after suite", func() {
   337  					done := make(chan interface{})
   338  					go func() {
   339  						defer GinkgoRecover()
   340  						success, _ := RunFixture("happy-path", fixture)
   341  						Ω(success).Should(BeFalse())
   342  						close(done)
   343  					}()
   344  					Consistently(done).ShouldNot(BeClosed())
   345  					close(exitChannels[1])
   346  					Eventually(done).Should(BeClosed())
   347  
   348  					Ω(rt).Should(HaveTracked("after-suite-all-procs"))
   349  
   350  					Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed(types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1().Error()))
   351  				})
   352  			})
   353  		})
   354  	})
   355  })