aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-09-01 12:57:36 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-09-01 12:57:36 -0700
commit97ec5eb61e9c2995387668c094d89389facb0878 (patch)
tree9df6655b4d92ebe4926f322f8cb33be44aaba68a
parent40f9c73d8a65e0cc1dd3a763b7e0c67d333cdaf2 (diff)
Add stats test
-rw-r--r--CMakeLists.txt42
-rw-r--r--Makefile48
-rw-r--r--build.yaml12
-rw-r--r--src/core/lib/debug/stats_data.c75
-rw-r--r--src/core/lib/debug/stats_data.h88
-rw-r--r--test/core/debug/stats_test.cc127
-rwxr-xr-xtools/codegen/core/gen_stats_data.py47
-rw-r--r--tools/run_tests/generated/sources_and_headers.json18
-rw-r--r--tools/run_tests/generated/tests.json22
9 files changed, 386 insertions, 93 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index efc33c0a6c..0567255dd6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -756,6 +756,7 @@ endif()
add_dependencies(buildtests_cxx server_crash_test_client)
add_dependencies(buildtests_cxx server_request_call_test)
add_dependencies(buildtests_cxx shutdown_test)
+add_dependencies(buildtests_cxx stats_test)
add_dependencies(buildtests_cxx status_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx streaming_throughput_test)
@@ -12688,6 +12689,47 @@ target_link_libraries(shutdown_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(stats_test
+ test/core/debug/stats_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(stats_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${BORINGSSL_ROOT_DIR}/include
+ PRIVATE ${PROTOBUF_ROOT_DIR}/src
+ PRIVATE ${BENCHMARK_ROOT_DIR}/include
+ PRIVATE ${ZLIB_ROOT_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+ PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+ PRIVATE ${CARES_INCLUDE_DIR}
+ PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(stats_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++_test_util
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(status_test
test/cpp/util/status_test.cc
third_party/googletest/googletest/src/gtest-all.cc
diff --git a/Makefile b/Makefile
index 4fd534df09..309ec18a47 100644
--- a/Makefile
+++ b/Makefile
@@ -1170,6 +1170,7 @@ server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
+stats_test: $(BINDIR)/$(CONFIG)/stats_test
status_test: $(BINDIR)/$(CONFIG)/status_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
@@ -1600,6 +1601,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
+ $(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
@@ -1715,6 +1717,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
+ $(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
@@ -2114,6 +2117,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 )
$(E) "[RUN] Testing shutdown_test"
$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
+ $(E) "[RUN] Testing stats_test"
+ $(Q) $(BINDIR)/$(CONFIG)/stats_test || ( echo test stats_test failed ; exit 1 )
$(E) "[RUN] Testing status_test"
$(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 )
$(E) "[RUN] Testing streaming_throughput_test"
@@ -16631,6 +16636,49 @@ endif
endif
+STATS_TEST_SRC = \
+ test/core/debug/stats_test.cc \
+
+STATS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STATS_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/stats_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_stats_test: $(STATS_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(STATS_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
STATUS_TEST_SRC = \
test/cpp/util/status_test.cc \
diff --git a/build.yaml b/build.yaml
index a43ad6ae31..2b69888e06 100644
--- a/build.yaml
+++ b/build.yaml
@@ -4515,6 +4515,18 @@ targets:
- grpc
- gpr_test_util
- gpr
+- name: stats_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/debug/stats_test.cc
+ deps:
+ - grpc++_test_util
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
- name: status_test
build: test
language: c++
diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c
index 177234ab5b..0ba10e68e3 100644
--- a/src/core/lib/debug/stats_data.c
+++ b/src/core/lib/debug/stats_data.c
@@ -19,6 +19,8 @@
*/
#include "src/core/lib/debug/stats_data.h"
+#include "src/core/lib/debug/stats.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = {
"client_calls_created", "server_calls_created", "syscall_write",
"syscall_read", "syscall_poll", "syscall_wait",
@@ -165,7 +167,80 @@ const uint8_t grpc_stats_table_3[52] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52};
+void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, double value) {
+ union {
+ double dbl;
+ uint64_t uint;
+ } _val;
+ _val.dbl = value;
+ if (_val.dbl < 0) _val.dbl = 0;
+ if (_val.dbl < 5.000000) {
+ GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE,
+ (int)_val.dbl);
+ } else {
+ if (_val.uint < 4715268809856909312ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE,
+ grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_0, 64));
+ }
+ }
+}
+void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double value) {
+ union {
+ double dbl;
+ uint64_t uint;
+ } _val;
+ _val.dbl = value;
+ if (_val.dbl < 0) _val.dbl = 0;
+ if (_val.dbl < 12.000000) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, (int)_val.dbl);
+ } else {
+ if (_val.uint < 4652218415073722368ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE,
+ grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 49)] +
+ 11);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_2, 64));
+ }
+ }
+}
+void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, double value) {
+ union {
+ double dbl;
+ uint64_t uint;
+ } _val;
+ _val.dbl = value;
+ if (_val.dbl < 0) _val.dbl = 0;
+ if (_val.dbl < 5.000000) {
+ GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE,
+ (int)_val.dbl);
+ } else {
+ if (_val.uint < 4715268809856909312ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE,
+ grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_0, 64));
+ }
+ }
+}
const int grpc_stats_histo_buckets[3] = {64, 64, 64};
const int grpc_stats_histo_start[3] = {0, 64, 128};
const double *const grpc_stats_histo_bucket_boundaries[3] = {
grpc_stats_table_0, grpc_stats_table_2, grpc_stats_table_0};
+void (*const grpc_stats_inc_histogram[3])(grpc_exec_ctx *exec_ctx, double x) = {
+ grpc_stats_inc_tcp_write_size, grpc_stats_inc_tcp_write_iov_size,
+ grpc_stats_inc_tcp_read_size};
diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h
index 9a4ba68655..4fff769450 100644
--- a/src/core/lib/debug/stats_data.h
+++ b/src/core/lib/debug/stats_data.h
@@ -22,6 +22,7 @@
#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H
#include <inttypes.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
typedef enum {
GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED,
@@ -64,84 +65,19 @@ typedef enum {
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_WAIT)
#define GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS(exec_ctx) \
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HISTOGRAM_SLOW_LOOKUPS)
-#define GRPC_STATS_INC_TCP_WRITE_SIZE(exec_ctx, value) \
- do { \
- union { \
- double dbl; \
- uint64_t uint; \
- } _val; \
- _val.dbl = (double)(value); \
- if (_val.dbl < 0) _val.dbl = 0; \
- if (_val.dbl < 5.000000) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, (int)_val.dbl); \
- } else { \
- if (_val.uint < 4715268809856909312ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, \
- grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_0, 64)); \
- } \
- } \
- } while (false)
-#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(exec_ctx, value) \
- do { \
- union { \
- double dbl; \
- uint64_t uint; \
- } _val; \
- _val.dbl = (double)(value); \
- if (_val.dbl < 0) _val.dbl = 0; \
- if (_val.dbl < 12.000000) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, (int)_val.dbl); \
- } else { \
- if (_val.uint < 4652218415073722368ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, \
- grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 49)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_2, 64)); \
- } \
- } \
- } while (false)
-#define GRPC_STATS_INC_TCP_READ_SIZE(exec_ctx, value) \
- do { \
- union { \
- double dbl; \
- uint64_t uint; \
- } _val; \
- _val.dbl = (double)(value); \
- if (_val.dbl < 0) _val.dbl = 0; \
- if (_val.dbl < 5.000000) { \
- GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \
- (int)_val.dbl); \
- } else { \
- if (_val.uint < 4715268809856909312ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \
- grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_0, 64)); \
- } \
- } \
- } while (false)
-extern const double grpc_stats_table_0[64];
-extern const uint8_t grpc_stats_table_1[87];
-extern const double grpc_stats_table_2[64];
-extern const uint8_t grpc_stats_table_3[52];
+#define GRPC_STATS_INC_TCP_WRITE_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_write_size((exec_ctx), (double)(value))
+void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, double x);
+#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_write_iov_size((exec_ctx), (double)(value))
+void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double x);
+#define GRPC_STATS_INC_TCP_READ_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_read_size((exec_ctx), (double)(value))
+void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, double x);
extern const int grpc_stats_histo_buckets[3];
extern const int grpc_stats_histo_start[3];
extern const double *const grpc_stats_histo_bucket_boundaries[3];
+extern void (*const grpc_stats_inc_histogram[3])(grpc_exec_ctx *exec_ctx,
+ double x);
#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */
diff --git a/test/core/debug/stats_test.cc b/test/core/debug/stats_test.cc
new file mode 100644
index 0000000000..65ccc7a5c8
--- /dev/null
+++ b/test/core/debug/stats_test.cc
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed 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.
+ *
+ */
+
+extern "C" {
+#include "src/core/lib/debug/stats.h"
+}
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <gtest/gtest.h>
+
+namespace grpc {
+namespace testing {
+
+class Snapshot {
+ public:
+ Snapshot() { grpc_stats_collect(&begin_); }
+
+ grpc_stats_data delta() {
+ grpc_stats_data now;
+ grpc_stats_collect(&now);
+ grpc_stats_data delta;
+ grpc_stats_diff(&now, &begin_, &delta);
+ return delta;
+ }
+
+ private:
+ grpc_stats_data begin_;
+};
+
+TEST(StatsTest, IncCounters) {
+ for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
+ Snapshot snapshot;
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GRPC_STATS_INC_COUNTER(&exec_ctx, (grpc_stats_counters)i);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ EXPECT_EQ(snapshot.delta().counters[i], 1);
+ }
+}
+
+TEST(StatsTest, IncSpecificCounter) {
+ Snapshot snapshot;
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GRPC_STATS_INC_SYSCALL_POLL(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ EXPECT_EQ(snapshot.delta().counters[GRPC_STATS_COUNTER_SYSCALL_POLL], 1);
+}
+
+static int FindExpectedBucket(int i, int j) {
+ if (j < 0) {
+ return 0;
+ }
+ if (j >=
+ grpc_stats_histo_bucket_boundaries[i][grpc_stats_histo_buckets[i] - 1]) {
+ return grpc_stats_histo_buckets[i] - 1;
+ }
+ int r = 0;
+ while (grpc_stats_histo_bucket_boundaries[i][r + 1] <= j) r++;
+ return r;
+}
+
+static int FindNonZeroBucket(const grpc_stats_data& data, int i) {
+ for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) {
+ if (data.histograms[grpc_stats_histo_start[i] + j] != 0) {
+ return j;
+ }
+ }
+ return -1;
+}
+
+TEST(StatsTest, IncHistogram) {
+ for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
+ for (int j = -1000;
+ j <
+ grpc_stats_histo_bucket_boundaries[i]
+ [grpc_stats_histo_buckets[i] - 1] +
+ 1000;
+ j++) {
+ gpr_log(GPR_DEBUG, "histo:%d value:%d", i, j);
+
+ Snapshot snapshot;
+
+ int expected_bucket = FindExpectedBucket(i, j);
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_stats_inc_histogram[i](&exec_ctx, j);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ auto delta = snapshot.delta();
+ int got_bucket = FindNonZeroBucket(delta, i);
+
+ EXPECT_EQ(expected_bucket, got_bucket);
+ EXPECT_EQ(delta.histograms[grpc_stats_histo_start[i] + expected_bucket],
+ 1);
+ }
+ }
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ grpc_init();
+ int ret = RUN_ALL_TESTS();
+ grpc_shutdown();
+ return ret;
+}
diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py
index 85489eb7dc..8ae8f6b831 100755
--- a/tools/codegen/core/gen_stats_data.py
+++ b/tools/codegen/core/gen_stats_data.py
@@ -125,32 +125,30 @@ def gen_bucket_code(histogram):
shift_data = find_ideal_shift(code_bounds[first_nontrivial:], 256 * histogram.buckets)
print first_nontrivial, shift_data, bounds
if shift_data is not None: print [hex(x >> shift_data[0]) for x in code_bounds[first_nontrivial:]]
- code = 'do {\\\n'
- code += ' union { double dbl; uint64_t uint; } _val;\\\n'
- code += '_val.dbl = (double)(value);\\\n'
- code += 'if (_val.dbl < 0) _val.dbl = 0;\\\n'
+ code = ' union { double dbl; uint64_t uint; } _val;\n'
+ code += '_val.dbl = value;\n'
+ code += 'if (_val.dbl < 0) _val.dbl = 0;\n'
map_table = gen_map_table(code_bounds[first_nontrivial:], shift_data)
if first_nontrivial is None:
- code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\\\n'
+ code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\n'
% histogram.name.upper())
else:
- code += 'if (_val.dbl < %f) {\\\n' % first_nontrivial
- code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\\\n'
+ code += 'if (_val.dbl < %f) {\n' % first_nontrivial
+ code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\n'
% histogram.name.upper())
code += '} else {'
first_nontrivial_code = dbl2u64(first_nontrivial)
if shift_data is not None:
map_table_idx = decl_static_table(map_table, type_for_uint_table(map_table))
- code += 'if (_val.uint < %dull) {\\\n' % ((map_table[-1] << shift_data[0]) + first_nontrivial_code)
+ code += 'if (_val.uint < %dull) {\n' % ((map_table[-1] << shift_data[0]) + first_nontrivial_code)
code += 'GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, ' % histogram.name.upper()
- code += 'grpc_stats_table_%d[((_val.uint - %dull) >> %d)]);\\\n' % (map_table_idx, first_nontrivial_code, shift_data[0])
- code += '} else {\\\n'
+ code += 'grpc_stats_table_%d[((_val.uint - %dull) >> %d)] + %d);\n' % (map_table_idx, first_nontrivial_code, shift_data[0], first_nontrivial-1)
+ code += '} else {\n'
code += 'GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, '% histogram.name.upper()
- code += 'grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, grpc_stats_table_%d, %d));\\\n' % (bounds_idx, len(bounds))
+ code += 'grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, grpc_stats_table_%d, %d));\n' % (bounds_idx, len(bounds))
if shift_data is not None:
code += '}'
code += '}'
- code += '} while (false)'
return (code, bounds_idx)
# utility: print a big comment block into a set of files
@@ -184,6 +182,7 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
print >>H, "#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H"
print >>H
print >>H, "#include <inttypes.h>"
+ print >>H, "#include \"src/core/lib/iomgr/exec_ctx.h\""
print >>H
for typename, instances in sorted(inst_map.items()):
@@ -215,11 +214,9 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
"GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_%s)") % (
ctr.name.upper(), ctr.name.upper())
for histogram in inst_map['Histogram']:
- code, bounds_idx = gen_bucket_code(histogram)
- histo_bucket_boundaries.append(bounds_idx)
- print >>H, ("#define GRPC_STATS_INC_%s(exec_ctx, value) %s") % (
- histogram.name.upper(),
- code)
+ print >>H, "#define GRPC_STATS_INC_%s(exec_ctx, value) grpc_stats_inc_%s((exec_ctx), (double)(value))" % (
+ histogram.name.upper(), histogram.name.lower())
+ print >>H, "void grpc_stats_inc_%s(grpc_exec_ctx *exec_ctx, double x);" % histogram.name.lower()
for i, tbl in enumerate(static_tables):
print >>H, "extern const %s grpc_stats_table_%d[%d];" % (tbl[0], i, len(tbl[1]))
@@ -227,6 +224,7 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
print >>H, "extern const int grpc_stats_histo_buckets[%d];" % len(inst_map['Histogram'])
print >>H, "extern const int grpc_stats_histo_start[%d];" % len(inst_map['Histogram'])
print >>H, "extern const double *const grpc_stats_histo_bucket_boundaries[%d];" % len(inst_map['Histogram'])
+ print >>H, "extern void (*const grpc_stats_inc_histogram[%d])(grpc_exec_ctx *exec_ctx, double x);" % len(inst_map['Histogram'])
print >>H
print >>H, "#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */"
@@ -250,6 +248,14 @@ with open('src/core/lib/debug/stats_data.c', 'w') as C:
put_banner([C], ["Automatically generated by tools/codegen/core/gen_stats_data.py"])
print >>C, "#include \"src/core/lib/debug/stats_data.h\""
+ print >>C, "#include \"src/core/lib/debug/stats.h\""
+ print >>C, "#include \"src/core/lib/iomgr/exec_ctx.h\""
+
+ histo_code = []
+ for histogram in inst_map['Histogram']:
+ code, bounds_idx = gen_bucket_code(histogram)
+ histo_bucket_boundaries.append(bounds_idx)
+ histo_code.append(code)
for typename, instances in sorted(inst_map.items()):
print >>C, "const char *grpc_stats_%s_name[GRPC_STATS_%s_COUNT] = {" % (
@@ -261,9 +267,16 @@ with open('src/core/lib/debug/stats_data.c', 'w') as C:
print >>C, "const %s grpc_stats_table_%d[%d] = {%s};" % (
tbl[0], i, len(tbl[1]), ','.join('%s' % x for x in tbl[1]))
+ for histogram, code in zip(inst_map['Histogram'], histo_code):
+ print >>C, ("void grpc_stats_inc_%s(grpc_exec_ctx *exec_ctx, double value) {%s}") % (
+ histogram.name.lower(),
+ code)
+
print >>C, "const int grpc_stats_histo_buckets[%d] = {%s};" % (
len(inst_map['Histogram']), ','.join('%s' % x for x in histo_buckets))
print >>C, "const int grpc_stats_histo_start[%d] = {%s};" % (
len(inst_map['Histogram']), ','.join('%s' % x for x in histo_start))
print >>C, "const double *const grpc_stats_histo_bucket_boundaries[%d] = {%s};" % (
len(inst_map['Histogram']), ','.join('grpc_stats_table_%d' % x for x in histo_bucket_boundaries))
+ print >>C, "void (*const grpc_stats_inc_histogram[%d])(grpc_exec_ctx *exec_ctx, double x) = {%s};" % (
+ len(inst_map['Histogram']), ','.join('grpc_stats_inc_%s' % histogram.name.lower() for histogram in inst_map['Histogram']))
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 5ce25dc14a..7326f8cf72 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -4018,6 +4018,24 @@
"gpr",
"gpr_test_util",
"grpc",
+ "grpc++_test_util",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "stats_test",
+ "src": [
+ "test/core/debug/stats_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
"grpc++",
"grpc_test_util"
],
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 4368a5768e..f77b45839e 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3943,6 +3943,28 @@
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "stats_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ]
+ },
+ {
+ "args": [],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
"gtest": false,
"language": "c++",
"name": "status_test",