commit 946b261e6ca9a9c5115621db7314d4073d4bcb9b Author: Karsten Loesing karsten.loesing@gmx.net Date: Mon Jun 26 18:12:45 2017 +0200
Remove more deprecated code for #22154.
This patch makes the following changes: - Remove (non-deprecated) method DescriptorParser#parseDescriptors(byte[], String) which we clearly forgot to deprecate earlier and which we shouldn't support in the future. It returns a List (rather than Iterable) and throws DescriptorParseException rather than include UnparseableDescriptor in the result. Might deserve an extra notice in the change log. - Put back a few lines `this.unrecognizedLines.add(line);` which got lost in previous commits. - Remove `failUnrecognizedDescriptorLines` parameters everywhere. - Remove more obsolete code from DescriptorReaderImpl. - Remove now obsolete attribute oldExitListEntries from ExitListImpl. --- .../torproject/descriptor/DescriptorParser.java | 10 -- .../descriptor/impl/BridgeNetworkStatusImpl.java | 1 + .../descriptor/impl/BridgePoolAssignmentImpl.java | 4 +- .../descriptor/impl/DescriptorParserImpl.java | 17 +-- .../descriptor/impl/DescriptorReaderImpl.java | 116 +-------------------- .../impl/DirectoryKeyCertificateImpl.java | 4 +- .../torproject/descriptor/impl/ExitListImpl.java | 3 +- .../impl/RelayNetworkStatusConsensusImpl.java | 1 + .../descriptor/impl/RelayNetworkStatusImpl.java | 3 +- .../descriptor/impl/DescriptorParserImplTest.java | 9 +- .../impl/RelayNetworkStatusImplTest.java | 4 +- .../impl/RelayNetworkStatusVoteImplTest.java | 21 ++-- .../descriptor/impl/ServerDescriptorImplTest.java | 6 +- 13 files changed, 34 insertions(+), 165 deletions(-)
diff --git a/src/main/java/org/torproject/descriptor/DescriptorParser.java b/src/main/java/org/torproject/descriptor/DescriptorParser.java index 0082b5f..0ad2790 100644 --- a/src/main/java/org/torproject/descriptor/DescriptorParser.java +++ b/src/main/java/org/torproject/descriptor/DescriptorParser.java @@ -24,16 +24,6 @@ import java.util.List; public interface DescriptorParser {
/** - * Parse descriptors in the given byte array, possibly parsing the - * publication time from the file name, depending on the descriptor - * type. - * - * @since 1.0.0 - */ - public List<Descriptor> parseDescriptors(byte[] rawDescriptorBytes, - String fileName) throws DescriptorParseException; - - /** * Parse descriptors in the given byte array and return the parsed/unparseable * descriptors. * diff --git a/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java index 01cd221..66a238e 100644 --- a/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java @@ -89,6 +89,7 @@ public class BridgeNetworkStatusImpl extends NetworkStatusImpl if (this.unrecognizedLines == null) { this.unrecognizedLines = new ArrayList<>(); } + this.unrecognizedLines.add(line); } } } diff --git a/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java index 195690b..e0e5cd8 100644 --- a/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java @@ -16,8 +16,8 @@ public class BridgePoolAssignmentImpl extends DescriptorImpl implements BridgePoolAssignment {
protected BridgePoolAssignmentImpl(byte[] rawDescriptorBytes, - int[] offsetAndlength, File descriptorFile, - boolean failUnrecognizedDescriptorLines) throws DescriptorParseException { + int[] offsetAndlength, File descriptorFile) + throws DescriptorParseException { super(rawDescriptorBytes, offsetAndlength, descriptorFile, false); this.parseDescriptorBytes(); this.checkExactlyOnceKeys(EnumSet.of(Key.BRIDGE_POOL_ASSIGNMENT)); diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java index 320139d..d39343d 100644 --- a/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java @@ -20,18 +20,11 @@ import java.util.List; public class DescriptorParserImpl implements DescriptorParser {
@Override - public List<Descriptor> parseDescriptors( - byte[] rawDescriptorBytes, String fileName) - throws DescriptorParseException { - return this.parseDescriptors(rawDescriptorBytes, null, fileName, false); - } - - @Override public Iterable<Descriptor> parseDescriptors(byte[] rawDescriptorBytes, File descriptorFile, String fileName) { try { - return this.parseDescriptors(rawDescriptorBytes, descriptorFile, fileName, - true); + return this.detectTypeAndParseDescriptors(rawDescriptorBytes, + descriptorFile, fileName); } catch (DescriptorParseException e) { /* Looks like we attempted to parse the whole raw descriptor bytes at once * below and ran into a parse issue. */ @@ -42,9 +35,9 @@ public class DescriptorParserImpl implements DescriptorParser { } }
- private List<Descriptor> parseDescriptors( - byte[] rawDescriptorBytes, File descriptorFile, String fileName, - boolean includeUnparseableDescriptors) throws DescriptorParseException { + private List<Descriptor> detectTypeAndParseDescriptors( + byte[] rawDescriptorBytes, File descriptorFile, String fileName) + throws DescriptorParseException { byte[] first100Chars = new byte[Math.min(100, rawDescriptorBytes.length)]; System.arraycopy(rawDescriptorBytes, 0, first100Chars, 0, diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java index e2bf987..2d58573 100644 --- a/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java @@ -4,7 +4,6 @@ package org.torproject.descriptor.impl;
import org.torproject.descriptor.Descriptor; -import org.torproject.descriptor.DescriptorParseException; import org.torproject.descriptor.DescriptorParser; import org.torproject.descriptor.DescriptorReader;
@@ -24,7 +23,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -38,12 +36,6 @@ public class DescriptorReaderImpl implements DescriptorReader { DescriptorReaderImpl.class); private boolean hasStartedReading = false;
- private List<File> directories = new ArrayList<>(); - - private List<File> tarballs = new ArrayList<>(); - - private File autoSaveHistoryFile; - private File manualSaveHistoryFile;
@Override @@ -84,8 +76,6 @@ public class DescriptorReaderImpl implements DescriptorReader { return new TreeMap<>(this.reader.parsedFilesAfter); }
- private Integer maxDescriptorFilesInQueue = null; - private int maxDescriptorsInQueue = 100;
@Override @@ -108,8 +98,7 @@ public class DescriptorReaderImpl implements DescriptorReader { this.hasStartedReading = true; BlockingIteratorImpl<Descriptor> descriptorQueue = new BlockingIteratorImpl<>(this.maxDescriptorsInQueue); - this.reader = new DescriptorReaderRunnable( - descriptorFiles, descriptorQueue, this.autoSaveHistoryFile, + this.reader = new DescriptorReaderRunnable(descriptorFiles, descriptorQueue, this.manualSaveHistoryFile, this.excludedFiles); Thread readerThread = new Thread(this.reader); readerThread.setDaemon(true); @@ -130,10 +119,6 @@ public class DescriptorReaderImpl implements DescriptorReader {
private File[] descriptorFiles;
- private List<File> directories; - - private List<File> tarballs; - private BlockingIteratorImpl<Descriptor> descriptorQueue;
private File autoSaveHistoryFile; @@ -146,16 +131,13 @@ public class DescriptorReaderImpl implements DescriptorReader {
private SortedMap<String, Long> parsedFilesAfter = new TreeMap<>();
- private boolean failUnrecognizedDescriptorLines; - private DescriptorParser descriptorParser;
private boolean hasFinishedReading = false;
private DescriptorReaderRunnable(File[] descriptorFiles, BlockingIteratorImpl<Descriptor> descriptorQueue, - File autoSaveHistoryFile, File manualSaveHistoryFile, - SortedMap<String, Long> excludedFiles) { + File manualSaveHistoryFile, SortedMap<String, Long> excludedFiles) { this.descriptorFiles = descriptorFiles; this.descriptorQueue = descriptorQueue; this.autoSaveHistoryFile = autoSaveHistoryFile; @@ -163,7 +145,6 @@ public class DescriptorReaderImpl implements DescriptorReader { if (excludedFiles != null) { this.excludedFilesBefore = excludedFiles; } - this.failUnrecognizedDescriptorLines = failUnrecognizedDescriptorLines; this.descriptorParser = new DescriptorParserImpl(); }
@@ -172,8 +153,6 @@ public class DescriptorReaderImpl implements DescriptorReader { this.readOldHistory(this.autoSaveHistoryFile); this.readOldHistory(this.manualSaveHistoryFile); this.readDescriptorFiles(); - this.readDescriptors(); - this.readTarballs(); this.hasFinishedReading = true; } catch (Throwable t) { log.error("Bug: uncaught exception or error while " @@ -322,97 +301,6 @@ public class DescriptorReaderImpl implements DescriptorReader { this.descriptorQueue.add(descriptor); } } - - private void readDescriptors() { - if (null == this.directories) { - return; - } - for (File directory : this.directories) { - if (!directory.exists() || !directory.isDirectory()) { - continue; - } - Stack<File> files = new Stack<>(); - files.add(directory); - boolean abortReading = false; - while (!abortReading && !files.isEmpty()) { - File file = files.pop(); - if (file.isDirectory()) { - files.addAll(Arrays.asList(file.listFiles())); - } else if (file.getName().endsWith(".tar") - || file.getName().endsWith(".tar.bz2") - || file.getName().endsWith(".tar.xz")) { - this.tarballs.add(file); - } else { - String absolutePath = file.getAbsolutePath(); - long lastModifiedMillis = file.lastModified(); - if (this.excludedFilesBefore.containsKey(absolutePath) - && this.excludedFilesBefore.get(absolutePath) - == lastModifiedMillis) { - this.excludedFilesAfter.put(absolutePath, - lastModifiedMillis); - continue; - } - this.parsedFilesAfter.put(absolutePath, lastModifiedMillis); - } - } - } - } - - private void readTarballs() { - if (null == this.tarballs) { - return; - } - List<File> files = new ArrayList<>(this.tarballs); - boolean abortReading = false; - while (!abortReading && !files.isEmpty()) { - File tarball = files.remove(0); - if (!tarball.getName().endsWith(".tar") - && !tarball.getName().endsWith(".tar.bz2") - && !tarball.getName().endsWith(".tar.xz")) { - continue; - } - String absolutePath = tarball.getAbsolutePath(); - long lastModifiedMillis = tarball.lastModified(); - if (this.excludedFilesBefore.containsKey(absolutePath) - && this.excludedFilesBefore.get(absolutePath) - == lastModifiedMillis) { - this.excludedFilesAfter.put(absolutePath, lastModifiedMillis); - continue; - } - this.parsedFilesAfter.put(absolutePath, lastModifiedMillis); - try { - FileInputStream in = new FileInputStream(tarball); - if (in.available() > 0) { - TarArchiveInputStream tais = null; - if (tarball.getName().endsWith(".tar.bz2")) { - tais = new TarArchiveInputStream( - new BZip2CompressorInputStream(in)); - } else if (tarball.getName().endsWith(".tar.xz")) { - tais = new TarArchiveInputStream( - new XZCompressorInputStream(in)); - } else if (tarball.getName().endsWith(".tar")) { - tais = new TarArchiveInputStream(in); - } - BufferedInputStream bis = new BufferedInputStream(tais); - TarArchiveEntry tae = null; - while ((tae = tais.getNextTarEntry()) != null) { - if (tae.isDirectory()) { - continue; - } - } - } - } catch (IOException e) { - abortReading = true; - } - } - } - - private List<Descriptor> readFile(File file) throws IOException, - DescriptorParseException { - byte[] rawDescriptorBytes = Files.readAllBytes(file.toPath()); - return this.descriptorParser.parseDescriptors(rawDescriptorBytes, - file.getName()); - } } }
diff --git a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java index 59357d5..81ece3c 100644 --- a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java @@ -16,8 +16,8 @@ public class DirectoryKeyCertificateImpl extends DescriptorImpl implements DirectoryKeyCertificate {
protected DirectoryKeyCertificateImpl(byte[] rawDescriptorBytes, - int[] offsetAndLength, File descriptorFile, - boolean failUnrecognizedDescriptorLines) throws DescriptorParseException { + int[] offsetAndLength, File descriptorFile) + throws DescriptorParseException { super(rawDescriptorBytes, offsetAndLength, descriptorFile, false); this.parseDescriptorBytes(); this.calculateDigestSha1Hex(Key.DIR_KEY_CERTIFICATE_VERSION.keyword + SP, diff --git a/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java b/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java index d67ccd9..454efdc 100644 --- a/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java @@ -89,6 +89,7 @@ public class ExitListImpl extends DescriptorImpl implements ExitList { if (this.unrecognizedLines == null) { this.unrecognizedLines = new ArrayList<>(); } + this.unrecognizedLines.add(line); } } /* Parse the last entry. */ @@ -117,8 +118,6 @@ public class ExitListImpl extends DescriptorImpl implements ExitList { return this.downloadedMillis; }
- private Set<ExitList.Entry> oldExitListEntries = new HashSet<>(); - private Set<ExitList.Entry> exitListEntries = new HashSet<>();
@Override diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java index 7c6f7e0..87ce59a 100644 --- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java @@ -109,6 +109,7 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl if (this.unrecognizedLines == null) { this.unrecognizedLines = new ArrayList<>(); } + this.unrecognizedLines.add(line); } } } diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java index f77e903..d2be570 100644 --- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java @@ -20,8 +20,7 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl implements RelayNetworkStatus {
protected RelayNetworkStatusImpl(byte[] statusBytes, int[] offsetAndLength, - File descriptorFile, boolean failUnrecognizedDescriptorLines) - throws DescriptorParseException { + File descriptorFile) throws DescriptorParseException { super(statusBytes, offsetAndLength, descriptorFile, false, true); Set<Key> exactlyOnceKeys = EnumSet.of( Key.NETWORK_STATUS_VERSION, Key.DIR_SOURCE, Key.FINGERPRINT, diff --git a/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java b/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java index 61dc119..df441f3 100644 --- a/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java +++ b/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java @@ -5,6 +5,7 @@ package org.torproject.descriptor.impl;
import static org.junit.Assert.assertEquals;
+import org.torproject.descriptor.Descriptor; import org.torproject.descriptor.DescriptorParseException;
import org.junit.Rule; @@ -39,8 +40,12 @@ public class DescriptorParserImplTest { public void testAnnotation() throws Exception { TestDescriptor des = makeTestDesc(MICRO.getBytes()); DescriptorParserImpl dpi = new DescriptorParserImpl(); - assertEquals(1, - dpi.parseDescriptors(des.getRawDescriptorBytes(), "dummy.file").size()); + int parsedDescriptors = 0; + for (Descriptor d : dpi.parseDescriptors(des.getRawDescriptorBytes(), null, + "dummy.file")) { + parsedDescriptors++; + } + assertEquals(1, parsedDescriptors); }
@Test diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java index 55ce6eb..a2328d3 100644 --- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java +++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java @@ -50,14 +50,14 @@ public class RelayNetworkStatusImplTest { byte[] statusBytes = (validAnnotation + invalidHeader + validFooter) .getBytes(); new RelayNetworkStatusImpl(statusBytes, new int[] { 0, statusBytes.length }, - null, true); + null); }
@Test public void testValidHeader() throws DescriptorParseException { byte[] statusBytes = validStatus.getBytes(); RelayNetworkStatusImpl rnsi = new RelayNetworkStatusImpl(statusBytes, - new int[] { 0, statusBytes.length }, null, true); + new int[] { 0, statusBytes.length }, null); assertEquals(rnsi.getContactLine(), "1024R/8D56913D Alex de Joode adejoode@sabotage.org"); } diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java index b0f53bd..8dc89bd 100644 --- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java +++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java @@ -470,8 +470,7 @@ public class RelayNetworkStatusVoteImplTest { private String unrecognizedHeaderLine = null;
protected static RelayNetworkStatusVote - createWithUnrecognizedHeaderLine(String line, - boolean failUnrecognizedDescriptorLines) + createWithUnrecognizedHeaderLine(String line) throws DescriptorParseException { VoteBuilder vb = new VoteBuilder(); vb.unrecognizedHeaderLine = line; @@ -481,8 +480,7 @@ public class RelayNetworkStatusVoteImplTest { private String unrecognizedDirSourceLine = null;
protected static RelayNetworkStatusVote - createWithUnrecognizedDirSourceLine(String line, - boolean failUnrecognizedDescriptorLines) + createWithUnrecognizedDirSourceLine(String line) throws DescriptorParseException { VoteBuilder vb = new VoteBuilder(); vb.unrecognizedDirSourceLine = line; @@ -492,8 +490,7 @@ public class RelayNetworkStatusVoteImplTest { private String unrecognizedStatusEntryLine = null;
protected static RelayNetworkStatusVote - createWithUnrecognizedStatusEntryLine(String line, - boolean failUnrecognizedDescriptorLines) + createWithUnrecognizedStatusEntryLine(String line) throws DescriptorParseException { VoteBuilder vb = new VoteBuilder(); vb.unrecognizedStatusEntryLine = line; @@ -503,8 +500,7 @@ public class RelayNetworkStatusVoteImplTest { private String unrecognizedFooterLine = null;
protected static RelayNetworkStatusVote - createWithUnrecognizedFooterLine(String line, - boolean failUnrecognizedDescriptorLines) + createWithUnrecognizedFooterLine(String line) throws DescriptorParseException { VoteBuilder vb = new VoteBuilder(); vb.unrecognizedFooterLine = line; @@ -514,8 +510,7 @@ public class RelayNetworkStatusVoteImplTest { private String unrecognizedDirectorySignatureLine = null;
protected static RelayNetworkStatusVote - createWithUnrecognizedDirectorySignatureLine(String line, - boolean failUnrecognizedDescriptorLines) + createWithUnrecognizedDirectorySignatureLine(String line) throws DescriptorParseException { VoteBuilder vb = new VoteBuilder(); vb.unrecognizedDirectorySignatureLine = line; @@ -1798,7 +1793,7 @@ public class RelayNetworkStatusVoteImplTest { throws DescriptorParseException { String unrecognizedLine = "unrecognized-line 1"; RelayNetworkStatusVote vote = VoteBuilder - .createWithUnrecognizedHeaderLine(unrecognizedLine, false); + .createWithUnrecognizedHeaderLine(unrecognizedLine); List<String> unrecognizedLines = new ArrayList<>(); unrecognizedLines.add(unrecognizedLine); assertEquals(unrecognizedLines, vote.getUnrecognizedLines()); @@ -1809,7 +1804,7 @@ public class RelayNetworkStatusVoteImplTest { throws DescriptorParseException { String unrecognizedLine = "unrecognized-line 1"; RelayNetworkStatusVote vote = VoteBuilder - .createWithUnrecognizedDirSourceLine(unrecognizedLine, false); + .createWithUnrecognizedDirSourceLine(unrecognizedLine); List<String> unrecognizedLines = new ArrayList<>(); unrecognizedLines.add(unrecognizedLine); assertEquals(unrecognizedLines, vote.getUnrecognizedLines()); @@ -1820,7 +1815,7 @@ public class RelayNetworkStatusVoteImplTest { throws DescriptorParseException { String unrecognizedLine = "unrecognized-line 1"; RelayNetworkStatusVote vote = VoteBuilder - .createWithUnrecognizedFooterLine(unrecognizedLine, false); + .createWithUnrecognizedFooterLine(unrecognizedLine); List<String> unrecognizedLines = new ArrayList<>(); unrecognizedLines.add(unrecognizedLine); assertEquals(unrecognizedLines, vote.getUnrecognizedLines()); diff --git a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java index 67145c7..972e207 100644 --- a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java +++ b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java @@ -315,8 +315,7 @@ public class ServerDescriptorImplTest { private byte[] nonAsciiLineBytes = null;
private static ServerDescriptor createWithNonAsciiLineBytes( - byte[] lineBytes, boolean failUnrecognizedDescriptorLines) - throws DescriptorParseException { + byte[] lineBytes) throws DescriptorParseException { DescriptorBuilder db = new DescriptorBuilder(); db.nonAsciiLineBytes = lineBytes; return db.buildDescriptor(); @@ -1558,8 +1557,7 @@ public class ServerDescriptorImplTest { 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x2d, // "allow-" 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x2d, // "single-" 0x68, 0x6f, 0x70, 0x2d, // "hop-" - 0x65, 0x78, 0x69, 0x74, 0x73 }, // "exits" (no newline) - false); + 0x65, 0x78, 0x69, 0x74, 0x73 }); // "exits" (no newline) }
@Test