Skip to content

Commit aadb2b8

Browse files
authored
Merge pull request #405 from xueweiz/test-pr
Rent Boskos project only once per test run.
2 parents 140a850 + fb8304b commit aadb2b8

File tree

2 files changed

+63
-17
lines changed

2 files changed

+63
-17
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ test: vet fmt
125125
GO111MODULE=on go test -mod vendor -timeout=1m -v -race -short -tags "$(BUILD_TAGS)" ./...
126126

127127
e2e-test: vet fmt build-tar
128-
GO111MODULE=on ginkgo -nodes=$(PARALLEL) -mod vendor -timeout=10m -v -tags "$(BUILD_TAGS)" \
128+
GO111MODULE=on ginkgo -nodes=$(PARALLEL) -mod vendor -timeout=10m -v -tags "$(BUILD_TAGS)" -stream \
129129
./test/e2e/metriconly/... -- \
130130
-project=$(PROJECT) -zone=$(ZONE) \
131131
-image=$(VM_IMAGE) -image-family=$(IMAGE_FAMILY) -image-project=$(IMAGE_PROJECT) \

test/e2e/metriconly/e2e_npd_test.go

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"testing"
2626
"time"
2727

28+
"k8s.io/node-problem-detector/pkg/util/tomb"
2829
"k8s.io/node-problem-detector/test/e2e/lib/gce"
2930
"k8s.io/test-infra/boskos/client"
3031

@@ -54,6 +55,16 @@ var boskosWaitDuration = flag.Duration("boskos-wait-duration", 2*time.Minute,
5455

5556
var computeService *compute.Service
5657

58+
// boskosClient helps renting project from Boskos, and is only initialized on Ginkgo node 1.
59+
var boskosClient *client.Client
60+
61+
// boskosRenewingTomb stops the goroutine keep renewing the Boskos resources.
62+
var boskosRenewingTomb *tomb.Tomb
63+
64+
// SynchronizedBeforeSuite and SynchronizedAfterSuite help manages singleton resource (a Boskos project) across Ginkgo nodes.
65+
var _ = ginkgo.SynchronizedBeforeSuite(rentBoskosProjectIfNeededOnNode1, acceptBoskosProjectIfNeededFromNode1)
66+
var _ = ginkgo.SynchronizedAfterSuite(func() {}, releaseBoskosResourcesOnNode1)
67+
5768
func TestNPD(t *testing.T) {
5869
if testing.Short() {
5970
t.Skip("skipping test in short mode.")
@@ -65,13 +76,6 @@ func TestNPD(t *testing.T) {
6576
panic(fmt.Sprintf("Unable to create gcloud compute service using defaults. Make sure you are authenticated. %v", err))
6677
}
6778

68-
if *project == "" {
69-
boskosClient := client.NewClient(*jobName, *boskosServerURL)
70-
*project = acquireProjectOrDie(boskosClient)
71-
72-
defer releaseProjectOrDie(boskosClient)
73-
}
74-
7579
if *artifactsDir != "" {
7680
_, err := os.Stat(*artifactsDir)
7781
if err != nil && os.IsNotExist(err) {
@@ -84,30 +88,72 @@ func TestNPD(t *testing.T) {
8488
ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "NPD Metric-only Suite", []ginkgo.Reporter{junitReporter})
8589
}
8690

87-
func acquireProjectOrDie(boskosClient *client.Client) string {
91+
// rentBoskosProjectIfNeededOnNode1 rents a GCP project from Boskos if no GCP project is specified.
92+
//
93+
// rentBoskosProjectIfNeededOnNode1 returns a byte slice containing the project name.
94+
// rentBoskosProjectIfNeededOnNode1 also initializes boskosClient if necessary.
95+
// When the tests run in parallel mode in Ginkgo, this rentBoskosProjectIfNeededOnNode1 runs only on
96+
// Ginkgo node 1. The output should be shared with all other Gingko nodes so that they all use the same
97+
// GCP project.
98+
func rentBoskosProjectIfNeededOnNode1() []byte {
99+
if *project != "" {
100+
return []byte{}
101+
}
102+
88103
fmt.Printf("Renting project from Boskos\n")
104+
boskosClient = client.NewClient(*jobName, *boskosServerURL)
105+
boskosRenewingTomb = tomb.NewTomb()
106+
89107
ctx, cancel := context.WithTimeout(context.Background(), *boskosWaitDuration)
90108
defer cancel()
91109
p, err := boskosClient.AcquireWait(ctx, *boskosProjectType, "free", "busy")
92110
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unable to rent project from Boskos: %v\n", err))
111+
fmt.Printf("Rented project %q from Boskos\n", p.Name)
112+
113+
go renewBoskosProject(boskosClient, p.Name, boskosRenewingTomb)
93114

94-
fmt.Printf("Rented project %s from Boskos", p.Name)
115+
return []byte(p.Name)
116+
}
117+
118+
// acceptBoskosProjectIfNeededFromNode1 accepts a GCP project rented from Boskos by Ginkgo node 1.
119+
//
120+
// acceptBoskosProjectIfNeededFromNode1 takes the output of rentBoskosProjectIfNeededOnNode1.
121+
// When the tests run in parallel mode in Ginkgo, this function runs on all Ginkgo nodes.
122+
func acceptBoskosProjectIfNeededFromNode1(data []byte) {
123+
if *project != "" {
124+
return
125+
}
126+
127+
boskosProject := string(data)
128+
fmt.Printf("Received Boskos project %q from Ginkgo node 1.\n", boskosProject)
129+
*project = boskosProject
130+
}
95131

96-
go func(boskosClient *client.Client, projectName string) {
97-
for range time.Tick(5 * time.Minute) {
132+
func renewBoskosProject(boskosClient *client.Client, projectName string, boskosRenewingTomb *tomb.Tomb) {
133+
defer boskosRenewingTomb.Done()
134+
for {
135+
select {
136+
case <-time.Tick(5 * time.Minute):
137+
fmt.Printf("Renewing boskosProject %q\n", projectName)
98138
if err := boskosClient.UpdateOne(projectName, "busy", nil); err != nil {
99-
fmt.Printf("Failed to update status for project %s with Boskos: %v\n", projectName, err)
139+
fmt.Printf("Failed to update status for project %q with Boskos: %v\n", projectName, err)
100140
}
141+
case <-boskosRenewingTomb.Stopping():
142+
return
101143
}
102-
}(boskosClient, p.Name)
103-
104-
return p.Name
144+
}
105145
}
106146

107-
func releaseProjectOrDie(boskosClient *client.Client) {
147+
// releaseBoskosResourcesOnNode1 releases all rented Boskos resources if there is any.
148+
func releaseBoskosResourcesOnNode1() {
149+
if boskosClient == nil {
150+
return
151+
}
152+
boskosRenewingTomb.Stop()
108153
if !boskosClient.HasResource() {
109154
return
110155
}
156+
fmt.Printf("Releasing all Boskos resources.\n")
111157
err := boskosClient.ReleaseAll("dirty")
112158
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to release project to Boskos: %v", err))
113159
}

0 commit comments

Comments
 (0)