View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.net.tftp;
18  
19  import java.io.BufferedOutputStream;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  
26  import org.apache.commons.io.FileUtils;
27  import org.apache.commons.net.tftp.TFTPServer.ServerMode;
28  
29  import junit.framework.TestCase;
30  
31  /**
32   * Test the TFTP Server and TFTP Client by creating some FILES in the system temp folder and then uploading and downloading them.
33   */
34  public class TFTPTest extends TestCase {
35      private static final int SERVER_PORT = 6902;
36      private static TFTPServer tftpS;
37      private static final File SERVER_DIR = FileUtils.getTempDirectory();
38      private static final String FILE_PREFIX = "tftp-";
39      private static final File[] FILES = new File[8];
40  
41      static int testsLeftToRun = 6;
42  
43      // only want to do this once...
44      static {
45          try {
46              FILES[0] = createFile(new File(SERVER_DIR, FILE_PREFIX + "empty.txt"), 0);
47              FILES[1] = createFile(new File(SERVER_DIR, FILE_PREFIX + "small.txt"), 1);
48              FILES[2] = createFile(new File(SERVER_DIR, FILE_PREFIX + "511.txt"), 511);
49              FILES[3] = createFile(new File(SERVER_DIR, FILE_PREFIX + "512.txt"), 512);
50              FILES[4] = createFile(new File(SERVER_DIR, FILE_PREFIX + "513.txt"), 513);
51              FILES[5] = createFile(new File(SERVER_DIR, FILE_PREFIX + "med.txt"), 1000 * 1024);
52              FILES[6] = createFile(new File(SERVER_DIR, FILE_PREFIX + "big.txt"), 5000 * 1024);
53              FILES[7] = createFile(new File(SERVER_DIR, FILE_PREFIX + "huge.txt"), 37000 * 1024);
54  
55              // Start the server
56              tftpS = new TFTPServer(SERVER_DIR, SERVER_DIR, SERVER_PORT, ServerMode.GET_AND_PUT, null, null);
57              tftpS.setSocketTimeout(2000);
58          } catch (final IOException e) {
59              e.printStackTrace();
60          }
61  
62      }
63  
64      /*
65       * Create a file, size specified in bytes
66       */
67      private static File createFile(final File file, final int size) throws IOException {
68          try (final OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
69              final byte[] temp = "0".getBytes();
70              for (int i = 0; i < size; i++) {
71                  os.write(temp);
72              }
73          }
74          return file;
75      }
76  
77      private boolean contentEquals(final File a, final File b) throws IOException {
78          return FileUtils.contentEquals(a, b);
79      }
80  
81      @Override
82      protected void tearDown() throws Exception {
83          testsLeftToRun--;
84          if (testsLeftToRun <= 0) {
85              if (tftpS != null) {
86                  tftpS.close();
87              }
88              for (final File file : FILES) {
89                  file.delete();
90              }
91          }
92          super.tearDown();
93      }
94  
95      public void testASCIIDownloads() {
96          // test with the smaller FILES
97          for (int i = 0; i < 6; i++) {
98              try {
99                  testDownload(TFTP.ASCII_MODE, FILES[i]);
100             } catch (final IOException e) {
101                 fail("Entry " + i + " Error " + e.toString());
102             }
103 
104         }
105     }
106 
107     public void testASCIIUploads() throws Exception {
108         // test with the smaller FILES
109         for (int i = 0; i < 6; i++) {
110             testUpload(TFTP.ASCII_MODE, FILES[i]);
111         }
112     }
113 
114     private void testDownload(final int mode, final File file) throws IOException {
115         // Create our TFTP instance to handle the file transfer.
116         try (TFTPClient tftp = new TFTPClient()) {
117             tftp.open();
118             tftp.setSoTimeout(2000);
119 
120             final File out = new File(SERVER_DIR, FILE_PREFIX + "download");
121 
122             // cleanup old failed runs
123             out.delete();
124             assertFalse("Couldn't clear output location", out.exists());
125 
126             try (final FileOutputStream output = new FileOutputStream(out)) {
127                 tftp.receiveFile(file.getName(), mode, output, "localhost", SERVER_PORT);
128             }
129 
130             assertTrue("file not created", out.exists());
131             assertTrue("FILES not identical on file " + file, contentEquals(out, file));
132 
133             // delete the downloaded file
134             out.delete();
135         }
136     }
137 
138     public void testHugeDownloads() throws Exception {
139         // test with the smaller FILES
140         for (int i = 5; i < FILES.length; i++) {
141             testDownload(TFTP.BINARY_MODE, FILES[i]);
142         }
143     }
144 
145     public void testHugeUploads() throws Exception {
146         for (int i = 5; i < FILES.length; i++) {
147             testUpload(TFTP.BINARY_MODE, FILES[i]);
148         }
149     }
150 
151     public void testTFTPBinaryDownloads() throws Exception {
152         // test with the smaller FILES
153         for (int i = 0; i < 6; i++) {
154             testDownload(TFTP.BINARY_MODE, FILES[i]);
155         }
156     }
157 
158     public void testTFTPBinaryUploads() throws Exception {
159         // test with the smaller FILES
160         for (int i = 0; i < 6; i++) {
161             testUpload(TFTP.BINARY_MODE, FILES[i]);
162         }
163     }
164 
165     private void testUpload(final int mode, final File file) throws Exception {
166         // Create our TFTP instance to handle the file transfer.
167         try (TFTPClient tftp = new TFTPClient()) {
168             tftp.open();
169             tftp.setSoTimeout(2000);
170 
171             final File in = new File(SERVER_DIR, FILE_PREFIX + "upload");
172             // cleanup old failed runs
173             in.delete();
174             assertFalse("Couldn't clear output location", in.exists());
175 
176             try (final FileInputStream fis = new FileInputStream(file)) {
177                 tftp.sendFile(in.getName(), mode, fis, "localhost", SERVER_PORT);
178             }
179 
180             // need to give the server a bit of time to receive our last packet, and
181             // close out its file buffers, etc.
182             Thread.sleep(100);
183             assertTrue("file not created", in.exists());
184             assertTrue("FILES not identical on file " + file, contentEquals(file, in));
185 
186             in.delete();
187         }
188     }
189 }