xref: /aosp_15_r20/external/grpc-grpc/test/cpp/ext/gcp/environment_autodetect_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2023 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "src/cpp/ext/gcp/environment_autodetect.h"
20 
21 #include <string>
22 #include <thread>  // NOLINT
23 #include <vector>
24 
25 #include "absl/strings/string_view.h"
26 #include "absl/synchronization/notification.h"
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29 
30 #include <grpc/grpc.h>
31 
32 #include "src/core/lib/gprpp/env.h"
33 #include "src/core/lib/gprpp/notification.h"
34 #include "test/core/util/test_config.h"
35 
36 namespace grpc {
37 namespace testing {
38 
39 namespace {
40 
41 class EnvironmentAutoDetectTest : public ::testing::Test {
42  protected:
GetNotifiedOnEnvironmentDetection(grpc::internal::EnvironmentAutoDetect * env,grpc_core::Notification * notify)43   void GetNotifiedOnEnvironmentDetection(
44       grpc::internal::EnvironmentAutoDetect* env,
45       grpc_core::Notification* notify) {
46     env->NotifyOnDone([notify]() { notify->Notify(); });
47   }
48 };
49 
50 // TODO(yashykt): We could create a mock MetadataServer to test this more end to
51 // end, but given that that should be covered by our integration testing so
52 // deferring to that.
53 
TEST_F(EnvironmentAutoDetectTest,Basic)54 TEST_F(EnvironmentAutoDetectTest, Basic) {
55   grpc::internal::EnvironmentAutoDetect env("project");
56 
57   grpc_core::Notification notify;
58   GetNotifiedOnEnvironmentDetection(&env, &notify);
59   notify.WaitForNotification();
60 
61   // Unless we test in a specific GCP resource, we should get "global" here.
62   // EXPECT_EQ(env.resource()->resource_type, "global");
63   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
64 }
65 
TEST_F(EnvironmentAutoDetectTest,GkeEnvironment)66 TEST_F(EnvironmentAutoDetectTest, GkeEnvironment) {
67   grpc_core::SetEnv("KUBERNETES_SERVICE_HOST", "k8s_service_host");
68   grpc::internal::EnvironmentAutoDetect env("project");
69 
70   grpc_core::Notification notify;
71   GetNotifiedOnEnvironmentDetection(&env, &notify);
72   notify.WaitForNotification();
73 
74   EXPECT_EQ(env.resource()->resource_type, "k8s_container");
75   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
76   grpc_core::UnsetEnv("KUBERNETES_SERVICE_HOST");
77 }
78 
TEST_F(EnvironmentAutoDetectTest,CloudFunctions)79 TEST_F(EnvironmentAutoDetectTest, CloudFunctions) {
80   grpc_core::SetEnv("FUNCTION_NAME", "function_name");
81   grpc::internal::EnvironmentAutoDetect env("project");
82 
83   grpc_core::Notification notify;
84   GetNotifiedOnEnvironmentDetection(&env, &notify);
85   notify.WaitForNotification();
86 
87   EXPECT_EQ(env.resource()->resource_type, "cloud_function");
88   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
89   grpc_core::UnsetEnv("FUNCTION_NAME");
90 }
91 
TEST_F(EnvironmentAutoDetectTest,CloudRun)92 TEST_F(EnvironmentAutoDetectTest, CloudRun) {
93   grpc_core::SetEnv("K_CONFIGURATION", "config");
94   grpc::internal::EnvironmentAutoDetect env("project");
95 
96   grpc_core::Notification notify;
97   GetNotifiedOnEnvironmentDetection(&env, &notify);
98   notify.WaitForNotification();
99 
100   EXPECT_EQ(env.resource()->resource_type, "cloud_run_revision");
101   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
102   grpc_core::UnsetEnv("K_CONFIGURATION");
103 }
104 
TEST_F(EnvironmentAutoDetectTest,AppEngine)105 TEST_F(EnvironmentAutoDetectTest, AppEngine) {
106   grpc_core::SetEnv("K_CONFIGURATION", "config");
107   grpc::internal::EnvironmentAutoDetect env("project");
108 
109   grpc_core::Notification notify;
110   GetNotifiedOnEnvironmentDetection(&env, &notify);
111   notify.WaitForNotification();
112 
113   EXPECT_EQ(env.resource()->resource_type, "cloud_run_revision");
114   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
115   grpc_core::UnsetEnv("K_CONFIGURATION");
116 }
117 
TEST_F(EnvironmentAutoDetectTest,MultipleNotifyWaiters)118 TEST_F(EnvironmentAutoDetectTest, MultipleNotifyWaiters) {
119   grpc::internal::EnvironmentAutoDetect env("project");
120 
121   grpc_core::Notification notify[10];
122   for (int i = 0; i < 10; ++i) {
123     GetNotifiedOnEnvironmentDetection(&env, &notify[i]);
124   }
125   for (int i = 0; i < 10; ++i) {
126     notify[i].WaitForNotification();
127   }
128 
129   // Unless we test in a specific GCP resource, we should get "global" here.
130   // EXPECT_EQ(env.resource()->resource_type, "global");
131   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
132 }
133 
134 }  // namespace
135 
136 }  // namespace testing
137 }  // namespace grpc
138 
main(int argc,char ** argv)139 int main(int argc, char** argv) {
140   grpc::testing::TestEnvironment env(&argc, argv);
141   ::testing::InitGoogleTest(&argc, argv);
142   grpc_init();
143   int ret_val = RUN_ALL_TESTS();
144   grpc_shutdown();
145   return ret_val;
146 }
147