2
0

test_swift_smoke.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. # test_smoke.py -- Functional tests for the Swift backend.
  2. # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
  3. #
  4. # Author: Fabien Boucher <fabien.boucher@enovance.com>
  5. #
  6. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  7. # General Public License as public by the Free Software Foundation; version 2.0
  8. # or (at your option) any later version. You can redistribute it and/or
  9. # modify it under the terms of either of these two licenses.
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #
  17. # You should have received a copy of the licenses; if not, see
  18. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  19. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  20. # License, Version 2.0.
  21. #
  22. """Start functional tests
  23. A Swift installation must be available before
  24. starting those tests. The account and authentication method used
  25. during this functional tests must be changed in the configuration file
  26. passed as environment variable.
  27. The container used to create a fake repository is defined
  28. in cls.fakerepo and will be deleted after the tests.
  29. DULWICH_SWIFT_CFG=/tmp/conf.cfg PYTHONPATH=. python -m unittest \
  30. dulwich.tests_swift.test_smoke
  31. """
  32. import os
  33. import unittest
  34. import tempfile
  35. import shutil
  36. import gevent
  37. from gevent import monkey
  38. monkey.patch_all()
  39. from dulwich import server
  40. from dulwich import repo
  41. from dulwich import index
  42. from dulwich import client
  43. from dulwich import objects
  44. from dulwich.contrib import swift
  45. class DulwichServer():
  46. """Start the TCPGitServer with Swift backend
  47. """
  48. def __init__(self, backend, port):
  49. self.port = port
  50. self.backend = backend
  51. def run(self):
  52. self.server = server.TCPGitServer(self.backend,
  53. 'localhost',
  54. port=self.port)
  55. self.job = gevent.spawn(self.server.serve_forever)
  56. def stop(self):
  57. self.server.shutdown()
  58. gevent.joinall((self.job,))
  59. class SwiftSystemBackend(server.Backend):
  60. def open_repository(self, path):
  61. return swift.SwiftRepo(path, conf=swift.load_conf())
  62. class SwiftRepoSmokeTest(unittest.TestCase):
  63. @classmethod
  64. def setUpClass(cls):
  65. cls.backend = SwiftSystemBackend()
  66. cls.port = 9148
  67. cls.server_address = 'localhost'
  68. cls.fakerepo = 'fakerepo'
  69. cls.th_server = DulwichServer(cls.backend, cls.port)
  70. cls.th_server.run()
  71. cls.conf = swift.load_conf()
  72. @classmethod
  73. def tearDownClass(cls):
  74. cls.th_server.stop()
  75. def setUp(self):
  76. self.scon = swift.SwiftConnector(self.fakerepo, self.conf)
  77. if self.scon.test_root_exists():
  78. try:
  79. self.scon.del_root()
  80. except swift.SwiftException:
  81. pass
  82. self.temp_d = tempfile.mkdtemp()
  83. if os.path.isdir(self.temp_d):
  84. shutil.rmtree(self.temp_d)
  85. def tearDown(self):
  86. if self.scon.test_root_exists():
  87. try:
  88. self.scon.del_root()
  89. except swift.SwiftException:
  90. pass
  91. if os.path.isdir(self.temp_d):
  92. shutil.rmtree(self.temp_d)
  93. def test_init_bare(self):
  94. swift.SwiftRepo.init_bare(self.scon, self.conf)
  95. self.assertTrue(self.scon.test_root_exists())
  96. obj = self.scon.get_container_objects()
  97. filtered = [o for o in obj if o['name'] == 'info/refs'
  98. or o['name'] == 'objects/pack']
  99. self.assertEqual(len(filtered), 2)
  100. def test_clone_bare(self):
  101. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  102. swift.SwiftRepo.init_bare(self.scon, self.conf)
  103. tcp_client = client.TCPGitClient(self.server_address,
  104. port=self.port)
  105. remote_refs = tcp_client.fetch(self.fakerepo, local_repo)
  106. # The remote repo is empty (no refs retreived)
  107. self.assertEqual(remote_refs, None)
  108. def test_push_commit(self):
  109. def determine_wants(*args):
  110. return {"refs/heads/master": local_repo.refs["HEAD"]}
  111. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  112. # Nothing in the staging area
  113. local_repo.do_commit('Test commit', 'fbo@localhost')
  114. sha = local_repo.refs.read_loose_ref('refs/heads/master')
  115. swift.SwiftRepo.init_bare(self.scon, self.conf)
  116. tcp_client = client.TCPGitClient(self.server_address,
  117. port=self.port)
  118. tcp_client.send_pack(self.fakerepo,
  119. determine_wants,
  120. local_repo.object_store.generate_pack_contents)
  121. swift_repo = swift.SwiftRepo("fakerepo", self.conf)
  122. remote_sha = swift_repo.refs.read_loose_ref('refs/heads/master')
  123. self.assertEqual(sha, remote_sha)
  124. def test_push_branch(self):
  125. def determine_wants(*args):
  126. return {"refs/heads/mybranch":
  127. local_repo.refs["refs/heads/mybranch"]}
  128. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  129. # Nothing in the staging area
  130. local_repo.do_commit('Test commit', 'fbo@localhost',
  131. ref='refs/heads/mybranch')
  132. sha = local_repo.refs.read_loose_ref('refs/heads/mybranch')
  133. swift.SwiftRepo.init_bare(self.scon, self.conf)
  134. tcp_client = client.TCPGitClient(self.server_address,
  135. port=self.port)
  136. tcp_client.send_pack("/fakerepo",
  137. determine_wants,
  138. local_repo.object_store.generate_pack_contents)
  139. swift_repo = swift.SwiftRepo(self.fakerepo, self.conf)
  140. remote_sha = swift_repo.refs.read_loose_ref('refs/heads/mybranch')
  141. self.assertEqual(sha, remote_sha)
  142. def test_push_multiple_branch(self):
  143. def determine_wants(*args):
  144. return {"refs/heads/mybranch":
  145. local_repo.refs["refs/heads/mybranch"],
  146. "refs/heads/master":
  147. local_repo.refs["refs/heads/master"],
  148. "refs/heads/pullr-108":
  149. local_repo.refs["refs/heads/pullr-108"]}
  150. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  151. # Nothing in the staging area
  152. local_shas = {}
  153. remote_shas = {}
  154. for branch in ('master', 'mybranch', 'pullr-108'):
  155. local_shas[branch] = local_repo.do_commit(
  156. 'Test commit %s' % branch, 'fbo@localhost',
  157. ref='refs/heads/%s' % branch)
  158. swift.SwiftRepo.init_bare(self.scon, self.conf)
  159. tcp_client = client.TCPGitClient(self.server_address,
  160. port=self.port)
  161. tcp_client.send_pack(self.fakerepo,
  162. determine_wants,
  163. local_repo.object_store.generate_pack_contents)
  164. swift_repo = swift.SwiftRepo("fakerepo", self.conf)
  165. for branch in ('master', 'mybranch', 'pullr-108'):
  166. remote_shas[branch] = swift_repo.refs.read_loose_ref(
  167. 'refs/heads/%s' % branch)
  168. self.assertDictEqual(local_shas, remote_shas)
  169. def test_push_data_branch(self):
  170. def determine_wants(*args):
  171. return {"refs/heads/master": local_repo.refs["HEAD"]}
  172. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  173. os.mkdir(os.path.join(self.temp_d, "dir"))
  174. files = ('testfile', 'testfile2', 'dir/testfile3')
  175. i = 0
  176. for f in files:
  177. file(os.path.join(self.temp_d, f), 'w').write("DATA %s" % i)
  178. i += 1
  179. local_repo.stage(files)
  180. local_repo.do_commit('Test commit', 'fbo@localhost',
  181. ref='refs/heads/master')
  182. swift.SwiftRepo.init_bare(self.scon, self.conf)
  183. tcp_client = client.TCPGitClient(self.server_address,
  184. port=self.port)
  185. tcp_client.send_pack(self.fakerepo,
  186. determine_wants,
  187. local_repo.object_store.generate_pack_contents)
  188. swift_repo = swift.SwiftRepo("fakerepo", self.conf)
  189. commit_sha = swift_repo.refs.read_loose_ref('refs/heads/master')
  190. otype, data = swift_repo.object_store.get_raw(commit_sha)
  191. commit = objects.ShaFile.from_raw_string(otype, data)
  192. otype, data = swift_repo.object_store.get_raw(commit._tree)
  193. tree = objects.ShaFile.from_raw_string(otype, data)
  194. objs = tree.items()
  195. objs_ = []
  196. for tree_entry in objs:
  197. objs_.append(swift_repo.object_store.get_raw(tree_entry.sha))
  198. # Blob
  199. self.assertEqual(objs_[1][1], 'DATA 0')
  200. self.assertEqual(objs_[2][1], 'DATA 1')
  201. # Tree
  202. self.assertEqual(objs_[0][0], 2)
  203. def test_clone_then_push_data(self):
  204. self.test_push_data_branch()
  205. shutil.rmtree(self.temp_d)
  206. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  207. tcp_client = client.TCPGitClient(self.server_address,
  208. port=self.port)
  209. remote_refs = tcp_client.fetch(self.fakerepo, local_repo)
  210. files = (os.path.join(self.temp_d, 'testfile'),
  211. os.path.join(self.temp_d, 'testfile2'))
  212. local_repo["HEAD"] = remote_refs["refs/heads/master"]
  213. indexfile = local_repo.index_path()
  214. tree = local_repo["HEAD"].tree
  215. index.build_index_from_tree(local_repo.path, indexfile,
  216. local_repo.object_store, tree)
  217. for f in files:
  218. self.assertEqual(os.path.isfile(f), True)
  219. def determine_wants(*args):
  220. return {"refs/heads/master": local_repo.refs["HEAD"]}
  221. os.mkdir(os.path.join(self.temp_d, "test"))
  222. files = ('testfile11', 'testfile22', 'test/testfile33')
  223. i = 0
  224. for f in files:
  225. file(os.path.join(self.temp_d, f), 'w').write("DATA %s" % i)
  226. i += 1
  227. local_repo.stage(files)
  228. local_repo.do_commit('Test commit', 'fbo@localhost',
  229. ref='refs/heads/master')
  230. tcp_client.send_pack("/fakerepo",
  231. determine_wants,
  232. local_repo.object_store.generate_pack_contents)
  233. def test_push_remove_branch(self):
  234. def determine_wants(*args):
  235. return {"refs/heads/pullr-108": objects.ZERO_SHA,
  236. "refs/heads/master":
  237. local_repo.refs['refs/heads/master'],
  238. "refs/heads/mybranch":
  239. local_repo.refs['refs/heads/mybranch'],
  240. }
  241. self.test_push_multiple_branch()
  242. local_repo = repo.Repo(self.temp_d)
  243. tcp_client = client.TCPGitClient(self.server_address,
  244. port=self.port)
  245. tcp_client.send_pack(self.fakerepo,
  246. determine_wants,
  247. local_repo.object_store.generate_pack_contents)
  248. swift_repo = swift.SwiftRepo("fakerepo", self.conf)
  249. self.assertNotIn('refs/heads/pullr-108', swift_repo.refs.allkeys())
  250. def test_push_annotated_tag(self):
  251. def determine_wants(*args):
  252. return {"refs/heads/master": local_repo.refs["HEAD"],
  253. "refs/tags/v1.0": local_repo.refs["refs/tags/v1.0"]}
  254. local_repo = repo.Repo.init(self.temp_d, mkdir=True)
  255. # Nothing in the staging area
  256. sha = local_repo.do_commit('Test commit', 'fbo@localhost')
  257. otype, data = local_repo.object_store.get_raw(sha)
  258. commit = objects.ShaFile.from_raw_string(otype, data)
  259. tag = objects.Tag()
  260. tag.tagger = "fbo@localhost"
  261. tag.message = "Annotated tag"
  262. tag.tag_timezone = objects.parse_timezone('-0200')[0]
  263. tag.tag_time = commit.author_time
  264. tag.object = (objects.Commit, commit.id)
  265. tag.name = "v0.1"
  266. local_repo.object_store.add_object(tag)
  267. local_repo.refs['refs/tags/v1.0'] = tag.id
  268. swift.SwiftRepo.init_bare(self.scon, self.conf)
  269. tcp_client = client.TCPGitClient(self.server_address,
  270. port=self.port)
  271. tcp_client.send_pack(self.fakerepo,
  272. determine_wants,
  273. local_repo.object_store.generate_pack_contents)
  274. swift_repo = swift.SwiftRepo(self.fakerepo, self.conf)
  275. tag_sha = swift_repo.refs.read_loose_ref('refs/tags/v1.0')
  276. otype, data = swift_repo.object_store.get_raw(tag_sha)
  277. rtag = objects.ShaFile.from_raw_string(otype, data)
  278. self.assertEqual(rtag.object[1], commit.id)
  279. self.assertEqual(rtag.id, tag.id)
  280. if __name__ == '__main__':
  281. unittest.main()