diff --git a/talk/app/webrtc/peerconnectionfactory_unittest.cc b/talk/app/webrtc/peerconnectionfactory_unittest.cc
new file mode 100644
index 0000000..6d54204
--- /dev/null
+++ b/talk/app/webrtc/peerconnectionfactory_unittest.cc
@@ -0,0 +1,270 @@
+/*
+ * libjingle
+ * Copyright 2012, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "talk/app/webrtc/fakeportallocatorfactory.h"
+#include "talk/app/webrtc/mediastreaminterface.h"
+#include "talk/app/webrtc/peerconnectionfactory.h"
+#include "talk/app/webrtc/videosourceinterface.h"
+#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
+#include "talk/base/gunit.h"
+#include "talk/base/scoped_ptr.h"
+#include "talk/base/thread.h"
+#include "talk/media/base/fakevideocapturer.h"
+#include "talk/media/webrtc/webrtccommon.h"
+#include "talk/media/webrtc/webrtcvoe.h"
+
+using webrtc::FakeVideoTrackRenderer;
+using webrtc::MediaStreamInterface;
+using webrtc::PeerConnectionFactoryInterface;
+using webrtc::PeerConnectionInterface;
+using webrtc::PeerConnectionObserver;
+using webrtc::PortAllocatorFactoryInterface;
+using webrtc::VideoSourceInterface;
+using webrtc::VideoTrackInterface;
+
+namespace {
+
+typedef std::vector<PortAllocatorFactoryInterface::StunConfiguration>
+    StunConfigurations;
+typedef std::vector<PortAllocatorFactoryInterface::TurnConfiguration>
+    TurnConfigurations;
+
+static const char kStunIceServer[] = "stun:stun.l.google.com:19302";
+static const char kTurnIceServer[] = "turn:test%40hello.com@test.com:1234";
+static const char kTurnIceServerWithTransport[] =
+    "turn:test@hello.com?transport=tcp";
+static const char kSecureTurnIceServer[] =
+    "turns:test@hello.com?transport=tcp";
+static const char kTurnIceServerWithNoUsernameInUri[] =
+    "turn:test.com:1234";
+static const char kTurnPassword[] = "turnpassword";
+static const int kDefaultPort = 3478;
+static const char kTurnUsername[] = "test";
+
+class NullPeerConnectionObserver : public PeerConnectionObserver {
+ public:
+  virtual void OnError() {}
+  virtual void OnMessage(const std::string& msg) {}
+  virtual void OnSignalingMessage(const std::string& msg) {}
+  virtual void OnSignalingChange(
+      PeerConnectionInterface::SignalingState new_state) {}
+  virtual void OnAddStream(MediaStreamInterface* stream) {}
+  virtual void OnRemoveStream(MediaStreamInterface* stream) {}
+  virtual void OnRenegotiationNeeded() {}
+  virtual void OnIceConnectionChange(
+      PeerConnectionInterface::IceConnectionState new_state) {}
+  virtual void OnIceGatheringChange(
+      PeerConnectionInterface::IceGatheringState new_state) {}
+  virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {}
+};
+
+}  // namespace
+
+class PeerConnectionFactoryTest : public testing::Test {
+  void SetUp() {
+    factory_ = webrtc::CreatePeerConnectionFactory(talk_base::Thread::Current(),
+                                                   talk_base::Thread::Current(),
+                                                   NULL,
+                                                   NULL,
+                                                   NULL);
+
+    ASSERT_TRUE(factory_.get() != NULL);
+    allocator_factory_ =  webrtc::FakePortAllocatorFactory::Create();
+  }
+
+ protected:
+  void VerifyStunConfigurations(StunConfigurations stun_config) {
+    webrtc::FakePortAllocatorFactory* allocator =
+        static_cast<webrtc::FakePortAllocatorFactory*>(
+            allocator_factory_.get());
+    ASSERT_TRUE(allocator != NULL);
+    EXPECT_EQ(stun_config.size(), allocator->stun_configs().size());
+    for (size_t i = 0; i < stun_config.size(); ++i) {
+      EXPECT_EQ(stun_config[i].server.ToString(),
+                allocator->stun_configs()[i].server.ToString());
+    }
+  }
+
+  void VerifyTurnConfigurations(TurnConfigurations turn_config) {
+    webrtc::FakePortAllocatorFactory* allocator =
+        static_cast<webrtc::FakePortAllocatorFactory*>(
+            allocator_factory_.get());
+    ASSERT_TRUE(allocator != NULL);
+    EXPECT_EQ(turn_config.size(), allocator->turn_configs().size());
+    for (size_t i = 0; i < turn_config.size(); ++i) {
+      EXPECT_EQ(turn_config[i].server.ToString(),
+                allocator->turn_configs()[i].server.ToString());
+      EXPECT_EQ(turn_config[i].username, allocator->turn_configs()[i].username);
+      EXPECT_EQ(turn_config[i].password, allocator->turn_configs()[i].password);
+      EXPECT_EQ(turn_config[i].transport_type,
+                allocator->turn_configs()[i].transport_type);
+    }
+  }
+
+  talk_base::scoped_refptr<PeerConnectionFactoryInterface> factory_;
+  NullPeerConnectionObserver observer_;
+  talk_base::scoped_refptr<PortAllocatorFactoryInterface> allocator_factory_;
+};
+
+// Verify creation of PeerConnection using internal ADM, video factory and
+// internal libjingle threads.
+TEST(PeerConnectionFactoryTestInternal, CreatePCUsingInternalModules) {
+  talk_base::scoped_refptr<PeerConnectionFactoryInterface> factory(
+      webrtc::CreatePeerConnectionFactory());
+
+  NullPeerConnectionObserver observer;
+  webrtc::PeerConnectionInterface::IceServers servers;
+
+  talk_base::scoped_refptr<PeerConnectionInterface> pc(
+      factory->CreatePeerConnection(servers, NULL, NULL, &observer));
+
+  EXPECT_TRUE(pc.get() != NULL);
+}
+
+// This test verifies creation of PeerConnection with valid STUN and TURN
+// configuration. Also verifies the URL's parsed correctly as expected.
+TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) {
+  webrtc::PeerConnectionInterface::IceServers ice_servers;
+  webrtc::PeerConnectionInterface::IceServer ice_server;
+  ice_server.uri = kStunIceServer;
+  ice_servers.push_back(ice_server);
+  ice_server.uri = kTurnIceServer;
+  ice_server.password = kTurnPassword;
+  ice_servers.push_back(ice_server);
+  talk_base::scoped_refptr<PeerConnectionInterface> pc(
+      factory_->CreatePeerConnection(ice_servers, NULL,
+                                     allocator_factory_.get(),
+                                     NULL,
+                                     &observer_));
+  EXPECT_TRUE(pc.get() != NULL);
+  StunConfigurations stun_configs;
+  webrtc::PortAllocatorFactoryInterface::StunConfiguration stun(
+      "stun.l.google.com", 19302);
+  stun_configs.push_back(stun);
+  webrtc::PortAllocatorFactoryInterface::StunConfiguration stun1(
+        "test.com", 1234);
+  stun_configs.push_back(stun1);
+  VerifyStunConfigurations(stun_configs);
+  TurnConfigurations turn_configs;
+  webrtc::PortAllocatorFactoryInterface::TurnConfiguration turn(
+      "test.com", 1234, "test@hello.com", kTurnPassword, "udp");
+  turn_configs.push_back(turn);
+  VerifyTurnConfigurations(turn_configs);
+}
+
+TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) {
+  webrtc::PeerConnectionInterface::IceServers ice_servers;
+  webrtc::PeerConnectionInterface::IceServer ice_server;
+  ice_server.uri = kStunIceServer;
+  ice_servers.push_back(ice_server);
+  ice_server.uri = kTurnIceServerWithNoUsernameInUri;
+  ice_server.username = kTurnUsername;
+  ice_server.password = kTurnPassword;
+  ice_servers.push_back(ice_server);
+  talk_base::scoped_refptr<PeerConnectionInterface> pc(
+      factory_->CreatePeerConnection(ice_servers, NULL,
+                                     allocator_factory_.get(),
+                                     NULL,
+                                     &observer_));
+  EXPECT_TRUE(pc.get() != NULL);
+  TurnConfigurations turn_configs;
+  webrtc::PortAllocatorFactoryInterface::TurnConfiguration turn(
+      "test.com", 1234, kTurnUsername, kTurnPassword, "udp");
+  turn_configs.push_back(turn);
+  VerifyTurnConfigurations(turn_configs);
+}
+
+// This test verifies the PeerConnection created properly with TURN url which
+// has transport parameter in it.
+TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) {
+  webrtc::PeerConnectionInterface::IceServers ice_servers;
+  webrtc::PeerConnectionInterface::IceServer ice_server;
+  ice_server.uri = kTurnIceServerWithTransport;
+  ice_server.password = kTurnPassword;
+  ice_servers.push_back(ice_server);
+  talk_base::scoped_refptr<PeerConnectionInterface> pc(
+      factory_->CreatePeerConnection(ice_servers, NULL,
+                                     allocator_factory_.get(),
+                                     NULL,
+                                     &observer_));
+  EXPECT_TRUE(pc.get() != NULL);
+  TurnConfigurations turn_configs;
+  webrtc::PortAllocatorFactoryInterface::TurnConfiguration turn(
+      "hello.com", kDefaultPort, "test", kTurnPassword, "tcp");
+  turn_configs.push_back(turn);
+  VerifyTurnConfigurations(turn_configs);
+  StunConfigurations stun_configs;
+  webrtc::PortAllocatorFactoryInterface::StunConfiguration stun(
+        "hello.com", kDefaultPort);
+  stun_configs.push_back(stun);
+  VerifyStunConfigurations(stun_configs);
+}
+
+// This test verifies factory failed to create a peerconneciton object when
+// a valid secure TURN url passed. Connecting to a secure TURN server is not
+// supported currently.
+TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) {
+  webrtc::PeerConnectionInterface::IceServers ice_servers;
+  webrtc::PeerConnectionInterface::IceServer ice_server;
+  ice_server.uri = kSecureTurnIceServer;
+  ice_server.password = kTurnPassword;
+  ice_servers.push_back(ice_server);
+  talk_base::scoped_refptr<PeerConnectionInterface> pc(
+      factory_->CreatePeerConnection(ice_servers, NULL,
+                                     allocator_factory_.get(),
+                                     NULL,
+                                     &observer_));
+  EXPECT_TRUE(pc.get() == NULL);
+  TurnConfigurations turn_configs;
+  VerifyTurnConfigurations(turn_configs);
+}
+
+// This test verifies the captured stream is rendered locally using a
+// local video track.
+TEST_F(PeerConnectionFactoryTest, LocalRendering) {
+  cricket::FakeVideoCapturer* capturer = new cricket::FakeVideoCapturer();
+  // The source take ownership of |capturer|.
+  talk_base::scoped_refptr<VideoSourceInterface> source(
+      factory_->CreateVideoSource(capturer, NULL));
+  ASSERT_TRUE(source.get() != NULL);
+  talk_base::scoped_refptr<VideoTrackInterface> track(
+      factory_->CreateVideoTrack("testlabel", source));
+  ASSERT_TRUE(track.get() != NULL);
+  FakeVideoTrackRenderer local_renderer(track);
+
+  EXPECT_EQ(0, local_renderer.num_rendered_frames());
+  EXPECT_TRUE(capturer->CaptureFrame());
+  EXPECT_EQ(1, local_renderer.num_rendered_frames());
+
+  track->set_enabled(false);
+  EXPECT_TRUE(capturer->CaptureFrame());
+  EXPECT_EQ(1, local_renderer.num_rendered_frames());
+
+  track->set_enabled(true);
+  EXPECT_TRUE(capturer->CaptureFrame());
+  EXPECT_EQ(2, local_renderer.num_rendered_frames());
+}
