From 2eb54afe6a5cb5dd2a108285ad1676b7798d5a15 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Sat, 6 Mar 2021 00:00:15 +0100 Subject: ApplyCommand: add streams to read/write binary patch hunks Add streams that can encode or decode git binary patch data on the fly. Git writes binary patches base-85 encoded, at most 52 un-encoded bytes, with the unencoded data length prefixed in a one-character encoding, and suffixed with a newline character. Add a test for both the new input and the output stream. The test roundtrips binary data of different lengths in different ways. Bug: 371725 Change-Id: Ic3faebaa4637520f5448b3d1acd78d5aaab3907a Signed-off-by: Thomas Wolf --- .../eclipse/jgit/util/io/BinaryHunkStreamTest.java | 146 +++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java (limited to 'org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io') diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java new file mode 100644 index 0000000000..b198c32a78 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2021 Thomas Wolf and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.util.io; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Test; + +/** + * Tests for {@link BinaryHunkInputStream} and {@link BinaryHunkOutputStream}. + */ +public class BinaryHunkStreamTest { + + @Test + public void testRoundtripWholeBuffer() throws IOException { + for (int length = 1; length < 520 + 52; length++) { + byte[] data = new byte[length]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (255 - (i % 256)); + } + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + BinaryHunkOutputStream out = new BinaryHunkOutputStream( + bos)) { + out.write(data); + out.flush(); + byte[] encoded = bos.toByteArray(); + assertFalse(Arrays.equals(data, encoded)); + try (BinaryHunkInputStream in = new BinaryHunkInputStream( + new ByteArrayInputStream(encoded))) { + byte[] decoded = new byte[data.length]; + int newLength = in.read(decoded); + assertEquals(newLength, decoded.length); + assertEquals(-1, in.read()); + assertArrayEquals(data, decoded); + } + } + } + } + + @Test + public void testRoundtripChunks() throws IOException { + for (int length = 1; length < 520 + 52; length++) { + byte[] data = new byte[length]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (255 - (i % 256)); + } + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + BinaryHunkOutputStream out = new BinaryHunkOutputStream( + bos)) { + out.write(data, 0, data.length / 2); + out.write(data, data.length / 2, data.length - data.length / 2); + out.flush(); + byte[] encoded = bos.toByteArray(); + assertFalse(Arrays.equals(data, encoded)); + try (BinaryHunkInputStream in = new BinaryHunkInputStream( + new ByteArrayInputStream(encoded))) { + byte[] decoded = new byte[data.length]; + int p = 0; + int n; + while ((n = in.read(decoded, p, + Math.min(decoded.length - p, 57))) >= 0) { + p += n; + if (p == decoded.length) { + break; + } + } + assertEquals(p, decoded.length); + assertEquals(-1, in.read()); + assertArrayEquals(data, decoded); + } + } + } + } + + @Test + public void testRoundtripBytes() throws IOException { + for (int length = 1; length < 520 + 52; length++) { + byte[] data = new byte[length]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (255 - (i % 256)); + } + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + BinaryHunkOutputStream out = new BinaryHunkOutputStream( + bos)) { + for (int i = 0; i < data.length; i++) { + out.write(data[i]); + } + out.flush(); + byte[] encoded = bos.toByteArray(); + assertFalse(Arrays.equals(data, encoded)); + try (BinaryHunkInputStream in = new BinaryHunkInputStream( + new ByteArrayInputStream(encoded))) { + byte[] decoded = new byte[data.length]; + for (int i = 0; i < decoded.length; i++) { + int val = in.read(); + assertTrue(0 <= val && val <= 255); + decoded[i] = (byte) val; + } + assertEquals(-1, in.read()); + assertArrayEquals(data, decoded); + } + } + } + } + + @Test + public void testRoundtripWithClose() throws IOException { + for (int length = 1; length < 520 + 52; length++) { + byte[] data = new byte[length]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (255 - (i % 256)); + } + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + try (BinaryHunkOutputStream out = new BinaryHunkOutputStream( + bos)) { + out.write(data); + } + byte[] encoded = bos.toByteArray(); + assertFalse(Arrays.equals(data, encoded)); + try (BinaryHunkInputStream in = new BinaryHunkInputStream( + new ByteArrayInputStream(encoded))) { + byte[] decoded = new byte[data.length]; + int newLength = in.read(decoded); + assertEquals(newLength, decoded.length); + assertEquals(-1, in.read()); + assertArrayEquals(data, decoded); + } + } + } + } +} -- cgit v1.2.3