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