• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #20020

17 Oct 2025 05:56PM UTC coverage: 88.611% (+0.01%) from 88.601%
#20020

push

github

grpc-bot
buildscripts: Convert GAE CI to Cloud Build

The Google App Engine build now requires Java 17, because the App Engine
libraries are now using Java 17 bytecode. The Kokoro environment doesn't
include Java 17, and while we could make some custom pools to resolve
it, it is easier to swap to Cloud Build than to fight and maintain the
Kokoro images. With Cloud Build we can also restrict permissions easier,
as the same workers aren't used for multiple tasks.

However, the Gradle App Engine plugin doesn't support choosing a service
account for GAE, so I swapped to using gcloud app deploy.

Although we'll be using restricted service accounts, we'll configure
Cloud Build to require a "/gcbrun" GitHub comment except for owners and
collaborators of the repository, similar to the "kokoro:run" label
today.

I swapped the Gradle code to use project properties instead of system
properties, as we really should have been using project properties to
begin with and I didn't want to add new system properties. The sleep has
probably been unnecessary since the turndown of GAE Java 7, when the
architecture of GAE changed considerably. But today it is very possible
a new instance is spun up for that request and GAE does a warmup
request, so the delay seems unlikely to help anything and was excessive
at 20 seconds.

The Cloud Build file _doesn't_ include GAE in its name because it can do
more than GAE testing and it is easy to run things in parallel in Cloud
Build (although they share the worker). In particular, some of the
Android tests may make sense to migrate away from Kokoro.

We're using e2-standard-16 for Kokoro and it takes about 10 minutes.
With the default Cloud Build worker e2-standard-2 it takes 20 minutes,
and with e2-highcpu-8 it takes 10 minutes with 4 minutes spent on app
deploy.

The expectation is to run this with a Java-CI-specific service account,
so we have configure logging ourselves. I chose CLOUD_LOGGING_ONLY
because it was easy, but we'll want to conf... (continued)

34943 of 39434 relevant lines covered (88.61%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/../netty/src/main/java/io/grpc/netty/ClientTransportLifecycleManager.java
1
/*
2
 * Copyright 2016 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.netty;
18

19
import com.google.errorprone.annotations.CanIgnoreReturnValue;
20
import io.grpc.Attributes;
21
import io.grpc.Status;
22
import io.grpc.internal.ManagedClientTransport;
23

24
/** Maintainer of transport lifecycle status. */
25
final class ClientTransportLifecycleManager {
26
  private final ManagedClientTransport.Listener listener;
27
  private boolean transportReady;
28
  private boolean transportShutdown;
29
  private boolean transportInUse;
30
  /** null iff !transportShutdown. */
31
  private Status shutdownStatus;
32
  /** null iff !transportShutdown. */
33
  private boolean transportTerminated;
34

35
  public ClientTransportLifecycleManager(ManagedClientTransport.Listener listener) {
1✔
36
    this.listener = listener;
1✔
37
  }
1✔
38

39
  public Attributes filterAttributes(Attributes attributes) {
40
    if (transportReady || transportShutdown) {
1✔
41
      return attributes;
×
42
    }
43
    return listener.filterTransport(attributes);
1✔
44
  }
45

46
  public void notifyReady() {
47
    if (transportReady || transportShutdown) {
1✔
48
      return;
×
49
    }
50
    transportReady = true;
1✔
51
    listener.transportReady();
1✔
52
  }
1✔
53

54
  /**
55
   * Marks transport as shutdown, but does not set the error status. This must eventually be
56
   * followed by a call to notifyShutdown.
57
   */
58
  public void notifyGracefulShutdown(Status s) {
59
    if (transportShutdown) {
1✔
60
      return;
1✔
61
    }
62
    transportShutdown = true;
1✔
63
    listener.transportShutdown(s);
1✔
64
  }
1✔
65

66
  /** Returns {@code true} if was the first shutdown. */
67
  @CanIgnoreReturnValue
68
  public boolean notifyShutdown(Status s) {
69
    notifyGracefulShutdown(s);
1✔
70
    if (shutdownStatus != null) {
1✔
71
      return false;
1✔
72
    }
73
    shutdownStatus = s;
1✔
74
    return true;
1✔
75
  }
76

77
  public void notifyInUse(boolean inUse) {
78
    if (inUse == transportInUse) {
1✔
79
      return;
×
80
    }
81
    transportInUse = inUse;
1✔
82
    listener.transportInUse(inUse);
1✔
83
  }
1✔
84

85
  public void notifyTerminated(Status s) {
86
    if (transportTerminated) {
1✔
87
      return;
×
88
    }
89
    transportTerminated = true;
1✔
90
    notifyShutdown(s);
1✔
91
    listener.transportTerminated();
1✔
92
  }
1✔
93

94
  public Status getShutdownStatus() {
95
    return shutdownStatus;
1✔
96
  }
97

98
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc