Path: blob/master/test/jdk/sun/net/ftp/TestFtpTimeValue.java
41149 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 825507826* @summary verify that datetime in MDTM and MLSD responses are properly parsed27* @library /test/lib28* @modules java.base/sun.net.ftp29* @build jdk.test.lib.Asserts30* @run main/othervm -Duser.timezone=UTC TestFtpTimeValue31* @run main/othervm -Duser.timezone=America/Los_Angeles TestFtpTimeValue32*/3334import jdk.test.lib.Asserts;35import sun.net.ftp.FtpClient;3637import java.io.*;38import java.net.*;39import java.util.Calendar;40import java.util.Date;41import java.util.GregorianCalendar;42import java.util.TimeZone;434445public class TestFtpTimeValue {46private enum TestCase {47AmTimeNoMilli(2019, 4, 20, 10, 57, 13, 0),48AmTimeWithMilli(2019, 4, 20, 10, 57, 13, 50),49PmTimeNoMilli(2019, 4, 20, 22, 57, 13, 0),50PmTimeWithMilli(2019, 4, 20, 22, 57, 13, 50),51;5253public final Date expectedCreated;54public final Date expectedModified;55public final String create;56public final String modify;5758TestCase(int year, int month, int day, int hrs, int min, int sec, int milliseconds) {59var calendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"));60// month is 0-based in Calendar61calendar.set(year, month - 1, day, hrs, min, sec);62calendar.set(Calendar.MILLISECOND, milliseconds);63expectedCreated = calendar.getTime();64var s = String.format("%4d%02d%02d%02d%02d%02d", year, month, day, hrs, min, sec);65if (milliseconds != 0) {66s += "." + String.format("%03d", milliseconds);67}68create = s;6970calendar.add(GregorianCalendar.SECOND, 1);71expectedModified = calendar.getTime();72s = String.format("%4d%02d%02d%02d%02d%02d", year, month, day, hrs, min, sec + 1);73if (milliseconds != 0) {74s += "." + String.format("%03d", milliseconds);75}76modify = s;77}78}7980public static void main(String[] args) throws Exception {81System.out.println("user.timezone: " + System.getProperty("user.timezone"));82try (FtpServer server = new FtpServer();83FtpClient client = FtpClient.create()) {84(new Thread(server)).start();85int port = server.getPort();86var loopback = InetAddress.getLoopbackAddress();87client.connect(new InetSocketAddress(loopback, port));88client.enablePassiveMode(true);89for (var testCase : TestCase.values()) {90Asserts.assertEQ(testCase.expectedModified, client.getLastModified(testCase.name()),91"wrong modified date from MDTM for " + testCase);92}93for (var it = client.listFiles(null); it.hasNext(); ) {94var e = it.next();95Asserts.assertEQ(TestCase.valueOf(e.getName()).expectedCreated, e.getCreated(),96"wrong created date from MLSD for " + e.getName());97Asserts.assertEQ(TestCase.valueOf(e.getName()).expectedModified, e.getLastModified(),98"wrong modified date from MLSD for " + e.getName());99}100}101}102103private static class FtpServer implements AutoCloseable, Runnable {104private final ServerSocket serverSocket;105private final ServerSocket pasv;106107FtpServer() throws IOException {108var loopback = InetAddress.getLoopbackAddress();109serverSocket = new ServerSocket();110serverSocket.bind(new InetSocketAddress(loopback, 0));111pasv = new ServerSocket();112pasv.bind(new InetSocketAddress(loopback, 0));113}114115public void handleClient(Socket client) throws IOException {116String str;117118client.setSoTimeout(2000);119BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));120PrintWriter out = new PrintWriter(client.getOutputStream(), true);121out.println("220 FTP serverSocket is ready.");122boolean done = false;123while (!done) {124try {125str = in.readLine();126} catch (SocketException e) {127done = true;128continue;129}130String cmd = str.substring(0, str.indexOf(" ") > 0 ? str.indexOf(" ") : str.length());131String args = (cmd.equals(str)) ? "" : str.substring(str.indexOf(" ") + 1);132System.err.println("C> " + str);133switch (cmd) {134case "QUIT":135out.println("221 Goodbye.");136System.err.println("S> 221");137done = true;138break;139case "MDTM": {140var testCase = TestCase.valueOf(args);141out.println("213 " + testCase.modify);142System.err.println("S> 213");143break;144}145case "MLSD":146try (var socket = pasv.accept();147var dout = new PrintWriter(socket.getOutputStream(), true)) {148out.println("150 MLSD start");149System.err.println("S> 150");150for (var testCase : TestCase.values()) {151dout.printf("modify=%s;create=%s; %s%n",152testCase.modify, testCase.create, testCase.name());153}154}155out.println("226 MLSD done.");156System.err.println("S> 226");157break;158case "EPSV":159if ("all".equalsIgnoreCase(args)) {160out.println("200 EPSV ALL command successful.");161System.err.println("S> 200");162continue;163}164out.println("229 Entering Extended Passive Mode (|||" + pasv.getLocalPort() + "|)");165System.err.println("S> 229");166break;167default:168System.err.println("S> 500");169out.println("500 unsupported command: " + str);170}171}172}173174public int getPort() {175return serverSocket.getLocalPort();176}177178public void close() throws IOException {179serverSocket.close();180pasv.close();181}182183@Override184public void run() {185try (Socket client = serverSocket.accept()) {186handleClient(client);187} catch (Throwable t) {188t.printStackTrace();189throw new RuntimeException("Problem in test execution", t);190}191}192}193}194195196