### Question:
ThreadDumpFactory { public @Nonnull ThreadDumpRuntime fromStream(@Nonnull InputStream stream) { Set<ThreadDumpThread.Builder> threads = new LinkedHashSet<ThreadDumpThread.Builder>(); List<String> header = new ArrayList<String>(); Scanner scanner = new Scanner(stream); scanner.useDelimiter(THREAD_DELIMITER); try { while (scanner.hasNext()) { String singleChunk = scanner.next(); if (singleChunk.startsWith("JNI global references") || singleChunk.startsWith("JNI global refs")) { break; } ThreadDumpThread.Builder thread = thread(singleChunk); if (thread != null) { threads.add(thread); continue; } if (header.isEmpty()) { header.addAll(Arrays.asList(singleChunk.split(NL))); continue; } if (singleChunk.startsWith("Threads class SMR info:")) { continue; } String msg = "Skipping unrecognized chunk: >>>" + singleChunk + "<<<"; if (failOnErrors) { throw new IllegalRuntimeStateException(msg); } else { LOG.warning(msg); } } } finally { scanner.close(); } if (threads.isEmpty()) throw new IllegalRuntimeStateException( "No threads found in threaddump" ); return new ThreadDumpRuntime(threads, header); }  ThreadDumpFactory failOnErrors(boolean failOnErrors); @Nonnull ThreadDumpRuntime fromFile(@Nonnull File threadDump); @Nonnull ThreadDumpRuntime fromStream(@Nonnull InputStream stream); @Nonnull ThreadDumpRuntime fromString(@Nonnull String runtime);  }### Answer:
@Test public void preserveThreadOrder() throws Exception { ThreadDumpThreadSet threads = FACTORY.fromStream(Util.resource(getClass(), "self-lock.log")).getThreads(); List<String> expectedNames = Arrays.asList( "Service Thread", "C2 CompilerThread1", "C2 CompilerThread0", "Signal Dispatcher", "Finalizer", "Reference Handler", "VM Thread", "GC task thread#0 (ParallelGC)", "GC task thread#1 (ParallelGC)", "GC task thread#2 (ParallelGC)", "GC task thread#3 (ParallelGC)", "VM Periodic Task Thread" ); List<String> actualNames = new ArrayList<String>(); for (ThreadDumpThread thread: threads) { actualNames.add(thread.getName()); } assertThat(actualNames, equalTo(expectedNames)); }
@Test public void isStreamClosed() throws Exception { InputStream stream = Util.resource(getClass(), "in-object-wait.log"); InputStream mock = spy(stream); FACTORY.fromStream(mock); Mockito.verify(mock).close(); }
@Test public void failToParseWhatIsNotAThreaddump() throws IOException, URISyntaxException { try { runtimeFrom("unknown-chunks.log"); fail(); } catch (IllegalRuntimeStateException e) { assertThat(e.getMessage(), startsWith("Skipping unrecognized chunk: ")); } try { runtimeFrom("no-threads.log"); fail(); } catch (IllegalRuntimeStateException e) { assertThat(e.getMessage(), startsWith("No threads found in threaddump")); } try { runtimeFrom("broken-synchronizers.log"); fail(); } catch (IllegalRuntimeStateException e) { assertThat(e.getMessage(), startsWith("Unable to parse ownable synchronizer: ")); } new ThreadDumpFactory().fromStream(Util.resource(getClass(), "unknown-chunks.log")); }