Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/net/pref_proxy_config_tracker_impl.h" | 5 #include "components/proxy_config/pref_proxy_config_tracker_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/prefs/pref_registry_simple.h" | 12 #include "base/prefs/pref_registry_simple.h" |
| 13 #include "base/prefs/testing_pref_service.h" | 13 #include "base/prefs/testing_pref_service.h" |
| 14 #include "base/test/histogram_tester.h" | 14 #include "base/test/histogram_tester.h" |
| 15 #include "chrome/browser/prefs/pref_service_mock_factory.h" | 15 #include "chrome/browser/prefs/pref_service_mock_factory.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 : ui_thread_(BrowserThread::UI, &loop_), | 82 : ui_thread_(BrowserThread::UI, &loop_), |
| 83 io_thread_(BrowserThread::IO, &loop_) {} | 83 io_thread_(BrowserThread::IO, &loop_) {} |
| 84 | 84 |
| 85 virtual void Init(PrefService* pref_service, PrefRegistrySimple* registry) { | 85 virtual void Init(PrefService* pref_service, PrefRegistrySimple* registry) { |
| 86 ASSERT_TRUE(pref_service); | 86 ASSERT_TRUE(pref_service); |
| 87 PrefProxyConfigTrackerImpl::RegisterPrefs(registry); | 87 PrefProxyConfigTrackerImpl::RegisterPrefs(registry); |
| 88 fixed_config_.set_pac_url(GURL(kFixedPacUrl)); | 88 fixed_config_.set_pac_url(GURL(kFixedPacUrl)); |
| 89 delegate_service_ = | 89 delegate_service_ = |
| 90 new TestProxyConfigService(fixed_config_, | 90 new TestProxyConfigService(fixed_config_, |
| 91 net::ProxyConfigService::CONFIG_VALID); | 91 net::ProxyConfigService::CONFIG_VALID); |
| 92 proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl(pref_service)); | 92 proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl( |
| 93 pref_service, | |
| 94 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))); | |
| 93 proxy_config_service_ = | 95 proxy_config_service_ = |
| 94 proxy_config_tracker_->CreateTrackingProxyConfigService( | 96 proxy_config_tracker_->CreateTrackingProxyConfigService( |
| 95 scoped_ptr<net::ProxyConfigService>(delegate_service_)); | 97 scoped_ptr<net::ProxyConfigService>(delegate_service_)); |
| 96 // SetChromeProxyConfigService triggers update of initial prefs proxy | 98 // SetChromeProxyConfigService triggers update of initial prefs proxy |
| 97 // config by tracker to chrome proxy config service, so flush all pending | 99 // config by tracker to chrome proxy config service, so flush all pending |
| 98 // tasks so that tests start fresh. | 100 // tasks so that tests start fresh. |
| 99 loop_.RunUntilIdle(); | 101 loop_.RunUntilIdle(); |
| 100 } | 102 } |
| 101 | 103 |
| 102 virtual void TearDown() { | 104 virtual void TearDown() { |
| 103 proxy_config_tracker_->DetachFromPrefService(); | 105 proxy_config_tracker_->DetachFromPrefService(); |
| 104 loop_.RunUntilIdle(); | 106 loop_.RunUntilIdle(); |
| 105 proxy_config_tracker_.reset(); | 107 proxy_config_tracker_.reset(); |
| 106 proxy_config_service_.reset(); | 108 proxy_config_service_.reset(); |
| 107 } | 109 } |
| 108 | 110 |
| 109 base::MessageLoop loop_; | 111 base::MessageLoop loop_; |
| 110 TestProxyConfigService* delegate_service_; // weak | 112 TestProxyConfigService* delegate_service_; // weak |
| 111 scoped_ptr<net::ProxyConfigService> proxy_config_service_; | 113 scoped_ptr<net::ProxyConfigService> proxy_config_service_; |
| 112 net::ProxyConfig fixed_config_; | 114 net::ProxyConfig fixed_config_; |
| 113 | 115 |
| 114 private: | 116 private: |
| 115 scoped_ptr<PrefProxyConfigTrackerImpl> proxy_config_tracker_; | 117 scoped_ptr<PrefProxyConfigTrackerImpl> proxy_config_tracker_; |
| 116 content::TestBrowserThread ui_thread_; | 118 content::TestBrowserThread ui_thread_; |
| 117 content::TestBrowserThread io_thread_; | 119 content::TestBrowserThread io_thread_; |
|
droger
2015/08/17 13:51:35
Can we remove these two threads and use ThreadTask
Abhishek
2015/08/19 08:30:49
Done.
| |
| 118 }; | 120 }; |
| 119 | 121 |
| 120 class PrefProxyConfigTrackerImplTest | 122 class PrefProxyConfigTrackerImplTest |
| 121 : public PrefProxyConfigTrackerImplTestBase<testing::Test> { | 123 : public PrefProxyConfigTrackerImplTestBase<testing::Test> { |
| 122 protected: | 124 protected: |
| 123 void SetUp() override { | 125 void SetUp() override { |
| 124 pref_service_.reset(new TestingPrefServiceSimple()); | 126 pref_service_.reset(new TestingPrefServiceSimple()); |
| 125 Init(pref_service_.get(), pref_service_->registry()); | 127 Init(pref_service_.get(), pref_service_->registry()); |
| 126 } | 128 } |
| 127 | 129 |
| 128 scoped_ptr<TestingPrefServiceSimple> pref_service_; | 130 scoped_ptr<TestingPrefServiceSimple> pref_service_; |
| 129 }; | 131 }; |
| 130 | 132 |
| 131 TEST_F(PrefProxyConfigTrackerImplTest, BaseConfiguration) { | 133 TEST_F(PrefProxyConfigTrackerImplTest, BaseConfiguration) { |
| 132 net::ProxyConfig actual_config; | 134 net::ProxyConfig actual_config; |
| 133 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, | 135 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, |
| 134 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 136 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 135 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url()); | 137 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url()); |
| 136 } | 138 } |
| 137 | 139 |
| 138 TEST_F(PrefProxyConfigTrackerImplTest, DynamicPrefOverrides) { | 140 TEST_F(PrefProxyConfigTrackerImplTest, DynamicPrefOverrides) { |
| 139 pref_service_->SetManagedPref(prefs::kProxy, | 141 pref_service_->SetManagedPref(ProxyPrefs::kProxy, |
| 140 ProxyConfigDictionary::CreateFixedServers( | 142 ProxyConfigDictionary::CreateFixedServers( |
| 141 "http://example.com:3128", std::string())); | 143 "http://example.com:3128", std::string())); |
| 142 loop_.RunUntilIdle(); | 144 loop_.RunUntilIdle(); |
| 143 | 145 |
| 144 net::ProxyConfig actual_config; | 146 net::ProxyConfig actual_config; |
| 145 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, | 147 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, |
| 146 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 148 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 147 EXPECT_FALSE(actual_config.auto_detect()); | 149 EXPECT_FALSE(actual_config.auto_detect()); |
| 148 EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY, | 150 EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY, |
| 149 actual_config.proxy_rules().type); | 151 actual_config.proxy_rules().type); |
| 150 EXPECT_EQ(actual_config.proxy_rules().single_proxies.Get(), | 152 EXPECT_EQ(actual_config.proxy_rules().single_proxies.Get(), |
| 151 net::ProxyServer::FromURI("http://example.com:3128", | 153 net::ProxyServer::FromURI("http://example.com:3128", |
| 152 net::ProxyServer::SCHEME_HTTP)); | 154 net::ProxyServer::SCHEME_HTTP)); |
| 153 | 155 |
| 154 pref_service_->SetManagedPref(prefs::kProxy, | 156 pref_service_->SetManagedPref(ProxyPrefs::kProxy, |
| 155 ProxyConfigDictionary::CreateAutoDetect()); | 157 ProxyConfigDictionary::CreateAutoDetect()); |
| 156 loop_.RunUntilIdle(); | 158 loop_.RunUntilIdle(); |
| 157 | 159 |
| 158 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, | 160 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, |
| 159 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 161 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 160 EXPECT_TRUE(actual_config.auto_detect()); | 162 EXPECT_TRUE(actual_config.auto_detect()); |
| 161 } | 163 } |
| 162 | 164 |
| 163 // Compares proxy configurations, but allows different identifiers. | 165 // Compares proxy configurations, but allows different identifiers. |
| 164 MATCHER_P(ProxyConfigMatches, config, "") { | 166 MATCHER_P(ProxyConfigMatches, config, "") { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 182 loop_.RunUntilIdle(); | 184 loop_.RunUntilIdle(); |
| 183 Mock::VerifyAndClearExpectations(&observer); | 185 Mock::VerifyAndClearExpectations(&observer); |
| 184 | 186 |
| 185 // Override configuration, this should trigger a notification. | 187 // Override configuration, this should trigger a notification. |
| 186 net::ProxyConfig pref_config; | 188 net::ProxyConfig pref_config; |
| 187 pref_config.set_pac_url(GURL(kFixedPacUrl)); | 189 pref_config.set_pac_url(GURL(kFixedPacUrl)); |
| 188 | 190 |
| 189 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config), | 191 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config), |
| 190 CONFIG_VALID)).Times(1); | 192 CONFIG_VALID)).Times(1); |
| 191 pref_service_->SetManagedPref( | 193 pref_service_->SetManagedPref( |
| 192 prefs::kProxy, | 194 ProxyPrefs::kProxy, |
| 193 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)); | 195 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)); |
| 194 loop_.RunUntilIdle(); | 196 loop_.RunUntilIdle(); |
| 195 Mock::VerifyAndClearExpectations(&observer); | 197 Mock::VerifyAndClearExpectations(&observer); |
| 196 | 198 |
| 197 // Since there are pref overrides, delegate changes should be ignored. | 199 // Since there are pref overrides, delegate changes should be ignored. |
| 198 net::ProxyConfig config3; | 200 net::ProxyConfig config3; |
| 199 config3.proxy_rules().ParseFromString("http=config3:80"); | 201 config3.proxy_rules().ParseFromString("http=config3:80"); |
| 200 EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0); | 202 EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0); |
| 201 fixed_config_.set_auto_detect(true); | 203 fixed_config_.set_auto_detect(true); |
| 202 delegate_service_->SetProxyConfig(config3, CONFIG_VALID); | 204 delegate_service_->SetProxyConfig(config3, CONFIG_VALID); |
| 203 loop_.RunUntilIdle(); | 205 loop_.RunUntilIdle(); |
| 204 Mock::VerifyAndClearExpectations(&observer); | 206 Mock::VerifyAndClearExpectations(&observer); |
| 205 | 207 |
| 206 // Clear the override should switch back to the fixed configuration. | 208 // Clear the override should switch back to the fixed configuration. |
| 207 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3), | 209 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3), |
| 208 CONFIG_VALID)).Times(1); | 210 CONFIG_VALID)).Times(1); |
| 209 pref_service_->RemoveManagedPref(prefs::kProxy); | 211 pref_service_->RemoveManagedPref(ProxyPrefs::kProxy); |
| 210 loop_.RunUntilIdle(); | 212 loop_.RunUntilIdle(); |
| 211 Mock::VerifyAndClearExpectations(&observer); | 213 Mock::VerifyAndClearExpectations(&observer); |
| 212 | 214 |
| 213 // Delegate service notifications should show up again. | 215 // Delegate service notifications should show up again. |
| 214 net::ProxyConfig config4; | 216 net::ProxyConfig config4; |
| 215 config4.proxy_rules().ParseFromString("socks:config4"); | 217 config4.proxy_rules().ParseFromString("socks:config4"); |
| 216 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4), | 218 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4), |
| 217 CONFIG_VALID)).Times(1); | 219 CONFIG_VALID)).Times(1); |
| 218 delegate_service_->SetProxyConfig(config4, CONFIG_VALID); | 220 delegate_service_->SetProxyConfig(config4, CONFIG_VALID); |
| 219 loop_.RunUntilIdle(); | 221 loop_.RunUntilIdle(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 233 | 235 |
| 234 // Prepare test data. | 236 // Prepare test data. |
| 235 net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect(); | 237 net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect(); |
| 236 net::ProxyConfig user_config = | 238 net::ProxyConfig user_config = |
| 237 net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl)); | 239 net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl)); |
| 238 | 240 |
| 239 // Set a recommended pref. | 241 // Set a recommended pref. |
| 240 EXPECT_CALL(observer, | 242 EXPECT_CALL(observer, |
| 241 OnProxyConfigChanged(ProxyConfigMatches(recommended_config), | 243 OnProxyConfigChanged(ProxyConfigMatches(recommended_config), |
| 242 CONFIG_VALID)).Times(1); | 244 CONFIG_VALID)).Times(1); |
| 243 pref_service_->SetRecommendedPref( | 245 pref_service_->SetRecommendedPref(ProxyPrefs::kProxy, |
| 244 prefs::kProxy, | 246 ProxyConfigDictionary::CreateAutoDetect()); |
| 245 ProxyConfigDictionary::CreateAutoDetect()); | |
| 246 loop_.RunUntilIdle(); | 247 loop_.RunUntilIdle(); |
| 247 Mock::VerifyAndClearExpectations(&observer); | 248 Mock::VerifyAndClearExpectations(&observer); |
| 248 EXPECT_EQ(CONFIG_VALID, | 249 EXPECT_EQ(CONFIG_VALID, |
| 249 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 250 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 250 EXPECT_TRUE(actual_config.Equals(recommended_config)); | 251 EXPECT_TRUE(actual_config.Equals(recommended_config)); |
| 251 | 252 |
| 252 // Override in user prefs. | 253 // Override in user prefs. |
| 253 EXPECT_CALL(observer, | 254 EXPECT_CALL(observer, |
| 254 OnProxyConfigChanged(ProxyConfigMatches(user_config), | 255 OnProxyConfigChanged(ProxyConfigMatches(user_config), |
| 255 CONFIG_VALID)).Times(1); | 256 CONFIG_VALID)).Times(1); |
| 256 pref_service_->SetManagedPref( | 257 pref_service_->SetManagedPref( |
| 257 prefs::kProxy, | 258 ProxyPrefs::kProxy, |
| 258 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)); | 259 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)); |
| 259 loop_.RunUntilIdle(); | 260 loop_.RunUntilIdle(); |
| 260 Mock::VerifyAndClearExpectations(&observer); | 261 Mock::VerifyAndClearExpectations(&observer); |
| 261 EXPECT_EQ(CONFIG_VALID, | 262 EXPECT_EQ(CONFIG_VALID, |
| 262 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 263 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 263 EXPECT_TRUE(actual_config.Equals(user_config)); | 264 EXPECT_TRUE(actual_config.Equals(user_config)); |
| 264 | 265 |
| 265 // Go back to recommended pref. | 266 // Go back to recommended pref. |
| 266 EXPECT_CALL(observer, | 267 EXPECT_CALL(observer, |
| 267 OnProxyConfigChanged(ProxyConfigMatches(recommended_config), | 268 OnProxyConfigChanged(ProxyConfigMatches(recommended_config), |
| 268 CONFIG_VALID)).Times(1); | 269 CONFIG_VALID)).Times(1); |
| 269 pref_service_->RemoveManagedPref(prefs::kProxy); | 270 pref_service_->RemoveManagedPref(ProxyPrefs::kProxy); |
| 270 loop_.RunUntilIdle(); | 271 loop_.RunUntilIdle(); |
| 271 Mock::VerifyAndClearExpectations(&observer); | 272 Mock::VerifyAndClearExpectations(&observer); |
| 272 EXPECT_EQ(CONFIG_VALID, | 273 EXPECT_EQ(CONFIG_VALID, |
| 273 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 274 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 274 EXPECT_TRUE(actual_config.Equals(recommended_config)); | 275 EXPECT_TRUE(actual_config.Equals(recommended_config)); |
| 275 | 276 |
| 276 proxy_config_service_->RemoveObserver(&observer); | 277 proxy_config_service_->RemoveObserver(&observer); |
| 277 } | 278 } |
| 278 | 279 |
| 279 TEST_F(PrefProxyConfigTrackerImplTest, ExplicitSystemSettings) { | 280 TEST_F(PrefProxyConfigTrackerImplTest, ExplicitSystemSettings) { |
| 280 pref_service_->SetRecommendedPref( | 281 pref_service_->SetRecommendedPref(ProxyPrefs::kProxy, |
| 281 prefs::kProxy, | 282 ProxyConfigDictionary::CreateAutoDetect()); |
| 282 ProxyConfigDictionary::CreateAutoDetect()); | 283 pref_service_->SetUserPref(ProxyPrefs::kProxy, |
| 283 pref_service_->SetUserPref( | 284 ProxyConfigDictionary::CreateSystem()); |
| 284 prefs::kProxy, | |
| 285 ProxyConfigDictionary::CreateSystem()); | |
| 286 loop_.RunUntilIdle(); | 285 loop_.RunUntilIdle(); |
| 287 | 286 |
| 288 // Test if we actually use the system setting, which is |kFixedPacUrl|. | 287 // Test if we actually use the system setting, which is |kFixedPacUrl|. |
| 289 net::ProxyConfig actual_config; | 288 net::ProxyConfig actual_config; |
| 290 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, | 289 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, |
| 291 proxy_config_service_->GetLatestProxyConfig(&actual_config)); | 290 proxy_config_service_->GetLatestProxyConfig(&actual_config)); |
| 292 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url()); | 291 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url()); |
| 293 } | 292 } |
| 294 | 293 |
| 295 void CheckResolvedProxyMatches(net::ProxyConfig* config, | 294 void CheckResolvedProxyMatches(net::ProxyConfig* config, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 {"direct://", | 355 {"direct://", |
| 357 "direct://", | 356 "direct://", |
| 358 "direct://", | 357 "direct://", |
| 359 "direct://", | 358 "direct://", |
| 360 0}, | 359 0}, |
| 361 }; | 360 }; |
| 362 | 361 |
| 363 // Test setting the proxy from a user pref. | 362 // Test setting the proxy from a user pref. |
| 364 for (const auto& test : test_cases) { | 363 for (const auto& test : test_cases) { |
| 365 base::HistogramTester histogram_tester; | 364 base::HistogramTester histogram_tester; |
| 366 pref_service_->SetUserPref(prefs::kProxy, | 365 pref_service_->SetUserPref(ProxyPrefs::kProxy, |
| 367 ProxyConfigDictionary::CreateFixedServers( | 366 ProxyConfigDictionary::CreateFixedServers( |
| 368 test.initial_proxy_rules, std::string())); | 367 test.initial_proxy_rules, std::string())); |
| 369 loop_.RunUntilIdle(); | 368 loop_.RunUntilIdle(); |
| 370 | 369 |
| 371 net::ProxyConfig config; | 370 net::ProxyConfig config; |
| 372 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, | 371 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, |
| 373 proxy_config_service_->GetLatestProxyConfig(&config)); | 372 proxy_config_service_->GetLatestProxyConfig(&config)); |
| 374 histogram_tester.ExpectUniqueSample( | 373 histogram_tester.ExpectUniqueSample( |
| 375 "Net.PrefProxyConfig.GooglezipProxyRemovalCount", | 374 "Net.PrefProxyConfig.GooglezipProxyRemovalCount", |
| 376 test.expected_num_removed_proxies, 1); | 375 test.expected_num_removed_proxies, 1); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 net::ProxyRulesExpectation::Empty(), | 569 net::ProxyRulesExpectation::Empty(), |
| 571 }, | 570 }, |
| 572 }; | 571 }; |
| 573 | 572 |
| 574 INSTANTIATE_TEST_CASE_P( | 573 INSTANTIATE_TEST_CASE_P( |
| 575 PrefProxyConfigTrackerImplCommandLineTestInstance, | 574 PrefProxyConfigTrackerImplCommandLineTestInstance, |
| 576 PrefProxyConfigTrackerImplCommandLineTest, | 575 PrefProxyConfigTrackerImplCommandLineTest, |
| 577 testing::ValuesIn(kCommandLineTestParams)); | 576 testing::ValuesIn(kCommandLineTestParams)); |
| 578 | 577 |
| 579 } // namespace | 578 } // namespace |
| OLD | NEW |