Skip to content

Commit 5b51e2e

Browse files
committed
Add test for zero-copy multipart
1 parent e32431d commit 5b51e2e

File tree

1 file changed

+65
-46
lines changed

1 file changed

+65
-46
lines changed
Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/*
2-
* Copyright (c) 2013 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2016 AsyncHttpClient Project. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
6-
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at
7+
* http://www.apache.org/licenses/LICENSE-2.0.
78
*
89
* Unless required by applicable law or agreed to in writing,
910
* software distributed under the Apache License Version 2.0 is distributed on an
@@ -12,43 +13,47 @@
1213
*/
1314
package com.ning.http.client.multipart;
1415

15-
import static java.nio.charset.StandardCharsets.*;
16+
import static java.nio.charset.StandardCharsets.UTF_8;
1617

1718
import org.testng.Assert;
1819
import org.testng.annotations.Test;
1920

20-
import com.ning.http.client.Body;
2121
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
22-
import com.ning.http.client.multipart.ByteArrayPart;
23-
import com.ning.http.client.multipart.FilePart;
24-
import com.ning.http.client.multipart.Part;
25-
import com.ning.http.client.multipart.StringPart;
2622

2723
import java.io.File;
2824
import java.io.IOException;
2925
import java.net.URISyntaxException;
3026
import java.net.URL;
3127
import java.nio.ByteBuffer;
28+
import java.nio.channels.WritableByteChannel;
3229
import java.util.ArrayList;
3330
import java.util.List;
31+
import java.util.concurrent.atomic.AtomicLong;
3432

3533
public class MultipartBodyTest {
3634

37-
@Test(groups = "fast")
38-
public void testBasics() {
39-
final List<Part> parts = new ArrayList<>();
35+
@Test
36+
public void transferWithCopy() throws IOException {
37+
try (MultipartBody multipartBody = buildMultipart()) {
38+
long tranferred = transferWithCopy(multipartBody);
39+
Assert.assertEquals(tranferred, multipartBody.getContentLength());
40+
}
41+
}
4042

41-
// add a file
42-
final File testFile = getTestfile();
43-
parts.add(new FilePart("filePart", testFile));
43+
@Test
44+
public void transferZeroCopy() throws IOException {
45+
try (MultipartBody multipartBody = buildMultipart()) {
46+
long tranferred = transferZeroCopy(multipartBody);
47+
Assert.assertEquals(tranferred, multipartBody.getContentLength());
48+
}
49+
}
4450

45-
// add a byte array
51+
private static MultipartBody buildMultipart() {
52+
List<Part> parts = new ArrayList<>();
53+
parts.add(new FilePart("filePart", getTestfile()));
4654
parts.add(new ByteArrayPart("baPart", "testMultiPart".getBytes(UTF_8), "application/test", UTF_8, "fileName"));
47-
48-
// add a string
4955
parts.add(new StringPart("stringPart", "testString"));
50-
51-
compareContentLength(parts);
56+
return MultipartUtils.newMultipartBody(parts, new FluentCaseInsensitiveStringsMap());
5257
}
5358

5459
private static File getTestfile() {
@@ -64,35 +69,49 @@ private static File getTestfile() {
6469
return file;
6570
}
6671

67-
private static void compareContentLength(final List<Part> parts) {
68-
Assert.assertNotNull(parts);
69-
// get expected values
70-
final Body multipartBody = MultipartUtils.newMultipartBody(parts, new FluentCaseInsensitiveStringsMap());
71-
final long expectedContentLength = multipartBody.getContentLength();
72-
try {
73-
final ByteBuffer buffer = ByteBuffer.allocate(8192);
74-
boolean last = false;
75-
long totalBytes = 0;
76-
while (!last) {
77-
long readBytes = 0;
78-
try {
79-
readBytes = multipartBody.read(buffer);
80-
} catch (IOException ie) {
81-
Assert.fail("read failure");
82-
}
83-
if (readBytes >= 0) {
84-
totalBytes += readBytes;
85-
} else {
86-
last = true;
87-
}
88-
buffer.clear();
72+
private static long transferWithCopy(MultipartBody multipartBody) throws IOException {
73+
74+
final ByteBuffer buffer = ByteBuffer.allocate(8192);
75+
long totalBytes = 0;
76+
while (true) {
77+
long readBytes = multipartBody.read(buffer);
78+
if (readBytes < 0) {
79+
break;
80+
}
81+
buffer.clear();
82+
totalBytes += readBytes;
83+
}
84+
return totalBytes;
85+
}
86+
87+
private static long transferZeroCopy(MultipartBody multipartBody) throws IOException {
88+
89+
final ByteBuffer buffer = ByteBuffer.allocate(8192);
90+
final AtomicLong transferred = new AtomicLong();
91+
92+
WritableByteChannel mockChannel = new WritableByteChannel() {
93+
@Override
94+
public boolean isOpen() {
95+
return true;
8996
}
90-
Assert.assertEquals(totalBytes, expectedContentLength);
91-
} finally {
92-
try {
93-
multipartBody.close();
94-
} catch (IOException ignore) {
97+
98+
@Override
99+
public void close() throws IOException {
100+
}
101+
102+
@Override
103+
public int write(ByteBuffer src) throws IOException {
104+
int written = src.remaining();
105+
transferred.set(transferred.get() + written);
106+
src.position(src.limit());
107+
return written;
95108
}
109+
};
110+
111+
while (transferred.get() < multipartBody.getContentLength()) {
112+
multipartBody.transferTo(0, mockChannel);
113+
buffer.clear();
96114
}
115+
return transferred.get();
97116
}
98117
}

0 commit comments

Comments
 (0)