OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 package org.chromium.net; | 5 package org.chromium.net; |
6 | 6 |
7 import android.os.ConditionVariable; | 7 import android.os.ConditionVariable; |
8 import android.test.suitebuilder.annotation.SmallTest; | 8 import android.test.suitebuilder.annotation.SmallTest; |
9 import android.util.Pair; | |
10 | 9 |
11 import org.chromium.base.test.util.Feature; | 10 import org.chromium.base.test.util.Feature; |
12 import org.chromium.net.TestUrlRequestListener.FailureType; | 11 import org.chromium.net.TestUrlRequestListener.FailureType; |
13 import org.chromium.net.TestUrlRequestListener.ResponseStep; | 12 import org.chromium.net.TestUrlRequestListener.ResponseStep; |
14 import org.chromium.net.test.FailurePhase; | 13 import org.chromium.net.test.FailurePhase; |
15 | 14 |
16 import java.nio.ByteBuffer; | 15 import java.nio.ByteBuffer; |
17 import java.util.ArrayList; | 16 import java.util.ArrayList; |
18 import java.util.List; | 17 import java.util.List; |
19 import java.util.Map; | 18 import java.util.Map; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 // Create request. | 53 // Create request. |
55 UrlRequest.Builder builder = new UrlRequest.Builder( | 54 UrlRequest.Builder builder = new UrlRequest.Builder( |
56 url, listener, listener.getExecutor(), mActivity.mCronetEngine); | 55 url, listener, listener.getExecutor(), mActivity.mCronetEngine); |
57 UrlRequest urlRequest = builder.build(); | 56 UrlRequest urlRequest = builder.build(); |
58 urlRequest.start(); | 57 urlRequest.start(); |
59 listener.blockForDone(); | 58 listener.blockForDone(); |
60 assertTrue(urlRequest.isDone()); | 59 assertTrue(urlRequest.isDone()); |
61 return listener; | 60 return listener; |
62 } | 61 } |
63 | 62 |
64 private void checkResponseInfo(ResponseInfo responseInfo, | 63 private void checkResponseInfo(UrlResponseInfo responseInfo, String expected Url, |
65 String expectedUrl, int expectedHttpStatusCode, | 64 int expectedHttpStatusCode, String expectedHttpStatusText) { |
66 String expectedHttpStatusText) { | |
67 assertEquals(expectedUrl, responseInfo.getUrl()); | 65 assertEquals(expectedUrl, responseInfo.getUrl()); |
68 assertEquals(expectedUrl, responseInfo.getUrlChain()[ | 66 assertEquals( |
69 responseInfo.getUrlChain().length - 1]); | 67 expectedUrl, responseInfo.getUrlChain().get(responseInfo.getUrlC hain().size() - 1)); |
70 assertEquals(expectedHttpStatusCode, responseInfo.getHttpStatusCode()); | 68 assertEquals(expectedHttpStatusCode, responseInfo.getHttpStatusCode()); |
71 assertEquals(expectedHttpStatusText, responseInfo.getHttpStatusText()); | 69 assertEquals(expectedHttpStatusText, responseInfo.getHttpStatusText()); |
72 assertFalse(responseInfo.wasCached()); | 70 assertFalse(responseInfo.wasCached()); |
71 assertTrue(responseInfo.toString().length() > 0); | |
xunjieli
2015/10/05 20:39:02
Instead of doing this, maybe add a check for testS
mef
2015/10/05 22:09:19
Done.
| |
73 } | 72 } |
74 | 73 |
75 private void checkResponseInfoHeader(ResponseInfo responseInfo, | 74 private void checkResponseInfoHeader( |
76 String headerName, String headerValue) { | 75 UrlResponseInfo responseInfo, String headerName, String headerValue) { |
77 Map<String, List<String>> responseHeaders = | 76 Map<String, List<String>> responseHeaders = |
78 responseInfo.getAllHeaders(); | 77 responseInfo.getAllHeaders(); |
79 List<String> header = responseHeaders.get(headerName); | 78 List<String> header = responseHeaders.get(headerName); |
80 assertNotNull(header); | 79 assertNotNull(header); |
81 assertTrue(header.contains(headerValue)); | 80 assertTrue(header.contains(headerValue)); |
82 } | 81 } |
83 | 82 |
84 @SmallTest | 83 @SmallTest |
85 @Feature({"Cronet"}) | 84 @Feature({"Cronet"}) |
86 public void testBuilderChecks() throws Exception { | 85 public void testBuilderChecks() throws Exception { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 public void testSimpleGet() throws Exception { | 121 public void testSimpleGet() throws Exception { |
123 TestUrlRequestListener listener = startAndWaitForComplete( | 122 TestUrlRequestListener listener = startAndWaitForComplete( |
124 NativeTestServer.getEchoMethodURL()); | 123 NativeTestServer.getEchoMethodURL()); |
125 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); | 124 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); |
126 // Default method is 'GET'. | 125 // Default method is 'GET'. |
127 assertEquals("GET", listener.mResponseAsString); | 126 assertEquals("GET", listener.mResponseAsString); |
128 assertEquals(0, listener.mRedirectCount); | 127 assertEquals(0, listener.mRedirectCount); |
129 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); | 128 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); |
130 checkResponseInfo(listener.mResponseInfo, | 129 checkResponseInfo(listener.mResponseInfo, |
131 NativeTestServer.getEchoMethodURL(), 200, "OK"); | 130 NativeTestServer.getEchoMethodURL(), 200, "OK"); |
132 checkResponseInfo(listener.mExtendedResponseInfo.getResponseInfo(), | |
133 NativeTestServer.getEchoMethodURL(), 200, "OK"); | |
134 } | 131 } |
135 | 132 |
136 /** | 133 /** |
137 * Tests a redirect by running it step-by-step. Also tests that delaying a | 134 * Tests a redirect by running it step-by-step. Also tests that delaying a |
138 * request works as expected. To make sure there are no unexpected pending | 135 * request works as expected. To make sure there are no unexpected pending |
139 * messages, does a GET between UrlRequestListener callbacks. | 136 * messages, does a GET between UrlRequestListener callbacks. |
140 */ | 137 */ |
141 @SmallTest | 138 @SmallTest |
142 @Feature({"Cronet"}) | 139 @Feature({"Cronet"}) |
143 public void testRedirectAsync() throws Exception { | 140 public void testRedirectAsync() throws Exception { |
144 // Start the request and wait to see the redirect. | 141 // Start the request and wait to see the redirect. |
145 TestUrlRequestListener listener = new TestUrlRequestListener(); | 142 TestUrlRequestListener listener = new TestUrlRequestListener(); |
146 listener.setAutoAdvance(false); | 143 listener.setAutoAdvance(false); |
147 UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.get RedirectURL(), | 144 UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.get RedirectURL(), |
148 listener, listener.getExecutor(), mActivity.mCronetEngine); | 145 listener, listener.getExecutor(), mActivity.mCronetEngine); |
149 UrlRequest urlRequest = builder.build(); | 146 UrlRequest urlRequest = builder.build(); |
150 urlRequest.start(); | 147 urlRequest.start(); |
151 listener.waitForNextStep(); | 148 listener.waitForNextStep(); |
152 | 149 |
153 // Check the redirect. | 150 // Check the redirect. |
154 assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, listener.mResponseStep); | 151 assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, listener.mResponseStep); |
155 assertEquals(1, listener.mRedirectResponseInfoList.size()); | 152 assertEquals(1, listener.mRedirectResponseInfoList.size()); |
156 checkResponseInfo(listener.mRedirectResponseInfoList.get(0), | 153 checkResponseInfo(listener.mRedirectResponseInfoList.get(0), |
157 NativeTestServer.getRedirectURL(), 302, "Found"); | 154 NativeTestServer.getRedirectURL(), 302, "Found"); |
158 assertEquals(1, | 155 assertEquals(1, listener.mRedirectResponseInfoList.get(0).getUrlChain(). size()); |
159 listener.mRedirectResponseInfoList.get(0).getUrlChain().length); | |
160 assertEquals(NativeTestServer.getSuccessURL(), listener.mRedirectUrlList .get(0)); | 156 assertEquals(NativeTestServer.getSuccessURL(), listener.mRedirectUrlList .get(0)); |
161 checkResponseInfoHeader(listener.mRedirectResponseInfoList.get(0), | 157 checkResponseInfoHeader(listener.mRedirectResponseInfoList.get(0), |
162 "redirect-header", "header-value"); | 158 "redirect-header", "header-value"); |
163 | 159 |
164 // Wait for an unrelated request to finish. The request should not | 160 // Wait for an unrelated request to finish. The request should not |
165 // advance until followRedirect is invoked. | 161 // advance until followRedirect is invoked. |
166 testSimpleGet(); | 162 testSimpleGet(); |
167 assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, listener.mResponseStep); | 163 assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, listener.mResponseStep); |
168 assertEquals(1, listener.mRedirectResponseInfoList.size()); | 164 assertEquals(1, listener.mRedirectResponseInfoList.size()); |
169 | 165 |
170 // Follow the redirect and wait for the next set of headers. | 166 // Follow the redirect and wait for the next set of headers. |
171 urlRequest.followRedirect(); | 167 urlRequest.followRedirect(); |
172 listener.waitForNextStep(); | 168 listener.waitForNextStep(); |
173 | 169 |
174 assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); | 170 assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); |
175 assertEquals(1, listener.mRedirectResponseInfoList.size()); | 171 assertEquals(1, listener.mRedirectResponseInfoList.size()); |
176 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); | 172 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); |
177 checkResponseInfo(listener.mResponseInfo, NativeTestServer.getSuccessURL (), 200, "OK"); | 173 checkResponseInfo(listener.mResponseInfo, NativeTestServer.getSuccessURL (), 200, "OK"); |
178 assertEquals(2, listener.mResponseInfo.getUrlChain().length); | 174 assertEquals(2, listener.mResponseInfo.getUrlChain().size()); |
179 assertEquals(NativeTestServer.getRedirectURL(), listener.mResponseInfo.g etUrlChain()[0]); | 175 assertEquals( |
180 assertEquals(NativeTestServer.getSuccessURL(), listener.mResponseInfo.ge tUrlChain()[1]); | 176 NativeTestServer.getRedirectURL(), listener.mResponseInfo.getUrl Chain().get(0)); |
177 assertEquals(NativeTestServer.getSuccessURL(), listener.mResponseInfo.ge tUrlChain().get(1)); | |
181 | 178 |
182 // Wait for an unrelated request to finish. The request should not | 179 // Wait for an unrelated request to finish. The request should not |
183 // advance until read is invoked. | 180 // advance until read is invoked. |
184 testSimpleGet(); | 181 testSimpleGet(); |
185 assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); | 182 assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); |
186 | 183 |
187 // One read should get all the characters, but best not to depend on | 184 // One read should get all the characters, but best not to depend on |
188 // how much is actually read from the socket at once. | 185 // how much is actually read from the socket at once. |
189 while (!listener.isDone()) { | 186 while (!listener.isDone()) { |
190 listener.startNextRead(urlRequest); | 187 listener.startNextRead(urlRequest); |
(...skipping 16 matching lines...) Expand all Loading... | |
207 // asserts in TestURLRequestListener. | 204 // asserts in TestURLRequestListener. |
208 testSimpleGet(); | 205 testSimpleGet(); |
209 } | 206 } |
210 | 207 |
211 @SmallTest | 208 @SmallTest |
212 @Feature({"Cronet"}) | 209 @Feature({"Cronet"}) |
213 public void testNotFound() throws Exception { | 210 public void testNotFound() throws Exception { |
214 String url = NativeTestServer.getFileURL("/notfound.html"); | 211 String url = NativeTestServer.getFileURL("/notfound.html"); |
215 TestUrlRequestListener listener = startAndWaitForComplete(url); | 212 TestUrlRequestListener listener = startAndWaitForComplete(url); |
216 checkResponseInfo(listener.mResponseInfo, url, 404, "Not Found"); | 213 checkResponseInfo(listener.mResponseInfo, url, 404, "Not Found"); |
217 checkResponseInfo(listener.mExtendedResponseInfo.getResponseInfo(), | |
218 url, 404, "Not Found"); | |
219 assertEquals( | 214 assertEquals( |
220 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n" | 215 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n" |
221 + "<p>Test page loaded.</p>\n</head>\n</html>\n", | 216 + "<p>Test page loaded.</p>\n</head>\n</html>\n", |
222 listener.mResponseAsString); | 217 listener.mResponseAsString); |
223 assertEquals(0, listener.mRedirectCount); | 218 assertEquals(0, listener.mRedirectCount); |
224 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); | 219 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); |
225 } | 220 } |
226 | 221 |
227 // Checks that UrlRequestListener.onFailed is only called once in the case | 222 // Checks that UrlRequestListener.onFailed is only called once in the case |
228 // of ERR_CONTENT_LENGTH_MISMATCH, which has an unusual failure path. | 223 // of ERR_CONTENT_LENGTH_MISMATCH, which has an unusual failure path. |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 assertEquals(2, multiHeader.size()); | 405 assertEquals(2, multiHeader.size()); |
411 assertEquals("header-value1", multiHeader.get(0)); | 406 assertEquals("header-value1", multiHeader.get(0)); |
412 assertEquals("header-value2", multiHeader.get(1)); | 407 assertEquals("header-value2", multiHeader.get(1)); |
413 } | 408 } |
414 | 409 |
415 @SmallTest | 410 @SmallTest |
416 @Feature({"Cronet"}) | 411 @Feature({"Cronet"}) |
417 public void testResponseHeadersList() throws Exception { | 412 public void testResponseHeadersList() throws Exception { |
418 TestUrlRequestListener listener = startAndWaitForComplete(NativeTestServ er.getSuccessURL()); | 413 TestUrlRequestListener listener = startAndWaitForComplete(NativeTestServ er.getSuccessURL()); |
419 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); | 414 assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); |
420 List<Pair<String, String>> responseHeaders = | 415 List<Map.Entry<String, String>> responseHeaders = |
421 listener.mResponseInfo.getAllHeadersAsList(); | 416 listener.mResponseInfo.getAllHeadersAsList(); |
422 assertEquals(5, responseHeaders.size()); | 417 assertEquals(5, responseHeaders.size()); |
423 assertEquals("Content-Type", responseHeaders.get(0).first); | 418 assertEquals("Content-Type", responseHeaders.get(0).getKey()); |
424 assertEquals("text/plain", responseHeaders.get(0).second); | 419 assertEquals("text/plain", responseHeaders.get(0).getValue()); |
425 assertEquals("Access-Control-Allow-Origin", | 420 assertEquals("Access-Control-Allow-Origin", responseHeaders.get(1).getKe y()); |
426 responseHeaders.get(1).first); | 421 assertEquals("*", responseHeaders.get(1).getValue()); |
427 assertEquals("*", responseHeaders.get(1).second); | 422 assertEquals("header-name", responseHeaders.get(2).getKey()); |
428 assertEquals("header-name", responseHeaders.get(2).first); | 423 assertEquals("header-value", responseHeaders.get(2).getValue()); |
429 assertEquals("header-value", responseHeaders.get(2).second); | 424 assertEquals("multi-header-name", responseHeaders.get(3).getKey()); |
430 assertEquals("multi-header-name", responseHeaders.get(3).first); | 425 assertEquals("header-value1", responseHeaders.get(3).getValue()); |
431 assertEquals("header-value1", responseHeaders.get(3).second); | 426 assertEquals("multi-header-name", responseHeaders.get(4).getKey()); |
432 assertEquals("multi-header-name", responseHeaders.get(4).first); | 427 assertEquals("header-value2", responseHeaders.get(4).getValue()); |
433 assertEquals("header-value2", responseHeaders.get(4).second); | |
434 } | 428 } |
435 | 429 |
436 @SmallTest | 430 @SmallTest |
437 @Feature({"Cronet"}) | 431 @Feature({"Cronet"}) |
438 public void testMockMultiRedirect() throws Exception { | 432 public void testMockMultiRedirect() throws Exception { |
439 TestUrlRequestListener listener = | 433 TestUrlRequestListener listener = |
440 startAndWaitForComplete(NativeTestServer.getMultiRedirectURL()); | 434 startAndWaitForComplete(NativeTestServer.getMultiRedirectURL()); |
441 ResponseInfo mResponseInfo = listener.mResponseInfo; | 435 UrlResponseInfo mResponseInfo = listener.mResponseInfo; |
442 assertEquals(2, listener.mRedirectCount); | 436 assertEquals(2, listener.mRedirectCount); |
443 assertEquals(200, mResponseInfo.getHttpStatusCode()); | 437 assertEquals(200, mResponseInfo.getHttpStatusCode()); |
444 assertEquals(2, listener.mRedirectResponseInfoList.size()); | 438 assertEquals(2, listener.mRedirectResponseInfoList.size()); |
445 | 439 |
446 // Check first redirect (multiredirect.html -> redirect.html) | 440 // Check first redirect (multiredirect.html -> redirect.html) |
447 ResponseInfo firstRedirectResponseInfo = | 441 UrlResponseInfo firstRedirectResponseInfo = listener.mRedirectResponseIn foList.get(0); |
448 listener.mRedirectResponseInfoList.get(0); | 442 assertEquals(1, firstRedirectResponseInfo.getUrlChain().size()); |
449 assertEquals(1, firstRedirectResponseInfo.getUrlChain().length); | 443 assertEquals(NativeTestServer.getMultiRedirectURL(), |
450 assertEquals( | 444 firstRedirectResponseInfo.getUrlChain().get(0)); |
451 NativeTestServer.getMultiRedirectURL(), firstRedirectResponseInf o.getUrlChain()[0]); | |
452 checkResponseInfo( | 445 checkResponseInfo( |
453 firstRedirectResponseInfo, NativeTestServer.getMultiRedirectURL( ), 302, "Found"); | 446 firstRedirectResponseInfo, NativeTestServer.getMultiRedirectURL( ), 302, "Found"); |
454 checkResponseInfoHeader(firstRedirectResponseInfo, | 447 checkResponseInfoHeader(firstRedirectResponseInfo, |
455 "redirect-header0", "header-value"); | 448 "redirect-header0", "header-value"); |
456 | 449 |
457 // Check second redirect (redirect.html -> success.txt) | 450 // Check second redirect (redirect.html -> success.txt) |
458 ResponseInfo secondRedirectResponseInfo = | 451 UrlResponseInfo secondRedirectResponseInfo = listener.mRedirectResponseI nfoList.get(1); |
459 listener.mRedirectResponseInfoList.get(1); | 452 assertEquals(2, secondRedirectResponseInfo.getUrlChain().size()); |
460 assertEquals(2, secondRedirectResponseInfo.getUrlChain().length); | |
461 assertEquals(NativeTestServer.getMultiRedirectURL(), | 453 assertEquals(NativeTestServer.getMultiRedirectURL(), |
462 secondRedirectResponseInfo.getUrlChain()[0]); | 454 secondRedirectResponseInfo.getUrlChain().get(0)); |
463 assertEquals( | 455 assertEquals( |
464 NativeTestServer.getRedirectURL(), secondRedirectResponseInfo.ge tUrlChain()[1]); | 456 NativeTestServer.getRedirectURL(), secondRedirectResponseInfo.ge tUrlChain().get(1)); |
465 checkResponseInfo( | 457 checkResponseInfo( |
466 secondRedirectResponseInfo, NativeTestServer.getRedirectURL(), 3 02, "Found"); | 458 secondRedirectResponseInfo, NativeTestServer.getRedirectURL(), 3 02, "Found"); |
467 checkResponseInfoHeader(secondRedirectResponseInfo, | 459 checkResponseInfoHeader(secondRedirectResponseInfo, |
468 "redirect-header", "header-value"); | 460 "redirect-header", "header-value"); |
469 | 461 |
470 // Check final response (success.txt). | 462 // Check final response (success.txt). |
471 assertEquals(NativeTestServer.getSuccessURL(), mResponseInfo.getUrl()); | 463 assertEquals(NativeTestServer.getSuccessURL(), mResponseInfo.getUrl()); |
472 assertEquals(3, mResponseInfo.getUrlChain().length); | 464 assertEquals(3, mResponseInfo.getUrlChain().size()); |
473 assertEquals(NativeTestServer.getMultiRedirectURL(), mResponseInfo.getUr lChain()[0]); | 465 assertEquals(NativeTestServer.getMultiRedirectURL(), mResponseInfo.getUr lChain().get(0)); |
474 assertEquals(NativeTestServer.getRedirectURL(), mResponseInfo.getUrlChai n()[1]); | 466 assertEquals(NativeTestServer.getRedirectURL(), mResponseInfo.getUrlChai n().get(1)); |
475 assertEquals(NativeTestServer.getSuccessURL(), mResponseInfo.getUrlChain ()[2]); | 467 assertEquals(NativeTestServer.getSuccessURL(), mResponseInfo.getUrlChain ().get(2)); |
476 assertTrue(listener.mHttpResponseDataLength != 0); | 468 assertTrue(listener.mHttpResponseDataLength != 0); |
477 assertEquals(2, listener.mRedirectCount); | 469 assertEquals(2, listener.mRedirectCount); |
478 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); | 470 assertEquals(listener.mResponseStep, ResponseStep.ON_SUCCEEDED); |
479 } | 471 } |
480 | 472 |
481 @SmallTest | 473 @SmallTest |
482 @Feature({"Cronet"}) | 474 @Feature({"Cronet"}) |
483 public void testMockNotFound() throws Exception { | 475 public void testMockNotFound() throws Exception { |
484 TestUrlRequestListener listener = | 476 TestUrlRequestListener listener = |
485 startAndWaitForComplete(NativeTestServer.getNotFoundURL()); | 477 startAndWaitForComplete(NativeTestServer.getNotFoundURL()); |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1537 int end) { | 1529 int end) { |
1538 // Use a duplicate to avoid modifying byteBuffer. | 1530 // Use a duplicate to avoid modifying byteBuffer. |
1539 ByteBuffer duplicate = byteBuffer.duplicate(); | 1531 ByteBuffer duplicate = byteBuffer.duplicate(); |
1540 duplicate.position(start); | 1532 duplicate.position(start); |
1541 duplicate.limit(end); | 1533 duplicate.limit(end); |
1542 byte[] contents = new byte[duplicate.remaining()]; | 1534 byte[] contents = new byte[duplicate.remaining()]; |
1543 duplicate.get(contents); | 1535 duplicate.get(contents); |
1544 return new String(contents); | 1536 return new String(contents); |
1545 } | 1537 } |
1546 } | 1538 } |
OLD | NEW |