View Javadoc
1   /*
2    * Copyright (C) 2011, GitHub Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  package org.eclipse.jgit.submodule;
44  
45  import static org.junit.Assert.assertEquals;
46  import static org.junit.Assert.assertNotNull;
47  import static org.junit.Assert.assertTrue;
48  
49  import java.io.File;
50  import java.io.IOException;
51  import java.util.Map;
52  import java.util.Map.Entry;
53  
54  import org.eclipse.jgit.api.Git;
55  import org.eclipse.jgit.api.SubmoduleStatusCommand;
56  import org.eclipse.jgit.api.errors.GitAPIException;
57  import org.eclipse.jgit.dircache.DirCache;
58  import org.eclipse.jgit.dircache.DirCacheEditor;
59  import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
60  import org.eclipse.jgit.dircache.DirCacheEntry;
61  import org.eclipse.jgit.junit.RepositoryTestCase;
62  import org.eclipse.jgit.lib.ConfigConstants;
63  import org.eclipse.jgit.lib.Constants;
64  import org.eclipse.jgit.lib.FileMode;
65  import org.eclipse.jgit.lib.ObjectId;
66  import org.eclipse.jgit.lib.RefUpdate;
67  import org.eclipse.jgit.lib.Repository;
68  import org.eclipse.jgit.lib.StoredConfig;
69  import org.eclipse.jgit.storage.file.FileBasedConfig;
70  import org.junit.Test;
71  
72  /**
73   * Unit tests of {@link SubmoduleStatusCommand}
74   */
75  public class SubmoduleStatusTest extends RepositoryTestCase {
76  
77  	@Test
78  	public void repositoryWithNoSubmodules() throws GitAPIException {
79  		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
80  		Map<String, SubmoduleStatus> statuses = command.call();
81  		assertNotNull(statuses);
82  		assertTrue(statuses.isEmpty());
83  	}
84  
85  	@Test
86  	public void repositoryWithMissingSubmodule() throws IOException,
87  			GitAPIException {
88  		final ObjectId id = ObjectId
89  				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
90  		final String path = "sub";
91  		DirCache cache = db.lockDirCache();
92  		DirCacheEditor editor = cache.editor();
93  		editor.add(new PathEdit(path) {
94  
95  			public void apply(DirCacheEntry ent) {
96  				ent.setFileMode(FileMode.GITLINK);
97  				ent.setObjectId(id);
98  			}
99  		});
100 		editor.commit();
101 
102 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
103 		Map<String, SubmoduleStatus> statuses = command.call();
104 		assertNotNull(statuses);
105 		assertEquals(1, statuses.size());
106 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
107 				.next();
108 		assertNotNull(module);
109 		assertEquals(path, module.getKey());
110 		SubmoduleStatus status = module.getValue();
111 		assertNotNull(status);
112 		assertEquals(path, status.getPath());
113 		assertEquals(id, status.getIndexId());
114 		assertEquals(SubmoduleStatusType.MISSING, status.getType());
115 	}
116 
117 	@Test
118 	public void repositoryWithUninitializedSubmodule() throws IOException,
119 			GitAPIException {
120 		final ObjectId id = ObjectId
121 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
122 		final String path = "sub";
123 		DirCache cache = db.lockDirCache();
124 		DirCacheEditor editor = cache.editor();
125 		editor.add(new PathEdit(path) {
126 
127 			public void apply(DirCacheEntry ent) {
128 				ent.setFileMode(FileMode.GITLINK);
129 				ent.setObjectId(id);
130 			}
131 		});
132 		editor.commit();
133 
134 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
135 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
136 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
137 				ConfigConstants.CONFIG_KEY_PATH, path);
138 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
139 				ConfigConstants.CONFIG_KEY_URL, "git://server/repo.git");
140 		modulesConfig.save();
141 
142 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
143 		Map<String, SubmoduleStatus> statuses = command.call();
144 		assertNotNull(statuses);
145 		assertEquals(1, statuses.size());
146 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
147 				.next();
148 		assertNotNull(module);
149 		assertEquals(path, module.getKey());
150 		SubmoduleStatus status = module.getValue();
151 		assertNotNull(status);
152 		assertEquals(path, status.getPath());
153 		assertEquals(id, status.getIndexId());
154 		assertEquals(SubmoduleStatusType.UNINITIALIZED, status.getType());
155 	}
156 
157 	@Test
158 	public void repositoryWithNoHeadInSubmodule() throws IOException,
159 			GitAPIException {
160 		final ObjectId id = ObjectId
161 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
162 		final String path = "sub";
163 		DirCache cache = db.lockDirCache();
164 		DirCacheEditor editor = cache.editor();
165 		editor.add(new PathEdit(path) {
166 
167 			public void apply(DirCacheEntry ent) {
168 				ent.setFileMode(FileMode.GITLINK);
169 				ent.setObjectId(id);
170 			}
171 		});
172 		editor.commit();
173 
174 		String url = "git://server/repo.git";
175 		StoredConfig config = db.getConfig();
176 		config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
177 				ConfigConstants.CONFIG_KEY_URL, url);
178 		config.save();
179 
180 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
181 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
182 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
183 				ConfigConstants.CONFIG_KEY_PATH, path);
184 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
185 				ConfigConstants.CONFIG_KEY_URL, url);
186 		modulesConfig.save();
187 
188 		Repository subRepo = Git.init().setBare(false)
189 				.setDirectory(new File(db.getWorkTree(), path)).call()
190 				.getRepository();
191 		assertNotNull(subRepo);
192 
193 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
194 		Map<String, SubmoduleStatus> statuses = command.call();
195 		assertNotNull(statuses);
196 		assertEquals(1, statuses.size());
197 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
198 				.next();
199 		assertNotNull(module);
200 		assertEquals(path, module.getKey());
201 		SubmoduleStatus status = module.getValue();
202 		assertNotNull(status);
203 		assertEquals(path, status.getPath());
204 		assertEquals(id, status.getIndexId());
205 		assertEquals(SubmoduleStatusType.UNINITIALIZED, status.getType());
206 	}
207 
208 	@Test
209 	public void repositoryWithNoSubmoduleRepository() throws IOException,
210 			GitAPIException {
211 		final ObjectId id = ObjectId
212 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
213 		final String path = "sub";
214 		DirCache cache = db.lockDirCache();
215 		DirCacheEditor editor = cache.editor();
216 		editor.add(new PathEdit(path) {
217 
218 			public void apply(DirCacheEntry ent) {
219 				ent.setFileMode(FileMode.GITLINK);
220 				ent.setObjectId(id);
221 			}
222 		});
223 		editor.commit();
224 
225 		String url = "git://server/repo.git";
226 		StoredConfig config = db.getConfig();
227 		config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
228 				ConfigConstants.CONFIG_KEY_URL, url);
229 		config.save();
230 
231 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
232 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
233 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
234 				ConfigConstants.CONFIG_KEY_PATH, path);
235 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
236 				ConfigConstants.CONFIG_KEY_URL, url);
237 		modulesConfig.save();
238 
239 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
240 		Map<String, SubmoduleStatus> statuses = command.call();
241 		assertNotNull(statuses);
242 		assertEquals(1, statuses.size());
243 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
244 				.next();
245 		assertNotNull(module);
246 		assertEquals(path, module.getKey());
247 		SubmoduleStatus status = module.getValue();
248 		assertNotNull(status);
249 		assertEquals(path, status.getPath());
250 		assertEquals(id, status.getIndexId());
251 		assertEquals(SubmoduleStatusType.UNINITIALIZED, status.getType());
252 	}
253 
254 	@Test
255 	public void repositoryWithInitializedSubmodule() throws IOException,
256 			GitAPIException {
257 		final ObjectId id = ObjectId
258 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
259 		final String path = "sub";
260 		DirCache cache = db.lockDirCache();
261 		DirCacheEditor editor = cache.editor();
262 		editor.add(new PathEdit(path) {
263 
264 			public void apply(DirCacheEntry ent) {
265 				ent.setFileMode(FileMode.GITLINK);
266 				ent.setObjectId(id);
267 			}
268 		});
269 		editor.commit();
270 
271 		String url = "git://server/repo.git";
272 		StoredConfig config = db.getConfig();
273 		config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
274 				ConfigConstants.CONFIG_KEY_URL, url);
275 		config.save();
276 
277 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
278 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
279 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
280 				ConfigConstants.CONFIG_KEY_PATH, path);
281 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
282 				ConfigConstants.CONFIG_KEY_URL, url);
283 		modulesConfig.save();
284 
285 		Repository subRepo = Git.init().setBare(false)
286 				.setDirectory(new File(db.getWorkTree(), path)).call()
287 				.getRepository();
288 		assertNotNull(subRepo);
289 
290 		RefUpdate update = subRepo.updateRef(Constants.HEAD, true);
291 		update.setNewObjectId(id);
292 		update.forceUpdate();
293 
294 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
295 		Map<String, SubmoduleStatus> statuses = command.call();
296 		assertNotNull(statuses);
297 		assertEquals(1, statuses.size());
298 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
299 				.next();
300 		assertNotNull(module);
301 		assertEquals(path, module.getKey());
302 		SubmoduleStatus status = module.getValue();
303 		assertNotNull(status);
304 		assertEquals(path, status.getPath());
305 		assertEquals(id, status.getIndexId());
306 		assertEquals(SubmoduleStatusType.INITIALIZED, status.getType());
307 	}
308 
309 	@Test
310 	public void repositoryWithDifferentRevCheckedOutSubmodule()
311 			throws IOException, GitAPIException {
312 		final ObjectId id = ObjectId
313 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
314 		final String path = "sub";
315 		DirCache cache = db.lockDirCache();
316 		DirCacheEditor editor = cache.editor();
317 		editor.add(new PathEdit(path) {
318 
319 			public void apply(DirCacheEntry ent) {
320 				ent.setFileMode(FileMode.GITLINK);
321 				ent.setObjectId(id);
322 			}
323 		});
324 		editor.commit();
325 
326 		String url = "git://server/repo.git";
327 		StoredConfig config = db.getConfig();
328 		config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
329 				ConfigConstants.CONFIG_KEY_URL, url);
330 		config.save();
331 
332 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
333 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
334 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
335 				ConfigConstants.CONFIG_KEY_PATH, path);
336 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
337 				ConfigConstants.CONFIG_KEY_URL, url);
338 		modulesConfig.save();
339 
340 		Repository subRepo = Git.init().setBare(false)
341 				.setDirectory(new File(db.getWorkTree(), path)).call()
342 				.getRepository();
343 		assertNotNull(subRepo);
344 
345 		RefUpdate update = subRepo.updateRef(Constants.HEAD, true);
346 		update.setNewObjectId(ObjectId
347 				.fromString("aaaa0000aaaa0000aaaa0000aaaa0000aaaa0000"));
348 		update.forceUpdate();
349 
350 		SubmoduleStatusCommand command = new SubmoduleStatusCommand(db);
351 		Map<String, SubmoduleStatus> statuses = command.call();
352 		assertNotNull(statuses);
353 		assertEquals(1, statuses.size());
354 		Entry<String, SubmoduleStatus> module = statuses.entrySet().iterator()
355 				.next();
356 		assertNotNull(module);
357 		assertEquals(path, module.getKey());
358 		SubmoduleStatus status = module.getValue();
359 		assertNotNull(status);
360 		assertEquals(path, status.getPath());
361 		assertEquals(id, status.getIndexId());
362 		assertEquals(update.getNewObjectId(), status.getHeadId());
363 		assertEquals(SubmoduleStatusType.REV_CHECKED_OUT, status.getType());
364 	}
365 }