You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/05/18 07:06:57 UTC

[29/38] git commit: [OLINGO-256] Added more tests

[OLINGO-256] Added more tests


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/d75041c4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/d75041c4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/d75041c4

Branch: refs/heads/Olingo-129_PocJpaDataStore
Commit: d75041c4545302ec431a23ac894ee0498aeab18a
Parents: 15abea3
Author: Michael Bolz <mi...@apache.org>
Authored: Fri Apr 25 14:14:20 2014 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Fri Apr 25 15:07:04 2014 +0200

----------------------------------------------------------------------
 .../odata2/core/batch/BatchRequestTest.java     | 283 +++++++++++++++++++
 .../core/batch/BatchRequestWriterTest.java      |  22 +-
 .../core/batch/BatchResponseParserTest.java     |   1 -
 .../odata2/core/batch/BatchResponseTest.java    | 141 +++++++++
 .../src/test/resources/batchResponse.batch      |   2 -
 .../odata2/testutil/helper/StringHelper.java    |  82 ++++++
 6 files changed, 518 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
new file mode 100644
index 0000000..40c3218
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.batch;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchRequestPart;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSet;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart;
+import org.apache.olingo.odata2.api.client.batch.BatchPart;
+import org.apache.olingo.odata2.api.client.batch.BatchQueryPart;
+import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
+import org.apache.olingo.odata2.core.PathInfoImpl;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test creation of a batch request with BatchRequestWriter and
+ * then parsing this request again with BatchRequestParser.
+ */
+public class BatchRequestTest {
+
+  private static final String POST = "POST";
+  private static final String GET = "GET";
+  private static final String PUT = "PUT";
+  private static final String BOUNDARY = "batch_123";
+  private static final String SERVICE_ROOT = "http://localhost/odata/";
+
+  private EntityProviderBatchProperties parseProperties;
+
+  public BatchRequestTest() throws URISyntaxException {
+    PathInfoImpl pathInfo = new PathInfoImpl();
+    pathInfo.setServiceRoot(new URI(SERVICE_ROOT));
+    parseProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
+  }
+
+  private void checkMimeHeaders(final String requestBody) {
+    assertTrue(requestBody.contains("Content-Type: application/http"));
+    assertTrue(requestBody.contains("Content-Transfer-Encoding: binary"));
+  }
+
+  @Test
+  public void testBatchQueryPart() throws BatchException, IOException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("Accept", "application/json");
+    BatchPart request = BatchQueryPart.method(GET).uri("Employees").headers(headers).build();
+    batch.add(request);
+
+    BatchRequestWriter writer = new BatchRequestWriter();
+    InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
+    assertNotNull(batchRequest);
+
+    StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
+    String requestBody = batchRequestStream.asString();
+    checkMimeHeaders(requestBody);
+
+    assertTrue(requestBody.contains("--batch_"));
+    assertTrue(requestBody.contains("GET Employees HTTP/1.1"));
+    checkHeaders(headers, requestBody);
+
+    String contentType = "multipart/mixed; boundary=" + BOUNDARY;
+    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
+    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    assertEquals(1, parseResult.size());
+  }
+
+  @Test
+  public void testBatchChangeSet() throws IOException, BatchException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("content-type", "application/json");
+    BatchChangeSetPart request = BatchChangeSetPart.method(PUT)
+        .uri("Employees('2')")
+        .body("{\"Возраст\":40}")
+        .headers(headers)
+        .contentId("111")
+        .build();
+    BatchChangeSet changeSet = BatchChangeSet.newBuilder().build();
+    changeSet.add(request);
+    batch.add(changeSet);
+
+    BatchRequestWriter writer = new BatchRequestWriter();
+    InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
+    assertNotNull(batchRequest);
+
+    StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
+    String requestBody = batchRequestStream.asString();
+    checkMimeHeaders(requestBody);
+    checkHeaders(headers, requestBody);
+
+    assertTrue(requestBody.contains("--batch_"));
+    assertTrue(requestBody.contains("--changeset_"));
+    assertTrue(requestBody.contains("PUT Employees('2') HTTP/1.1"));
+    assertTrue(requestBody.contains("{\"Возраст\":40}"));
+
+    String contentType = "multipart/mixed; boundary=" + BOUNDARY;
+    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
+    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    assertEquals(1, parseResult.size());
+  }
+
+  @Test
+  public void testBatchWithGetAndPost() throws BatchException, IOException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("Accept", "application/json");
+    BatchPart request = BatchQueryPart.method(GET).uri("Employees").headers(headers).contentId("000").build();
+    batch.add(request);
+
+    Map<String, String> changeSetHeaders = new HashMap<String, String>();
+    changeSetHeaders.put("content-type", "application/json");
+    String body = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA";
+    BatchChangeSetPart changeRequest = BatchChangeSetPart.method(POST)
+        .uri("Employees")
+        .body(body)
+        .headers(changeSetHeaders)
+        .contentId("111")
+        .build();
+    BatchChangeSet changeSet = BatchChangeSet.newBuilder().build();
+    changeSet.add(changeRequest);
+    batch.add(changeSet);
+    BatchRequestWriter writer = new BatchRequestWriter();
+    InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
+    assertNotNull(batchRequest);
+
+    StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
+    String requestBody = batchRequestStream.asString();
+    checkMimeHeaders(requestBody);
+
+    checkHeaders(headers, requestBody);
+    checkHeaders(changeSetHeaders, requestBody);
+    assertTrue(requestBody.contains("GET Employees HTTP/1.1"));
+    assertTrue(requestBody.contains("POST Employees HTTP/1.1"));
+    assertTrue(requestBody.contains(body));
+
+    String contentType = "multipart/mixed; boundary=" + BOUNDARY;
+    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
+    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    assertEquals(2, parseResult.size());
+  }
+
+  @Test
+  public void testChangeSetWithContentIdReferencing() throws BatchException, IOException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+
+    Map<String, String> changeSetHeaders = new HashMap<String, String>();
+    changeSetHeaders.put("content-type", "application/json");
+    String body = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA";
+    BatchChangeSetPart changeRequest = BatchChangeSetPart.method(POST)
+        .uri("Employees('2')")
+        .body(body)
+        .headers(changeSetHeaders)
+        .contentId("1")
+        .build();
+    BatchChangeSet changeSet = BatchChangeSet.newBuilder().build();
+    changeSet.add(changeRequest);
+
+    changeSetHeaders = new HashMap<String, String>();
+    changeSetHeaders.put("content-type", "application/json;odata=verbose");
+    BatchChangeSetPart changeRequest2 = BatchChangeSetPart.method(PUT)
+        .uri("$/ManagerId")
+        .body("{\"ManagerId\":1}")
+        .headers(changeSetHeaders)
+        .contentId("2")
+        .build();
+    changeSet.add(changeRequest2);
+    batch.add(changeSet);
+
+    BatchRequestWriter writer = new BatchRequestWriter();
+    InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
+    assertNotNull(batchRequest);
+
+    StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
+    String requestBody = batchRequestStream.asString();
+    checkMimeHeaders(requestBody);
+
+    assertTrue(requestBody.contains("POST Employees('2') HTTP/1.1"));
+    assertTrue(requestBody.contains("PUT $/ManagerId HTTP/1.1"));
+    assertTrue(requestBody.contains(BatchHelper.HTTP_CONTENT_ID + ": 1"));
+    assertTrue(requestBody.contains(BatchHelper.HTTP_CONTENT_ID + ": 2"));
+    assertTrue(requestBody.contains(body));
+
+    String contentType = "multipart/mixed; boundary=" + BOUNDARY;
+    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
+    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    assertEquals(1, parseResult.size());
+  }
+
+  @Test
+  public void testBatchWithTwoChangeSets() throws BatchException, IOException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+
+    Map<String, String> changeSetHeaders = new HashMap<String, String>();
+    changeSetHeaders.put("content-type", "application/json");
+    changeSetHeaders.put("content-Id", "111");
+    String body = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA";
+    BatchChangeSetPart changeRequest = BatchChangeSetPart.method(POST)
+        .uri("Employees")
+        .body(body)
+        .headers(changeSetHeaders)
+        .build();
+    BatchChangeSet changeSet = BatchChangeSet.newBuilder().build();
+    changeSet.add(changeRequest);
+    batch.add(changeSet);
+
+    Map<String, String> changeSetHeaders2 = new HashMap<String, String>();
+    changeSetHeaders2.put("content-type", "application/json;odata=verbose");
+    changeSetHeaders2.put("content-Id", "222");
+    BatchChangeSetPart changeRequest2 = BatchChangeSetPart.method(PUT)
+        .uri("Employees('2')/ManagerId")
+        .body("{\"ManagerId\":1}")
+        .headers(changeSetHeaders2)
+        .build();
+    BatchChangeSet changeSet2 = BatchChangeSet.newBuilder().build();
+    changeSet2.add(changeRequest2);
+    batch.add(changeSet2);
+
+    BatchRequestWriter writer = new BatchRequestWriter();
+    InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
+    assertNotNull(batchRequest);
+
+    StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
+    String requestBody = batchRequestStream.asString();
+    checkMimeHeaders(requestBody);
+
+    assertTrue(requestBody.contains("POST Employees HTTP/1.1"));
+    assertTrue(requestBody.contains("PUT Employees('2')/ManagerId HTTP/1.1"));
+
+    assertTrue(requestBody.contains(body));
+
+    String contentType = "multipart/mixed; boundary=" + BOUNDARY;
+    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
+    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    assertEquals(2, parseResult.size());
+  }
+
+  private void checkHeaders(final Map<String, String> headers, final String requestBody) {
+    for (Map.Entry<String, String> header : headers.entrySet()) {
+      assertTrue(requestBody.contains(header.getKey() + ": " + header.getValue()));
+    }
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testBatchQueryPartWithInvalidMethod() throws BatchException, IOException {
+    BatchQueryPart.method(PUT).uri("Employees").build();
+
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testBatchChangeSetPartWithInvalidMethod() throws BatchException, IOException {
+    BatchChangeSetPart.method(GET).uri("Employees('2')").build();
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterTest.java
index 1331e73..496686d 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterTest.java
@@ -18,8 +18,13 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.batch;
 
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSet;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart;
+import org.apache.olingo.odata2.api.client.batch.BatchPart;
+import org.apache.olingo.odata2.api.client.batch.BatchQueryPart;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -28,13 +33,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.olingo.odata2.api.batch.BatchException;
-import org.apache.olingo.odata2.api.client.batch.BatchChangeSet;
-import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart;
-import org.apache.olingo.odata2.api.client.batch.BatchPart;
-import org.apache.olingo.odata2.api.client.batch.BatchQueryPart;
-import org.apache.olingo.odata2.testutil.helper.StringHelper;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class BatchRequestWriterTest {
 
@@ -59,13 +60,14 @@ public class BatchRequestWriterTest {
     BatchRequestWriter writer = new BatchRequestWriter();
     InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
 
-    String requestBody = StringHelper.inputStreamToString(batchRequest);
+    String requestBody = StringHelper.toStream(batchRequest).asString();
     assertNotNull(batchRequest);
     checkMimeHeaders(requestBody);
 
     assertTrue(requestBody.contains("--batch_"));
     assertTrue(requestBody.contains("GET Employees HTTP/1.1"));
     checkHeaders(headers, requestBody);
+    assertEquals(10, StringHelper.countLines(requestBody));
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
index 06daa2a..592c054 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
@@ -48,7 +48,6 @@ public class BatchResponseParserTest {
         + "Content-length: 22" + LF
         + LF
         + "Frederic Fall MODIFIED" + LF
-        + LF
         + "--batch_123--";
 
     InputStream in = new ByteArrayInputStream(getResponse.getBytes());

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
new file mode 100644
index 0000000..29dd774
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.batch;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test creation of a batch response with BatchResponseWriter and
+ * then parsing this response again with BatchResponseParser.
+ */
+public class BatchResponseTest {
+
+  @Test
+  public void testBatchResponse() throws BatchException, IOException {
+    List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+    ODataResponse response = ODataResponse.entity("Walter Winter")
+        .status(HttpStatusCodes.OK)
+        .contentHeader("application/json")
+        .build();
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(BatchResponsePart.responses(responses).changeSet(false).build());
+
+    ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+    BatchResponseWriter writer = new BatchResponseWriter();
+    ODataResponse batchResponse = writer.writeResponse(parts);
+
+    assertEquals(202, batchResponse.getStatus().getStatusCode());
+    assertNotNull(batchResponse.getEntity());
+    String body = (String) batchResponse.getEntity();
+
+    assertTrue(body.contains("--batch"));
+    assertTrue(body.contains("--changeset"));
+    assertTrue(body.contains("HTTP/1.1 200 OK"));
+    assertTrue(body.contains("Content-Type: application/http"));
+    assertTrue(body.contains("Content-Transfer-Encoding: binary"));
+    assertTrue(body.contains("Walter Winter"));
+    assertTrue(body.contains("multipart/mixed; boundary=changeset"));
+    assertTrue(body.contains("HTTP/1.1 204 No Content"));
+
+    String contentHeader = batchResponse.getContentHeader();
+    BatchResponseParser parser = new BatchResponseParser(contentHeader);
+    List<BatchSingleResponse> result = parser.parse(new ByteArrayInputStream(body.getBytes()));
+    assertEquals(2, result.size());
+  }
+
+  @Test
+  public void testChangeSetResponse() throws BatchException, IOException {
+    List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+    ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+    BatchResponseWriter writer = new BatchResponseWriter();
+    ODataResponse batchResponse = writer.writeResponse(parts);
+
+    assertEquals(202, batchResponse.getStatus().getStatusCode());
+    assertNotNull(batchResponse.getEntity());
+    String body = (String) batchResponse.getEntity();
+    assertTrue(body.contains("--batch"));
+    assertTrue(body.contains("--changeset"));
+    assertTrue(body.indexOf("--changeset") != body.lastIndexOf("--changeset"));
+    assertFalse(body.contains("HTTP/1.1 200 OK" + "\r\n"));
+    assertTrue(body.contains("Content-Type: application/http" + "\r\n"));
+    assertTrue(body.contains("Content-Transfer-Encoding: binary" + "\r\n"));
+    assertTrue(body.contains("HTTP/1.1 204 No Content" + "\r\n"));
+    assertTrue(body.contains("Content-Type: multipart/mixed; boundary=changeset"));
+
+    String contentHeader = batchResponse.getContentHeader();
+    BatchResponseParser parser = new BatchResponseParser(contentHeader);
+    List<BatchSingleResponse> result = parser.parse(new ByteArrayInputStream(body.getBytes()));
+    assertEquals(1, result.size());
+  }
+
+  @Test
+  public void testTwoChangeSetResponse() throws BatchException, IOException {
+    List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+    ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+    ODataResponse changeSetResponseTwo = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    responses.add(changeSetResponseTwo);
+    parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+    BatchResponseWriter writer = new BatchResponseWriter();
+    ODataResponse batchResponse = writer.writeResponse(parts);
+
+    assertEquals(202, batchResponse.getStatus().getStatusCode());
+    assertNotNull(batchResponse.getEntity());
+    String body = (String) batchResponse.getEntity();
+    assertTrue(body.contains("--batch"));
+    assertTrue(body.contains("--changeset"));
+    assertTrue(body.indexOf("--changeset") != body.lastIndexOf("--changeset"));
+    assertFalse(body.contains("HTTP/1.1 200 OK" + "\r\n"));
+    assertTrue(body.contains("Content-Type: application/http" + "\r\n"));
+    assertTrue(body.contains("Content-Transfer-Encoding: binary" + "\r\n"));
+    assertTrue(body.contains("HTTP/1.1 204 No Content" + "\r\n"));
+    assertTrue(body.contains("Content-Type: multipart/mixed; boundary=changeset"));
+
+    String contentHeader = batchResponse.getContentHeader();
+    BatchResponseParser parser = new BatchResponseParser(contentHeader);
+    StringHelper.Stream content = StringHelper.toStream(body);
+    List<BatchSingleResponse> result = parser.parse(content.asStream());
+    assertEquals(2, result.size());
+    assertEquals("Failing content:\n" + content.asString(), 19, content.countCrLf());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-core/src/test/resources/batchResponse.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/batchResponse.batch b/odata2-lib/odata-core/src/test/resources/batchResponse.batch
index ff65bb1..f9e043b 100644
--- a/odata2-lib/odata-core/src/test/resources/batchResponse.batch
+++ b/odata2-lib/odata-core/src/test/resources/batchResponse.batch
@@ -21,7 +21,6 @@ Content-Type: application/json
 Content-Length: 918
 
 {"d":{"__metadata":{"id":"http://localhost:19000/ClientBatchTest/Employees('7')","uri":"http://localhost:19000/ClientBatchTest/Employees('7')","type":"RefScenario.Employee","content_type":"application/octet-stream","media_src":"Employees('7')/$value","edit_media":"http://localhost:19000/ClientBatchTest/Employees('7')/$value"},"EmployeeId":"7","EmployeeName":"Employee 7","ManagerId":null,"RoomId":null,"TeamId":null,"Location":{"__metadata":{"type":"RefScenario.c_Location"},"City":{"__metadata":{"type":"RefScenario.c_City"},"PostalCode":null,"CityName":null},"Country":null},"Age":0,"EntryDate":null,"ImageUrl":null,"ne_Manager":{"__deferred":{"uri":"http://localhost:19000/ClientBatchTest/Employees('7')/ne_Manager"}},"ne_Team":{"__deferred":{"uri":"http://localhost:19000/ClientBatchTest/Employees('7')/ne_Team"}},"ne_Room":{"__deferred":{"uri":"http://localhost:19000/ClientBatchTest/Employees('7')/ne_Room"}}}}
-
 --changeset_12ks93js84d--
 
 --batch_123
@@ -35,5 +34,4 @@ Content-Type: text/plain;charset=utf-8
 Content-length: 13
 
 Frederic Fall
-
 --batch_123--
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d75041c4/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/StringHelper.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/StringHelper.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/StringHelper.java
index 3d17fbff..1d46767 100644
--- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/StringHelper.java
+++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/StringHelper.java
@@ -35,6 +35,72 @@ import org.apache.olingo.odata2.testutil.TestUtilRuntimeException;
  */
 public class StringHelper {
 
+
+  public static class Stream {
+    private final byte[] data;
+
+    private Stream(byte[] data) {
+      this.data = data;
+    }
+
+    public Stream(String content, String charset) throws UnsupportedEncodingException {
+      this(content.getBytes(charset));
+    }
+
+    public InputStream asStream() {
+      return new ByteArrayInputStream(data);
+    }
+
+    public byte[] asArray() {
+      return data;
+    }
+
+    public String asString() {
+      return asString("UTF-8");
+    }
+
+    public String asString(String charsetName) {
+      return new String(data, Charset.forName(charsetName));
+    }
+
+    public Stream print(OutputStream out) throws IOException {
+      out.write(data);
+      return this;
+    }
+
+    public Stream print() throws IOException {
+      return print(System.out);
+    }
+
+    public int countCrLf() {
+      return StringHelper.countLines(asString(), "\r\n");
+    }
+  }
+
+  public static Stream toStream(InputStream stream) throws IOException {
+    byte[] result = new byte[0];
+    byte[] tmp = new byte[8192];
+    int readCount = stream.read(tmp);
+    while (readCount >= 0) {
+      byte[] innerTmp = new byte[result.length + readCount];
+      System.arraycopy(result, 0, innerTmp, 0, result.length);
+      System.arraycopy(tmp, 0, innerTmp, result.length, readCount);
+      result = innerTmp;
+      readCount = stream.read(tmp);
+    }
+    stream.close();
+    return new Stream(result);
+  }
+
+  public static Stream toStream(String content) {
+    try {
+      return new Stream(content, "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 should be supported on each system.");
+    }
+  }
+
+
   public static String inputStreamToString(final InputStream in, final boolean preserveLineBreaks) throws IOException {
     final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8")));
     final StringBuilder stringBuilder = new StringBuilder();
@@ -54,6 +120,22 @@ public class StringHelper {
     return result;
   }
 
+  public static int countLines(String content) {
+    return countLines(content, "\r\n");
+  }
+
+  public static int countLines(String content, String lineBreak) {
+    int lastPos = 0;
+    int count = -1;
+
+    while (lastPos >= 0) {
+      lastPos = content.indexOf(lineBreak, lastPos+1);
+      count++;
+    }
+
+    return count;
+  }
+
   public static String inputStreamToString(final InputStream in) throws IOException {
     return inputStreamToString(in, false);
   }