Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 13b1a2f

Browse files
authored
stats_exporter_test: add lock around exported data. (#425)
Otherwise TSAN thinks we're relying on sleep().
1 parent a82f154 commit 13b1a2f

File tree

1 file changed

+31
-22
lines changed

1 file changed

+31
-22
lines changed

opencensus/stats/internal/stats_exporter_test.cc

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,38 @@
3131
namespace opencensus {
3232
namespace stats {
3333

34+
struct ExportedData {
35+
std::vector<std::pair<ViewDescriptor, ViewData>> Get() const {
36+
absl::MutexLock l(&mu);
37+
return data;
38+
}
39+
40+
mutable absl::Mutex mu;
41+
std::vector<std::pair<ViewDescriptor, ViewData>> data GUARDED_BY(mu);
42+
};
43+
3444
// A mock exporter that assigns exported data to the provided pointer.
3545
class MockExporter : public StatsExporter::Handler {
3646
public:
37-
static void Register(
38-
std::vector<std::pair<ViewDescriptor, ViewData>>* output) {
47+
static void Register(ExportedData* output) {
3948
opencensus::stats::StatsExporter::RegisterPushHandler(
4049
absl::make_unique<MockExporter>(output));
4150
}
4251

43-
MockExporter(std::vector<std::pair<ViewDescriptor, ViewData>>* output)
44-
: output_(output) {}
52+
MockExporter(ExportedData* output) : output_(output) {}
4553

4654
void ExportViewData(
4755
const std::vector<std::pair<ViewDescriptor, ViewData>>& data) override {
56+
absl::MutexLock l(&output_->mu);
4857
// Looping because ViewData is (intentionally) copy-constructable but not
4958
// copy_assignable.
5059
for (const auto& datum : data) {
51-
output_->emplace_back(datum.first, datum.second);
60+
output_->data.emplace_back(datum.first, datum.second);
5261
}
5362
}
5463

5564
private:
56-
std::vector<std::pair<ViewDescriptor, ViewData>>* output_;
65+
ExportedData* output_;
5766
};
5867

5968
constexpr char kMeasureId[] = "test_measure_id";
@@ -96,21 +105,21 @@ class StatsExporterTest : public ::testing::Test {
96105
};
97106

98107
TEST_F(StatsExporterTest, AddView) {
99-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
108+
ExportedData exported_data;
100109
MockExporter::Register(&exported_data);
101110
descriptor1_.RegisterForExport();
102111
descriptor2_.RegisterForExport();
103112
EXPECT_THAT(StatsExporter::GetViewData(),
104113
::testing::UnorderedElementsAre(::testing::Key(descriptor1_),
105114
::testing::Key(descriptor2_)));
106115
Export();
107-
EXPECT_THAT(exported_data,
116+
EXPECT_THAT(exported_data.Get(),
108117
::testing::UnorderedElementsAre(::testing::Key(descriptor1_),
109118
::testing::Key(descriptor2_)));
110119
}
111120

112121
TEST_F(StatsExporterTest, UpdateView) {
113-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
122+
ExportedData exported_data;
114123
MockExporter::Register(&exported_data);
115124
descriptor1_.RegisterForExport();
116125
descriptor2_.RegisterForExport();
@@ -120,55 +129,55 @@ TEST_F(StatsExporterTest, UpdateView) {
120129
::testing::UnorderedElementsAre(::testing::Key(descriptor1_edited_),
121130
::testing::Key(descriptor2_)));
122131
Export();
123-
EXPECT_THAT(exported_data, ::testing::UnorderedElementsAre(
124-
::testing::Key(descriptor1_edited_),
125-
::testing::Key(descriptor2_)));
132+
EXPECT_THAT(exported_data.Get(), ::testing::UnorderedElementsAre(
133+
::testing::Key(descriptor1_edited_),
134+
::testing::Key(descriptor2_)));
126135
}
127136

128137
TEST_F(StatsExporterTest, RemoveView) {
129-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
138+
ExportedData exported_data;
130139
MockExporter::Register(&exported_data);
131140
descriptor1_.RegisterForExport();
132141
descriptor2_.RegisterForExport();
133142
StatsExporter::RemoveView(descriptor1_.name());
134143
EXPECT_THAT(StatsExporter::GetViewData(),
135144
::testing::UnorderedElementsAre(::testing::Key(descriptor2_)));
136145
Export();
137-
EXPECT_THAT(exported_data,
146+
EXPECT_THAT(exported_data.Get(),
138147
::testing::UnorderedElementsAre(::testing::Key(descriptor2_)));
139148
}
140149

141150
TEST_F(StatsExporterTest, MultipleExporters) {
142-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data_1;
151+
ExportedData exported_data_1;
143152
MockExporter::Register(&exported_data_1);
144-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data_2;
153+
ExportedData exported_data_2;
145154
MockExporter::Register(&exported_data_2);
146155
descriptor1_.RegisterForExport();
147156
Export();
148-
EXPECT_THAT(exported_data_1,
157+
EXPECT_THAT(exported_data_1.Get(),
149158
::testing::UnorderedElementsAre(::testing::Key(descriptor1_)));
150-
EXPECT_THAT(exported_data_2,
159+
EXPECT_THAT(exported_data_2.Get(),
151160
::testing::UnorderedElementsAre(::testing::Key(descriptor1_)));
152161
}
153162

154163
TEST_F(StatsExporterTest, IntervalViewRejected) {
155-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
164+
ExportedData exported_data;
156165
MockExporter::Register(&exported_data);
157166
ViewDescriptor interval_descriptor = ViewDescriptor().set_name("interval");
158167
SetAggregationWindow(AggregationWindow::Interval(absl::Hours(1)),
159168
&interval_descriptor);
160169
interval_descriptor.RegisterForExport();
161170
EXPECT_TRUE(StatsExporter::GetViewData().empty());
162171
Export();
163-
EXPECT_TRUE(exported_data.empty());
172+
EXPECT_TRUE(exported_data.Get().empty());
164173
}
165174

166175
TEST_F(StatsExporterTest, TimedExport) {
167-
std::vector<std::pair<ViewDescriptor, ViewData>> exported_data;
176+
ExportedData exported_data;
168177
MockExporter::Register(&exported_data);
169178
descriptor1_.RegisterForExport();
170179
absl::SleepFor(absl::Seconds(6));
171-
EXPECT_THAT(exported_data,
180+
EXPECT_THAT(exported_data.Get(),
172181
::testing::UnorderedElementsAre(::testing::Key(descriptor1_)));
173182
}
174183

0 commit comments

Comments
 (0)