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.FileWriter;
30 import java.io.FileInputStream;
31 import java.io.OutputStream;
32 import java.io.InputStream;
33 import java.io.IOException;
34 import java.net.URI;
35 import java.util.Map;
36 
37 /**
38  * This class is used for testing the ISVNRepos interface
39  *
40  * More methodes for testing are still needed
41  */
42 public class SVNReposTests extends SVNTests
43 {
44     /**
45      * Base name of all our tests.
46      */
47     public final static String testName = "repos_test";
48 
SVNReposTests()49     public SVNReposTests()
50     {
51         init();
52     }
53 
SVNReposTests(String name)54     public SVNReposTests(String name)
55     {
56         super(name);
57         init();
58     }
59 
60     /**
61      * Initialize the testBaseName and the testCounter, if this is the
62      * first test of this class.
63      */
init()64     private void init()
65     {
66         if (!testName.equals(testBaseName))
67         {
68             testCounter = 0;
69             testBaseName = testName;
70         }
71     }
72 
73     /**
74      * Test the basic ISVNRepos.create functionality
75      * @throws SubversionException
76      */
testCreate()77     public void testCreate()
78         throws SubversionException, IOException
79     {
80         OneTest thisTest = new OneTest(false);
81         assertTrue("repository exists", thisTest.getRepository().exists());
82     }
83 
testSetRevProp()84     public void testSetRevProp()
85         throws SubversionException, IOException
86     {
87         OneTest thisTest = new OneTest(false);
88         final String MSG = "Initial repository creation";
89         admin.setRevProp(thisTest.getRepository(), Revision.getInstance(0),
90                          "svn:log", MSG, false, false);
91         Map<String, byte[]> pdata = client.revProperties(
92                            makeReposUrl(thisTest.getRepository()).toString(),
93                            Revision.getInstance(0));
94         assertNotNull("expect non null rev props");
95         String logMessage = new String(pdata.get("svn:log"));
96         assertEquals("expect rev prop change to take effect", MSG, logMessage);
97     }
98 
99     /* This test only tests the call down to the C++ layer. */
testVerify()100     public void testVerify()
101         throws SubversionException, IOException
102     {
103         OneTest thisTest = new OneTest(false, true);
104         admin.verify(thisTest.getRepository(), Revision.getInstance(0),
105                      Revision.HEAD, null);
106     }
107 
108     private class VerifyCallback implements ReposVerifyCallback
109     {
110         public int mderr = 0;
111         public int reverr = 0;
112         public boolean keepGoing = false;
113 
onVerifyError(long revision, ClientException verifyError)114         public void onVerifyError(long revision, ClientException verifyError)
115             throws ClientException
116         {
117             if (revision == Revision.SVN_INVALID_REVNUM) {
118                 ++mderr;
119             }
120             else {
121                 ++reverr;
122             }
123             if (keepGoing) {
124                 return;
125             }
126             else {
127                 throw verifyError;
128             }
129         }
130 
131     }
132 
tryToBreakRepo(OneTest test)133     private boolean tryToBreakRepo(OneTest test) throws IOException
134     {
135         File repo = test.getRepository();
136 
137         // Check for a sharded repo first
138         File rev1 = new File(repo, "db/revs/0/1");
139         if (!rev1.exists() || !rev1.setWritable(true))
140         {
141             // Try non-sharded
142             rev1 = new File(repo, "db/revs/1");
143         }
144         if (!rev1.exists() || !rev1.setWritable(true))
145             return false;
146 
147         FileWriter fd = new FileWriter(rev1);
148         fd.write("inserting junk to corrupt the rev");
149         fd.close();
150         return true;
151     }
152 
testVerifyBrokenRepo()153     public void testVerifyBrokenRepo() throws Throwable
154     {
155         OneTest thisTest = new OneTest(false, true);
156 
157         if (!tryToBreakRepo(thisTest)) {
158             // We don't support the repos format
159             System.err.print("Cannot break repository for verify test.");
160             return;
161         }
162 
163         VerifyCallback cb = new VerifyCallback();
164         cb.keepGoing = false;
165 
166         try {
167             admin.verify(thisTest.getRepository(),
168                          Revision.getInstance(0),
169                          Revision.HEAD,
170                          false, false, null, cb);
171         }
172         catch(ClientException ex) {
173             assertEquals(cb.mderr, 1);
174             assertEquals(cb.reverr, 0);
175             return;
176         }
177 
178         assert("Verify did not catch repository corruption." == "");
179     }
180 
testVerifyBrokenRepo_KeepGoing()181     public void testVerifyBrokenRepo_KeepGoing() throws Throwable
182     {
183         OneTest thisTest = new OneTest(false, true);
184 
185         if (!tryToBreakRepo(thisTest)) {
186             // We don't support the repos format
187             System.err.print("Cannot break repository for verify test.");
188             return;
189         }
190 
191         VerifyCallback cb = new VerifyCallback();
192         cb.keepGoing = true;
193 
194         admin.verify(thisTest.getRepository(),
195                      Revision.getInstance(0),
196                      Revision.HEAD,
197                      false, false, null, cb);
198 
199         assertEquals(cb.mderr, 1);
200         assertEquals(cb.reverr, 1);
201     }
202 
203     /* this test only tests the call down to the C++ layer. */
testUpgrade()204     public void testUpgrade()
205         throws SubversionException, IOException
206     {
207         OneTest thisTest = new OneTest(false);
208         admin.upgrade(thisTest.getRepository(), null);
209     }
210 
211     /* This test only tests the call down to the C++ layer. */
testPack()212     public void testPack()
213         throws SubversionException, IOException
214     {
215         OneTest thisTest = new OneTest(false);
216         admin.pack(thisTest.getRepository(), null);
217     }
218 
219     /* Check that the freeze() callback gets invoked. */
220     private class FreezeAction implements ReposFreezeAction
221     {
222         int invoked = 0;
invoke()223         public void invoke() { ++invoked; }
224     }
225 
testFreeze()226     public void testFreeze()
227         throws SubversionException, IOException
228     {
229         OneTest thisTest = new OneTest(false);
230         FreezeAction action = new FreezeAction();
231         admin.freeze(action, thisTest.getRepository());
232         assertEquals("expect freeze callback to be invoked once", 1, action.invoked);
233     }
234 
testLoadRepo()235     public void testLoadRepo()
236         throws SubversionException, IOException
237     {
238         /* Make sure ISVNRepos.load() works, with a repo dump file known
239          * to provoke bug 2979
240          */
241         // makes repos with nothing in it
242         OneTest thisTest = new OneTest(false,false);
243         // verify zero revisions in new repos
244         URI repoUrl = makeReposUrl(thisTest.getRepository());
245         final Info[] infoHolder = new Info[1];
246         InfoCallback mycallback = new InfoCallback()
247         {
248             public void singleInfo(Info info)
249             {
250                 infoHolder[0] = info;
251             }
252         };
253         client.info2(repoUrl.toString(), Revision.HEAD, Revision.HEAD,
254                 Depth.immediates, null, mycallback);
255         assertNotNull("expect info callback", infoHolder[0]);
256         assertEquals("expect zero revisions in new repository",
257                 0L, infoHolder[0].getLastChangedRev());
258 
259         // locate dump file in test environment
260         String testSrcdir = System.getProperty("test.srcdir",
261                 "subversion/bindings/javahl");
262         File dump = new File(testSrcdir, "tests/data/issue2979.dump");
263         InputStream input = new FileInputStream(dump);
264         admin.load(thisTest.getRepository(),
265                    input, true, true, false, false, null, null);
266         // should have two revs after the load
267         infoHolder[0] = null;
268         client.info2(repoUrl.toString(), Revision.HEAD, Revision.HEAD,
269                      Depth.immediates, null, mycallback);
270         assertEquals("expect two revisions after load()",
271                      2L, infoHolder[0].getLastChangedRev());
272         // verify that the repos is faithful rep. of the dump file,
273         // e.g., correct author
274         assertEquals("expect 'svn4ant' as author of r2",
275                      "svn4ant", infoHolder[0].getLastChangedAuthor());
276     }
277 }
278