1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.transport;
12
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.fail;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.eclipse.jgit.errors.TransportException;
22 import org.eclipse.jgit.internal.JGitText;
23 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
24 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
25 import org.eclipse.jgit.junit.TestRepository;
26 import org.eclipse.jgit.lib.NullProgressMonitor;
27 import org.eclipse.jgit.lib.ObjectId;
28 import org.eclipse.jgit.lib.Repository;
29 import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
30 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
31 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35
36 public class AtomicPushTest {
37 private URIish uri;
38 private TestProtocol<Object> testProtocol;
39 private Object ctx = new Object();
40 private InMemoryRepository server;
41 private InMemoryRepository client;
42 private ObjectId commit1;
43 private ObjectId commit2;
44
45 @Before
46 public void setUp() throws Exception {
47 server = newRepo("server");
48 client = newRepo("client");
49 testProtocol = new TestProtocol<>(
50 null,
51 new ReceivePackFactory<Object>() {
52 @Override
53 public ReceivePack create(Object req, Repository db)
54 throws ServiceNotEnabledException,
55 ServiceNotAuthorizedException {
56 return new ReceivePack(db);
57 }
58 });
59 uri = testProtocol.register(ctx, server);
60
61 try (TestRepository<?> clientRepo = new TestRepository<>(client)) {
62 commit1 = clientRepo.commit().noFiles().message("test commit 1")
63 .create();
64 commit2 = clientRepo.commit().noFiles().message("test commit 2")
65 .create();
66 }
67 }
68
69 @After
70 public void tearDown() {
71 Transport.unregister(testProtocol);
72 }
73
74 private static InMemoryRepository newRepo(String name) {
75 return new InMemoryRepository(new DfsRepositoryDescription(name));
76 }
77
78 @Test
79 public void pushNonAtomic() throws Exception {
80 PushResult r;
81 server.setPerformsAtomicTransactions(false);
82 try (Transport tn = testProtocol.open(uri, client, "server")) {
83 tn.setPushAtomic(false);
84 r = tn.push(NullProgressMonitor.INSTANCE, commands());
85 }
86
87 RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
88 RemoteRefUpdate two = r.getRemoteUpdate("refs/heads/two");
89 assertSame(RemoteRefUpdate.Status.OK, one.getStatus());
90 assertSame(
91 RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
92 two.getStatus());
93 }
94
95 @Test
96 public void pushAtomicClientGivesUpEarly() throws Exception {
97 PushResult r;
98 try (Transport tn = testProtocol.open(uri, client, "server")) {
99 tn.setPushAtomic(true);
100 r = tn.push(NullProgressMonitor.INSTANCE, commands());
101 }
102
103 RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
104 RemoteRefUpdate two = r.getRemoteUpdate("refs/heads/two");
105 assertSame(
106 RemoteRefUpdate.Status.REJECTED_OTHER_REASON,
107 one.getStatus());
108 assertSame(
109 RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
110 two.getStatus());
111 assertEquals(JGitText.get().transactionAborted, one.getMessage());
112 }
113
114 @Test
115 public void pushAtomicDisabled() throws Exception {
116 List<RemoteRefUpdate> cmds = new ArrayList<>();
117 cmds.add(new RemoteRefUpdate(
118 null, null,
119 commit1, "refs/heads/one",
120 true ,
121 null ,
122 ObjectId.zeroId()));
123 cmds.add(new RemoteRefUpdate(
124 null, null,
125 commit2, "refs/heads/two",
126 true ,
127 null ,
128 ObjectId.zeroId()));
129
130 server.setPerformsAtomicTransactions(false);
131 try (Transport tn = testProtocol.open(uri, client, "server")) {
132 tn.setPushAtomic(true);
133 tn.push(NullProgressMonitor.INSTANCE, cmds);
134 fail("did not throw TransportException");
135 } catch (TransportException e) {
136 assertEquals(
137 uri + ": " + JGitText.get().atomicPushNotSupported,
138 e.getMessage());
139 }
140 }
141
142 private List<RemoteRefUpdate> commands() throws IOException {
143 List<RemoteRefUpdate> cmds = new ArrayList<>();
144 cmds.add(new RemoteRefUpdate(
145 null, null,
146 commit1, "refs/heads/one",
147 true ,
148 null ,
149 ObjectId.zeroId()));
150 cmds.add(new RemoteRefUpdate(
151 null, null,
152 commit2, "refs/heads/two",
153 true ,
154 null ,
155 commit1));
156 return cmds;
157 }
158 }