Issue #3010 - Moving old MultiPart Parser
+ Moving MultiPartInputStreamParser from jetty-util to jetty-http/internal + Moving related classes ReadLineInputStream to jetty-http/internal + Moving related tests to jetty-http as well + Moved MultiPartFormDataCompliance to jetty-http + Renaming test to have same name as implementation Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
6bbc26fab8
commit
d77714698b
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
/**
|
||||
* The compliance level for parsing <code>multiPart/form-data</code>
|
||||
|
@ -27,7 +27,7 @@ public enum MultiPartFormDataCompliance
|
|||
/**
|
||||
* Legacy <code>multiPart/form-data</code> parsing which is slow but forgiving.
|
||||
* It will accept non compliant preambles and inconsistent line termination.
|
||||
* @see org.eclipse.jetty.util.MultiPartInputStreamParser
|
||||
* @see org.eclipse.jetty.http.internal.MultiPartInputStreamParser
|
||||
*/
|
||||
LEGACY,
|
||||
/**
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
package org.eclipse.jetty.http.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
|
@ -43,7 +43,13 @@ import javax.servlet.MultipartConfigElement;
|
|||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.eclipse.jetty.util.ReadLineInputStream.Termination;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.http.internal.ReadLineInputStream.Termination;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -59,7 +65,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* @deprecated Replaced by org.eclipse.jetty.http.MultiPartFormInputStream
|
||||
* The code for MultiPartInputStream is slower than its replacement MultiPartFormInputStream. However
|
||||
* this class accepts formats non compliant the RFC that the new MultiPartFormInputStream does not accept.
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public class MultiPartInputStreamParser
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
package org.eclipse.jetty.http.internal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -24,8 +24,6 @@ import java.io.InputStream;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser.NonCompliance;
|
||||
|
||||
/**
|
||||
* ReadLineInputStream
|
||||
*
|
|
@ -43,6 +43,7 @@ import java.util.stream.Stream;
|
|||
import javax.servlet.MultipartConfigElement;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.toolchain.test.Hex;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
|
@ -166,7 +167,7 @@ public class MultiPartCaptureTest
|
|||
MultipartConfigElement config = newMultipartConfigElement(outputDir);
|
||||
try (InputStream in = Files.newInputStream(multipartRawFile))
|
||||
{
|
||||
org.eclipse.jetty.util.MultiPartInputStreamParser parser = new org.eclipse.jetty.util.MultiPartInputStreamParser(in,multipartExpectations.contentType,config,outputDir.toFile());
|
||||
MultiPartInputStreamParser parser = new MultiPartInputStreamParser(in,multipartExpectations.contentType,config,outputDir.toFile());
|
||||
|
||||
multipartExpectations.checkParts(parser.getParts(),s->
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
package org.eclipse.jetty.http.internal;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -46,8 +46,11 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser.MultiPart;
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser.NonCompliance;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser.MultiPart;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser.NonCompliance;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
|
@ -56,7 +59,7 @@ import org.junit.jupiter.api.Test;
|
|||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MultiPartInputStreamTest
|
||||
public class MultiPartInputStreamParserTest
|
||||
{
|
||||
private static final String FILENAME = "stuff.txt";
|
||||
protected String _contentType = "multipart/form-data, boundary=AaB03x";
|
||||
|
@ -64,7 +67,7 @@ public class MultiPartInputStreamTest
|
|||
protected String _dirname = System.getProperty("java.io.tmpdir")+File.separator+"myfiles-"+TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
protected File _tmpDir = new File(_dirname);
|
||||
|
||||
public MultiPartInputStreamTest ()
|
||||
public MultiPartInputStreamParserTest()
|
||||
{
|
||||
_tmpDir.deleteOnExit();
|
||||
}
|
||||
|
@ -81,7 +84,7 @@ public class MultiPartInputStreamTest
|
|||
"\r\n--" + boundary + "-\r\n\r\n";
|
||||
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
|
||||
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
|
||||
MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
|
||||
"multipart/form-data, boundary="+boundary,
|
||||
config,
|
||||
_tmpDir);
|
||||
|
@ -996,7 +999,7 @@ public class MultiPartInputStreamTest
|
|||
"Content-Transfer-Encoding: base64\r\n"+
|
||||
"Content-Type: application/octet-stream\r\n"+
|
||||
"\r\n"+
|
||||
B64Code.encode("hello jetty") + "\r\n"+
|
||||
B64Code.encode("hello jetty") + "\r\n"+
|
||||
"--AaB03x\r\n"+
|
||||
"Content-disposition: form-data; name=\"final\"\r\n"+
|
||||
"Content-Type: text/plain\r\n"+
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
package org.eclipse.jetty.http.internal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
@ -27,9 +27,9 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.EnumSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.ReadLineInputStream.Termination;
|
||||
import org.eclipse.jetty.http.internal.ReadLineInputStream.Termination;
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class ReadLineInputStreamTest
|
|||
volatile PipedOutputStream _pout;
|
||||
ReadLineInputStream _in;
|
||||
volatile Thread _writer;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void before() throws Exception
|
||||
{
|
||||
|
@ -80,12 +80,12 @@ public class ReadLineInputStreamTest
|
|||
{
|
||||
_writer=null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
_writer.start();
|
||||
}
|
||||
|
||||
|
||||
@AfterEach
|
||||
public void after() throws Exception
|
||||
{
|
||||
|
@ -93,13 +93,13 @@ public class ReadLineInputStreamTest
|
|||
while (_writer!=null)
|
||||
Thread.sleep(10);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCR() throws Exception
|
||||
{
|
||||
_queue.add("\rHello\rWorld\r\r");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -107,13 +107,13 @@ public class ReadLineInputStreamTest
|
|||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.CR), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLF() throws Exception
|
||||
{
|
||||
_queue.add("\nHello\nWorld\n\n");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -121,13 +121,13 @@ public class ReadLineInputStreamTest
|
|||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.LF), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCRLF() throws Exception
|
||||
{
|
||||
_queue.add("\r\nHello\r\nWorld\r\n\r\n");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -135,7 +135,7 @@ public class ReadLineInputStreamTest
|
|||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.CRLF), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCRBlocking() throws Exception
|
||||
|
@ -146,7 +146,7 @@ public class ReadLineInputStreamTest
|
|||
_queue.add("\rWorld\r");
|
||||
_queue.add("\r");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -154,7 +154,7 @@ public class ReadLineInputStreamTest
|
|||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.CR), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLFBlocking() throws Exception
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ public class ReadLineInputStreamTest
|
|||
_queue.add("\nWorld\n");
|
||||
_queue.add("\n");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -172,7 +172,7 @@ public class ReadLineInputStreamTest
|
|||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.LF), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCRLFBlocking() throws Exception
|
||||
{
|
||||
|
@ -183,7 +183,7 @@ public class ReadLineInputStreamTest
|
|||
_queue.add("\n");
|
||||
_queue.add("");
|
||||
_queue.add("__CLOSE__");
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals("Hello",_in.readLine());
|
||||
assertEquals("World",_in.readLine());
|
||||
|
@ -208,12 +208,12 @@ public class ReadLineInputStreamTest
|
|||
byte[] body = new byte[6];
|
||||
_in.read(body);
|
||||
assertEquals("\nBody\n",new String(body,0,6,StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.LF), _in.getLineTerminations());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHeaderCRBodyLF() throws Exception
|
||||
{
|
||||
|
@ -229,13 +229,13 @@ public class ReadLineInputStreamTest
|
|||
byte[] body = new byte[6];
|
||||
_in.read(body);
|
||||
assertEquals("\nBody\n",new String(body,0,6,StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.CR), _in.getLineTerminations());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHeaderCRLFBodyLF() throws Exception
|
||||
{
|
||||
|
@ -251,12 +251,12 @@ public class ReadLineInputStreamTest
|
|||
byte[] body = new byte[6];
|
||||
_in.read(body);
|
||||
assertEquals("\nBody\n",new String(body,0,6,StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
assertEquals("",_in.readLine());
|
||||
assertEquals(null,_in.readLine());
|
||||
assertEquals(EnumSet.of(Termination.CRLF), _in.getLineTerminations());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.http.jmh;
|
|||
|
||||
import org.eclipse.jetty.http.MultiPartCaptureTest.MultipartExpectations;
|
||||
import org.eclipse.jetty.http.MultiPartFormInputStream;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
|
@ -181,7 +182,7 @@ public class MultiPartBenchmark
|
|||
|
||||
case "UTIL":
|
||||
{
|
||||
org.eclipse.jetty.util.MultiPartInputStreamParser parser = new org.eclipse.jetty.util.MultiPartInputStreamParser(in, _contentType, config, outputDir.toFile());
|
||||
MultiPartInputStreamParser parser = new MultiPartInputStreamParser(in, _contentType, config, outputDir.toFile());
|
||||
if (parser.getParts().size() != _numSections)
|
||||
throw new IllegalStateException("Incorrect Parsing");
|
||||
for (Part p : parser.getParts())
|
||||
|
@ -249,7 +250,7 @@ public class MultiPartBenchmark
|
|||
break;
|
||||
case "UTIL":
|
||||
{
|
||||
org.eclipse.jetty.util.MultiPartInputStreamParser parser = new org.eclipse.jetty.util.MultiPartInputStreamParser(in, multipartExpectations.contentType, config, outputDir.toFile());
|
||||
MultiPartInputStreamParser parser = new MultiPartInputStreamParser(in, multipartExpectations.contentType, config, outputDir.toFile());
|
||||
for (Part p : parser.getParts())
|
||||
{
|
||||
count += p.getSize();
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<Set name="blockingTimeout"><Property deprecated="jetty.httpConfig.blockingTimeout" name="jetty.httpConfig.blockingTimeout.DEPRECATED" default="-1"/></Set>
|
||||
<Set name="persistentConnectionsEnabled"><Property name="jetty.httpConfig.persistentConnectionsEnabled" default="true"/></Set>
|
||||
<Set name="cookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>
|
||||
<Set name="multiPartFormDataCompliance"><Call class="org.eclipse.jetty.server.MultiPartFormDataCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.multiPartFormDataCompliance" default="RFC7578"/></Arg></Call></Set>
|
||||
<Set name="multiPartFormDataCompliance"><Call class="org.eclipse.jetty.http.MultiPartFormDataCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.multiPartFormDataCompliance" default="RFC7578"/></Arg></Call></Set>
|
||||
</New>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
import org.eclipse.jetty.http.CookieCompliance;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.MultiPartFormDataCompliance;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.TreeTrie;
|
||||
import org.eclipse.jetty.util.Trie;
|
||||
|
|
|
@ -34,8 +34,8 @@ import org.eclipse.jetty.http.HttpCompliance;
|
|||
import org.eclipse.jetty.http.MultiPartFormInputStream;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser.NonCompliance;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser.NonCompliance;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -44,13 +44,12 @@ import org.eclipse.jetty.util.MultiPartInputStreamParser.NonCompliance;
|
|||
*/
|
||||
public interface MultiParts extends Closeable
|
||||
{
|
||||
public Collection<Part> getParts();
|
||||
public Part getPart(String name);
|
||||
public boolean isEmpty();
|
||||
public ContextHandler.Context getContext();
|
||||
|
||||
|
||||
public class MultiPartsHttpParser implements MultiParts
|
||||
Collection<Part> getParts();
|
||||
Part getPart(String name);
|
||||
boolean isEmpty();
|
||||
ContextHandler.Context getContext();
|
||||
|
||||
class MultiPartsHttpParser implements MultiParts
|
||||
{
|
||||
private final MultiPartFormInputStream _httpParser;
|
||||
private final ContextHandler.Context _context;
|
||||
|
@ -107,9 +106,8 @@ public interface MultiParts extends Closeable
|
|||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MultiPartsUtilParser implements MultiParts
|
||||
@SuppressWarnings("deprecation")
|
||||
class MultiPartsUtilParser implements MultiParts
|
||||
{
|
||||
private final MultiPartInputStreamParser _utilParser;
|
||||
private final ContextHandler.Context _context;
|
||||
|
|
|
@ -79,6 +79,7 @@ import org.eclipse.jetty.http.HttpURI;
|
|||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.MultiPartFormDataCompliance;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
|
|
|
@ -64,6 +64,7 @@ import org.eclipse.jetty.http.BadMessageException;
|
|||
import org.eclipse.jetty.http.HttpCompliance;
|
||||
import org.eclipse.jetty.http.HttpTester;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.MultiPartFormDataCompliance;
|
||||
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.servlets;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -51,7 +49,7 @@ import org.eclipse.jetty.http.MimeTypes;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.http.internal.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ import org.eclipse.jetty.servlet.FilterMapping;
|
|||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletTester;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.ReadLineInputStream;
|
||||
import org.eclipse.jetty.http.internal.ReadLineInputStream;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
Loading…
Reference in New Issue