1# Software License Agreement (BSD License) 2# 3# Copyright (c) 2009, Willow Garage, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 10# * Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# * Redistributions in binary form must reproduce the above 13# copyright notice, this list of conditions and the following 14# disclaimer in the documentation and/or other materials provided 15# with the distribution. 16# * Neither the name of Willow Garage, Inc. nor the names of its 17# contributors may be used to endorse or promote products derived 18# from this software without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31# POSSIBILITY OF SUCH DAMAGE. 32 33from __future__ import unicode_literals 34 35import os 36import sys 37from test.io_wrapper import StringIO 38import subprocess 39import re 40 41import wstool 42import wstool.helpers 43import wstool.wstool_cli 44from wstool.wstool_cli import WstoolCLI 45from wstool.wstool_cli import wstool_main 46 47import test.scm_test_base 48from test.scm_test_base import AbstractSCMTest, _add_to_file, _nth_line_split 49 50 51def create_svn_repo(test_root_path, remote_path, filler_path, svn_uri): 52 # create a "remote" repo 53 subprocess.check_call(["svnadmin", "create", remote_path], cwd=test_root_path) 54 subprocess.check_call(["svn", "checkout", svn_uri, filler_path], cwd=test_root_path) 55 subprocess.check_call(["touch", "fixed.txt"], cwd=filler_path) 56 subprocess.check_call(["touch", "modified.txt"], cwd=filler_path) 57 subprocess.check_call(["touch", "modified-fs.txt"], cwd=filler_path) 58 subprocess.check_call(["touch", "deleted.txt"], cwd=filler_path) 59 subprocess.check_call(["touch", "deleted-fs.txt"], cwd=filler_path) 60 subprocess.check_call(["svn", "add", "fixed.txt"], cwd=filler_path) 61 subprocess.check_call(["svn", "add", "modified.txt"], cwd=filler_path) 62 subprocess.check_call(["svn", "add", "modified-fs.txt"], cwd=filler_path) 63 subprocess.check_call(["svn", "add", "deleted.txt"], cwd=filler_path) 64 subprocess.check_call(["svn", "add", "deleted-fs.txt"], cwd=filler_path) 65 subprocess.check_call(["svn", "commit", "-m", "modified"], cwd=filler_path) 66 67 68def modify_svn_repo(clone_path): 69 # make local modifications 70 subprocess.check_call(["rm", "deleted-fs.txt"], cwd=clone_path) 71 subprocess.check_call(["svn", "rm", "deleted.txt"], cwd=clone_path) 72 73 #_add_to_file(os.path.join(clone_path, "modified-fs.txt"), "foo\n") 74 _add_to_file(os.path.join(clone_path, "modified.txt"), "foo\n") 75 _add_to_file(os.path.join(clone_path, "added-fs.txt"), "tada\n") 76 _add_to_file(os.path.join(clone_path, "added.txt"), "flam\n") 77 subprocess.check_call(["svn", "add", "--no-auto-props", "added.txt"], cwd=clone_path) 78 79 80class WstoolDiffSvnTest(AbstractSCMTest): 81 82 @classmethod 83 def setUpClass(self): 84 AbstractSCMTest.setUpClass() 85 remote_path = os.path.join(self.test_root_path, "remote") 86 filler_path = os.path.join(self.test_root_path, "filler") 87 88 svn_uri = "file://localhost" + remote_path 89 90 create_svn_repo(self.test_root_path, remote_path, filler_path, svn_uri) 91 92 # wstool the remote repo and fake ros 93 _add_to_file(os.path.join(self.local_path, ".rosinstall"), "- other: {local-name: ../ros}\n- svn: {local-name: clone, uri: '" + svn_uri + "'}") 94 95 cmd = ["wstool", "update", "-t", "ws"] 96 os.chdir(self.test_root_path) 97 wstool_main(cmd) 98 clone_path = os.path.join(self.local_path, "clone") 99 100 modify_svn_repo(clone_path) 101 102 def check_diff_output(self, output): 103 # svn 1.9 added the "nonexistent" output, replace it with the 104 # revision 0 that the test results expect. 105 output_fixed = re.sub("\(nonexistent\)", "(revision 0)", output) 106 # svn output order varies between versions 107 expected = ["""\ 108Index: clone/added.txt 109=================================================================== 110--- clone/added.txt\t(revision 0) 111+++ clone/added.txt\t""", 112"""@@ -0,0 +1 @@ 113+flam""", 114 """\ 115Index: clone/modified.txt 116=================================================================== 117--- clone/modified.txt\t(revision 1) 118+++ clone/modified.txt\t(working copy) 119@@ -0,0 +1 @@ 120+foo"""] 121 for snippet in expected: 122 for line in snippet.splitlines(): 123 # assertIn is not supported in Python2.6 124 self.assertTrue(line in output_fixed, output) 125 126 def test_wstool_diff_svn_outside(self): 127 """Test diff output for svn when run outside workspace""" 128 129 cmd = ["wstool", "diff", "-t", "ws"] 130 os.chdir(self.test_root_path) 131 sys.stdout = output = StringIO() 132 wstool_main(cmd) 133 sys.stdout = sys.__stdout__ 134 output = output.getvalue() 135 self.check_diff_output(output) 136 137 cli = WstoolCLI() 138 self.assertEqual(0, cli.cmd_diff(os.path.join(self.test_root_path, 'ws'), [])) 139 140 def test_wstool_diff_svn_inside(self): 141 """Test diff output for svn when run inside workspace""" 142 directory = self.test_root_path + "/ws" 143 144 cmd = ["wstool", "diff"] 145 os.chdir(directory) 146 sys.stdout = output = StringIO() 147 wstool_main(cmd) 148 output = output.getvalue() 149 sys.stdout = sys.__stdout__ 150 self.check_diff_output(output) 151 152 cli = WstoolCLI() 153 self.assertEqual(0, cli.cmd_status(directory, [])) 154 155 def test_wstool_status_svn_inside(self): 156 """Test status output for svn when run inside workspace""" 157 directory = self.test_root_path + "/ws" 158 159 cmd = ["wstool", "status"] 160 os.chdir(directory) 161 sys.stdout = output = StringIO() 162 wstool_main(cmd) 163 output = output.getvalue() 164 sys.stdout = sys.__stdout__ 165 166 self.assertStatusListEqual('A clone/added.txt\nD clone/deleted.txt\n! clone/deleted-fs.txt\nM clone/modified.txt\n', output) 167 168 cli = WstoolCLI() 169 self.assertEqual(0, cli.cmd_diff(directory, [])) 170 171 def test_wstool_status_svn_outside(self): 172 """Test status output for svn when run outside workspace""" 173 174 cmd = ["wstool", "status", "-t", "ws"] 175 os.chdir(self.test_root_path) 176 sys.stdout = output = StringIO() 177 wstool_main(cmd) 178 sys.stdout = sys.__stdout__ 179 output = output.getvalue() 180 self.assertStatusListEqual('A clone/added.txt\nD clone/deleted.txt\n! clone/deleted-fs.txt\nM clone/modified.txt\n', output) 181 182 cli = WstoolCLI() 183 self.assertEqual(0, cli.cmd_status(os.path.join(self.test_root_path, 'ws'), [])) 184 185 def test_wstool_status_svn_untracked(self): 186 """Test status output for svn when run outside workspace""" 187 188 cmd = ["wstool", "status", "-t", "ws", "--untracked"] 189 os.chdir(self.test_root_path) 190 sys.stdout = output = StringIO() 191 wstool_main(cmd) 192 sys.stdout = sys.__stdout__ 193 output = output.getvalue() 194 self.assertStatusListEqual('? clone/added-fs.txt\nA clone/added.txt\nD clone/deleted.txt\n! clone/deleted-fs.txt\nM clone/modified.txt\n', output) 195 196 cli = WstoolCLI() 197 self.assertEqual(0, cli.cmd_status(os.path.join(self.test_root_path, 'ws'), ["--untracked"])) 198 199 def test_wstool_info_svn(self): 200 cmd = ["wstool", "info", "-t", "ws"] 201 os.chdir(self.test_root_path) 202 sys.stdout = output = StringIO() 203 wstool_main(cmd) 204 output = output.getvalue() 205 tokens = _nth_line_split(-2, output) 206 self.assertEqual(['clone', 'M', 'svn'], tokens[0:3]) 207 208 cli = WstoolCLI() 209 self.assertEqual(0, cli.cmd_info(os.path.join(self.test_root_path, 'ws'), [])) 210 211 212class WstoolInfoSvnTest(AbstractSCMTest): 213 214 def setUp(self): 215 AbstractSCMTest.setUp(self) 216 remote_path = os.path.join(self.test_root_path, "remote") 217 filler_path = os.path.join(self.test_root_path, "filler") 218 self.svn_uri = "file://localhost" + remote_path 219 220 # create a "remote" repo 221 subprocess.check_call(["svnadmin", "create", remote_path], cwd=self.test_root_path) 222 subprocess.check_call(["svn", "checkout", self.svn_uri, filler_path], cwd=self.test_root_path) 223 subprocess.check_call(["touch", "test.txt"], cwd=filler_path) 224 subprocess.check_call(["svn", "add", "test.txt"], cwd=filler_path) 225 subprocess.check_call(["svn", "commit", "-m", "modified"], cwd=filler_path) 226 subprocess.check_call(["touch", "test2.txt"], cwd=filler_path) 227 subprocess.check_call(["svn", "add", "test2.txt"], cwd=filler_path) 228 subprocess.check_call(["svn", "commit", "-m", "modified"], cwd=filler_path) 229 230 self.version_init = "-r1" 231 self.version_end = "-r2" 232 233 # wstool the remote repo and fake ros 234 _add_to_file(os.path.join(self.local_path, ".rosinstall"), "- other: {local-name: ../ros}\n- svn: {local-name: clone, uri: '" + self.svn_uri + "'}") 235 236 cmd = ["wstool", "update"] 237 os.chdir(self.local_path) 238 sys.stdout = output = StringIO() 239 wstool_main(cmd) 240 output = output.getvalue() 241 sys.stdout = sys.__stdout__ 242 243 def test_rosinstall_detailed_locapath_info(self): 244 cmd = ["wstool", "info", "-t", "ws"] 245 os.chdir(self.test_root_path) 246 sys.stdout = output = StringIO() 247 wstool_main(cmd) 248 output = output.getvalue() 249 tokens = _nth_line_split(-2, output) 250 self.assertEqual(['clone', 'svn', self.version_end, self.svn_uri], tokens) 251 252 clone_path = os.path.join(self.local_path, "clone") 253 # make local modifications check 254 subprocess.check_call(["touch", "test3.txt"], cwd=clone_path) 255 subprocess.check_call(["svn", "add", "test3.txt"], cwd=clone_path) 256 os.chdir(self.test_root_path) 257 sys.stdout = output = StringIO() 258 wstool_main(cmd) 259 output = output.getvalue() 260 tokens = _nth_line_split(-2, output) 261 self.assertEqual(['clone', 'M', 'svn', self.version_end, self.svn_uri], tokens) 262 263 subprocess.check_call(["rm", ".rosinstall"], cwd=self.local_path) 264 _add_to_file(os.path.join(self.local_path, ".rosinstall"), "- other: {local-name: ../ros}\n- svn: {local-name: clone, uri: '" + self.svn_uri + "', version: \"1\"}") 265 os.chdir(self.test_root_path) 266 sys.stdout = output = StringIO() 267 wstool_main(cmd) 268 output = output.getvalue() 269 tokens = _nth_line_split(-2, output) 270 self.assertEqual(['clone', 'MV', 'svn', '1', '(-)', self.version_end, "(%s)" % self.version_init, self.svn_uri], tokens) 271 272 subprocess.check_call(["rm", "-rf", "clone"], cwd=self.local_path) 273 os.chdir(self.test_root_path) 274 sys.stdout = output = StringIO() 275 wstool_main(cmd) 276 output = output.getvalue() 277 tokens = _nth_line_split(-2, output) 278 self.assertEqual(['clone', 'x', 'svn', '(-)', self.svn_uri], tokens) 279