Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1096)

Unified Diff: webrtc/media/engine/webrtcvoiceengine_unittest.cc

Issue 1830213002: Remove WVoE::SetAudioDeviceModule() - it is now set in ctor. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: removed Construct() method Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/media/engine/webrtcvoiceengine_unittest.cc
diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
index 30be07d21398f97572f453ed08bb930c805f5986..d5a8a3e44acb13554bfc09f2f04aeff90e42bc7f 100644
--- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc
+++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
@@ -74,29 +74,30 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
explicit WebRtcVoiceEngineTestFake(const char* field_trials)
: call_(webrtc::Call::Config()),
- engine_(new FakeVoEWrapper(&voe_)),
- channel_(nullptr),
+ engine_(nullptr, new FakeVoEWrapper(&voe_)),
override_field_trials_(field_trials) {
send_parameters_.codecs.push_back(kPcmuCodec);
recv_parameters_.codecs.push_back(kPcmuCodec);
}
bool SetupEngine() {
- if (!engine_.Init(rtc::Thread::Current())) {
- return false;
+ return engine_.Init();
+ }
+ bool SetupEngineWithChannel() {
+ if (SetupEngine()) {
+ channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
+ cricket::AudioOptions());
}
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
return (channel_ != nullptr);
}
bool SetupEngineWithRecvStream() {
- if (!SetupEngine()) {
+ if (!SetupEngineWithChannel()) {
return false;
}
return channel_->AddRecvStream(
cricket::StreamParams::CreateLegacy(kSsrc1));
}
bool SetupEngineWithSendStream() {
- if (!SetupEngine()) {
+ if (!SetupEngineWithChannel()) {
return false;
}
if (!channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc1))) {
@@ -142,10 +143,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
}
void TestInsertDtmf(uint32_t ssrc, bool caller) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
- EXPECT_TRUE(channel_ != nullptr);
+ EXPECT_TRUE(SetupEngineWithChannel());
if (caller) {
// If this is a caller, local description will be applied and add the
// send stream.
@@ -401,7 +399,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
cricket::FakeCall call_;
cricket::FakeWebRtcVoiceEngine voe_;
cricket::WebRtcVoiceEngine engine_;
- cricket::VoiceMediaChannel* channel_;
+ cricket::VoiceMediaChannel* channel_ = nullptr;
cricket::AudioSendParameters send_parameters_;
cricket::AudioRecvParameters recv_parameters_;
FakeAudioSource fake_source_;
@@ -413,7 +411,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
// Tests that our stub library "works".
TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
EXPECT_FALSE(voe_.IsInited());
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
+ EXPECT_TRUE(engine_.Init());
EXPECT_TRUE(voe_.IsInited());
engine_.Terminate();
EXPECT_FALSE(voe_.IsInited());
@@ -421,15 +419,13 @@ TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
// Tests that we can create and destroy a channel.
TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
- EXPECT_TRUE(channel_ != nullptr);
+ EXPECT_TRUE(SetupEngineWithChannel());
}
// Tests that the list of supported codecs is created properly and ordered
// correctly
TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
+ EXPECT_TRUE(SetupEngine());
const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
ASSERT_FALSE(codecs.empty());
EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
@@ -444,6 +440,7 @@ TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
}
TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) {
+ EXPECT_TRUE(SetupEngine());
const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
bool opus_found = false;
for (cricket::AudioCodec codec : codecs) {
@@ -494,7 +491,7 @@ TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
// Test that we set our inbound codecs properly, including changing PT.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -521,7 +518,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
// Test that we fail to set an unknown inbound codec.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
@@ -530,7 +527,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
// Test that we fail if we have duplicate types in the inbound list.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kCn16000Codec);
@@ -540,7 +537,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
// Test that we can decode OPUS without stereo parameters.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -562,7 +559,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
// Test that we can decode OPUS with stereo = 0.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -585,7 +582,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
// Test that we can decode OPUS with stereo = 1.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -607,7 +604,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
// Test that changes to recv codecs are applied to all streams.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioRecvParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -733,7 +730,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
}
TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
const int kDesiredBitrate = 128000;
cricket::AudioSendParameters parameters;
parameters.codecs = engine_.codecs();
@@ -1299,7 +1296,7 @@ TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
}
TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioSendParameters send_parameters;
send_parameters.codecs.push_back(kOpusCodec);
EXPECT_TRUE(send_parameters.codecs[0].feedback_params.params().empty());
@@ -1730,11 +1727,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
// Test that we set VAD and DTMF types correctly as callee.
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
- EXPECT_TRUE(channel_ != nullptr);
-
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioSendParameters parameters;
parameters.codecs.push_back(kIsacCodec);
parameters.codecs.push_back(kPcmuCodec);
@@ -1848,11 +1841,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
// Test that we set up RED correctly as callee.
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
- EXPECT_TRUE(channel_ != nullptr);
-
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::AudioSendParameters parameters;
parameters.codecs.push_back(kRedCodec);
parameters.codecs.push_back(kIsacCodec);
@@ -2389,10 +2378,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
// Test that the local SSRC is the same on sending and receiving channels if the
// receive channel is created before the send channel.
TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
- channel_ = engine_.CreateChannel(&call_, cricket::MediaConfig(),
- cricket::AudioOptions());
-
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
int receive_channel_num = voe_.GetLastChannel();
EXPECT_TRUE(channel_->AddSendStream(
@@ -2404,7 +2390,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
// Test that we can properly receive packets.
TEST_F(WebRtcVoiceEngineTestFake, Recv) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
int channel_num = voe_.GetLastChannel();
@@ -2413,7 +2399,7 @@ TEST_F(WebRtcVoiceEngineTestFake, Recv) {
// Test that we can properly receive packets on multiple streams.
TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
int channel_num1 = voe_.GetLastChannel();
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
@@ -2458,7 +2444,7 @@ TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
// Test that receiving on an unsignalled stream works (default channel will be
// created).
TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
int channel_num = voe_.GetLastChannel();
EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
@@ -2468,7 +2454,7 @@ TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
// created), and that packets will be forwarded to the default channel
// regardless of their SSRCs.
TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
char packet[sizeof(kPcmuFrame)];
memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
@@ -2488,7 +2474,7 @@ TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
// Test that a default channel is created even after a signalled stream has been
// added, and that this stream will get any packets for unknown SSRCs.
TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
char packet[sizeof(kPcmuFrame)];
memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
@@ -2515,14 +2501,14 @@ TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
// Test that we properly handle failures to add a receive stream.
TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
voe_.set_fail_create_channel(true);
EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
}
// Test that we properly handle failures to add a send stream.
TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
voe_.set_fail_create_channel(true);
EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
}
@@ -2572,7 +2558,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
}
TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
// Manually delete channel to simulate a failure.
int channel = voe_.GetLastChannel();
@@ -2806,7 +2792,7 @@ TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
set_config.digitalCompressionGaindB = 9;
set_config.limiterEnable = true;
EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
- EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
+ EXPECT_TRUE(SetupEngine());
webrtc::AgcConfig config = {0};
EXPECT_EQ(0, voe_.GetAgcConfig(config));
@@ -2945,7 +2931,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
}
TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::WebRtcVoiceMediaChannel* media_channel =
static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
@@ -2961,7 +2947,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
}
TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
cricket::WebRtcVoiceMediaChannel* media_channel =
static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
@@ -2977,7 +2963,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
}
TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
cricket::StreamParams stream;
stream.ssrcs.push_back(kSsrc2);
@@ -2990,7 +2976,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
}
TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
int channel_id = voe_.GetLastChannel();
@@ -3148,7 +3134,7 @@ TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
}
TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
@@ -3168,7 +3154,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
}
TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
std::unique_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
std::unique_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
@@ -3196,7 +3182,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
// Test that, just like the video channel, the voice channel communicates the
// network state to the call.
TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
- EXPECT_TRUE(SetupEngine());
+ EXPECT_TRUE(SetupEngineWithChannel());
EXPECT_EQ(webrtc::kNetworkUp,
call_.GetNetworkState(webrtc::MediaType::AUDIO));
@@ -3218,8 +3204,8 @@ TEST_F(WebRtcVoiceEngineTestFake, OnReadyToSendSignalsNetworkState) {
// Tests that the library initializes and shuts down properly.
TEST(WebRtcVoiceEngineTest, StartupShutdown) {
- cricket::WebRtcVoiceEngine engine;
- EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
+ cricket::WebRtcVoiceEngine engine(nullptr);
+ EXPECT_TRUE(engine.Init());
std::unique_ptr<webrtc::Call> call(
webrtc::Call::Create(webrtc::Call::Config()));
cricket::VoiceMediaChannel* channel = engine.CreateChannel(
@@ -3229,7 +3215,7 @@ TEST(WebRtcVoiceEngineTest, StartupShutdown) {
engine.Terminate();
// Reinit to catch regression where VoiceEngineObserver reference is lost
- EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
+ EXPECT_TRUE(engine.Init());
engine.Terminate();
}
@@ -3288,7 +3274,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
cricket::AudioCodec(0, "", 0, 5000, 1, 0), nullptr));
// Verify the payload id of common audio codecs, including CN, ISAC, and G722.
- cricket::WebRtcVoiceEngine engine;
+ cricket::WebRtcVoiceEngine engine(nullptr);
for (std::vector<cricket::AudioCodec>::const_iterator it =
engine.codecs().begin(); it != engine.codecs().end(); ++it) {
if (it->name == "CN" && it->clockrate == 16000) {
@@ -3320,8 +3306,8 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
// Tests that VoE supports at least 32 channels
TEST(WebRtcVoiceEngineTest, Has32Channels) {
- cricket::WebRtcVoiceEngine engine;
- EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
+ cricket::WebRtcVoiceEngine engine(nullptr);
+ EXPECT_TRUE(engine.Init());
std::unique_ptr<webrtc::Call> call(
webrtc::Call::Create(webrtc::Call::Config()));
@@ -3346,8 +3332,8 @@ TEST(WebRtcVoiceEngineTest, Has32Channels) {
// Test that we set our preferred codecs properly.
TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
- cricket::WebRtcVoiceEngine engine;
- EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
+ cricket::WebRtcVoiceEngine engine(nullptr);
+ EXPECT_TRUE(engine.Init());
std::unique_ptr<webrtc::Call> call(
webrtc::Call::Create(webrtc::Call::Config()));
cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),

Powered by Google App Engine
This is Rietveld 408576698