aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/android/apksig/internal/apk/ApkSigningBlockUtilsTest.java
blob: 77a8dab3847b04687762bbb436461fa673fc01de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.android.apksig.internal.apk;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import com.android.apksig.util.DataSource;
import com.android.apksig.util.DataSources;
import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class ApkSigningBlockUtilsTest {
    @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();

    private static int BASE = 255; // Intentionally not power of 2 to test properly

    @Test
    public void testMultithreadVersionMatchesSinglethreaded() throws Exception {
        Set<ContentDigestAlgorithm> algos = new HashSet<>(Arrays
                .asList(ContentDigestAlgorithm.CHUNKED_SHA512));
        Map<ContentDigestAlgorithm, byte[]> outputContentDigests = new HashMap<>();
        Map<ContentDigestAlgorithm, byte[]> outputContentDigestsMultithread = new HashMap<>();

        byte[] part1 = new byte[80 * 1024 * 1024 + 12345];
        for (int i = 0; i < part1.length; ++i) {
            part1[i] = (byte)(i % BASE);
        }

        File dataFile = temporaryFolder.newFile("fake.apk");

        try (FileOutputStream fos = new FileOutputStream(dataFile)) {
            fos.write(part1);
        }
        RandomAccessFile raf = new RandomAccessFile(dataFile, "r");

        byte[] part2 = new byte[1_500_000];
        for (int i = 0; i < part2.length; ++i) {
            part2[i] = (byte)(i % BASE);
        }
        byte[] part3 = new byte[30_000];
        for (int i = 0; i < part3.length; ++i) {
            part3[i] = (byte)(i % BASE);
        }

        DataSource[] dataSource = {
                DataSources.asDataSource(raf),
                DataSources.asDataSource(ByteBuffer.wrap(part2)),
                DataSources.asDataSource(ByteBuffer.wrap(part3)),
        };

        ApkSigningBlockUtils.computeOneMbChunkContentDigests(
                algos, dataSource, outputContentDigests);

        ApkSigningBlockUtils.computeOneMbChunkContentDigestsMultithread(
                algos, dataSource, outputContentDigestsMultithread);

        assertEquals(outputContentDigestsMultithread.keySet(), outputContentDigests.keySet());
        for (ContentDigestAlgorithm algo : outputContentDigests.keySet()) {
            byte[] digest1 = outputContentDigestsMultithread.get(algo);
            byte[] digest2 = outputContentDigests.get(algo);
            assertArrayEquals(digest1, digest2);
        }
    }
}