diff --git a/src/kubernetes.cc b/src/kubernetes.cc index f4c4da44..cde233b3 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -1143,7 +1143,9 @@ void KubernetesReader::WatchPods( } catch (const KubernetesReader::QueryException& e) { LOG(ERROR) << "No more pod metadata will be collected"; } - health_checker_->SetUnhealthy("kubernetes_pod_thread"); + if (health_checker_) { + health_checker_->SetUnhealthy("kubernetes_pod_thread"); + } LOG(INFO) << "Watch thread (pods) exiting"; } @@ -1176,7 +1178,9 @@ void KubernetesReader::WatchNodes( } catch (const KubernetesReader::QueryException& e) { LOG(ERROR) << "No more node metadata will be collected"; } - health_checker_->SetUnhealthy("kubernetes_node_thread"); + if (health_checker_) { + health_checker_->SetUnhealthy("kubernetes_node_thread"); + } LOG(INFO) << "Watch thread (node) exiting"; } diff --git a/src/kubernetes.h b/src/kubernetes.h index 46ccf494..1ca245ca 100644 --- a/src/kubernetes.h +++ b/src/kubernetes.h @@ -60,6 +60,7 @@ class KubernetesReader { const std::string& CurrentNode() const; private: + friend class KubernetesTest; // A representation of all query-related errors. class QueryException { public: diff --git a/test/Makefile b/test/Makefile index 5214c799..7d1cf8ca 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,18 +9,29 @@ GMOCK_DIR=$(LIBDIR)/googletest/googlemock # TODO: Factor out the common variables. CPP_NETLIB_DIR=$(LIBDIR)/cpp-netlib +CPP_NETLIB_LIBDIR=$(CPP_NETLIB_DIR)/libs/network/src +NETWORK_URI_DIR=$(CPP_NETLIB_DIR)/deps/uri +NETWORK_URI_LIBDIR=$(NETWORK_URI_DIR)/src YAML_CPP_DIR=$(LIBDIR)/yaml-cpp YAML_CPP_LIBDIR=$(YAML_CPP_DIR) +CPP_NETLIB_LIBS=\ + $(CPP_NETLIB_LIBDIR)/libcppnetlib-client-connections.a \ + $(CPP_NETLIB_LIBDIR)/libcppnetlib-server-parsers.a \ + $(NETWORK_URI_LIBDIR)/libnetwork-uri.a YAML_CPP_LIBS=$(YAML_CPP_LIBDIR)/libyaml-cpp.a CPPFLAGS+= \ + -DENABLE_KUBERNETES_METADATA \ -isystem $(GTEST_DIR)/include -I$(GMOCK_DIR)/include \ -I$(YAML_CPP_DIR)/include CXXFLAGS=\ -std=c++11 -g -pthread -Wno-write-strings -Wno-deprecated -LDLIBS=-lpthread -lboost_program_options -lyaml-cpp -lyajl -LDFLAGS=-L$(YAML_CPP_LIBDIR) +LDFLAGS=-L$(CPP_NETLIB_LIBDIR) -L$(NETWORK_URI_LIBDIR) -L$(YAML_CPP_LIBDIR) +LDLIBS=\ + -lcppnetlib-client-connections -lcppnetlib-server-parsers -lnetwork-uri \ + -lboost_program_options -lboost_system -lboost_thread -lboost_filesystem \ + -lpthread -lyajl -lssl -lcrypto -lyaml-cpp # Where to find code under test. SRC_DIR=../src @@ -34,6 +45,7 @@ TESTS=\ format_unittest \ health_checker_unittest \ json_unittest \ + kubernetes_unittest \ resource_unittest \ time_unittest @@ -60,6 +72,9 @@ init-submodules: git submodule update --init $(GTEST_MODULE) touch init-submodules +$(CPP_NETLIB_LIBS): + cd $(SRC_DIR) && $(MAKE) $@ + $(YAML_CPP_LIBS): cd $(SRC_DIR) && $(MAKE) $@ @@ -77,12 +92,16 @@ gtest_main.o: $(GTEST_SOURCEDIR)/gtest_main.cc $(GTEST_LIB): gtest-all.o gtest_main.o $(AR) $(ARFLAGS) $@ $^ +$(TESTS): $(CPP_NETLIB_LIBS) $(YAML_CPP_LIBS) + format_unittest: $(GTEST_LIB) format_unittest.o $(SRC_DIR)/format.o $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ base64_unittest: $(GTEST_LIB) base64_unittest.o $(SRC_DIR)/base64.o $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ configuration_unittest: $(GTEST_LIB) $(YAML_CPP_LIBS) configuration_unittest.o $(SRC_DIR)/configuration.o $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ +kubernetes_unittest: $(GTEST_LIB) kubernetes_unittest.o $(SRC_DIR)/kubernetes.o $(SRC_DIR)/json.o $(SRC_DIR)/logging.o $(SRC_DIR)/environment.o $(SRC_DIR)/time.o $(SRC_DIR)/store.o $(SRC_DIR)/resource.o $(SRC_DIR)/updater.o $(SRC_DIR)/instance.o $(SRC_DIR)/format.o $(SRC_DIR)/configuration.o $(SRC_DIR)/health_checker.o + $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ resource_unittest: $(GTEST_LIB) resource_unittest.o $(SRC_DIR)/resource.o $(SRC_DIR)/json.o $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ time_unittest: $(GTEST_LIB) time_unittest.o $(SRC_DIR)/time.o diff --git a/test/kubernetes_unittest.cc b/test/kubernetes_unittest.cc new file mode 100644 index 00000000..79e4ac94 --- /dev/null +++ b/test/kubernetes_unittest.cc @@ -0,0 +1,71 @@ +#include "../src/configuration.h" +#include "../src/kubernetes.h" +#include "../src/updater.h" +#include "gtest/gtest.h" + +namespace google { + +class KubernetesTest : public ::testing::Test { + protected: + MetadataUpdater::ResourceMetadata GetNodeMetadata( + const KubernetesReader& reader, const json::Object *node, + Timestamp collected_at, bool is_deleted) const + throw(json::Exception) { + return reader.GetNodeMetadata(node, collected_at, is_deleted); + } +}; + +TEST_F(KubernetesTest, GetNodeMetadata) { + Configuration config(std::stringstream( + "KubernetesClusterName: TestClusterName\n" + "KubernetesClusterLocation: TestClusterLocation\n" + "MetadataIngestionRawContentVersion: TestVersion\n" + "InstanceResourceType: gce_instance\n" + "InstanceZone: TestZone\n" + "InstanceId: TestID\n" + )); + Environment environment(config); + KubernetesReader reader(config, nullptr); // Don't need HealthChecker. + json::value node = json::object({ + {"metadata", json::object({ + {"name", json::string("testname")}, + {"creationTimestamp", json::string("2018-03-03T01:23:45.678901234Z")}, + })} + }); + const auto m = + GetNodeMetadata(reader, node->As(), Timestamp(), false); + EXPECT_EQ(1, m.ids.size()); + EXPECT_EQ("k8s_node.testname", m.ids[0]); + EXPECT_EQ(MonitoredResource("k8s_node", { + {"cluster_name", "TestClusterName"}, + {"node_name", "testname"}, + {"location", "TestClusterLocation"}, + }), m.resource); + EXPECT_EQ("TestVersion", m.metadata.version); + EXPECT_EQ(false, m.metadata.is_deleted); + EXPECT_EQ(time::rfc3339::FromString("2018-03-03T01:23:45.678901234Z"), + m.metadata.created_at); + EXPECT_EQ(Timestamp(), m.metadata.collected_at); + json::value big = json::object({ + {"blobs", json::object({ + {"association", json::object({ + {"version", json::string("TestVersion")}, + {"raw", json::object({ + {"infrastructureResource", json::object({ + {"type", json::string("gce_instance")}, + {"labels", json::object({ + {"instance_id", json::string("TestID")}, + {"zone", json::string("TestZone")}, + })}, + })}, + })}, + })}, + {"api", json::object({ + {"version", json::string("1.6")}, // Hard-coded in kubernetes.cc. + {"raw", std::move(node)}, + })}, + })}, + }); + EXPECT_EQ(big->ToString(), m.metadata.metadata->ToString()); +} +} // namespace google