1/*******************************************************************************
2 * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.core.internal;
13
14import static org.junit.Assert.assertEquals;
15
16import java.io.ByteArrayInputStream;
17import java.io.ByteArrayOutputStream;
18import java.io.IOException;
19import java.io.InputStream;
20import java.io.OutputStream;
21import java.util.jar.JarInputStream;
22import java.util.jar.Pack200;
23import java.util.zip.GZIPOutputStream;
24import java.util.zip.ZipEntry;
25import java.util.zip.ZipOutputStream;
26
27import org.jacoco.core.test.TargetLoader;
28import org.junit.Test;
29
30/**
31 * Unit tests for {@link ContentTypeDetector}.
32 */
33public class ContentTypeDetectorTest {
34
35	private byte[] data;
36
37	private ContentTypeDetector detector;
38
39	@Test
40	public void testEmptyStream() throws IOException {
41		initData();
42		assertEquals(ContentTypeDetector.UNKNOWN, detector.getType());
43		assertContent();
44	}
45
46	@Test
47	public void testClassFile() throws IOException {
48		initData(TargetLoader
49				.getClassDataAsBytes(ContentTypeDetectorTest.class));
50		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
51		assertContent();
52	}
53
54	@Test
55	public void testClassFile11() throws IOException {
56		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x03, 0x00, 0x2D);
57		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
58		assertContent();
59	}
60
61	@Test
62	public void testClassFile12() throws IOException {
63		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2E);
64		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
65		assertContent();
66	}
67
68	@Test
69	public void testClassFile13() throws IOException {
70		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2F);
71		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
72		assertContent();
73	}
74
75	@Test
76	public void testClassFile14() throws IOException {
77		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x30);
78		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
79		assertContent();
80	}
81
82	@Test
83	public void testClassFile15() throws IOException {
84		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x31);
85		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
86		assertContent();
87	}
88
89	@Test
90	public void testClassFile16() throws IOException {
91		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x32);
92		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
93		assertContent();
94	}
95
96	@Test
97	public void testClassFile17() throws IOException {
98		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x33);
99		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
100		assertContent();
101	}
102
103	@Test
104	public void testClassFile18() throws IOException {
105		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x34);
106		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
107		assertContent();
108	}
109
110	@Test
111	public void testClassFile19() throws IOException {
112		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x35);
113		assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
114		assertContent();
115	}
116
117	@Test
118	public void testMachObjectFile() throws IOException {
119		initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x02);
120		assertEquals(ContentTypeDetector.UNKNOWN, detector.getType());
121		assertContent();
122	}
123
124	@Test
125	public void testZipFile() throws IOException {
126		final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
127		final ZipOutputStream zip = new ZipOutputStream(buffer);
128		zip.putNextEntry(new ZipEntry("hello.txt"));
129		zip.write("Hello Zip!".getBytes());
130		zip.close();
131		initData(buffer.toByteArray());
132		assertEquals(ContentTypeDetector.ZIPFILE, detector.getType());
133		assertContent();
134	}
135
136	@Test
137	public void testPack200File() throws IOException {
138		final ByteArrayOutputStream zipbuffer = new ByteArrayOutputStream();
139		final ZipOutputStream zip = new ZipOutputStream(zipbuffer);
140		zip.putNextEntry(new ZipEntry("hello.txt"));
141		zip.write("Hello Zip!".getBytes());
142		zip.close();
143
144		final ByteArrayOutputStream pack200buffer = new ByteArrayOutputStream();
145		Pack200.newPacker().pack(
146				new JarInputStream(new ByteArrayInputStream(
147						zipbuffer.toByteArray())), pack200buffer);
148		initData(pack200buffer.toByteArray());
149		assertEquals(ContentTypeDetector.PACK200FILE, detector.getType());
150		assertContent();
151	}
152
153	@Test
154	public void testGZipFile() throws IOException {
155		final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
156		final OutputStream gz = new GZIPOutputStream(buffer);
157		gz.write("Hello gz!".getBytes());
158		gz.close();
159		initData(buffer.toByteArray());
160		assertEquals(ContentTypeDetector.GZFILE, detector.getType());
161		assertContent();
162	}
163
164	@Test
165	public void testStreamWithoutMarkSupport() throws IOException {
166		initData(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
167		detector = new ContentTypeDetector(new ByteArrayInputStream(data) {
168
169			@Override
170			public void mark(int readlimit) {
171			}
172
173			@Override
174			public void reset() {
175			}
176
177			@Override
178			public boolean markSupported() {
179				return false;
180			}
181
182		});
183		assertContent();
184	}
185
186	private void initData(byte[] bytes) throws IOException {
187		this.data = bytes;
188		this.detector = new ContentTypeDetector(new ByteArrayInputStream(data));
189	}
190
191	private void initData(final int... bytes) throws IOException {
192		byte[] data = new byte[bytes.length];
193		for (int i = 0; i < bytes.length; i++) {
194			data[i] = (byte) bytes[i];
195		}
196		initData(data);
197	}
198
199	private void assertContent() throws IOException {
200		final InputStream actual = detector.getInputStream();
201		for (int b : data) {
202			assertEquals(b, (byte) actual.read());
203		}
204		assertEquals(-1, actual.read());
205	}
206
207}
208