• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <grpc/grpc.h>
22 
23 #include <string>
24 #include <thread>  // NOLINT
25 #include <vector>
26 
27 #include "absl/strings/string_view.h"
28 #include "absl/synchronization/notification.h"
29 #include "gmock/gmock.h"
30 #include "gtest/gtest.h"
31 #include "src/core/util/env.h"
32 #include "src/core/util/notification.h"
33 #include "test/core/test_util/test_config.h"
34 
35 namespace grpc {
36 namespace testing {
37 
38 namespace {
39 
40 class EnvironmentAutoDetectTest : public ::testing::Test {
41  protected:
GetNotifiedOnEnvironmentDetection(grpc::internal::EnvironmentAutoDetect * env,grpc_core::Notification * notify)42   void GetNotifiedOnEnvironmentDetection(
43       grpc::internal::EnvironmentAutoDetect* env,
44       grpc_core::Notification* notify) {
45     env->NotifyOnDone([notify]() { notify->Notify(); });
46   }
47 };
48 
49 // TODO(yashykt): We could create a mock MetadataServer to test this more end to
50 // end, but given that that should be covered by our integration testing so
51 // deferring to that.
52 
TEST_F(EnvironmentAutoDetectTest,Basic)53 TEST_F(EnvironmentAutoDetectTest, Basic) {
54   grpc::internal::EnvironmentAutoDetect env("project");
55 
56   grpc_core::Notification notify;
57   GetNotifiedOnEnvironmentDetection(&env, &notify);
58   notify.WaitForNotification();
59 
60   // Unless we test in a specific GCP resource, we should get "global" here.
61   // EXPECT_EQ(env.resource()->resource_type, "global");
62   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
63 }
64 
TEST_F(EnvironmentAutoDetectTest,GkeEnvironment)65 TEST_F(EnvironmentAutoDetectTest, GkeEnvironment) {
66   grpc_core::SetEnv("KUBERNETES_SERVICE_HOST", "k8s_service_host");
67   grpc::internal::EnvironmentAutoDetect env("project");
68 
69   grpc_core::Notification notify;
70   GetNotifiedOnEnvironmentDetection(&env, &notify);
71   notify.WaitForNotification();
72 
73   EXPECT_EQ(env.resource()->resource_type, "k8s_container");
74   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
75   grpc_core::UnsetEnv("KUBERNETES_SERVICE_HOST");
76 }
77 
TEST_F(EnvironmentAutoDetectTest,CloudFunctions)78 TEST_F(EnvironmentAutoDetectTest, CloudFunctions) {
79   grpc_core::SetEnv("FUNCTION_NAME", "function_name");
80   grpc::internal::EnvironmentAutoDetect env("project");
81 
82   grpc_core::Notification notify;
83   GetNotifiedOnEnvironmentDetection(&env, &notify);
84   notify.WaitForNotification();
85 
86   EXPECT_EQ(env.resource()->resource_type, "cloud_function");
87   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
88   grpc_core::UnsetEnv("FUNCTION_NAME");
89 }
90 
TEST_F(EnvironmentAutoDetectTest,CloudRun)91 TEST_F(EnvironmentAutoDetectTest, CloudRun) {
92   grpc_core::SetEnv("K_CONFIGURATION", "config");
93   grpc::internal::EnvironmentAutoDetect env("project");
94 
95   grpc_core::Notification notify;
96   GetNotifiedOnEnvironmentDetection(&env, &notify);
97   notify.WaitForNotification();
98 
99   EXPECT_EQ(env.resource()->resource_type, "cloud_run_revision");
100   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
101   grpc_core::UnsetEnv("K_CONFIGURATION");
102 }
103 
TEST_F(EnvironmentAutoDetectTest,AppEngine)104 TEST_F(EnvironmentAutoDetectTest, AppEngine) {
105   grpc_core::SetEnv("K_CONFIGURATION", "config");
106   grpc::internal::EnvironmentAutoDetect env("project");
107 
108   grpc_core::Notification notify;
109   GetNotifiedOnEnvironmentDetection(&env, &notify);
110   notify.WaitForNotification();
111 
112   EXPECT_EQ(env.resource()->resource_type, "cloud_run_revision");
113   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
114   grpc_core::UnsetEnv("K_CONFIGURATION");
115 }
116 
TEST_F(EnvironmentAutoDetectTest,MultipleNotifyWaiters)117 TEST_F(EnvironmentAutoDetectTest, MultipleNotifyWaiters) {
118   grpc::internal::EnvironmentAutoDetect env("project");
119 
120   grpc_core::Notification notify[10];
121   for (int i = 0; i < 10; ++i) {
122     GetNotifiedOnEnvironmentDetection(&env, &notify[i]);
123   }
124   for (int i = 0; i < 10; ++i) {
125     notify[i].WaitForNotification();
126   }
127 
128   // Unless we test in a specific GCP resource, we should get "global" here.
129   // EXPECT_EQ(env.resource()->resource_type, "global");
130   EXPECT_EQ((env.resource()->labels).at("project_id"), "project");
131 }
132 
133 }  // namespace
134 
135 }  // namespace testing
136 }  // namespace grpc
137 
main(int argc,char ** argv)138 int main(int argc, char** argv) {
139   grpc::testing::TestEnvironment env(&argc, argv);
140   ::testing::InitGoogleTest(&argc, argv);
141   grpc_init();
142   int ret_val = RUN_ALL_TESTS();
143   grpc_shutdown();
144   return ret_val;
145 }
146