Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93e9bcf5 authored by Tobias Thierer's avatar Tobias Thierer Committed by Android (Google) Code Review
Browse files

Merge "HexDumpTest: provide test coverage"

parents 9f93606a e121ca0a
Loading
Loading
Loading
Loading
+145 −2
Original line number Diff line number Diff line
@@ -16,8 +16,16 @@

package com.android.internal.util;

import static com.android.internal.util.HexDump.hexStringToByteArray;
import static com.android.internal.util.HexDump.toHexString;

import junit.framework.TestCase;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Random;

public final class HexDumpTest extends TestCase {
    public void testBytesToHexString() {
        assertEquals("abcdef", HexDump.toHexString(
@@ -25,7 +33,142 @@ public final class HexDumpTest extends TestCase {
        assertEquals("ABCDEF", HexDump.toHexString(
                new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true));
    }
    public void testNullArray() {
        assertEquals("(null)", HexDump.toHexString(null));

    public void testNullByteArray() {
        assertThrows(
                NullPointerException.class,
                () -> HexDump.toHexString(null));
    }

    public void testBytesToHexString_allByteValues() {
        byte[] bytes = new byte[256];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (i % 256);
        }

        StringBuilder sb = new StringBuilder();
        for (char firstChar : "0123456789ABCDEF".toCharArray()) {
            for (char secondChar : "0123456789ABCDEF".toCharArray()) {
                sb.append(firstChar).append(secondChar);
            }
        }
        String expected = sb.toString();

        assertEquals(expected, HexDump.toHexString(bytes));
    }

    public void testRoundTrip_fromBytes() {
        Random deterministicRandom = new Random(31337); // arbitrary but deterministic
        for (int length = 0; length < 100; length++) {
            byte[] bytes = new byte[length];
            deterministicRandom.nextBytes(bytes);
            byte[] reconstruction = hexStringToByteArray(toHexString(bytes));

            assertBytesEqual(bytes, reconstruction);
        }
    }

    public void testRoundTrip_fromString() {
        String hexString = "0123456789ABCDEF72f9a3438934c378d34f32a8b932";
        for (int length = 0; length < hexString.length(); length += 2) {
            String original = hexString.substring(0, length);
            String reconstruction = toHexString(hexStringToByteArray(original));
            assertEquals(original.toUpperCase(), reconstruction);
        }
    }

    public void testToHexString_offsetLength() {
        byte[] bytes = new byte[32];
        for (int i = 0; i < 16; i++) {
            bytes[i] = (byte) i;
            bytes[16 + i] = (byte) (16 * i);
        }
        String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0";
        for (int offset = 0; offset < bytes.length; offset++) {
            for (int len = 0; len < (bytes.length - offset); len++) {

                byte[] subBytes = new byte[len];
                System.arraycopy(bytes, offset, subBytes, 0, len);

                String actual = toHexString(bytes, offset, len);
                assertEquals(expected.substring(2 * offset, 2 * offset + 2 * len), actual);
                assertEquals(toHexString(subBytes), actual);
            }
        }
    }

    public void testToHexString_case() {
        byte[] bytes = new byte[32];
        for (int i = 0; i < 16; i++) {
            bytes[i] = (byte) i;
            bytes[16 + i] = (byte) (16 * i);
        }

        String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0";

        assertEquals(expected.toUpperCase(), toHexString(bytes, true));
        assertEquals(expected.toLowerCase(), toHexString(bytes, false));

        // default is uppercase
        assertEquals(expected.toUpperCase(), toHexString(bytes));
    }

    public void testHexStringToByteArray_empty() {
        assertBytesEqual(new byte[0], HexDump.hexStringToByteArray(""));
    }

    public void testHexStringToByteArray_null() {
        assertThrows(
                NullPointerException.class,
                () -> HexDump.hexStringToByteArray((String) null));
    }

    public void testHexStringToByteArray_invalidCharacters() {
        // IllegalArgumentException would probably have been better than RuntimeException, but it
        // might be too late to change now.
        assertThrows(
                RuntimeException.class,
                () -> HexDump.hexStringToByteArray("GG"));
        assertThrows(
                RuntimeException.class,
                () -> HexDump.hexStringToByteArray("\0\0"));
        assertThrows(
                RuntimeException.class,
                () -> HexDump.hexStringToByteArray("abcdefgh"));
    }

    public void testHexStringToByteArray_oddLength() {
        // IllegalArgumentException would probably have been better than
        // StringIndexOutOfBoundsException, but it might be too late to change now.
        assertThrows(
                StringIndexOutOfBoundsException.class,
                () -> HexDump.hexStringToByteArray("A"));
        assertThrows(
                StringIndexOutOfBoundsException.class,
                () -> HexDump.hexStringToByteArray("123"));
        assertThrows(
                StringIndexOutOfBoundsException.class,
                () -> HexDump.hexStringToByteArray("ABCDE"));
    }

    private static void assertBytesEqual(byte[] expected, byte[] actual) {
        if (!Arrays.equals(expected, actual)) {
            fail("Expected " + Arrays.toString(expected) + ", got " + Arrays.toString(actual));
        }
    }

    private static void assertThrows(Class<? extends RuntimeException> clazz, Runnable runnable) {
        try {
            runnable.run();
        } catch (RuntimeException exception) {
            assertEquals(toStrackTrace(exception), clazz, exception.getClass());
        }
    }

    private static String toStrackTrace(Throwable throwable) {
        StringWriter stringWriter = new StringWriter();
        throwable.printStackTrace(new PrintWriter(stringWriter));
        return stringWriter.toString();
    }

}