1 /** 2 * @copyright 3 * ==================================================================== 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 * ==================================================================== 21 * @endcopyright 22 */ 23 package org.apache.subversion.javahl; 24 25 import org.apache.subversion.javahl.callback.*; 26 import org.apache.subversion.javahl.types.*; 27 28 import java.io.File; 29 import java.io.FileOutputStream; 30 import java.io.FileNotFoundException; 31 import java.io.FileReader; 32 import java.io.IOException; 33 import java.io.PrintWriter; 34 import java.io.ByteArrayOutputStream; 35 import java.io.UnsupportedEncodingException; 36 import java.nio.ByteBuffer; 37 import java.nio.channels.ReadableByteChannel; 38 import java.nio.channels.WritableByteChannel; 39 import java.text.ParseException; 40 import java.util.Collection; 41 import java.util.Arrays; 42 import java.util.ArrayList; 43 import java.util.Date; 44 import java.util.HashMap; 45 import java.util.HashSet; 46 import java.util.List; 47 import java.util.Set; 48 import java.util.Map; 49 import java.text.DateFormat; 50 import java.text.SimpleDateFormat; 51 52 53 /** 54 * Tests the basic functionality of javahl binding (inspired by the 55 * tests in subversion/tests/cmdline/basic_tests.py). 56 */ 57 public class ExceptionTests extends SVNTests 58 { 59 /** 60 * Base name of all our tests. 61 */ 62 public final static String testName = "exception_test"; 63 ExceptionTests()64 public ExceptionTests() 65 { 66 init(); 67 } 68 ExceptionTests(String name)69 public ExceptionTests(String name) 70 { 71 super(name); 72 init(); 73 } 74 75 /** 76 * Initialize the testBaseName and the testCounter, if this is the 77 * first test of this class. 78 */ init()79 private void init() 80 { 81 if (!testName.equals(testBaseName)) 82 { 83 testCounter = 0; 84 testBaseName = testName; 85 } 86 } 87 88 /** 89 * Specific exception class to verify if the marshalling of errors 90 * through Subversion is handled properly. 91 */ 92 final class TestException extends RuntimeException 93 { 94 private static final long serialVersionUID = 1L; 95 TestException(String message)96 public TestException(String message) 97 { 98 super(message); 99 } 100 TestException(String message, Throwable cause)101 public TestException(String message, Throwable cause) 102 { 103 super(message, cause); 104 } 105 } 106 testStatusCallback()107 public void testStatusCallback() throws Exception 108 { 109 // build the test setup 110 OneTest thisTest = new OneTest(); 111 112 final TestException theException = new TestException("The Exception"); 113 boolean handled = false; 114 // Test status of non-existent file 115 try 116 { 117 client.status(thisTest.getWorkingCopy() + "/A", Depth.immediates, 118 false, true, true, false, false, false, null, 119 new StatusCallback() 120 { 121 public void doStatus(String path, Status status) 122 { 123 throw new TestException("inner", theException); 124 } 125 }); 126 } 127 catch (ClientException e) 128 { 129 if (VerifyCause(e, theException)) 130 handled = true; 131 else 132 throw e; 133 } 134 assertTrue(handled); 135 } 136 testInfoCallback()137 public void testInfoCallback() throws Exception 138 { 139 // build the test setup 140 OneTest thisTest = new OneTest(); 141 142 final TestException theException = new TestException("The Exception"); 143 boolean handled = false; 144 // Test status of non-existent file 145 try 146 { 147 client.info(thisTest.getWorkingCopy() + "/A", null, null, Depth.immediates, 148 true, true, false, null, 149 new InfoCallback() 150 { 151 public void singleInfo(Info info) 152 { 153 throw new TestException("inner", theException); 154 } 155 }); 156 } 157 catch (ClientException e) 158 { 159 if (VerifyCause(e, theException)) 160 handled = true; 161 else 162 throw e; 163 } 164 assertTrue(handled); 165 } 166 testListCallback()167 public void testListCallback() throws Exception 168 { 169 // build the test setup 170 OneTest thisTest = new OneTest(); 171 172 final TestException theException = new TestException("The Exception"); 173 boolean handled = false; 174 // Test status of non-existent file 175 try 176 { 177 client.list(thisTest.getWorkingCopy() + "/A", null, null, Depth.immediates, 178 7, false, 179 new ListCallback() 180 { 181 public void doEntry(DirEntry dirent, Lock lock) 182 { 183 throw new TestException("inner", theException); 184 } 185 }); 186 } 187 catch (ClientException e) 188 { 189 if (VerifyCause(e, theException)) 190 handled = true; 191 else 192 throw e; 193 } 194 assertTrue(handled); 195 } 196 testBlameCallback()197 public void testBlameCallback() throws Exception 198 { 199 // build the test setup 200 OneTest thisTest = new OneTest(); 201 202 final TestException theException = new TestException("The Exception"); 203 boolean handled = false; 204 // Test status of non-existent file 205 try 206 { 207 client.blame(thisTest.getWorkingCopy() + "/iota", 208 Revision.getInstance(1), Revision.getInstance(1), 209 Revision.getInstance(1), false, false, null, null, 210 new BlameLineCallback() { 211 public void singleLine(long lineNum, long revision, 212 Map<String, byte[]> revProps, long mergedRevision, 213 Map<String, byte[]> mergedRevProps, 214 String mergedPath, boolean localChange, 215 byte[] line) 216 { 217 throw new TestException("inner", theException); 218 } 219 }); 220 } 221 catch (ClientException e) 222 { 223 if (VerifyCause(e, theException)) 224 handled = true; 225 else 226 throw e; 227 } 228 assertTrue(handled); 229 } 230 testLogMessageCallback()231 public void testLogMessageCallback() throws Exception 232 { 233 // build the test setup 234 OneTest thisTest = new OneTest(); 235 236 final TestException theException = new TestException("The Exception"); 237 boolean handled = false; 238 // Test status of non-existent file 239 try 240 { 241 List<RevisionRange> ranges = new ArrayList<RevisionRange>(1); 242 ranges.add(new RevisionRange(null, null)); 243 // Testing variant with allRevProps = false 244 client.logMessages(thisTest.getWorkingCopy() + "/iota", 245 Revision.getInstance(1), ranges, 246 false, false, false, 247 null, false, 2, 248 new LogMessageCallback() 249 { 250 public void singleMessage( 251 Set<ChangePath> changedPaths, 252 long revision, 253 Map<String, byte[]> revprops, 254 boolean hasChildren) 255 { 256 throw new TestException("inner", 257 theException); 258 } 259 }); 260 } 261 catch (ClientException e) 262 { 263 if (VerifyCause(e, theException)) 264 handled = true; 265 else 266 throw e; 267 } 268 assertTrue(handled); 269 } 270 testDiffSummaryReceiver()271 public void testDiffSummaryReceiver() throws Exception 272 { 273 // build the test setup 274 OneTest thisTest = new OneTest(); 275 276 final TestException theException = new TestException("The Exception"); 277 boolean handled = false; 278 // Test status of non-existent file 279 try 280 { 281 List<RevisionRange> ranges = new ArrayList<RevisionRange>(1); 282 ranges.add(new RevisionRange(null, null)); 283 client.diffSummarize(thisTest.getUrl() + "/A", 284 Revision.getInstance(1), 285 thisTest.getUrl() + "/A", 286 Revision.getInstance(0), 287 Depth.infinity, null, true, 288 new DiffSummaryCallback() 289 { 290 public void onSummary( 291 DiffSummary descriptor) 292 { 293 throw new TestException("inner", 294 theException); 295 } 296 }); 297 } 298 catch (ClientException e) 299 { 300 if (VerifyCause(e, theException)) 301 handled = true; 302 else 303 throw e; 304 } 305 assertTrue(handled); 306 } 307 testNotify()308 public void testNotify() throws Exception 309 { 310 // build the test setup 311 OneTest thisTest = new OneTest(); 312 313 final TestException theException = new TestException("The Exception"); 314 boolean handled = false; 315 // Test status of non-existent file 316 try 317 { 318 client.notification2(new ClientNotifyCallback() 319 { 320 public void onNotify(ClientNotifyInformation info) 321 { 322 throw new TestException("inner", 323 theException); 324 } 325 }); 326 327 client.remove(thisTest.getWCPathSet("/A"), false, false, 328 null, null, null); 329 } 330 catch (ClientException e) 331 { 332 if (VerifyCause(e, theException)) 333 handled = true; 334 else 335 throw e; 336 } 337 assertTrue(handled); 338 } 339 340 /** 341 * Verifies if a specific throwable instance is recorded in the exception chain 342 */ VerifyCause(Throwable caught, Throwable needle)343 private boolean VerifyCause(Throwable caught, Throwable needle) 344 { 345 if (caught == needle) 346 return true; 347 348 Throwable cause = caught.getCause(); 349 if (cause == null) 350 return false; 351 352 return VerifyCause(cause, needle); 353 } 354 } 355