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.BufferedInputStream;
20  import java.io.BufferedOutputStream;
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  
28  import org.apache.commons.net.tftp.TFTPServer.ServerMode;
29  
30  import junit.framework.TestCase;
31  
32  /**
33   * Test the TFTP Server and TFTP Client by creating some files in the system temp folder and then
34   * uploading and downloading them.
35   *
36   * @author <A HREF="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</A>
37   *
38   */
39  public class TFTPTest extends TestCase
40  {
41      private static TFTPServer tftpS;
42      private static final File serverDirectory = new File(System.getProperty("java.io.tmpdir"));
43      private static final String filePrefix = "tftp-";
44      private static final File[] files = new File[8];
45  
46      static int testsLeftToRun = 6;
47  
48      // only want to do this once...
49      static
50      {
51          try
52          {
53              files[0] = createFile(new File(serverDirectory, filePrefix + "empty.txt"), 0);
54              files[1] = createFile(new File(serverDirectory, filePrefix + "small.txt"), 1);
55              files[2] = createFile(new File(serverDirectory, filePrefix + "511.txt"), 511);
56              files[3] = createFile(new File(serverDirectory, filePrefix + "512.txt"), 512);
57              files[4] = createFile(new File(serverDirectory, filePrefix + "513.txt"), 513);
58              files[5] = createFile(new File(serverDirectory, filePrefix + "med.txt"), 1000 * 1024);
59              files[6] = createFile(new File(serverDirectory, filePrefix + "big.txt"), 5000 * 1024);
60              files[7] = createFile(new File(serverDirectory, filePrefix + "huge.txt"), 37000 * 1024);
61  
62              // Start the server
63              tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900, ServerMode.GET_AND_PUT,
64                      null, null);
65              tftpS.setSocketTimeout(2000);
66          }
67          catch (IOException e)
68          {
69              e.printStackTrace();
70          }
71  
72      }
73  
74      @Override
75      protected void tearDown() throws Exception
76      {
77          testsLeftToRun--;
78          if (testsLeftToRun <= 0)
79          {
80              if (tftpS != null)
81              {
82                  tftpS.shutdown();
83              }
84              for (File file : files)
85              {
86                  file.delete();
87              }
88          }
89          super.tearDown();
90      }
91  
92      /*
93       * Create a file, size specified in bytes
94       */
95      private static File createFile(File file, int size) throws IOException
96      {
97          OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
98          byte[] temp = "0".getBytes();
99          for (int i = 0; i < size; i++)
100         {
101             os.write(temp);
102         }
103         os.close();
104         return file;
105     }
106 
107     public void testTFTPBinaryDownloads() throws Exception
108     {
109         // test with the smaller files
110         for (int i = 0; i < 6; i++)
111         {
112             testDownload(TFTP.BINARY_MODE, files[i]);
113         }
114     }
115 
116     public void testASCIIDownloads() throws Exception
117     {
118         // test with the smaller files
119         for (int i = 0; i < 6; i++)
120         {
121             try {
122                 testDownload(TFTP.ASCII_MODE, files[i]);
123             } catch (IOException e) {
124                 fail("Entry "+i+" Error "+e.toString());
125             }
126 
127         }
128     }
129 
130     public void testTFTPBinaryUploads() throws Exception
131     {
132         // test with the smaller files
133         for (int i = 0; i < 6; i++)
134         {
135             testUpload(TFTP.BINARY_MODE, files[i]);
136         }
137     }
138 
139     public void testASCIIUploads() throws Exception
140     {
141         // test with the smaller files
142         for (int i = 0; i < 6; i++)
143         {
144             testUpload(TFTP.ASCII_MODE, files[i]);
145         }
146     }
147 
148     public void testHugeUploads() throws Exception
149     {
150         for (int i = 5; i < files.length; i++)
151         {
152             testUpload(TFTP.BINARY_MODE, files[i]);
153         }
154     }
155 
156     public void testHugeDownloads() throws Exception
157     {
158         // test with the smaller files
159         for (int i = 5; i < files.length; i++)
160         {
161             testDownload(TFTP.BINARY_MODE, files[i]);
162         }
163     }
164 
165     private void testDownload(int mode, File file) throws IOException
166     {
167         // Create our TFTP instance to handle the file transfer.
168         TFTPClient tftp = new TFTPClient();
169         tftp.open();
170         tftp.setSoTimeout(2000);
171 
172         File out = new File(serverDirectory, filePrefix + "download");
173 
174         // cleanup old failed runs
175         out.delete();
176         assertTrue("Couldn't clear output location", !out.exists());
177 
178         FileOutputStream output = new FileOutputStream(out);
179 
180         tftp.receiveFile(file.getName(), mode, output, "localhost", 6900);
181         output.close();
182 
183         assertTrue("file not created", out.exists());
184         assertTrue("files not identical on file " + file, filesIdentical(out, file));
185 
186         // delete the downloaded file
187         out.delete();
188     }
189 
190     private void testUpload(int mode, File file) throws Exception
191     {
192         // Create our TFTP instance to handle the file transfer.
193         TFTPClient tftp = new TFTPClient();
194         tftp.open();
195         tftp.setSoTimeout(2000);
196 
197         File in = new File(serverDirectory, filePrefix + "upload");
198         // cleanup old failed runs
199         in.delete();
200         assertTrue("Couldn't clear output location", !in.exists());
201 
202         FileInputStream fis = new FileInputStream(file);
203         tftp.sendFile(in.getName(), mode, fis, "localhost", 6900);
204         fis.close();
205 
206         // need to give the server a bit of time to receive our last packet, and
207         // close out its file buffers, etc.
208         Thread.sleep(100);
209         assertTrue("file not created", in.exists());
210         assertTrue("files not identical on file " + file, filesIdentical(file, in));
211 
212         in.delete();
213     }
214 
215     private boolean filesIdentical(File a, File b) throws IOException
216     {
217         if (!a.exists() || !b.exists())
218         {
219             return false;
220         }
221 
222         if (a.length() != b.length())
223         {
224             return false;
225         }
226 
227         InputStream fisA = new BufferedInputStream(new FileInputStream(a));
228         InputStream fisB = new BufferedInputStream(new FileInputStream(b));
229 
230         int aBit = fisA.read();
231         int bBit = fisB.read();
232 
233         while (aBit != -1)
234         {
235             if (aBit != bBit)
236             {
237                 fisA.close();
238                 fisB.close();
239                 return false;
240             }
241             aBit = fisA.read();
242             bBit = fisB.read();
243         }
244 
245         fisA.close();
246         fisB.close();
247         return true;
248     }
249 }