| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "kudu/util/cloud/instance_detector.h" |
| |
| #include <memory> |
| #include <ostream> |
| #include <string> |
| |
| #include <gflags/gflags_declare.h> |
| #include <glog/logging.h> |
| #include <gtest/gtest.h> |
| |
| #include "kudu/gutil/strings/substitute.h" |
| #include "kudu/util/cloud/instance_metadata.h" |
| #include "kudu/util/status.h" |
| |
| DECLARE_string(cloud_curl_dns_servers_for_testing); |
| DECLARE_uint32(cloud_metadata_server_request_timeout_ms); |
| |
| using std::string; |
| using std::unique_ptr; |
| using strings::Substitute; |
| |
| namespace kudu { |
| namespace cloud { |
| |
| // Test the destruction of the object if not running the auto-detection. |
| TEST(InstanceDetectorTest, NoDetectionRun) { |
| InstanceDetector detector; |
| } |
| |
| // Basic scenario to verify the functionality of the InstanceDetector::Detect() |
| // method. |
| TEST(InstanceDetectorTest, Basic) { |
| #ifdef THREAD_SANITIZER |
| // In case of TSAN builds, it takes longer to spawn threads and overall work |
| // with the sanitized version of libcurl while having a lot of concurrent |
| // activity. It doesn't make the metadata server taking more time to respond, |
| // but it takes longer to process a response: it's often turns into a time-out |
| // error even if the server responds in a timely manner. |
| FLAGS_cloud_metadata_server_request_timeout_ms = 10000; |
| #endif |
| InstanceDetector detector; |
| unique_ptr<InstanceMetadata> metadata; |
| const auto s = detector.Detect(&metadata); |
| |
| const auto s_aws = AwsInstanceMetadata().Init(); |
| const auto s_azure = AzureInstanceMetadata().Init(); |
| const auto s_gce = GceInstanceMetadata().Init(); |
| const auto s_openstack = OpenStackInstanceMetadata().Init(); |
| |
| if (s_aws.ok() || s_azure.ok() || s_gce.ok() || s_openstack.ok()) { |
| ASSERT_TRUE(s.ok()) << s.ToString(); |
| ASSERT_NE(nullptr, metadata.get()); |
| LOG(INFO) << Substitute("detected $0 environment", |
| TypeToString(metadata->type())); |
| } else { |
| ASSERT_TRUE(s.IsNotFound()) << s.ToString(); |
| ASSERT_EQ(nullptr, metadata.get()); |
| LOG(INFO) << "detected non-cloud environment"; |
| } |
| |
| if (s_aws.ok()) { |
| ASSERT_FALSE(s_azure.ok()); |
| ASSERT_FALSE(s_gce.ok()); |
| ASSERT_FALSE(s_openstack.ok()); |
| ASSERT_EQ(CloudType::AWS, metadata->type()); |
| } else if (s_azure.ok()) { |
| ASSERT_FALSE(s_aws.ok()); |
| ASSERT_FALSE(s_gce.ok()); |
| ASSERT_FALSE(s_openstack.ok()); |
| ASSERT_EQ(CloudType::AZURE, metadata->type()); |
| } else if (s_gce.ok()) { |
| ASSERT_FALSE(s_aws.ok()); |
| ASSERT_FALSE(s_azure.ok()); |
| ASSERT_FALSE(s_openstack.ok()); |
| ASSERT_EQ(CloudType::GCE, metadata->type()); |
| } else if (s_openstack.ok()) { |
| ASSERT_FALSE(s_aws.ok()); |
| ASSERT_FALSE(s_azure.ok()); |
| ASSERT_FALSE(s_gce.ok()); |
| ASSERT_EQ(CloudType::OPENSTACK, metadata->type()); |
| } |
| } |
| |
| // If the timeout for auto-detection is set too low, the detector should return |
| // Status::NotFound(). Even if the timeout is set too low to get a response |
| // from the metadata servers, the detector has no other choice but to rely |
| // on the results from the metadata fetchers. |
| TEST(InstanceDetectorTest, Timeout) { |
| // Set very short interval for the timeout. |
| FLAGS_cloud_metadata_server_request_timeout_ms = 1; |
| // Configure a bad DNS server to ensure a timeout, |
| // even when run on fast cloud instances. |
| FLAGS_cloud_curl_dns_servers_for_testing = "192.0.2.0"; |
| |
| InstanceDetector detector; |
| unique_ptr<InstanceMetadata> metadata; |
| const auto s = detector.Detect(&metadata); |
| ASSERT_TRUE(s.IsNotFound()) << s.ToString(); |
| ASSERT_EQ(nullptr, metadata.get()); |
| } |
| |
| } // namespace cloud |
| } // namespace kudu |