1// Copyright 2019 Istio Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package integration
16
17import (
18	"sync"
19	"testing"
20	"time"
21
22	"istio.io/istio/pkg/test/framework"
23)
24
25func TestParallel(t *testing.T) {
26	var top, l1a, l1b, l2a, l2b, l2c, l2d *component
27
28	closeTimes := make(map[string]time.Time)
29	mutex := &sync.Mutex{}
30	closeHandler := func(c *component) {
31		mutex.Lock()
32		defer mutex.Unlock()
33		closeTimes[c.name] = time.Now()
34
35		// Sleep briefly to force time separation between close events.
36		time.Sleep(100 * time.Millisecond)
37	}
38
39	assertClosedBefore := func(t *testing.T, c1, c2 *component) {
40		t.Helper()
41		if !closeTimes[c1.name].Before(closeTimes[c2.name]) {
42			t.Fatalf("%s closed after %s", c1.name, c2.name)
43		}
44	}
45
46	framework.NewTest(t).
47		Run(func(ctx framework.TestContext) {
48			ctx.NewSubTest("top").
49				Run(func(ctx framework.TestContext) {
50					// NOTE: top can't be parallel for this test since it will exit before the children run,
51					// which means we won't be able to verify the results here.
52					top = newComponent(ctx, ctx.Name(), closeHandler)
53
54					ctx.NewSubTest("l1a").
55						RunParallel(func(ctx framework.TestContext) {
56							l1a = newComponent(ctx, ctx.Name(), closeHandler)
57
58							ctx.NewSubTest("l2a").
59								RunParallel(func(ctx framework.TestContext) {
60									l2a = newComponent(ctx, ctx.Name(), closeHandler)
61								})
62
63							ctx.NewSubTest("l2b").
64								RunParallel(func(ctx framework.TestContext) {
65									l2b = newComponent(ctx, ctx.Name(), closeHandler)
66								})
67						})
68
69					ctx.NewSubTest("l1b").
70						RunParallel(func(ctx framework.TestContext) {
71							l1b = newComponent(ctx, ctx.Name(), closeHandler)
72
73							ctx.NewSubTest("l2c").
74								RunParallel(func(ctx framework.TestContext) {
75									l2c = newComponent(ctx, ctx.Name(), closeHandler)
76								})
77
78							ctx.NewSubTest("l2d").
79								RunParallel(func(ctx framework.TestContext) {
80									l2d = newComponent(ctx, ctx.Name(), closeHandler)
81								})
82						})
83				})
84		})
85
86	assertClosedBefore(t, l2a, l1a)
87	assertClosedBefore(t, l2b, l1a)
88	assertClosedBefore(t, l2c, l1b)
89	assertClosedBefore(t, l2d, l1b)
90	assertClosedBefore(t, l1a, top)
91	assertClosedBefore(t, l1b, top)
92}
93