Minor improvements for tramp-interrupt-process, documentation
[emacs.git] / test / lisp / net / tramp-tests.el
blob55f4b52ccdf2632fb34a1d9126cc1e154265d077
1 ;;; tramp-tests.el --- Tests of remote file access -*- lexical-binding:t -*-
3 ;; Copyright (C) 2013-2017 Free Software Foundation, Inc.
5 ;; Author: Michael Albinus <michael.albinus@gmx.de>
7 ;; This program is free software: you can redistribute it and/or
8 ;; modify it under the terms of the GNU General Public License as
9 ;; published by the Free Software Foundation, either version 3 of the
10 ;; License, or (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see `http://www.gnu.org/licenses/'.
20 ;;; Commentary:
22 ;; The tests require a recent ert.el from Emacs 24.4.
24 ;; Some of the tests require access to a remote host files. Since
25 ;; this could be problematic, a mock-up connection method "mock" is
26 ;; used. Emulating a remote connection, it simply calls "sh -i".
27 ;; Tramp's file name handlers still run, so this test is sufficient
28 ;; except for connection establishing.
30 ;; If you want to test a real Tramp connection, set
31 ;; $REMOTE_TEMPORARY_FILE_DIRECTORY to a suitable value in order to
32 ;; overwrite the default value. If you want to skip tests accessing a
33 ;; remote host, set this environment variable to "/dev/null" or
34 ;; whatever is appropriate on your system.
36 ;; A whole test run can be performed calling the command `tramp-test-all'.
38 ;;; Code:
40 (require 'dired)
41 (require 'ert)
42 (require 'seq)
43 (require 'tramp)
44 (require 'vc)
45 (require 'vc-bzr)
46 (require 'vc-git)
47 (require 'vc-hg)
49 (declare-function tramp-find-executable "tramp-sh")
50 (declare-function tramp-get-remote-path "tramp-sh")
51 (declare-function tramp-get-remote-stat "tramp-sh")
52 (declare-function tramp-get-remote-perl "tramp-sh")
53 (defvar auto-save-file-name-transforms)
54 (defvar tramp-copy-size-limit)
55 (defvar tramp-persistency-file-name)
56 (defvar tramp-remote-process-environment)
57 ;; Suppress nasty messages.
58 (fset 'shell-command-sentinel 'ignore)
60 ;; There is no default value on w32 systems, which could work out of the box.
61 (defconst tramp-test-temporary-file-directory
62 (cond
63 ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
64 ((eq system-type 'windows-nt) null-device)
65 (t (add-to-list
66 'tramp-methods
67 '("mock"
68 (tramp-login-program "sh")
69 (tramp-login-args (("-i")))
70 (tramp-remote-shell "/bin/sh")
71 (tramp-remote-shell-args ("-c"))
72 (tramp-connection-timeout 10)))
73 (add-to-list
74 'tramp-default-host-alist
75 `("\\`mock\\'" nil ,(system-name)))
76 ;; Emacs' Makefile sets $HOME to a nonexistent value. Needed in
77 ;; batch mode only, therefore.
78 (unless (and (null noninteractive) (file-directory-p "~/"))
79 (setenv "HOME" temporary-file-directory))
80 (format "/mock::%s" temporary-file-directory)))
81 "Temporary directory for Tramp tests.")
83 (setq password-cache-expiry nil
84 tramp-verbose 0
85 tramp-cache-read-persistent-data t ;; For auth-sources.
86 tramp-copy-size-limit nil
87 tramp-message-show-message nil
88 tramp-persistency-file-name nil)
90 ;; This should happen on hydra only.
91 (when (getenv "EMACS_HYDRA_CI")
92 (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
94 (defvar tramp--test-expensive-test
95 (null
96 (string-equal (getenv "SELECTOR") "(quote (not (tag :expensive-test)))"))
97 "Whether expensive tests are run.")
99 (defvar tramp--test-enabled-checked nil
100 "Cached result of `tramp--test-enabled'.
101 If the function did run, the value is a cons cell, the `cdr'
102 being the result.")
104 (defun tramp--test-enabled ()
105 "Whether remote file access is enabled."
106 (unless (consp tramp--test-enabled-checked)
107 (setq
108 tramp--test-enabled-checked
109 (cons
110 t (ignore-errors
111 (and
112 (file-remote-p tramp-test-temporary-file-directory)
113 (file-directory-p tramp-test-temporary-file-directory)
114 (file-writable-p tramp-test-temporary-file-directory))))))
116 (when (cdr tramp--test-enabled-checked)
117 ;; Cleanup connection.
118 (ignore-errors
119 (tramp-cleanup-connection
120 (tramp-dissect-file-name tramp-test-temporary-file-directory)
121 nil 'keep-password)))
123 ;; Return result.
124 (cdr tramp--test-enabled-checked))
126 (defun tramp--test-make-temp-name (&optional local quoted)
127 "Return a temporary file name for test.
128 If LOCAL is non-nil, a local file name is returned.
129 If QUOTED is non-nil, the local part of the file name is quoted.
130 The temporary file is not created."
131 (funcall
132 (if quoted 'tramp-compat-file-name-quote 'identity)
133 (expand-file-name
134 (make-temp-name "tramp-test")
135 (if local temporary-file-directory tramp-test-temporary-file-directory))))
137 ;; Don't print messages in nested `tramp--test-instrument-test-case' calls.
138 (defvar tramp--test-instrument-test-case-p nil
139 "Whether `tramp--test-instrument-test-case' run.
140 This shall used dynamically bound only.")
142 (defmacro tramp--test-instrument-test-case (verbose &rest body)
143 "Run BODY with `tramp-verbose' equal VERBOSE.
144 Print the the content of the Tramp debug buffer, if BODY does not
145 eval properly in `should' or `should-not'. `should-error' is not
146 handled properly. BODY shall not contain a timeout."
147 (declare (indent 1) (debug (natnump body)))
148 `(let ((tramp-verbose (max (or ,verbose 0) (or tramp-verbose 0)))
149 (tramp-message-show-message t)
150 (tramp-debug-on-error t)
151 (debug-ignored-errors
152 (cons "^make-symbolic-link not supported$" debug-ignored-errors))
153 inhibit-message)
154 (unwind-protect
155 (let ((tramp--test-instrument-test-case-p t)) ,@body)
156 ;; Unwind forms.
157 (when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 3))
158 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
159 (with-current-buffer (tramp-get-connection-buffer v)
160 (message "%s" (buffer-string)))
161 (with-current-buffer (tramp-get-debug-buffer v)
162 (message "%s" (buffer-string))))))))
164 (defsubst tramp--test-message (fmt-string &rest arguments)
165 "Emit a message into ERT *Messages*."
166 (tramp--test-instrument-test-case 0
167 (apply
168 'tramp-message
169 (tramp-dissect-file-name tramp-test-temporary-file-directory) 0
170 fmt-string arguments)))
172 (defsubst tramp--test-backtrace ()
173 "Dump a backtrace into ERT *Messages*."
174 (tramp--test-instrument-test-case 10
175 (tramp-backtrace
176 (tramp-dissect-file-name tramp-test-temporary-file-directory))))
178 (ert-deftest tramp-test00-availability ()
179 "Test availability of Tramp functions."
180 :expected-result (if (tramp--test-enabled) :passed :failed)
181 (tramp--test-message
182 "Remote directory: `%s'" tramp-test-temporary-file-directory)
183 (should (ignore-errors
184 (and
185 (file-remote-p tramp-test-temporary-file-directory)
186 (file-directory-p tramp-test-temporary-file-directory)
187 (file-writable-p tramp-test-temporary-file-directory)))))
189 (ert-deftest tramp-test01-file-name-syntax ()
190 "Check remote file name syntax."
191 ;; Simple cases.
192 (should (tramp-tramp-file-p "/method::"))
193 (should (tramp-tramp-file-p "/method:host:"))
194 (should (tramp-tramp-file-p "/method:user@:"))
195 (should (tramp-tramp-file-p "/method:user@host:"))
196 (should (tramp-tramp-file-p "/method:user@email@host:"))
198 ;; Using a port.
199 (should (tramp-tramp-file-p "/method:host#1234:"))
200 (should (tramp-tramp-file-p "/method:user@host#1234:"))
202 ;; Using an IPv4 address.
203 (should (tramp-tramp-file-p "/method:1.2.3.4:"))
204 (should (tramp-tramp-file-p "/method:user@1.2.3.4:"))
206 ;; Using an IPv6 address.
207 (should (tramp-tramp-file-p "/method:[::1]:"))
208 (should (tramp-tramp-file-p "/method:user@[::1]:"))
210 ;; Local file name part.
211 (should (tramp-tramp-file-p "/method:::"))
212 (should (tramp-tramp-file-p "/method::/:"))
213 (should (tramp-tramp-file-p "/method::/path/to/file"))
214 (should (tramp-tramp-file-p "/method::/:/path/to/file"))
215 (should (tramp-tramp-file-p "/method::file"))
216 (should (tramp-tramp-file-p "/method::/:file"))
218 ;; Multihop.
219 (should (tramp-tramp-file-p "/method1:|method2::"))
220 (should (tramp-tramp-file-p "/method1:host1|method2:host2:"))
221 (should (tramp-tramp-file-p "/method1:user1@host1|method2:user2@host2:"))
222 (should (tramp-tramp-file-p
223 "/method1:user1@host1|method2:user2@host2|method3:user3@host3:"))
225 ;; No strings.
226 (should-not (tramp-tramp-file-p nil))
227 (should-not (tramp-tramp-file-p 'symbol))
228 ;; Ange-ftp syntax.
229 (should-not (tramp-tramp-file-p "/host:"))
230 (should-not (tramp-tramp-file-p "/user@host:"))
231 (should-not (tramp-tramp-file-p "/1.2.3.4:"))
232 (should-not (tramp-tramp-file-p "/[]:"))
233 (should-not (tramp-tramp-file-p "/[::1]:"))
234 (should-not (tramp-tramp-file-p "/host:/:"))
235 (should-not (tramp-tramp-file-p "/host1|host2:"))
236 (should-not (tramp-tramp-file-p "/user1@host1|user2@host2:"))
237 ;; Quote with "/:" suppresses file name handlers.
238 (should-not (tramp-tramp-file-p "/::"))
239 (should-not (tramp-tramp-file-p "/:@:"))
240 (should-not (tramp-tramp-file-p "/:[]:"))
241 ;; Methods shall be at least two characters on MS Windows, except
242 ;; the default method.
243 (let ((system-type 'windows-nt))
244 (should-not (tramp-tramp-file-p "/c:/path/to/file"))
245 (should-not (tramp-tramp-file-p "/c::/path/to/file"))
246 (should (tramp-tramp-file-p "/-::/path/to/file")))
247 (let ((system-type 'gnu/linux))
248 (should (tramp-tramp-file-p "/-:h:/path/to/file"))
249 (should (tramp-tramp-file-p "/m::/path/to/file"))))
251 (ert-deftest tramp-test01-file-name-syntax-simplified ()
252 "Check simplified file name syntax."
253 :tags '(:expensive-test)
254 (let ((syntax tramp-syntax))
255 (unwind-protect
256 (progn
257 (tramp-change-syntax 'simplified)
258 ;; Simple cases.
259 (should (tramp-tramp-file-p "/host:"))
260 (should (tramp-tramp-file-p "/user@:"))
261 (should (tramp-tramp-file-p "/user@host:"))
262 (should (tramp-tramp-file-p "/user@email@host:"))
264 ;; Using a port.
265 (should (tramp-tramp-file-p "/host#1234:"))
266 (should (tramp-tramp-file-p "/user@host#1234:"))
268 ;; Using an IPv4 address.
269 (should (tramp-tramp-file-p "/1.2.3.4:"))
270 (should (tramp-tramp-file-p "/user@1.2.3.4:"))
272 ;; Using an IPv6 address.
273 (should (tramp-tramp-file-p "/[::1]:"))
274 (should (tramp-tramp-file-p "/user@[::1]:"))
276 ;; Local file name part.
277 (should (tramp-tramp-file-p "/host::"))
278 (should (tramp-tramp-file-p "/host:/:"))
279 (should (tramp-tramp-file-p "/host:/path/to/file"))
280 (should (tramp-tramp-file-p "/host:/:/path/to/file"))
281 (should (tramp-tramp-file-p "/host:file"))
282 (should (tramp-tramp-file-p "/host:/:file"))
284 ;; Multihop.
285 (should (tramp-tramp-file-p "/host1|host2:"))
286 (should (tramp-tramp-file-p "/user1@host1|user2@host2:"))
287 (should (tramp-tramp-file-p "/user1@host1|user2@host2|user3@host3:"))
289 ;; No strings.
290 (should-not (tramp-tramp-file-p nil))
291 (should-not (tramp-tramp-file-p 'symbol))
292 ;; Quote with "/:" suppresses file name handlers.
293 (should-not (tramp-tramp-file-p "/::"))
294 (should-not (tramp-tramp-file-p "/:@:"))
295 (should-not (tramp-tramp-file-p "/:[]:")))
297 ;; Exit.
298 (tramp-change-syntax syntax))))
300 (ert-deftest tramp-test01-file-name-syntax-separate ()
301 "Check separate file name syntax."
302 :tags '(:expensive-test)
303 (let ((syntax tramp-syntax))
304 (unwind-protect
305 (progn
306 (tramp-change-syntax 'separate)
307 ;; Simple cases.
308 (should (tramp-tramp-file-p "/[method/]"))
309 (should (tramp-tramp-file-p "/[method/host]"))
310 (should (tramp-tramp-file-p "/[method/user@]"))
311 (should (tramp-tramp-file-p "/[method/user@host]"))
312 (should (tramp-tramp-file-p "/[method/user@email@host]"))
314 ;; Using a port.
315 (should (tramp-tramp-file-p "/[method/host#1234]"))
316 (should (tramp-tramp-file-p "/[method/user@host#1234]"))
318 ;; Using an IPv4 address.
319 (should (tramp-tramp-file-p "/[method/1.2.3.4]"))
320 (should (tramp-tramp-file-p "/[method/user@1.2.3.4]"))
322 ;; Using an IPv6 address.
323 (should (tramp-tramp-file-p "/[method/::1]"))
324 (should (tramp-tramp-file-p "/[method/user@::1]"))
326 ;; Local file name part.
327 (should (tramp-tramp-file-p "/[method/]"))
328 (should (tramp-tramp-file-p "/[method/]/:"))
329 (should (tramp-tramp-file-p "/[method/]/path/to/file"))
330 (should (tramp-tramp-file-p "/[method/]/:/path/to/file"))
331 (should (tramp-tramp-file-p "/[method/]file"))
332 (should (tramp-tramp-file-p "/[method/]/:file"))
334 ;; Multihop.
335 (should (tramp-tramp-file-p "/[method1/|method2/]"))
336 (should (tramp-tramp-file-p "/[method1/host1|method2/host2]"))
337 (should
338 (tramp-tramp-file-p
339 "/[method1/user1@host1|method2/user2@host2]"))
340 (should
341 (tramp-tramp-file-p
342 "/[method1/user1@host1|method2/user2@host2|method3/user3@host3]"))
344 ;; No strings.
345 (should-not (tramp-tramp-file-p nil))
346 (should-not (tramp-tramp-file-p 'symbol))
347 ;; Ange-ftp syntax.
348 (should-not (tramp-tramp-file-p "/host:"))
349 (should-not (tramp-tramp-file-p "/user@host:"))
350 (should-not (tramp-tramp-file-p "/1.2.3.4:"))
351 (should-not (tramp-tramp-file-p "/host:/:"))
352 (should-not (tramp-tramp-file-p "/host1|host2:"))
353 (should-not (tramp-tramp-file-p "/user1@host1|user2@host2:"))
354 ;; Quote with "/:" suppresses file name handlers.
355 (should-not (tramp-tramp-file-p "/:[]")))
357 ;; Exit.
358 (tramp-change-syntax syntax))))
360 (ert-deftest tramp-test02-file-name-dissect ()
361 "Check remote file name components."
362 (let ((tramp-default-method "default-method")
363 (tramp-default-user "default-user")
364 (tramp-default-host "default-host"))
365 ;; Expand `tramp-default-user' and `tramp-default-host'.
366 (should (string-equal
367 (file-remote-p "/method::")
368 (format "/%s:%s@%s:" "method" "default-user" "default-host")))
369 (should (string-equal (file-remote-p "/method::" 'method) "method"))
370 (should (string-equal (file-remote-p "/method::" 'user) "default-user"))
371 (should (string-equal (file-remote-p "/method::" 'host) "default-host"))
372 (should (string-equal (file-remote-p "/method::" 'localname) ""))
373 (should (string-equal (file-remote-p "/method::" 'hop) nil))
375 ;; Expand `tramp-default-method' and `tramp-default-user'.
376 (should (string-equal
377 (file-remote-p "/-:host:")
378 (format "/%s:%s@%s:" "default-method" "default-user" "host")))
379 (should (string-equal (file-remote-p "/-:host:" 'method) "default-method"))
380 (should (string-equal (file-remote-p "/-:host:" 'user) "default-user"))
381 (should (string-equal (file-remote-p "/-:host:" 'host) "host"))
382 (should (string-equal (file-remote-p "/-:host:" 'localname) ""))
383 (should (string-equal (file-remote-p "/-:host:" 'hop) nil))
385 ;; Expand `tramp-default-method' and `tramp-default-host'.
386 (should (string-equal
387 (file-remote-p "/-:user@:")
388 (format "/%s:%s@%s:" "default-method" "user" "default-host")))
389 (should (string-equal (file-remote-p "/-:user@:" 'method) "default-method"))
390 (should (string-equal (file-remote-p "/-:user@:" 'user) "user"))
391 (should (string-equal (file-remote-p "/-:user@:" 'host) "default-host"))
392 (should (string-equal (file-remote-p "/-:user@:" 'localname) ""))
393 (should (string-equal (file-remote-p "/-:user@:" 'hop) nil))
395 ;; Expand `tramp-default-method'.
396 (should (string-equal
397 (file-remote-p "/-:user@host:")
398 (format "/%s:%s@%s:" "default-method" "user" "host")))
399 (should (string-equal
400 (file-remote-p "/-:user@host:" 'method) "default-method"))
401 (should (string-equal (file-remote-p "/-:user@host:" 'user) "user"))
402 (should (string-equal (file-remote-p "/-:user@host:" 'host) "host"))
403 (should (string-equal (file-remote-p "/-:user@host:" 'localname) ""))
404 (should (string-equal (file-remote-p "/-:user@host:" 'hop) nil))
406 ;; Expand `tramp-default-user'.
407 (should (string-equal
408 (file-remote-p "/method:host:")
409 (format "/%s:%s@%s:" "method" "default-user" "host")))
410 (should (string-equal (file-remote-p "/method:host:" 'method) "method"))
411 (should (string-equal (file-remote-p "/method:host:" 'user) "default-user"))
412 (should (string-equal (file-remote-p "/method:host:" 'host) "host"))
413 (should (string-equal (file-remote-p "/method:host:" 'localname) ""))
414 (should (string-equal (file-remote-p "/method:host:" 'hop) nil))
416 ;; Expand `tramp-default-host'.
417 (should (string-equal
418 (file-remote-p "/method:user@:")
419 (format "/%s:%s@%s:" "method" "user" "default-host")))
420 (should (string-equal (file-remote-p "/method:user@:" 'method) "method"))
421 (should (string-equal (file-remote-p "/method:user@:" 'user) "user"))
422 (should (string-equal (file-remote-p "/method:user@:" 'host)
423 "default-host"))
424 (should (string-equal (file-remote-p "/method:user@:" 'localname) ""))
425 (should (string-equal (file-remote-p "/method:user@:" 'hop) nil))
427 ;; No expansion.
428 (should (string-equal
429 (file-remote-p "/method:user@host:")
430 (format "/%s:%s@%s:" "method" "user" "host")))
431 (should (string-equal
432 (file-remote-p "/method:user@host:" 'method) "method"))
433 (should (string-equal (file-remote-p "/method:user@host:" 'user) "user"))
434 (should (string-equal (file-remote-p "/method:user@host:" 'host) "host"))
435 (should (string-equal (file-remote-p "/method:user@host:" 'localname) ""))
436 (should (string-equal (file-remote-p "/method:user@host:" 'hop) nil))
438 ;; No expansion.
439 (should (string-equal
440 (file-remote-p "/method:user@email@host:")
441 (format "/%s:%s@%s:" "method" "user@email" "host")))
442 (should (string-equal
443 (file-remote-p "/method:user@email@host:" 'method) "method"))
444 (should (string-equal
445 (file-remote-p "/method:user@email@host:" 'user) "user@email"))
446 (should (string-equal
447 (file-remote-p "/method:user@email@host:" 'host) "host"))
448 (should (string-equal
449 (file-remote-p "/method:user@email@host:" 'localname) ""))
450 (should (string-equal
451 (file-remote-p "/method:user@email@host:" 'hop) nil))
453 ;; Expand `tramp-default-method' and `tramp-default-user'.
454 (should (string-equal
455 (file-remote-p "/-:host#1234:")
456 (format "/%s:%s@%s:" "default-method" "default-user" "host#1234")))
457 (should (string-equal
458 (file-remote-p "/-:host#1234:" 'method) "default-method"))
459 (should (string-equal (file-remote-p "/-:host#1234:" 'user) "default-user"))
460 (should (string-equal (file-remote-p "/-:host#1234:" 'host) "host#1234"))
461 (should (string-equal (file-remote-p "/-:host#1234:" 'localname) ""))
462 (should (string-equal (file-remote-p "/-:host#1234:" 'hop) nil))
464 ;; Expand `tramp-default-method'.
465 (should (string-equal
466 (file-remote-p "/-:user@host#1234:")
467 (format "/%s:%s@%s:" "default-method" "user" "host#1234")))
468 (should (string-equal
469 (file-remote-p "/-:user@host#1234:" 'method) "default-method"))
470 (should (string-equal (file-remote-p "/-:user@host#1234:" 'user) "user"))
471 (should (string-equal (file-remote-p "/-:user@host#1234:" 'host) "host#1234"))
472 (should (string-equal (file-remote-p "/-:user@host#1234:" 'localname) ""))
473 (should (string-equal (file-remote-p "/-:user@host#1234:" 'hop) nil))
475 ;; Expand `tramp-default-user'.
476 (should (string-equal
477 (file-remote-p "/method:host#1234:")
478 (format "/%s:%s@%s:" "method" "default-user" "host#1234")))
479 (should (string-equal
480 (file-remote-p "/method:host#1234:" 'method) "method"))
481 (should (string-equal
482 (file-remote-p "/method:host#1234:" 'user) "default-user"))
483 (should (string-equal
484 (file-remote-p "/method:host#1234:" 'host) "host#1234"))
485 (should (string-equal (file-remote-p "/method:host#1234:" 'localname) ""))
486 (should (string-equal (file-remote-p "/method:host#1234:" 'hop) nil))
488 ;; No expansion.
489 (should (string-equal
490 (file-remote-p "/method:user@host#1234:")
491 (format "/%s:%s@%s:" "method" "user" "host#1234")))
492 (should (string-equal
493 (file-remote-p "/method:user@host#1234:" 'method) "method"))
494 (should (string-equal
495 (file-remote-p "/method:user@host#1234:" 'user) "user"))
496 (should (string-equal
497 (file-remote-p "/method:user@host#1234:" 'host) "host#1234"))
498 (should (string-equal
499 (file-remote-p "/method:user@host#1234:" 'localname) ""))
500 (should (string-equal
501 (file-remote-p "/method:user@host#1234:" 'hop) nil))
503 ;; Expand `tramp-default-method' and `tramp-default-user'.
504 (should (string-equal
505 (file-remote-p "/-:1.2.3.4:")
506 (format "/%s:%s@%s:" "default-method" "default-user" "1.2.3.4")))
507 (should (string-equal (file-remote-p "/-:1.2.3.4:" 'method) "default-method"))
508 (should (string-equal (file-remote-p "/-:1.2.3.4:" 'user) "default-user"))
509 (should (string-equal (file-remote-p "/-:1.2.3.4:" 'host) "1.2.3.4"))
510 (should (string-equal (file-remote-p "/-:1.2.3.4:" 'localname) ""))
511 (should (string-equal (file-remote-p "/-:1.2.3.4:" 'hop) nil))
513 ;; Expand `tramp-default-method'.
514 (should (string-equal
515 (file-remote-p "/-:user@1.2.3.4:")
516 (format "/%s:%s@%s:" "default-method" "user" "1.2.3.4")))
517 (should (string-equal
518 (file-remote-p "/-:user@1.2.3.4:" 'method) "default-method"))
519 (should (string-equal (file-remote-p "/-:user@1.2.3.4:" 'user) "user"))
520 (should (string-equal (file-remote-p "/-:user@1.2.3.4:" 'host) "1.2.3.4"))
521 (should (string-equal (file-remote-p "/-:user@1.2.3.4:" 'localname) ""))
522 (should (string-equal (file-remote-p "/-:user@1.2.3.4:" 'hop) nil))
524 ;; Expand `tramp-default-user'.
525 (should (string-equal
526 (file-remote-p "/method:1.2.3.4:")
527 (format "/%s:%s@%s:" "method" "default-user" "1.2.3.4")))
528 (should (string-equal (file-remote-p "/method:1.2.3.4:" 'method) "method"))
529 (should (string-equal
530 (file-remote-p "/method:1.2.3.4:" 'user) "default-user"))
531 (should (string-equal (file-remote-p "/method:1.2.3.4:" 'host) "1.2.3.4"))
532 (should (string-equal (file-remote-p "/method:1.2.3.4:" 'localname) ""))
533 (should (string-equal (file-remote-p "/method:1.2.3.4:" 'hop) nil))
535 ;; No expansion.
536 (should (string-equal
537 (file-remote-p "/method:user@1.2.3.4:")
538 (format "/%s:%s@%s:" "method" "user" "1.2.3.4")))
539 (should (string-equal
540 (file-remote-p "/method:user@1.2.3.4:" 'method) "method"))
541 (should (string-equal (file-remote-p "/method:user@1.2.3.4:" 'user) "user"))
542 (should (string-equal
543 (file-remote-p "/method:user@1.2.3.4:" 'host) "1.2.3.4"))
544 (should (string-equal
545 (file-remote-p "/method:user@1.2.3.4:" 'localname) ""))
546 (should (string-equal
547 (file-remote-p "/method:user@1.2.3.4:" 'hop) nil))
549 ;; Expand `tramp-default-method', `tramp-default-user' and
550 ;; `tramp-default-host'.
551 (should (string-equal
552 (file-remote-p "/-:[]:")
553 (format
554 "/%s:%s@%s:" "default-method" "default-user" "default-host")))
555 (should (string-equal (file-remote-p "/-:[]:" 'method) "default-method"))
556 (should (string-equal (file-remote-p "/-:[]:" 'user) "default-user"))
557 (should (string-equal (file-remote-p "/-:[]:" 'host) "default-host"))
558 (should (string-equal (file-remote-p "/-:[]:" 'localname) ""))
559 (should (string-equal (file-remote-p "/-:[]:" 'hop) nil))
561 ;; Expand `tramp-default-method' and `tramp-default-user'.
562 (let ((tramp-default-host "::1"))
563 (should (string-equal
564 (file-remote-p "/-:[]:")
565 (format "/%s:%s@%s:" "default-method" "default-user" "[::1]")))
566 (should (string-equal (file-remote-p "/-:[]:" 'method) "default-method"))
567 (should (string-equal (file-remote-p "/-:[]:" 'user) "default-user"))
568 (should (string-equal (file-remote-p "/-:[]:" 'host) "::1"))
569 (should (string-equal (file-remote-p "/-:[]:" 'localname) ""))
570 (should (string-equal (file-remote-p "/-:[]:" 'hop) nil)))
572 ;; Expand `tramp-default-method' and `tramp-default-user'.
573 (should (string-equal
574 (file-remote-p "/-:[::1]:")
575 (format "/%s:%s@%s:" "default-method" "default-user" "[::1]")))
576 (should (string-equal (file-remote-p "/-:[::1]:" 'method) "default-method"))
577 (should (string-equal (file-remote-p "/-:[::1]:" 'user) "default-user"))
578 (should (string-equal (file-remote-p "/-:[::1]:" 'host) "::1"))
579 (should (string-equal (file-remote-p "/-:[::1]:" 'localname) ""))
580 (should (string-equal (file-remote-p "/-:[::1]:" 'hop) nil))
582 ;; Expand `tramp-default-method'.
583 (should (string-equal
584 (file-remote-p "/-:user@[::1]:")
585 (format "/%s:%s@%s:" "default-method" "user" "[::1]")))
586 (should (string-equal
587 (file-remote-p "/-:user@[::1]:" 'method) "default-method"))
588 (should (string-equal (file-remote-p "/-:user@[::1]:" 'user) "user"))
589 (should (string-equal (file-remote-p "/-:user@[::1]:" 'host) "::1"))
590 (should (string-equal (file-remote-p "/-:user@[::1]:" 'localname) ""))
591 (should (string-equal (file-remote-p "/-:user@[::1]:" 'hop) nil))
593 ;; Expand `tramp-default-user'.
594 (should (string-equal
595 (file-remote-p "/method:[::1]:")
596 (format "/%s:%s@%s:" "method" "default-user" "[::1]")))
597 (should (string-equal (file-remote-p "/method:[::1]:" 'method) "method"))
598 (should (string-equal
599 (file-remote-p "/method:[::1]:" 'user) "default-user"))
600 (should (string-equal (file-remote-p "/method:[::1]:" 'host) "::1"))
601 (should (string-equal (file-remote-p "/method:[::1]:" 'localname) ""))
602 (should (string-equal (file-remote-p "/method:[::1]:" 'hop) nil))
604 ;; No expansion.
605 (should (string-equal
606 (file-remote-p "/method:user@[::1]:")
607 (format "/%s:%s@%s:" "method" "user" "[::1]")))
608 (should (string-equal
609 (file-remote-p "/method:user@[::1]:" 'method) "method"))
610 (should (string-equal (file-remote-p "/method:user@[::1]:" 'user) "user"))
611 (should (string-equal (file-remote-p "/method:user@[::1]:" 'host) "::1"))
612 (should (string-equal
613 (file-remote-p "/method:user@[::1]:" 'localname) ""))
614 (should (string-equal (file-remote-p "/method:user@[::1]:" 'hop) nil))
616 ;; Local file name part.
617 (should (string-equal (file-remote-p "/-:host:/:" 'localname) "/:"))
618 (should (string-equal (file-remote-p "/method:::" 'localname) ":"))
619 (should (string-equal (file-remote-p "/method:: " 'localname) " "))
620 (should (string-equal (file-remote-p "/method::file" 'localname) "file"))
621 (should (string-equal
622 (file-remote-p "/method::/path/to/file" 'localname)
623 "/path/to/file"))
625 ;; Multihop.
626 (should
627 (string-equal
628 (file-remote-p "/method1:user1@host1|method2:user2@host2:/path/to/file")
629 (format "/%s:%s@%s|%s:%s@%s:"
630 "method1" "user1" "host1" "method2" "user2" "host2")))
631 (should
632 (string-equal
633 (file-remote-p
634 "/method1:user1@host1|method2:user2@host2:/path/to/file" 'method)
635 "method2"))
636 (should
637 (string-equal
638 (file-remote-p
639 "/method1:user1@host1|method2:user2@host2:/path/to/file" 'user)
640 "user2"))
641 (should
642 (string-equal
643 (file-remote-p
644 "/method1:user1@host1|method2:user2@host2:/path/to/file" 'host)
645 "host2"))
646 (should
647 (string-equal
648 (file-remote-p
649 "/method1:user1@host1|method2:user2@host2:/path/to/file" 'localname)
650 "/path/to/file"))
651 (should
652 (string-equal
653 (file-remote-p
654 "/method1:user1@host1|method2:user2@host2:/path/to/file" 'hop)
655 (format "%s:%s@%s|"
656 "method1" "user1" "host1")))
658 (should
659 (string-equal
660 (file-remote-p
661 (concat
662 "/method1:user1@host1"
663 "|method2:user2@host2"
664 "|method3:user3@host3:/path/to/file"))
665 (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
666 "method1" "user1" "host1"
667 "method2" "user2" "host2"
668 "method3" "user3" "host3")))
669 (should
670 (string-equal
671 (file-remote-p
672 (concat
673 "/method1:user1@host1"
674 "|method2:user2@host2"
675 "|method3:user3@host3:/path/to/file")
676 'method)
677 "method3"))
678 (should
679 (string-equal
680 (file-remote-p
681 (concat
682 "/method1:user1@host1"
683 "|method2:user2@host2"
684 "|method3:user3@host3:/path/to/file")
685 'user)
686 "user3"))
687 (should
688 (string-equal
689 (file-remote-p
690 (concat
691 "/method1:user1@host1"
692 "|method2:user2@host2"
693 "|method3:user3@host3:/path/to/file")
694 'host)
695 "host3"))
696 (should
697 (string-equal
698 (file-remote-p
699 (concat
700 "/method1:user1@host1"
701 "|method2:user2@host2"
702 "|method3:user3@host3:/path/to/file")
703 'localname)
704 "/path/to/file"))
705 (should
706 (string-equal
707 (file-remote-p
708 (concat
709 "/method1:user1@host1"
710 "|method2:user2@host2"
711 "|method3:user3@host3:/path/to/file")
712 'hop)
713 (format "%s:%s@%s|%s:%s@%s|"
714 "method1" "user1" "host1" "method2" "user2" "host2")))))
716 (ert-deftest tramp-test02-file-name-dissect-simplified ()
717 "Check simplified file name components."
718 :tags '(:expensive-test)
719 (let ((tramp-default-method "default-method")
720 (tramp-default-user "default-user")
721 (tramp-default-host "default-host")
722 (syntax tramp-syntax))
723 (unwind-protect
724 (progn
725 (tramp-change-syntax 'simplified)
726 ;; Expand `tramp-default-method' and `tramp-default-user'.
727 (should (string-equal
728 (file-remote-p "/host:")
729 (format "/%s@%s:" "default-user" "host")))
730 (should (string-equal
731 (file-remote-p "/host:" 'method) "default-method"))
732 (should (string-equal (file-remote-p "/host:" 'user) "default-user"))
733 (should (string-equal (file-remote-p "/host:" 'host) "host"))
734 (should (string-equal (file-remote-p "/host:" 'localname) ""))
735 (should (string-equal (file-remote-p "/host:" 'hop) nil))
737 ;; Expand `tramp-default-method' and `tramp-default-host'.
738 (should (string-equal
739 (file-remote-p "/user@:")
740 (format "/%s@%s:" "user" "default-host")))
741 (should (string-equal
742 (file-remote-p "/user@:" 'method) "default-method"))
743 (should (string-equal (file-remote-p "/user@:" 'user) "user"))
744 (should (string-equal (file-remote-p "/user@:" 'host) "default-host"))
745 (should (string-equal (file-remote-p "/user@:" 'localname) ""))
746 (should (string-equal (file-remote-p "/user@:" 'hop) nil))
748 ;; Expand `tramp-default-method'.
749 (should (string-equal
750 (file-remote-p "/user@host:")
751 (format "/%s@%s:" "user" "host")))
752 (should (string-equal
753 (file-remote-p "/user@host:" 'method) "default-method"))
754 (should (string-equal (file-remote-p "/user@host:" 'user) "user"))
755 (should (string-equal (file-remote-p "/user@host:" 'host) "host"))
756 (should (string-equal (file-remote-p "/user@host:" 'localname) ""))
757 (should (string-equal (file-remote-p "/user@host:" 'hop) nil))
759 ;; No expansion.
760 (should (string-equal
761 (file-remote-p "/user@email@host:")
762 (format "/%s@%s:" "user@email" "host")))
763 (should (string-equal
764 (file-remote-p
765 "/user@email@host:" 'method) "default-method"))
766 (should (string-equal
767 (file-remote-p "/user@email@host:" 'user) "user@email"))
768 (should (string-equal
769 (file-remote-p "/user@email@host:" 'host) "host"))
770 (should (string-equal
771 (file-remote-p "/user@email@host:" 'localname) ""))
772 (should (string-equal
773 (file-remote-p "/user@email@host:" 'hop) nil))
775 ;; Expand `tramp-default-method' and `tramp-default-user'.
776 (should (string-equal
777 (file-remote-p "/host#1234:")
778 (format "/%s@%s:" "default-user" "host#1234")))
779 (should (string-equal
780 (file-remote-p "/host#1234:" 'method) "default-method"))
781 (should (string-equal
782 (file-remote-p "/host#1234:" 'user) "default-user"))
783 (should (string-equal
784 (file-remote-p "/host#1234:" 'host) "host#1234"))
785 (should (string-equal (file-remote-p "/host#1234:" 'localname) ""))
786 (should (string-equal (file-remote-p "/host#1234:" 'hop) nil))
788 ;; Expand `tramp-default-method'.
789 (should (string-equal
790 (file-remote-p "/user@host#1234:")
791 (format "/%s@%s:" "user" "host#1234")))
792 (should (string-equal
793 (file-remote-p "/user@host#1234:" 'method) "default-method"))
794 (should (string-equal
795 (file-remote-p "/user@host#1234:" 'user) "user"))
796 (should (string-equal
797 (file-remote-p "/user@host#1234:" 'host) "host#1234"))
798 (should (string-equal
799 (file-remote-p "/user@host#1234:" 'localname) ""))
800 (should (string-equal (file-remote-p "/user@host#1234:" 'hop) nil))
802 ;; Expand `tramp-default-method' and `tramp-default-user'.
803 (should (string-equal
804 (file-remote-p "/1.2.3.4:")
805 (format "/%s@%s:" "default-user" "1.2.3.4")))
806 (should (string-equal
807 (file-remote-p "/1.2.3.4:" 'method) "default-method"))
808 (should (string-equal
809 (file-remote-p "/1.2.3.4:" 'user) "default-user"))
810 (should (string-equal (file-remote-p "/1.2.3.4:" 'host) "1.2.3.4"))
811 (should (string-equal (file-remote-p "/1.2.3.4:" 'localname) ""))
812 (should (string-equal (file-remote-p "/1.2.3.4:" 'hop) nil))
814 ;; Expand `tramp-default-method'.
815 (should (string-equal
816 (file-remote-p "/user@1.2.3.4:")
817 (format "/%s@%s:" "user" "1.2.3.4")))
818 (should (string-equal
819 (file-remote-p "/user@1.2.3.4:" 'method) "default-method"))
820 (should (string-equal (file-remote-p "/user@1.2.3.4:" 'user) "user"))
821 (should (string-equal
822 (file-remote-p "/user@1.2.3.4:" 'host) "1.2.3.4"))
823 (should (string-equal (file-remote-p "/user@1.2.3.4:" 'localname) ""))
824 (should (string-equal (file-remote-p "/user@1.2.3.4:" 'hop) nil))
826 ;; Expand `tramp-default-method', `tramp-default-user' and
827 ;; `tramp-default-host'.
828 (should (string-equal
829 (file-remote-p "/[]:")
830 (format
831 "/%s@%s:" "default-user" "default-host")))
832 (should (string-equal
833 (file-remote-p "/[]:" 'method) "default-method"))
834 (should (string-equal (file-remote-p "/[]:" 'user) "default-user"))
835 (should (string-equal (file-remote-p "/[]:" 'host) "default-host"))
836 (should (string-equal (file-remote-p "/[]:" 'localname) ""))
837 (should (string-equal (file-remote-p "/[]:" 'hop) nil))
839 ;; Expand `tramp-default-method' and `tramp-default-user'.
840 (let ((tramp-default-host "::1"))
841 (should (string-equal
842 (file-remote-p "/[]:")
843 (format "/%s@%s:" "default-user" "[::1]")))
844 (should (string-equal
845 (file-remote-p "/[]:" 'method) "default-method"))
846 (should (string-equal (file-remote-p "/[]:" 'user) "default-user"))
847 (should (string-equal (file-remote-p "/[]:" 'host) "::1"))
848 (should (string-equal (file-remote-p "/[]:" 'localname) ""))
849 (should (string-equal (file-remote-p "/[]:" 'hop) nil)))
851 ;; Expand `tramp-default-method' and `tramp-default-user'.
852 (should (string-equal
853 (file-remote-p "/[::1]:")
854 (format "/%s@%s:" "default-user" "[::1]")))
855 (should (string-equal
856 (file-remote-p "/[::1]:" 'method) "default-method"))
857 (should (string-equal (file-remote-p "/[::1]:" 'user) "default-user"))
858 (should (string-equal (file-remote-p "/[::1]:" 'host) "::1"))
859 (should (string-equal (file-remote-p "/[::1]:" 'localname) ""))
860 (should (string-equal (file-remote-p "/[::1]:" 'hop) nil))
862 ;; Expand `tramp-default-method'.
863 (should (string-equal
864 (file-remote-p "/user@[::1]:")
865 (format "/%s@%s:" "user" "[::1]")))
866 (should (string-equal
867 (file-remote-p "/user@[::1]:" 'method) "default-method"))
868 (should (string-equal (file-remote-p "/user@[::1]:" 'user) "user"))
869 (should (string-equal (file-remote-p "/user@[::1]:" 'host) "::1"))
870 (should (string-equal (file-remote-p "/user@[::1]:" 'localname) ""))
871 (should (string-equal (file-remote-p "/user@[::1]:" 'hop) nil))
873 ;; Local file name part.
874 (should (string-equal (file-remote-p "/host:/:" 'localname) "/:"))
875 (should (string-equal (file-remote-p "/host::" 'localname) ":"))
876 (should (string-equal (file-remote-p "/host: " 'localname) " "))
877 (should (string-equal (file-remote-p "/host:file" 'localname) "file"))
878 (should (string-equal
879 (file-remote-p "/host:/path/to/file" 'localname)
880 "/path/to/file"))
882 ;; Multihop.
883 (should
884 (string-equal
885 (file-remote-p "/user1@host1|user2@host2:/path/to/file")
886 (format "/%s@%s|%s@%s:" "user1" "host1" "user2" "host2")))
887 (should
888 (string-equal
889 (file-remote-p
890 "/user1@host1|user2@host2:/path/to/file" 'method)
891 "default-method"))
892 (should
893 (string-equal
894 (file-remote-p
895 "/user1@host1|user2@host2:/path/to/file" 'user)
896 "user2"))
897 (should
898 (string-equal
899 (file-remote-p
900 "/user1@host1|user2@host2:/path/to/file" 'host)
901 "host2"))
902 (should
903 (string-equal
904 (file-remote-p
905 "/user1@host1|user2@host2:/path/to/file" 'localname)
906 "/path/to/file"))
907 (should
908 (string-equal
909 (file-remote-p
910 "/user1@host1|user2@host2:/path/to/file" 'hop)
911 (format "%s@%s|" "user1" "host1")))
913 (should
914 (string-equal
915 (file-remote-p
916 (concat
917 "/user1@host1"
918 "|user2@host2"
919 "|user3@host3:/path/to/file"))
920 (format "/%s@%s|%s@%s|%s@%s:"
921 "user1" "host1"
922 "user2" "host2"
923 "user3" "host3")))
924 (should
925 (string-equal
926 (file-remote-p
927 (concat
928 "/user1@host1"
929 "|user2@host2"
930 "|user3@host3:/path/to/file")
931 'method)
932 "default-method"))
933 (should
934 (string-equal
935 (file-remote-p
936 (concat
937 "/user1@host1"
938 "|user2@host2"
939 "|user3@host3:/path/to/file")
940 'user)
941 "user3"))
942 (should
943 (string-equal
944 (file-remote-p
945 (concat
946 "/user1@host1"
947 "|user2@host2"
948 "|user3@host3:/path/to/file")
949 'host)
950 "host3"))
951 (should
952 (string-equal
953 (file-remote-p
954 (concat
955 "/user1@host1"
956 "|user2@host2"
957 "|user3@host3:/path/to/file")
958 'localname)
959 "/path/to/file"))
960 (should
961 (string-equal
962 (file-remote-p
963 (concat
964 "/user1@host1"
965 "|user2@host2"
966 "|user3@host3:/path/to/file")
967 'hop)
968 (format "%s@%s|%s@%s|"
969 "user1" "host1" "user2" "host2"))))
971 ;; Exit.
972 (tramp-change-syntax syntax))))
974 (ert-deftest tramp-test02-file-name-dissect-separate ()
975 "Check separate file name components."
976 :tags '(:expensive-test)
977 (let ((tramp-default-method "default-method")
978 (tramp-default-user "default-user")
979 (tramp-default-host "default-host")
980 (syntax tramp-syntax))
981 (unwind-protect
982 (progn
983 (tramp-change-syntax 'separate)
984 ;; Expand `tramp-default-user' and `tramp-default-host'.
985 (should (string-equal
986 (file-remote-p "/[method/]")
987 (format
988 "/[%s/%s@%s]" "method" "default-user" "default-host")))
989 (should (string-equal (file-remote-p "/[method/]" 'method) "method"))
990 (should (string-equal
991 (file-remote-p "/[method/]" 'user) "default-user"))
992 (should (string-equal
993 (file-remote-p "/[method/]" 'host) "default-host"))
994 (should (string-equal (file-remote-p "/[method/]" 'localname) ""))
995 (should (string-equal (file-remote-p "/[method/]" 'hop) nil))
997 ;; Expand `tramp-default-method' and `tramp-default-user'.
998 (should (string-equal
999 (file-remote-p "/[/host]")
1000 (format
1001 "/[%s/%s@%s]" "default-method" "default-user" "host")))
1002 (should (string-equal
1003 (file-remote-p "/[/host]" 'method) "default-method"))
1004 (should (string-equal
1005 (file-remote-p "/[/host]" 'user) "default-user"))
1006 (should (string-equal (file-remote-p "/[/host]" 'host) "host"))
1007 (should (string-equal (file-remote-p "/[/host]" 'localname) ""))
1008 (should (string-equal (file-remote-p "/[/host]" 'hop) nil))
1010 ;; Expand `tramp-default-method' and `tramp-default-host'.
1011 (should (string-equal
1012 (file-remote-p "/[/user@]")
1013 (format
1014 "/[%s/%s@%s]" "default-method" "user" "default-host")))
1015 (should (string-equal
1016 (file-remote-p "/[/user@]" 'method) "default-method"))
1017 (should (string-equal (file-remote-p "/[/user@]" 'user) "user"))
1018 (should (string-equal
1019 (file-remote-p "/[/user@]" 'host) "default-host"))
1020 (should (string-equal (file-remote-p "/[/user@]" 'localname) ""))
1021 (should (string-equal (file-remote-p "/[/user@]" 'hop) nil))
1023 ;; Expand `tramp-default-method'.
1024 (should (string-equal
1025 (file-remote-p "/[/user@host]")
1026 (format "/[%s/%s@%s]" "default-method" "user" "host")))
1027 (should (string-equal
1028 (file-remote-p "/[/user@host]" 'method) "default-method"))
1029 (should (string-equal (file-remote-p "/[/user@host]" 'user) "user"))
1030 (should (string-equal (file-remote-p "/[/user@host]" 'host) "host"))
1031 (should (string-equal (file-remote-p "/[/user@host]" 'localname) ""))
1032 (should (string-equal (file-remote-p "/[/user@host]" 'hop) nil))
1034 ;; Expand `tramp-default-method' and `tramp-default-user'.
1035 (should (string-equal
1036 (file-remote-p "/[-/host]")
1037 (format
1038 "/[%s/%s@%s]" "default-method" "default-user" "host")))
1039 (should (string-equal
1040 (file-remote-p "/[-/host]" 'method) "default-method"))
1041 (should (string-equal
1042 (file-remote-p "/[-/host]" 'user) "default-user"))
1043 (should (string-equal (file-remote-p "/[-/host]" 'host) "host"))
1044 (should (string-equal (file-remote-p "/[-/host]" 'localname) ""))
1045 (should (string-equal (file-remote-p "/[-/host]" 'hop) nil))
1047 ;; Expand `tramp-default-method' and `tramp-default-host'.
1048 (should (string-equal
1049 (file-remote-p "/[-/user@]")
1050 (format
1051 "/[%s/%s@%s]" "default-method" "user" "default-host")))
1052 (should (string-equal
1053 (file-remote-p "/[-/user@]" 'method) "default-method"))
1054 (should (string-equal (file-remote-p "/[-/user@]" 'user) "user"))
1055 (should (string-equal
1056 (file-remote-p "/[-/user@]" 'host) "default-host"))
1057 (should (string-equal (file-remote-p "/[-/user@]" 'localname) ""))
1058 (should (string-equal (file-remote-p "/[-/user@]" 'hop) nil))
1060 ;; Expand `tramp-default-method'.
1061 (should (string-equal
1062 (file-remote-p "/[-/user@host]")
1063 (format "/[%s/%s@%s]" "default-method" "user" "host")))
1064 (should (string-equal
1065 (file-remote-p "/[-/user@host]" 'method) "default-method"))
1066 (should (string-equal (file-remote-p "/[-/user@host]" 'user) "user"))
1067 (should (string-equal (file-remote-p "/[-/user@host]" 'host) "host"))
1068 (should (string-equal (file-remote-p "/[-/user@host]" 'localname) ""))
1069 (should (string-equal (file-remote-p "/[-/user@host]" 'hop) nil))
1071 ;; Expand `tramp-default-user'.
1072 (should (string-equal
1073 (file-remote-p "/[method/host]")
1074 (format "/[%s/%s@%s]" "method" "default-user" "host")))
1075 (should (string-equal
1076 (file-remote-p "/[method/host]" 'method) "method"))
1077 (should (string-equal
1078 (file-remote-p "/[method/host]" 'user) "default-user"))
1079 (should (string-equal (file-remote-p "/[method/host]" 'host) "host"))
1080 (should (string-equal (file-remote-p "/[method/host]" 'localname) ""))
1081 (should (string-equal (file-remote-p "/[method/host]" 'hop) nil))
1083 ;; Expand `tramp-default-host'.
1084 (should (string-equal
1085 (file-remote-p "/[method/user@]")
1086 (format "/[%s/%s@%s]" "method" "user" "default-host")))
1087 (should (string-equal
1088 (file-remote-p "/[method/user@]" 'method) "method"))
1089 (should (string-equal (file-remote-p "/[method/user@]" 'user) "user"))
1090 (should (string-equal
1091 (file-remote-p "/[method/user@]" 'host) "default-host"))
1092 (should (string-equal
1093 (file-remote-p "/[method/user@]" 'localname) ""))
1094 (should (string-equal (file-remote-p "/[method/user@]" 'hop) nil))
1096 ;; No expansion.
1097 (should (string-equal
1098 (file-remote-p "/[method/user@host]")
1099 (format "/[%s/%s@%s]" "method" "user" "host")))
1100 (should (string-equal
1101 (file-remote-p "/[method/user@host]" 'method) "method"))
1102 (should (string-equal
1103 (file-remote-p "/[method/user@host]" 'user) "user"))
1104 (should (string-equal
1105 (file-remote-p "/[method/user@host]" 'host) "host"))
1106 (should (string-equal
1107 (file-remote-p "/[method/user@host]" 'localname) ""))
1108 (should (string-equal
1109 (file-remote-p "/[method/user@host]" 'hop) nil))
1111 ;; No expansion.
1112 (should (string-equal
1113 (file-remote-p "/[method/user@email@host]")
1114 (format "/[%s/%s@%s]" "method" "user@email" "host")))
1115 (should (string-equal
1116 (file-remote-p
1117 "/[method/user@email@host]" 'method) "method"))
1118 (should (string-equal
1119 (file-remote-p
1120 "/[method/user@email@host]" 'user) "user@email"))
1121 (should (string-equal
1122 (file-remote-p "/[method/user@email@host]" 'host) "host"))
1123 (should (string-equal
1124 (file-remote-p "/[method/user@email@host]" 'localname) ""))
1125 (should (string-equal
1126 (file-remote-p "/[method/user@email@host]" 'hop) nil))
1128 ;; Expand `tramp-default-method' and `tramp-default-user'.
1129 (should (string-equal
1130 (file-remote-p "/[/host#1234]")
1131 (format
1132 "/[%s/%s@%s]" "default-method" "default-user" "host#1234")))
1133 (should (string-equal
1134 (file-remote-p "/[/host#1234]" 'method) "default-method"))
1135 (should (string-equal
1136 (file-remote-p "/[/host#1234]" 'user) "default-user"))
1137 (should (string-equal
1138 (file-remote-p "/[/host#1234]" 'host) "host#1234"))
1139 (should (string-equal (file-remote-p "/[/host#1234]" 'localname) ""))
1140 (should (string-equal (file-remote-p "/[/host#1234]" 'hop) nil))
1142 ;; Expand `tramp-default-method'.
1143 (should (string-equal
1144 (file-remote-p "/[/user@host#1234]")
1145 (format "/[%s/%s@%s]" "default-method" "user" "host#1234")))
1146 (should (string-equal
1147 (file-remote-p
1148 "/[/user@host#1234]" 'method) "default-method"))
1149 (should (string-equal
1150 (file-remote-p
1151 "/[/user@host#1234]" 'user) "user"))
1152 (should (string-equal
1153 (file-remote-p "/[/user@host#1234]" 'host) "host#1234"))
1154 (should (string-equal
1155 (file-remote-p "/[/user@host#1234]" 'localname) ""))
1156 (should (string-equal (file-remote-p "/[/user@host#1234]" 'hop) nil))
1158 ;; Expand `tramp-default-method' and `tramp-default-user'.
1159 (should (string-equal
1160 (file-remote-p "/[-/host#1234]")
1161 (format
1162 "/[%s/%s@%s]" "default-method" "default-user" "host#1234")))
1163 (should (string-equal
1164 (file-remote-p "/[-/host#1234]" 'method) "default-method"))
1165 (should (string-equal
1166 (file-remote-p "/[-/host#1234]" 'user) "default-user"))
1167 (should (string-equal
1168 (file-remote-p "/[-/host#1234]" 'host) "host#1234"))
1169 (should (string-equal (file-remote-p "/[-/host#1234]" 'localname) ""))
1170 (should (string-equal (file-remote-p "/[-/host#1234]" 'hop) nil))
1172 ;; Expand `tramp-default-method'.
1173 (should (string-equal
1174 (file-remote-p "/[-/user@host#1234]")
1175 (format "/[%s/%s@%s]" "default-method" "user" "host#1234")))
1176 (should (string-equal
1177 (file-remote-p
1178 "/[-/user@host#1234]" 'method) "default-method"))
1179 (should (string-equal
1180 (file-remote-p
1181 "/[-/user@host#1234]" 'user) "user"))
1182 (should (string-equal
1183 (file-remote-p "/[-/user@host#1234]" 'host) "host#1234"))
1184 (should (string-equal
1185 (file-remote-p "/[-/user@host#1234]" 'localname) ""))
1186 (should (string-equal (file-remote-p "/[-/user@host#1234]" 'hop) nil))
1188 ;; Expand `tramp-default-user'.
1189 (should (string-equal
1190 (file-remote-p "/[method/host#1234]")
1191 (format "/[%s/%s@%s]" "method" "default-user" "host#1234")))
1192 (should (string-equal
1193 (file-remote-p "/[method/host#1234]" 'method) "method"))
1194 (should (string-equal
1195 (file-remote-p "/[method/host#1234]" 'user) "default-user"))
1196 (should (string-equal
1197 (file-remote-p "/[method/host#1234]" 'host) "host#1234"))
1198 (should (string-equal
1199 (file-remote-p "/[method/host#1234]" 'localname) ""))
1200 (should (string-equal (file-remote-p "/[method/host#1234]" 'hop) nil))
1202 ;; No expansion.
1203 (should (string-equal
1204 (file-remote-p "/[method/user@host#1234]")
1205 (format "/[%s/%s@%s]" "method" "user" "host#1234")))
1206 (should (string-equal
1207 (file-remote-p "/[method/user@host#1234]" 'method) "method"))
1208 (should (string-equal
1209 (file-remote-p "/[method/user@host#1234]" 'user) "user"))
1210 (should (string-equal
1211 (file-remote-p
1212 "/[method/user@host#1234]" 'host) "host#1234"))
1213 (should (string-equal
1214 (file-remote-p "/[method/user@host#1234]" 'localname) ""))
1215 (should (string-equal
1216 (file-remote-p "/[method/user@host#1234]" 'hop) nil))
1218 ;; Expand `tramp-default-method' and `tramp-default-user'.
1219 (should (string-equal
1220 (file-remote-p "/[/1.2.3.4]")
1221 (format
1222 "/[%s/%s@%s]" "default-method" "default-user" "1.2.3.4")))
1223 (should (string-equal
1224 (file-remote-p "/[/1.2.3.4]" 'method) "default-method"))
1225 (should (string-equal
1226 (file-remote-p "/[/1.2.3.4]" 'user) "default-user"))
1227 (should (string-equal
1228 (file-remote-p "/[/1.2.3.4]" 'host) "1.2.3.4"))
1229 (should (string-equal (file-remote-p "/[/1.2.3.4]" 'localname) ""))
1230 (should (string-equal (file-remote-p "/[/1.2.3.4]" 'hop) nil))
1232 ;; Expand `tramp-default-method'.
1233 (should (string-equal
1234 (file-remote-p "/[/user@1.2.3.4]")
1235 (format "/[%s/%s@%s]" "default-method" "user" "1.2.3.4")))
1236 (should (string-equal
1237 (file-remote-p
1238 "/[/user@1.2.3.4]" 'method) "default-method"))
1239 (should (string-equal
1240 (file-remote-p "/[/user@1.2.3.4]" 'user) "user"))
1241 (should (string-equal
1242 (file-remote-p "/[/user@1.2.3.4]" 'host) "1.2.3.4"))
1243 (should (string-equal
1244 (file-remote-p "/[/user@1.2.3.4]" 'localname) ""))
1245 (should (string-equal (file-remote-p "/[/user@1.2.3.4]" 'hop) nil))
1247 ;; Expand `tramp-default-method' and `tramp-default-user'.
1248 (should (string-equal
1249 (file-remote-p "/[-/1.2.3.4]")
1250 (format
1251 "/[%s/%s@%s]" "default-method" "default-user" "1.2.3.4")))
1252 (should (string-equal
1253 (file-remote-p "/[-/1.2.3.4]" 'method) "default-method"))
1254 (should (string-equal
1255 (file-remote-p "/[-/1.2.3.4]" 'user) "default-user"))
1256 (should (string-equal
1257 (file-remote-p "/[-/1.2.3.4]" 'host) "1.2.3.4"))
1258 (should (string-equal (file-remote-p "/[-/1.2.3.4]" 'localname) ""))
1259 (should (string-equal (file-remote-p "/[-/1.2.3.4]" 'hop) nil))
1261 ;; Expand `tramp-default-method'.
1262 (should (string-equal
1263 (file-remote-p "/[-/user@1.2.3.4]")
1264 (format "/[%s/%s@%s]" "default-method" "user" "1.2.3.4")))
1265 (should (string-equal
1266 (file-remote-p
1267 "/[-/user@1.2.3.4]" 'method) "default-method"))
1268 (should (string-equal
1269 (file-remote-p "/[-/user@1.2.3.4]" 'user) "user"))
1270 (should (string-equal
1271 (file-remote-p "/[-/user@1.2.3.4]" 'host) "1.2.3.4"))
1272 (should (string-equal
1273 (file-remote-p "/[-/user@1.2.3.4]" 'localname) ""))
1274 (should (string-equal (file-remote-p "/[-/user@1.2.3.4]" 'hop) nil))
1276 ;; Expand `tramp-default-user'.
1277 (should (string-equal
1278 (file-remote-p "/[method/1.2.3.4]")
1279 (format "/[%s/%s@%s]" "method" "default-user" "1.2.3.4")))
1280 (should (string-equal
1281 (file-remote-p "/[method/1.2.3.4]" 'method) "method"))
1282 (should (string-equal
1283 (file-remote-p "/[method/1.2.3.4]" 'user) "default-user"))
1284 (should (string-equal
1285 (file-remote-p "/[method/1.2.3.4]" 'host) "1.2.3.4"))
1286 (should (string-equal
1287 (file-remote-p "/[method/1.2.3.4]" 'localname) ""))
1288 (should (string-equal (file-remote-p "/[method/1.2.3.4]" 'hop) nil))
1290 ;; No expansion.
1291 (should (string-equal
1292 (file-remote-p "/[method/user@1.2.3.4]")
1293 (format "/[%s/%s@%s]" "method" "user" "1.2.3.4")))
1294 (should (string-equal
1295 (file-remote-p "/[method/user@1.2.3.4]" 'method) "method"))
1296 (should (string-equal
1297 (file-remote-p "/[method/user@1.2.3.4]" 'user) "user"))
1298 (should (string-equal
1299 (file-remote-p "/[method/user@1.2.3.4]" 'host) "1.2.3.4"))
1300 (should (string-equal
1301 (file-remote-p "/[method/user@1.2.3.4]" 'localname) ""))
1302 (should (string-equal
1303 (file-remote-p "/[method/user@1.2.3.4]" 'hop) nil))
1305 ;; Expand `tramp-default-method', `tramp-default-user' and
1306 ;; `tramp-default-host'.
1307 (should (string-equal
1308 (file-remote-p "/[/]")
1309 (format
1310 "/[%s/%s@%s]"
1311 "default-method" "default-user" "default-host")))
1312 (should (string-equal
1313 (file-remote-p "/[/]" 'method) "default-method"))
1314 (should (string-equal (file-remote-p "/[/]" 'user) "default-user"))
1315 (should (string-equal (file-remote-p "/[/]" 'host) "default-host"))
1316 (should (string-equal (file-remote-p "/[/]" 'localname) ""))
1317 (should (string-equal (file-remote-p "/[/]" 'hop) nil))
1319 ;; Expand `tramp-default-method' and `tramp-default-user'.
1320 (let ((tramp-default-host "::1"))
1321 (should (string-equal
1322 (file-remote-p "/[/]")
1323 (format
1324 "/[%s/%s@%s]"
1325 "default-method" "default-user" "::1")))
1326 (should (string-equal
1327 (file-remote-p "/[/]" 'method) "default-method"))
1328 (should (string-equal (file-remote-p "/[/]" 'user) "default-user"))
1329 (should (string-equal (file-remote-p "/[/]" 'host) "::1"))
1330 (should (string-equal (file-remote-p "/[/]" 'localname) ""))
1331 (should (string-equal (file-remote-p "/[/]" 'hop) nil)))
1333 ;; Expand `tramp-default-method' and `tramp-default-user'.
1334 (should (string-equal
1335 (file-remote-p "/[/::1]")
1336 (format
1337 "/[%s/%s@%s]" "default-method" "default-user" "::1")))
1338 (should (string-equal
1339 (file-remote-p "/[/::1]" 'method) "default-method"))
1340 (should (string-equal
1341 (file-remote-p "/[/::1]" 'user) "default-user"))
1342 (should (string-equal (file-remote-p "/[/::1]" 'host) "::1"))
1343 (should (string-equal (file-remote-p "/[/::1]" 'localname) ""))
1344 (should (string-equal (file-remote-p "/[/::1]" 'hop) nil))
1346 ;; Expand `tramp-default-method'.
1347 (should (string-equal
1348 (file-remote-p "/[/user@::1]")
1349 (format "/[%s/%s@%s]" "default-method" "user" "::1")))
1350 (should (string-equal
1351 (file-remote-p "/[/user@::1]" 'method) "default-method"))
1352 (should (string-equal (file-remote-p "/[/user@::1]" 'user) "user"))
1353 (should (string-equal (file-remote-p "/[/user@::1]" 'host) "::1"))
1354 (should (string-equal (file-remote-p "/[/user@::1]" 'localname) ""))
1355 (should (string-equal (file-remote-p "/[/user@::1]" 'hop) nil))
1357 ;; Expand `tramp-default-method', `tramp-default-user' and
1358 ;; `tramp-default-host'.
1359 (should (string-equal
1360 (file-remote-p "/[-/]")
1361 (format
1362 "/[%s/%s@%s]"
1363 "default-method" "default-user" "default-host")))
1364 (should (string-equal
1365 (file-remote-p "/[-/]" 'method) "default-method"))
1366 (should (string-equal (file-remote-p "/[-/]" 'user) "default-user"))
1367 (should (string-equal (file-remote-p "/[-/]" 'host) "default-host"))
1368 (should (string-equal (file-remote-p "/[-/]" 'localname) ""))
1369 (should (string-equal (file-remote-p "/[-/]" 'hop) nil))
1371 ;; Expand `tramp-default-method' and `tramp-default-user'.
1372 (let ((tramp-default-host "::1"))
1373 (should (string-equal
1374 (file-remote-p "/[-/]")
1375 (format
1376 "/[%s/%s@%s]"
1377 "default-method" "default-user" "::1")))
1378 (should (string-equal
1379 (file-remote-p "/[-/]" 'method) "default-method"))
1380 (should (string-equal (file-remote-p "/[-/]" 'user) "default-user"))
1381 (should (string-equal (file-remote-p "/[-/]" 'host) "::1"))
1382 (should (string-equal (file-remote-p "/[-/]" 'localname) ""))
1383 (should (string-equal (file-remote-p "/[-/]" 'hop) nil)))
1385 ;; Expand `tramp-default-method' and `tramp-default-user'.
1386 (should (string-equal
1387 (file-remote-p "/[-/::1]")
1388 (format
1389 "/[%s/%s@%s]" "default-method" "default-user" "::1")))
1390 (should (string-equal
1391 (file-remote-p "/[-/::1]" 'method) "default-method"))
1392 (should (string-equal
1393 (file-remote-p "/[-/::1]" 'user) "default-user"))
1394 (should (string-equal (file-remote-p "/[-/::1]" 'host) "::1"))
1395 (should (string-equal (file-remote-p "/[-/::1]" 'localname) ""))
1396 (should (string-equal (file-remote-p "/[-/::1]" 'hop) nil))
1398 ;; Expand `tramp-default-method'.
1399 (should (string-equal
1400 (file-remote-p "/[-/user@::1]")
1401 (format "/[%s/%s@%s]" "default-method" "user" "::1")))
1402 (should (string-equal
1403 (file-remote-p "/[-/user@::1]" 'method) "default-method"))
1404 (should (string-equal (file-remote-p "/[-/user@::1]" 'user) "user"))
1405 (should (string-equal (file-remote-p "/[-/user@::1]" 'host) "::1"))
1406 (should (string-equal (file-remote-p "/[-/user@::1]" 'localname) ""))
1407 (should (string-equal (file-remote-p "/[-/user@::1]" 'hop) nil))
1409 ;; Expand `tramp-default-user'.
1410 (should (string-equal
1411 (file-remote-p "/[method/::1]")
1412 (format "/[%s/%s@%s]" "method" "default-user" "::1")))
1413 (should (string-equal
1414 (file-remote-p "/[method/::1]" 'method) "method"))
1415 (should (string-equal
1416 (file-remote-p "/[method/::1]" 'user) "default-user"))
1417 (should (string-equal (file-remote-p "/[method/::1]" 'host) "::1"))
1418 (should (string-equal (file-remote-p "/[method/::1]" 'localname) ""))
1419 (should (string-equal (file-remote-p "/[method/::1]" 'hop) nil))
1421 ;; No expansion.
1422 (should (string-equal
1423 (file-remote-p "/[method/user@::1]")
1424 (format "/[%s/%s@%s]" "method" "user" "::1")))
1425 (should (string-equal
1426 (file-remote-p "/[method/user@::1]" 'method) "method"))
1427 (should (string-equal
1428 (file-remote-p "/[method/user@::1]" 'user) "user"))
1429 (should (string-equal
1430 (file-remote-p "/[method/user@::1]" 'host) "::1"))
1431 (should (string-equal
1432 (file-remote-p "/[method/user@::1]" 'localname) ""))
1433 (should (string-equal (file-remote-p "/[method/user@::1]" 'hop) nil))
1435 ;; Local file name part.
1436 (should (string-equal (file-remote-p "/[/host]/:" 'localname) "/:"))
1437 (should (string-equal (file-remote-p "/[-/host]/:" 'localname) "/:"))
1438 (should (string-equal (file-remote-p "/[method/]:" 'localname) ":"))
1439 (should (string-equal (file-remote-p "/[method/] " 'localname) " "))
1440 (should (string-equal
1441 (file-remote-p "/[method/]file" 'localname) "file"))
1442 (should (string-equal
1443 (file-remote-p "/[method/]/path/to/file" 'localname)
1444 "/path/to/file"))
1446 ;; Multihop.
1447 (should
1448 (string-equal
1449 (file-remote-p
1450 "/[method1/user1@host1|method2/user2@host2]/path/to/file")
1451 (format "/[%s/%s@%s|%s/%s@%s]"
1452 "method1" "user1" "host1" "method2" "user2" "host2")))
1453 (should
1454 (string-equal
1455 (file-remote-p
1456 "/[method1/user1@host1|method2/user2@host2]/path/to/file" 'method)
1457 "method2"))
1458 (should
1459 (string-equal
1460 (file-remote-p
1461 "/[method1/user1@host1|method2/user2@host2]/path/to/file" 'user)
1462 "user2"))
1463 (should
1464 (string-equal
1465 (file-remote-p
1466 "/[method1/user1@host1|method2/user2@host2]/path/to/file" 'host)
1467 "host2"))
1468 (should
1469 (string-equal
1470 (file-remote-p
1471 "/[method1/user1@host1|method2/user2@host2]/path/to/file"
1472 'localname)
1473 "/path/to/file"))
1474 (should
1475 (string-equal
1476 (file-remote-p
1477 "/[method1/user1@host1|method2/user2@host2]/path/to/file" 'hop)
1478 (format "%s/%s@%s|"
1479 "method1" "user1" "host1")))
1481 (should
1482 (string-equal
1483 (file-remote-p
1484 (concat
1485 "/[method1/user1@host1"
1486 "|method2/user2@host2"
1487 "|method3/user3@host3]/path/to/file"))
1488 (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
1489 "method1" "user1" "host1"
1490 "method2" "user2" "host2"
1491 "method3" "user3" "host3")))
1492 (should
1493 (string-equal
1494 (file-remote-p
1495 (concat
1496 "/[method1/user1@host1"
1497 "|method2/user2@host2"
1498 "|method3/user3@host3]/path/to/file")
1499 'method)
1500 "method3"))
1501 (should
1502 (string-equal
1503 (file-remote-p
1504 (concat
1505 "/[method1/user1@host1"
1506 "|method2/user2@host2"
1507 "|method3/user3@host3]/path/to/file")
1508 'user)
1509 "user3"))
1510 (should
1511 (string-equal
1512 (file-remote-p
1513 (concat
1514 "/[method1/user1@host1"
1515 "|method2/user2@host2"
1516 "|method3/user3@host3]/path/to/file")
1517 'host)
1518 "host3"))
1519 (should
1520 (string-equal
1521 (file-remote-p
1522 (concat
1523 "/[method1/user1@host1"
1524 "|method2/user2@host2"
1525 "|method3/user3@host3]/path/to/file")
1526 'localname)
1527 "/path/to/file"))
1528 (should
1529 (string-equal
1530 (file-remote-p
1531 (concat
1532 "/[method1/user1@host1"
1533 "|method2/user2@host2"
1534 "|method3/user3@host3]/path/to/file")
1535 'hop)
1536 (format "%s/%s@%s|%s/%s@%s|"
1537 "method1" "user1" "host1" "method2" "user2" "host2"))))
1539 ;; Exit.
1540 (tramp-change-syntax syntax))))
1542 (ert-deftest tramp-test03-file-name-defaults ()
1543 "Check default values for some methods."
1544 ;; Default values in tramp-adb.el.
1545 (should (string-equal (file-remote-p "/adb::" 'host) ""))
1546 ;; Default values in tramp-ftp.el.
1547 (should (string-equal (file-remote-p "/-:ftp.host:" 'method) "ftp"))
1548 (dolist (u '("ftp" "anonymous"))
1549 (should (string-equal (file-remote-p (format "/-:%s@:" u) 'method) "ftp")))
1550 ;; Default values in tramp-gvfs.el.
1551 (when (and (load "tramp-gvfs" 'noerror 'nomessage)
1552 (symbol-value 'tramp-gvfs-enabled))
1553 (should (string-equal (file-remote-p "/synce::" 'user) nil)))
1554 ;; Default values in tramp-sh.el.
1555 (dolist (h `("127.0.0.1" "[::1]" "localhost" "localhost6" ,(system-name)))
1556 (should
1557 (string-equal (file-remote-p (format "/-:root@%s:" h) 'method) "su")))
1558 (dolist (m '("su" "sudo" "ksu"))
1559 (should (string-equal (file-remote-p (format "/%s::" m) 'user) "root")))
1560 (dolist (m '("rcp" "remcp" "rsh" "telnet" "krlogin" "fcp"))
1561 (should
1562 (string-equal (file-remote-p (format "/%s::" m) 'user) (user-login-name))))
1563 ;; Default values in tramp-smb.el.
1564 (should (string-equal (file-remote-p "/smb::" 'user) nil)))
1566 (ert-deftest tramp-test04-substitute-in-file-name ()
1567 "Check `substitute-in-file-name'."
1568 (should (string-equal (substitute-in-file-name "/method:host://foo") "/foo"))
1569 (should
1570 (string-equal
1571 (substitute-in-file-name "/method:host:/path//foo") "/method:host:/foo"))
1572 (should
1573 (string-equal (substitute-in-file-name "/method:host:/path///foo") "/foo"))
1574 ;; Quoting local part.
1575 (should
1576 (string-equal
1577 (substitute-in-file-name "/method:host:/://foo") "/method:host:/://foo"))
1578 (should
1579 (string-equal
1580 (substitute-in-file-name "/method:host:/:/path//foo")
1581 "/method:host:/:/path//foo"))
1582 (should
1583 (string-equal
1584 (substitute-in-file-name "/method:host:/:/path///foo")
1585 "/method:host:/:/path///foo"))
1587 (should
1588 (string-equal
1589 (substitute-in-file-name "/method:host:/path/~/foo") "/method:host:~/foo"))
1590 (should
1591 (string-equal (substitute-in-file-name "/method:host:/path//~/foo") "~/foo"))
1592 ;; Quoting local part.
1593 (should
1594 (string-equal
1595 (substitute-in-file-name "/method:host:/:/path/~/foo")
1596 "/method:host:/:/path/~/foo"))
1597 (should
1598 (string-equal
1599 (substitute-in-file-name "/method:host:/:/path//~/foo")
1600 "/method:host:/:/path//~/foo"))
1602 (let (process-environment)
1603 (should
1604 (string-equal
1605 (substitute-in-file-name "/method:host:/path/$FOO")
1606 "/method:host:/path/$FOO"))
1607 (setenv "FOO" "bla")
1608 (should
1609 (string-equal
1610 (substitute-in-file-name "/method:host:/path/$FOO")
1611 "/method:host:/path/bla"))
1612 (should
1613 (string-equal
1614 (substitute-in-file-name "/method:host:/path/$$FOO")
1615 "/method:host:/path/$FOO"))
1616 ;; Quoting local part.
1617 (should
1618 (string-equal
1619 (substitute-in-file-name "/method:host:/:/path/$FOO")
1620 "/method:host:/:/path/$FOO"))
1621 (setenv "FOO" "bla")
1622 (should
1623 (string-equal
1624 (substitute-in-file-name "/method:host:/:/path/$FOO")
1625 "/method:host:/:/path/$FOO"))
1626 (should
1627 (string-equal
1628 (substitute-in-file-name "/method:host:/:/path/$$FOO")
1629 "/method:host:/:/path/$$FOO"))))
1631 (ert-deftest tramp-test05-expand-file-name ()
1632 "Check `expand-file-name'."
1633 (should
1634 (string-equal
1635 (expand-file-name "/method:host:/path/./file") "/method:host:/path/file"))
1636 (should
1637 (string-equal
1638 (expand-file-name "/method:host:/path/../file") "/method:host:/file"))
1639 ;; Quoting local part.
1640 (should
1641 (string-equal
1642 (expand-file-name "/method:host:/:/path/./file")
1643 "/method:host:/:/path/file"))
1644 (should
1645 (string-equal
1646 (expand-file-name "/method:host:/:/path/../file") "/method:host:/:/file"))
1647 (should
1648 (string-equal
1649 (expand-file-name "/method:host:/:/~/path/./file")
1650 "/method:host:/:/~/path/file")))
1652 ;; The following test is inspired by Bug#26911. It is rather a bug in
1653 ;; `expand-file-name', and it fails for all Emacs versions. Test
1654 ;; added for later, when it is fixed.
1655 (ert-deftest tramp-test05-expand-file-name-relative ()
1656 "Check `expand-file-name'."
1657 ;; Mark as failed until bug has been fixed.
1658 :expected-result :failed
1659 (skip-unless (tramp--test-enabled))
1660 ;; These are the methods the test doesn't fail.
1661 (when (or (tramp--test-adb-p) (tramp--test-gvfs-p)
1662 (tramp-smb-file-name-p tramp-test-temporary-file-directory))
1663 (setf (ert-test-expected-result-type
1664 (ert-get-test 'tramp-test05-expand-file-name-relative))
1665 :passed))
1667 (should
1668 (string-equal
1669 (let ((default-directory
1670 (concat
1671 (file-remote-p tramp-test-temporary-file-directory) "/path")))
1672 (expand-file-name ".." "./"))
1673 (concat (file-remote-p tramp-test-temporary-file-directory) "/"))))
1675 (ert-deftest tramp-test06-directory-file-name ()
1676 "Check `directory-file-name'.
1677 This checks also `file-name-as-directory', `file-name-directory',
1678 `file-name-nondirectory' and `unhandled-file-name-directory'."
1679 (should
1680 (string-equal
1681 (directory-file-name "/method:host:/path/to/file")
1682 "/method:host:/path/to/file"))
1683 (should
1684 (string-equal
1685 (directory-file-name "/method:host:/path/to/file/")
1686 "/method:host:/path/to/file"))
1687 (should
1688 (string-equal
1689 (file-name-as-directory "/method:host:/path/to/file")
1690 "/method:host:/path/to/file/"))
1691 (should
1692 (string-equal
1693 (file-name-as-directory "/method:host:/path/to/file/")
1694 "/method:host:/path/to/file/"))
1695 (should
1696 (string-equal
1697 (file-name-directory "/method:host:/path/to/file")
1698 "/method:host:/path/to/"))
1699 (should
1700 (string-equal
1701 (file-name-directory "/method:host:/path/to/file/")
1702 "/method:host:/path/to/file/"))
1703 (should
1704 (string-equal (file-name-nondirectory "/method:host:/path/to/file") "file"))
1705 (should
1706 (string-equal (file-name-nondirectory "/method:host:/path/to/file/") ""))
1707 (should-not
1708 (unhandled-file-name-directory "/method:host:/path/to/file"))
1710 ;; Bug#10085.
1711 (when (tramp--test-enabled) ;; Packages like tramp-gvfs.el might be disabled.
1712 (dolist (n-e '(nil t))
1713 ;; We must clear `tramp-default-method'. On hydra, it is "ftp",
1714 ;; which ruins the tests.
1715 (let ((non-essential n-e)
1716 tramp-default-method)
1717 (dolist
1718 (file
1719 `(,(format
1720 "/%s::"
1721 (file-remote-p tramp-test-temporary-file-directory 'method))
1722 ,(format
1723 "/-:%s:"
1724 (file-remote-p tramp-test-temporary-file-directory 'host))))
1725 (should (string-equal (directory-file-name file) file))
1726 (should
1727 (string-equal
1728 (file-name-as-directory file)
1729 (if (tramp-completion-mode-p)
1730 file (concat file "./"))))
1731 (should (string-equal (file-name-directory file) file))
1732 (should (string-equal (file-name-nondirectory file) "")))))))
1734 (ert-deftest tramp-test07-file-exists-p ()
1735 "Check `file-exist-p', `write-region' and `delete-file'."
1736 (skip-unless (tramp--test-enabled))
1738 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1739 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
1740 (should-not (file-exists-p tmp-name))
1741 (write-region "foo" nil tmp-name)
1742 (should (file-exists-p tmp-name))
1743 (delete-file tmp-name)
1744 (should-not (file-exists-p tmp-name)))))
1746 (ert-deftest tramp-test08-file-local-copy ()
1747 "Check `file-local-copy'."
1748 (skip-unless (tramp--test-enabled))
1750 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1751 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
1752 tmp-name2)
1753 (unwind-protect
1754 (progn
1755 (write-region "foo" nil tmp-name1)
1756 (should (setq tmp-name2 (file-local-copy tmp-name1)))
1757 (with-temp-buffer
1758 (insert-file-contents tmp-name2)
1759 (should (string-equal (buffer-string) "foo")))
1760 ;; Check also that a file transfer with compression works.
1761 (let ((default-directory tramp-test-temporary-file-directory)
1762 (tramp-copy-size-limit 4)
1763 (tramp-inline-compress-start-size 2))
1764 (delete-file tmp-name2)
1765 (should (setq tmp-name2 (file-local-copy tmp-name1)))))
1767 ;; Cleanup.
1768 (ignore-errors
1769 (delete-file tmp-name1)
1770 (delete-file tmp-name2))))))
1772 (ert-deftest tramp-test09-insert-file-contents ()
1773 "Check `insert-file-contents'."
1774 (skip-unless (tramp--test-enabled))
1776 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1777 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
1778 (unwind-protect
1779 (progn
1780 (write-region "foo" nil tmp-name)
1781 (with-temp-buffer
1782 (insert-file-contents tmp-name)
1783 (should (string-equal (buffer-string) "foo"))
1784 (insert-file-contents tmp-name)
1785 (should (string-equal (buffer-string) "foofoo"))
1786 ;; Insert partly.
1787 (insert-file-contents tmp-name nil 1 3)
1788 (should (string-equal (buffer-string) "oofoofoo"))
1789 ;; Replace.
1790 (insert-file-contents tmp-name nil nil nil 'replace)
1791 (should (string-equal (buffer-string) "foo"))))
1793 ;; Cleanup.
1794 (ignore-errors (delete-file tmp-name))))))
1796 (ert-deftest tramp-test10-write-region ()
1797 "Check `write-region'."
1798 (skip-unless (tramp--test-enabled))
1800 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1801 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
1802 (unwind-protect
1803 (progn
1804 ;; Write buffer. Use absolute and relative file name.
1805 (with-temp-buffer
1806 (insert "foo")
1807 (write-region nil nil tmp-name))
1808 (with-temp-buffer
1809 (insert-file-contents tmp-name)
1810 (should (string-equal (buffer-string) "foo")))
1811 (delete-file tmp-name)
1812 (with-temp-buffer
1813 (insert "foo")
1814 (should-not (file-exists-p tmp-name))
1815 (let ((default-directory (file-name-directory tmp-name)))
1816 (should-not (file-exists-p (file-name-nondirectory tmp-name)))
1817 (write-region nil nil (file-name-nondirectory tmp-name))
1818 (should (file-exists-p (file-name-nondirectory tmp-name))))
1819 (should (file-exists-p tmp-name)))
1820 (with-temp-buffer
1821 (insert-file-contents tmp-name)
1822 (should (string-equal (buffer-string) "foo")))
1824 ;; Append.
1825 (with-temp-buffer
1826 (insert "bla")
1827 (write-region nil nil tmp-name 'append))
1828 (with-temp-buffer
1829 (insert-file-contents tmp-name)
1830 (should (string-equal (buffer-string) "foobla")))
1831 (with-temp-buffer
1832 (insert "baz")
1833 (write-region nil nil tmp-name 3))
1834 (with-temp-buffer
1835 (insert-file-contents tmp-name)
1836 (should (string-equal (buffer-string) "foobaz")))
1838 ;; Write string.
1839 (write-region "foo" nil tmp-name)
1840 (with-temp-buffer
1841 (insert-file-contents tmp-name)
1842 (should (string-equal (buffer-string) "foo")))
1844 ;; Write partly.
1845 (with-temp-buffer
1846 (insert "123456789")
1847 (write-region 3 5 tmp-name))
1848 (with-temp-buffer
1849 (insert-file-contents tmp-name)
1850 (should (string-equal (buffer-string) "34")))
1852 ;; Do not overwrite if excluded.
1853 (cl-letf (((symbol-function 'y-or-n-p) (lambda (_prompt) t)))
1854 (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
1855 ;; `mustbenew' is passed to Tramp since Emacs 26.1. We
1856 ;; have no test for this, so we check function
1857 ;; `temporary-file-directory', which has been added to
1858 ;; Emacs 26.1 as well.
1859 (when (fboundp 'temporary-file-directory)
1860 (should-error
1861 (cl-letf (((symbol-function 'y-or-n-p) 'ignore))
1862 (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
1863 :type 'file-already-exists)
1864 (should-error
1865 (write-region "foo" nil tmp-name nil nil nil 'excl)
1866 :type 'file-already-exists)))
1868 ;; Cleanup.
1869 (ignore-errors (delete-file tmp-name))))))
1871 (ert-deftest tramp-test11-copy-file ()
1872 "Check `copy-file'."
1873 (skip-unless (tramp--test-enabled))
1875 ;; TODO: The quoted case does not work.
1876 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1877 (let (quoted)
1878 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
1879 (tmp-name2 (tramp--test-make-temp-name nil quoted))
1880 (tmp-name3 (tramp--test-make-temp-name nil quoted))
1881 (tmp-name4 (tramp--test-make-temp-name 'local quoted))
1882 (tmp-name5 (tramp--test-make-temp-name 'local quoted)))
1884 ;; Copy on remote side.
1885 (unwind-protect
1886 (progn
1887 (write-region "foo" nil tmp-name1)
1888 (copy-file tmp-name1 tmp-name2)
1889 (should (file-exists-p tmp-name2))
1890 (with-temp-buffer
1891 (insert-file-contents tmp-name2)
1892 (should (string-equal (buffer-string) "foo")))
1893 (should-error (copy-file tmp-name1 tmp-name2))
1894 (copy-file tmp-name1 tmp-name2 'ok)
1895 (make-directory tmp-name3)
1896 (copy-file tmp-name1 tmp-name3)
1897 (should
1898 (file-exists-p
1899 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name3))))
1901 ;; Cleanup.
1902 (ignore-errors (delete-file tmp-name1))
1903 (ignore-errors (delete-file tmp-name2))
1904 (ignore-errors (delete-directory tmp-name3 'recursive)))
1906 ;; Copy from remote side to local side.
1907 (unwind-protect
1908 (progn
1909 (write-region "foo" nil tmp-name1)
1910 (copy-file tmp-name1 tmp-name4)
1911 (should (file-exists-p tmp-name4))
1912 (with-temp-buffer
1913 (insert-file-contents tmp-name4)
1914 (should (string-equal (buffer-string) "foo")))
1915 (should-error (copy-file tmp-name1 tmp-name4))
1916 (copy-file tmp-name1 tmp-name4 'ok)
1917 (make-directory tmp-name5)
1918 (copy-file tmp-name1 tmp-name5)
1919 (should
1920 (file-exists-p
1921 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name5))))
1923 ;; Cleanup.
1924 (ignore-errors (delete-file tmp-name1))
1925 (ignore-errors (delete-file tmp-name4))
1926 (ignore-errors (delete-directory tmp-name5 'recursive)))
1928 ;; Copy from local side to remote side.
1929 (unwind-protect
1930 (progn
1931 (write-region "foo" nil tmp-name4 nil 'nomessage)
1932 (copy-file tmp-name4 tmp-name1)
1933 (should (file-exists-p tmp-name1))
1934 (with-temp-buffer
1935 (insert-file-contents tmp-name1)
1936 (should (string-equal (buffer-string) "foo")))
1937 (should-error (copy-file tmp-name4 tmp-name1))
1938 (copy-file tmp-name4 tmp-name1 'ok)
1939 (make-directory tmp-name3)
1940 (copy-file tmp-name4 tmp-name3)
1941 (should
1942 (file-exists-p
1943 (expand-file-name (file-name-nondirectory tmp-name4) tmp-name3))))
1945 ;; Cleanup.
1946 (ignore-errors (delete-file tmp-name1))
1947 (ignore-errors (delete-file tmp-name4))
1948 (ignore-errors (delete-directory tmp-name3 'recursive))))))
1950 (ert-deftest tramp-test12-rename-file ()
1951 "Check `rename-file'."
1952 (skip-unless (tramp--test-enabled))
1954 ;; TODO: The quoted case does not work.
1955 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1956 (let (quoted)
1957 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
1958 (tmp-name2 (tramp--test-make-temp-name nil quoted))
1959 (tmp-name3 (tramp--test-make-temp-name nil quoted))
1960 (tmp-name4 (tramp--test-make-temp-name 'local quoted))
1961 (tmp-name5 (tramp--test-make-temp-name 'local quoted)))
1963 ;; Rename on remote side.
1964 (unwind-protect
1965 (progn
1966 (write-region "foo" nil tmp-name1)
1967 (rename-file tmp-name1 tmp-name2)
1968 (should-not (file-exists-p tmp-name1))
1969 (should (file-exists-p tmp-name2))
1970 (with-temp-buffer
1971 (insert-file-contents tmp-name2)
1972 (should (string-equal (buffer-string) "foo")))
1973 (write-region "foo" nil tmp-name1)
1974 (should-error (rename-file tmp-name1 tmp-name2))
1975 (rename-file tmp-name1 tmp-name2 'ok)
1976 (should-not (file-exists-p tmp-name1))
1977 (write-region "foo" nil tmp-name1)
1978 (make-directory tmp-name3)
1979 (rename-file tmp-name1 tmp-name3)
1980 (should-not (file-exists-p tmp-name1))
1981 (should
1982 (file-exists-p
1983 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name3))))
1985 ;; Cleanup.
1986 (ignore-errors (delete-file tmp-name1))
1987 (ignore-errors (delete-file tmp-name2))
1988 (ignore-errors (delete-directory tmp-name3 'recursive)))
1990 ;; Rename from remote side to local side.
1991 (unwind-protect
1992 (progn
1993 (write-region "foo" nil tmp-name1)
1994 (rename-file tmp-name1 tmp-name4)
1995 (should-not (file-exists-p tmp-name1))
1996 (should (file-exists-p tmp-name4))
1997 (with-temp-buffer
1998 (insert-file-contents tmp-name4)
1999 (should (string-equal (buffer-string) "foo")))
2000 (write-region "foo" nil tmp-name1)
2001 (should-error (rename-file tmp-name1 tmp-name4))
2002 (rename-file tmp-name1 tmp-name4 'ok)
2003 (should-not (file-exists-p tmp-name1))
2004 (write-region "foo" nil tmp-name1)
2005 (make-directory tmp-name5)
2006 (rename-file tmp-name1 tmp-name5)
2007 (should-not (file-exists-p tmp-name1))
2008 (should
2009 (file-exists-p
2010 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name5))))
2012 ;; Cleanup.
2013 (ignore-errors (delete-file tmp-name1))
2014 (ignore-errors (delete-file tmp-name4))
2015 (ignore-errors (delete-directory tmp-name5 'recursive)))
2017 ;; Rename from local side to remote side.
2018 (unwind-protect
2019 (progn
2020 (write-region "foo" nil tmp-name4 nil 'nomessage)
2021 (rename-file tmp-name4 tmp-name1)
2022 (should-not (file-exists-p tmp-name4))
2023 (should (file-exists-p tmp-name1))
2024 (with-temp-buffer
2025 (insert-file-contents tmp-name1)
2026 (should (string-equal (buffer-string) "foo")))
2027 (write-region "foo" nil tmp-name4 nil 'nomessage)
2028 (should-error (rename-file tmp-name4 tmp-name1))
2029 (rename-file tmp-name4 tmp-name1 'ok)
2030 (should-not (file-exists-p tmp-name4))
2031 (write-region "foo" nil tmp-name4 nil 'nomessage)
2032 (make-directory tmp-name3)
2033 (rename-file tmp-name4 tmp-name3)
2034 (should-not (file-exists-p tmp-name4))
2035 (should
2036 (file-exists-p
2037 (expand-file-name (file-name-nondirectory tmp-name4) tmp-name3))))
2039 ;; Cleanup.
2040 (ignore-errors (delete-file tmp-name1))
2041 (ignore-errors (delete-file tmp-name4))
2042 (ignore-errors (delete-directory tmp-name3 'recursive))))))
2044 (ert-deftest tramp-test13-make-directory ()
2045 "Check `make-directory'.
2046 This tests also `file-directory-p' and `file-accessible-directory-p'."
2047 (skip-unless (tramp--test-enabled))
2049 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2050 (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2051 (tmp-name2 (expand-file-name "foo/bar" tmp-name1)))
2052 (unwind-protect
2053 (progn
2054 (make-directory tmp-name1)
2055 (should (file-directory-p tmp-name1))
2056 (should (file-accessible-directory-p tmp-name1))
2057 (should-error (make-directory tmp-name2))
2058 (make-directory tmp-name2 'parents)
2059 (should (file-directory-p tmp-name2))
2060 (should (file-accessible-directory-p tmp-name2)))
2062 ;; Cleanup.
2063 (ignore-errors (delete-directory tmp-name1 'recursive))))))
2065 (ert-deftest tramp-test14-delete-directory ()
2066 "Check `delete-directory'."
2067 (skip-unless (tramp--test-enabled))
2069 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2070 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
2071 ;; Delete empty directory.
2072 (make-directory tmp-name)
2073 (should (file-directory-p tmp-name))
2074 (delete-directory tmp-name)
2075 (should-not (file-directory-p tmp-name))
2076 ;; Delete non-empty directory.
2077 (make-directory tmp-name)
2078 (should (file-directory-p tmp-name))
2079 (write-region "foo" nil (expand-file-name "bla" tmp-name))
2080 (should (file-exists-p (expand-file-name "bla" tmp-name)))
2081 (should-error (delete-directory tmp-name))
2082 (delete-directory tmp-name 'recursive)
2083 (should-not (file-directory-p tmp-name)))))
2085 (ert-deftest tramp-test15-copy-directory ()
2086 "Check `copy-directory'."
2087 (skip-unless (tramp--test-enabled))
2089 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2090 (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2091 (tmp-name2 (tramp--test-make-temp-name nil quoted))
2092 (tmp-name3 (expand-file-name
2093 (file-name-nondirectory tmp-name1) tmp-name2))
2094 (tmp-name4 (expand-file-name "foo" tmp-name1))
2095 (tmp-name5 (expand-file-name "foo" tmp-name2))
2096 (tmp-name6 (expand-file-name "foo" tmp-name3)))
2098 ;; Copy complete directory.
2099 (unwind-protect
2100 (progn
2101 ;; Copy empty directory.
2102 (make-directory tmp-name1)
2103 (write-region "foo" nil tmp-name4)
2104 (should (file-directory-p tmp-name1))
2105 (should (file-exists-p tmp-name4))
2106 (copy-directory tmp-name1 tmp-name2)
2107 (should (file-directory-p tmp-name2))
2108 (should (file-exists-p tmp-name5))
2109 ;; Target directory does exist already.
2110 (copy-directory tmp-name1 tmp-name2)
2111 (should (file-directory-p tmp-name3))
2112 (should (file-exists-p tmp-name6)))
2114 ;; Cleanup.
2115 (ignore-errors
2116 (delete-directory tmp-name1 'recursive)
2117 (delete-directory tmp-name2 'recursive)))
2119 ;; Copy directory contents.
2120 (unwind-protect
2121 (progn
2122 ;; Copy empty directory.
2123 (make-directory tmp-name1)
2124 (write-region "foo" nil tmp-name4)
2125 (should (file-directory-p tmp-name1))
2126 (should (file-exists-p tmp-name4))
2127 (copy-directory tmp-name1 tmp-name2 nil 'parents 'contents)
2128 (should (file-directory-p tmp-name2))
2129 (should (file-exists-p tmp-name5))
2130 ;; Target directory does exist already.
2131 (delete-file tmp-name5)
2132 (should-not (file-exists-p tmp-name5))
2133 (copy-directory tmp-name1 tmp-name2 nil 'parents 'contents)
2134 (should (file-directory-p tmp-name2))
2135 (should (file-exists-p tmp-name5))
2136 (should-not (file-directory-p tmp-name3))
2137 (should-not (file-exists-p tmp-name6)))
2139 ;; Cleanup.
2140 (ignore-errors
2141 (delete-directory tmp-name1 'recursive)
2142 (delete-directory tmp-name2 'recursive))))))
2144 (ert-deftest tramp-test16-directory-files ()
2145 "Check `directory-files'."
2146 (skip-unless (tramp--test-enabled))
2148 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2149 (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2150 (tmp-name2 (expand-file-name "bla" tmp-name1))
2151 (tmp-name3 (expand-file-name "foo" tmp-name1)))
2152 (unwind-protect
2153 (progn
2154 (make-directory tmp-name1)
2155 (write-region "foo" nil tmp-name2)
2156 (write-region "bla" nil tmp-name3)
2157 (should (file-directory-p tmp-name1))
2158 (should (file-exists-p tmp-name2))
2159 (should (file-exists-p tmp-name3))
2160 (should (equal (directory-files tmp-name1) '("." ".." "bla" "foo")))
2161 (should (equal (directory-files tmp-name1 'full)
2162 `(,(concat tmp-name1 "/.")
2163 ,(concat tmp-name1 "/..")
2164 ,tmp-name2 ,tmp-name3)))
2165 (should (equal (directory-files
2166 tmp-name1 nil directory-files-no-dot-files-regexp)
2167 '("bla" "foo")))
2168 (should (equal (directory-files
2169 tmp-name1 'full directory-files-no-dot-files-regexp)
2170 `(,tmp-name2 ,tmp-name3))))
2172 ;; Cleanup.
2173 (ignore-errors (delete-directory tmp-name1 'recursive))))))
2175 ;; This is not a file name handler test. But Tramp needed to apply an
2176 ;; advice for older Emacs versions, so we check that this has been fixed.
2177 (ert-deftest tramp-test16-file-expand-wildcards ()
2178 "Check `file-expand-wildcards'."
2179 (skip-unless (tramp--test-enabled))
2181 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2182 (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2183 (tmp-name2 (expand-file-name "foo" tmp-name1))
2184 (tmp-name3 (expand-file-name "bar" tmp-name1))
2185 (tmp-name4 (expand-file-name "baz" tmp-name1))
2186 (default-directory tmp-name1))
2187 (unwind-protect
2188 (progn
2189 (make-directory tmp-name1)
2190 (write-region "foo" nil tmp-name2)
2191 (write-region "bar" nil tmp-name3)
2192 (write-region "baz" nil tmp-name4)
2193 (should (file-directory-p tmp-name1))
2194 (should (file-exists-p tmp-name2))
2195 (should (file-exists-p tmp-name3))
2196 (should (file-exists-p tmp-name4))
2198 ;; We cannot use `sort', it works destructive.
2199 (should (equal (file-expand-wildcards "*")
2200 (seq-sort 'string< '("foo" "bar" "baz"))))
2201 (should (equal (file-expand-wildcards "ba?")
2202 (seq-sort 'string< '("bar" "baz"))))
2203 (should (equal (file-expand-wildcards "ba[rz]")
2204 (seq-sort 'string< '("bar" "baz"))))
2206 (should (equal (file-expand-wildcards "*" 'full)
2207 (seq-sort
2208 'string< `(,tmp-name2 ,tmp-name3 ,tmp-name4))))
2209 (should (equal (file-expand-wildcards "ba?" 'full)
2210 (seq-sort 'string< `(,tmp-name3 ,tmp-name4))))
2211 (should (equal (file-expand-wildcards "ba[rz]" 'full)
2212 (seq-sort 'string< `(,tmp-name3 ,tmp-name4))))
2214 (should (equal (file-expand-wildcards (concat tmp-name1 "/" "*"))
2215 (seq-sort
2216 'string< `(,tmp-name2 ,tmp-name3 ,tmp-name4))))
2217 (should (equal (file-expand-wildcards (concat tmp-name1 "/" "ba?"))
2218 (seq-sort 'string< `(,tmp-name3 ,tmp-name4))))
2219 (should (equal (file-expand-wildcards
2220 (concat tmp-name1 "/" "ba[rz]"))
2221 (seq-sort 'string< `(,tmp-name3 ,tmp-name4)))))
2223 ;; Cleanup.
2224 (ignore-errors
2225 (delete-directory tmp-name1))))))
2227 (ert-deftest tramp-test17-insert-directory ()
2228 "Check `insert-directory'."
2229 (skip-unless (tramp--test-enabled))
2231 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2232 (let* ((tmp-name1
2233 (expand-file-name (tramp--test-make-temp-name nil quoted)))
2234 (tmp-name2 (expand-file-name "foo" tmp-name1))
2235 ;; We test for the summary line. Keyword "total" could be localized.
2236 (process-environment
2237 (append '("LANG=C" "LANGUAGE=C" "LC_ALL=C") process-environment)))
2238 (unwind-protect
2239 (progn
2240 (make-directory tmp-name1)
2241 (write-region "foo" nil tmp-name2)
2242 (should (file-directory-p tmp-name1))
2243 (should (file-exists-p tmp-name2))
2244 (with-temp-buffer
2245 (insert-directory tmp-name1 nil)
2246 (goto-char (point-min))
2247 (should (looking-at-p (regexp-quote tmp-name1))))
2248 (with-temp-buffer
2249 (insert-directory tmp-name1 "-al")
2250 (goto-char (point-min))
2251 (should
2252 (looking-at-p (format "^.+ %s$" (regexp-quote tmp-name1)))))
2253 (with-temp-buffer
2254 (insert-directory (file-name-as-directory tmp-name1) "-al")
2255 (goto-char (point-min))
2256 (should
2257 (looking-at-p (format "^.+ %s/$" (regexp-quote tmp-name1)))))
2258 (with-temp-buffer
2259 (insert-directory
2260 (file-name-as-directory tmp-name1) "-al" nil 'full-directory-p)
2261 (goto-char (point-min))
2262 (should
2263 (looking-at-p
2264 (concat
2265 ;; There might be a summary line.
2266 "\\(total.+[[:digit:]]+\n\\)?"
2267 ;; We don't know in which order ".", ".." and "foo" appear.
2268 "\\(.+ \\(\\.?\\.\\|foo\\)\n\\)\\{3\\}")))))
2270 ;; Cleanup.
2271 (ignore-errors (delete-directory tmp-name1 'recursive))))))
2273 (ert-deftest tramp-test17-dired-with-wildcards ()
2274 "Check `dired' with wildcards."
2275 (skip-unless (tramp--test-enabled))
2276 (skip-unless (tramp--test-sh-p))
2277 ;; Since Emacs 26.1.
2278 (skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
2280 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2281 (let* ((tmp-name1
2282 (expand-file-name (tramp--test-make-temp-name nil quoted)))
2283 (tmp-name2
2284 (expand-file-name (tramp--test-make-temp-name nil quoted)))
2285 (tmp-name3 (expand-file-name "foo" tmp-name1))
2286 (tmp-name4 (expand-file-name "bar" tmp-name2))
2287 (tramp-test-temporary-file-directory
2288 (funcall
2289 (if quoted 'tramp-compat-file-name-quote 'identity)
2290 tramp-test-temporary-file-directory))
2291 buffer)
2292 (unwind-protect
2293 (progn
2294 (make-directory tmp-name1)
2295 (write-region "foo" nil tmp-name3)
2296 (should (file-directory-p tmp-name1))
2297 (should (file-exists-p tmp-name3))
2298 (make-directory tmp-name2)
2299 (write-region "foo" nil tmp-name4)
2300 (should (file-directory-p tmp-name2))
2301 (should (file-exists-p tmp-name4))
2303 ;; Check for expanded directory names.
2304 (with-current-buffer
2305 (setq buffer
2306 (dired-noselect
2307 (expand-file-name
2308 "tramp-test*" tramp-test-temporary-file-directory)))
2309 (goto-char (point-min))
2310 (should
2311 (re-search-forward
2312 (regexp-quote
2313 (file-relative-name
2314 tmp-name1 tramp-test-temporary-file-directory))))
2315 (goto-char (point-min))
2316 (should
2317 (re-search-forward
2318 (regexp-quote
2319 (file-relative-name
2320 tmp-name2 tramp-test-temporary-file-directory)))))
2321 (kill-buffer buffer)
2323 ;; Check for expanded directory and file names.
2324 (with-current-buffer
2325 (setq buffer
2326 (dired-noselect
2327 (expand-file-name
2328 "tramp-test*/*" tramp-test-temporary-file-directory)))
2329 (goto-char (point-min))
2330 (should
2331 (re-search-forward
2332 (regexp-quote
2333 (file-relative-name
2334 tmp-name3 tramp-test-temporary-file-directory))))
2335 (goto-char (point-min))
2336 (should
2337 (re-search-forward
2338 (regexp-quote
2339 (file-relative-name
2340 tmp-name4
2341 tramp-test-temporary-file-directory)))))
2342 (kill-buffer buffer)
2344 ;; Check for special characters.
2345 (setq tmp-name3 (expand-file-name "*?" tmp-name1))
2346 (setq tmp-name4 (expand-file-name "[a-z0-9]" tmp-name2))
2347 (write-region "foo" nil tmp-name3)
2348 (should (file-exists-p tmp-name3))
2349 (write-region "foo" nil tmp-name4)
2350 (should (file-exists-p tmp-name4))
2352 (with-current-buffer
2353 (setq buffer
2354 (dired-noselect
2355 (expand-file-name
2356 "tramp-test*/*" tramp-test-temporary-file-directory)))
2357 (goto-char (point-min))
2358 (should
2359 (re-search-forward
2360 (regexp-quote
2361 (file-relative-name
2362 tmp-name3 tramp-test-temporary-file-directory))))
2363 (goto-char (point-min))
2364 (should
2365 (re-search-forward
2366 (regexp-quote
2367 (file-relative-name
2368 tmp-name4
2369 tramp-test-temporary-file-directory)))))
2370 (kill-buffer buffer))
2372 ;; Cleanup.
2373 (ignore-errors (kill-buffer buffer))
2374 (ignore-errors (delete-directory tmp-name1 'recursive))
2375 (ignore-errors (delete-directory tmp-name2 'recursive))))))
2377 (ert-deftest tramp-test18-file-attributes ()
2378 "Check `file-attributes'.
2379 This tests also `file-readable-p', `file-regular-p' and
2380 `file-ownership-preserved-p'."
2381 (skip-unless (tramp--test-enabled))
2383 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2384 ;; We must use `file-truename' for the temporary directory,
2385 ;; because it could be located on a symlinked directory. This
2386 ;; would let the test fail.
2387 (let* ((tramp-test-temporary-file-directory
2388 (file-truename tramp-test-temporary-file-directory))
2389 (tmp-name1 (tramp--test-make-temp-name nil quoted))
2390 (tmp-name2 (tramp--test-make-temp-name nil quoted))
2391 ;; File name with "//".
2392 (tmp-name3
2393 (format
2394 "%s%s"
2395 (file-remote-p tmp-name1)
2396 (replace-regexp-in-string
2397 "/" "//" (file-remote-p tmp-name1 'localname))))
2398 attr)
2399 (unwind-protect
2400 (progn
2401 ;; `file-ownership-preserved-p' should return t for
2402 ;; non-existing files. It is implemented only in tramp-sh.el.
2403 (when (tramp--test-sh-p)
2404 (should (file-ownership-preserved-p tmp-name1 'group)))
2405 (write-region "foo" nil tmp-name1)
2406 (should (file-exists-p tmp-name1))
2407 (should (file-readable-p tmp-name1))
2408 (should (file-regular-p tmp-name1))
2409 (when (tramp--test-sh-p)
2410 (should (file-ownership-preserved-p tmp-name1 'group)))
2412 ;; We do not test inodes and device numbers.
2413 (setq attr (file-attributes tmp-name1))
2414 (should (consp attr))
2415 (should (null (car attr)))
2416 (should (numberp (nth 1 attr))) ;; Link.
2417 (should (numberp (nth 2 attr))) ;; Uid.
2418 (should (numberp (nth 3 attr))) ;; Gid.
2419 ;; Last access time.
2420 (should (stringp (current-time-string (nth 4 attr))))
2421 ;; Last modification time.
2422 (should (stringp (current-time-string (nth 5 attr))))
2423 ;; Last status change time.
2424 (should (stringp (current-time-string (nth 6 attr))))
2425 (should (numberp (nth 7 attr))) ;; Size.
2426 (should (stringp (nth 8 attr))) ;; Modes.
2428 (setq attr (file-attributes tmp-name1 'string))
2429 (should (stringp (nth 2 attr))) ;; Uid.
2430 (should (stringp (nth 3 attr))) ;; Gid.
2432 (condition-case err
2433 (progn
2434 (when (tramp--test-sh-p)
2435 (should (file-ownership-preserved-p tmp-name2 'group)))
2436 (make-symbolic-link tmp-name1 tmp-name2)
2437 (should (file-exists-p tmp-name2))
2438 (should (file-symlink-p tmp-name2))
2439 (when (tramp--test-sh-p)
2440 (should (file-ownership-preserved-p tmp-name2 'group)))
2441 (setq attr (file-attributes tmp-name2))
2442 (should
2443 (string-equal
2444 (funcall
2445 (if quoted 'tramp-compat-file-name-quote 'identity)
2446 (car attr))
2447 (file-remote-p (file-truename tmp-name1) 'localname)))
2448 (delete-file tmp-name2))
2449 (file-error
2450 (should (string-equal (error-message-string err)
2451 "make-symbolic-link not supported"))))
2453 ;; Check, that "//" in symlinks are handled properly.
2454 (with-temp-buffer
2455 (let ((default-directory tramp-test-temporary-file-directory))
2456 (shell-command
2457 (format
2458 "ln -s %s %s"
2459 (tramp-file-name-localname
2460 (tramp-dissect-file-name tmp-name3))
2461 (tramp-file-name-localname
2462 (tramp-dissect-file-name tmp-name2)))
2463 t)))
2464 (when (file-symlink-p tmp-name2)
2465 (setq attr (file-attributes tmp-name2))
2466 (should
2467 (string-equal
2468 (car attr)
2469 (tramp-file-name-localname
2470 (tramp-dissect-file-name tmp-name3))))
2471 (delete-file tmp-name2))
2473 (when (tramp--test-sh-p)
2474 (should (file-ownership-preserved-p tmp-name1 'group)))
2475 (delete-file tmp-name1)
2476 (make-directory tmp-name1)
2477 (should (file-exists-p tmp-name1))
2478 (should (file-readable-p tmp-name1))
2479 (should-not (file-regular-p tmp-name1))
2480 (when (tramp--test-sh-p)
2481 (should (file-ownership-preserved-p tmp-name1 'group)))
2482 (setq attr (file-attributes tmp-name1))
2483 (should (eq (car attr) t)))
2485 ;; Cleanup.
2486 (ignore-errors (delete-directory tmp-name1))
2487 (ignore-errors (delete-file tmp-name1))
2488 (ignore-errors (delete-file tmp-name2))))))
2490 (ert-deftest tramp-test19-directory-files-and-attributes ()
2491 "Check `directory-files-and-attributes'."
2492 (skip-unless (tramp--test-enabled))
2494 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2495 ;; `directory-files-and-attributes' contains also values for
2496 ;; "../". Ensure that this doesn't change during tests, for
2497 ;; example due to handling temporary files.
2498 (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2499 (tmp-name2 (expand-file-name "bla" tmp-name1))
2500 attr)
2501 (unwind-protect
2502 (progn
2503 (make-directory tmp-name1)
2504 (should (file-directory-p tmp-name1))
2505 (make-directory tmp-name2)
2506 (should (file-directory-p tmp-name2))
2507 (write-region "foo" nil (expand-file-name "foo" tmp-name2))
2508 (write-region "bar" nil (expand-file-name "bar" tmp-name2))
2509 (write-region "boz" nil (expand-file-name "boz" tmp-name2))
2510 (setq attr (directory-files-and-attributes tmp-name2))
2511 (should (consp attr))
2512 ;; Dumb remote shells without perl(1) or stat(1) are not
2513 ;; able to return the date correctly. They say "don't know".
2514 (dolist (elt attr)
2515 (unless
2516 (equal
2517 (nth
2518 5 (file-attributes (expand-file-name (car elt) tmp-name2)))
2519 '(0 0))
2520 (should
2521 (equal (file-attributes (expand-file-name (car elt) tmp-name2))
2522 (cdr elt)))))
2523 (setq attr (directory-files-and-attributes tmp-name2 'full))
2524 (dolist (elt attr)
2525 (unless (equal (nth 5 (file-attributes (car elt))) '(0 0))
2526 (should
2527 (equal (file-attributes (car elt)) (cdr elt)))))
2528 (setq attr (directory-files-and-attributes tmp-name2 nil "^b"))
2529 (should (equal (mapcar 'car attr) '("bar" "boz"))))
2531 ;; Cleanup.
2532 (ignore-errors (delete-directory tmp-name1 'recursive))))))
2534 (ert-deftest tramp-test20-file-modes ()
2535 "Check `file-modes'.
2536 This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
2537 (skip-unless (tramp--test-enabled))
2538 (skip-unless (tramp--test-sh-p))
2540 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2541 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
2542 (unwind-protect
2543 (progn
2544 (write-region "foo" nil tmp-name)
2545 (should (file-exists-p tmp-name))
2546 (set-file-modes tmp-name #o777)
2547 (should (= (file-modes tmp-name) #o777))
2548 (should (file-executable-p tmp-name))
2549 (should (file-writable-p tmp-name))
2550 (set-file-modes tmp-name #o444)
2551 (should (= (file-modes tmp-name) #o444))
2552 (should-not (file-executable-p tmp-name))
2553 ;; A file is always writable for user "root".
2554 (unless (zerop (nth 2 (file-attributes tmp-name)))
2555 (should-not (file-writable-p tmp-name))))
2557 ;; Cleanup.
2558 (ignore-errors (delete-file tmp-name))))))
2560 (ert-deftest tramp-test21-file-links ()
2561 "Check `file-symlink-p'.
2562 This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
2563 (skip-unless (tramp--test-enabled))
2565 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2566 ;; We must use `file-truename' for the temporary directory,
2567 ;; because it could be located on a symlinked directory. This
2568 ;; would let the test fail.
2569 (let* ((tramp-test-temporary-file-directory
2570 (file-truename tramp-test-temporary-file-directory))
2571 (tmp-name1 (tramp--test-make-temp-name nil quoted))
2572 (tmp-name2 (tramp--test-make-temp-name nil quoted))
2573 (tmp-name3 (tramp--test-make-temp-name 'local quoted)))
2575 ;; Check `make-symbolic-link'.
2576 (unwind-protect
2577 (progn
2578 (write-region "foo" nil tmp-name1)
2579 (should (file-exists-p tmp-name1))
2580 ;; Method "smb" supports `make-symbolic-link' only if the
2581 ;; remote host has CIFS capabilities. tramp-adb.el and
2582 ;; tramp-gvfs.el do not support symbolic links at all.
2583 (condition-case err
2584 (make-symbolic-link tmp-name1 tmp-name2)
2585 (file-error
2586 (skip-unless
2587 (not (string-equal (error-message-string err)
2588 "make-symbolic-link not supported")))))
2589 (should (file-symlink-p tmp-name2))
2590 (should-error (make-symbolic-link tmp-name1 tmp-name2))
2591 (make-symbolic-link tmp-name1 tmp-name2 'ok-if-already-exists)
2592 (should (file-symlink-p tmp-name2))
2593 ;; `tmp-name3' is a local file name.
2594 (should-error (make-symbolic-link tmp-name1 tmp-name3)))
2596 ;; Cleanup.
2597 (ignore-errors
2598 (delete-file tmp-name1)
2599 (delete-file tmp-name2)))
2601 ;; Check `add-name-to-file'.
2602 (unwind-protect
2603 (progn
2604 (write-region "foo" nil tmp-name1)
2605 (should (file-exists-p tmp-name1))
2606 (add-name-to-file tmp-name1 tmp-name2)
2607 (should-not (file-symlink-p tmp-name2))
2608 (should-error (add-name-to-file tmp-name1 tmp-name2))
2609 (add-name-to-file tmp-name1 tmp-name2 'ok-if-already-exists)
2610 (should-not (file-symlink-p tmp-name2))
2611 ;; `tmp-name3' is a local file name.
2612 (should-error (add-name-to-file tmp-name1 tmp-name3)))
2614 ;; Cleanup.
2615 (ignore-errors
2616 (delete-file tmp-name1)
2617 (delete-file tmp-name2)))
2619 ;; Check `file-truename'.
2620 (unwind-protect
2621 (progn
2622 (write-region "foo" nil tmp-name1)
2623 (should (file-exists-p tmp-name1))
2624 (make-symbolic-link tmp-name1 tmp-name2)
2625 (should (file-symlink-p tmp-name2))
2626 (should-not (string-equal tmp-name2 (file-truename tmp-name2)))
2627 (should
2628 (string-equal (file-truename tmp-name1) (file-truename tmp-name2)))
2629 (should (file-equal-p tmp-name1 tmp-name2)))
2630 (ignore-errors
2631 (delete-file tmp-name1)
2632 (delete-file tmp-name2)))
2634 ;; `file-truename' shall preserve trailing link of directories.
2635 (unless (file-symlink-p tramp-test-temporary-file-directory)
2636 (let* ((dir1 (directory-file-name tramp-test-temporary-file-directory))
2637 (dir2 (file-name-as-directory dir1)))
2638 (should (string-equal (file-truename dir1) (expand-file-name dir1)))
2639 (should
2640 (string-equal (file-truename dir2) (expand-file-name dir2))))))))
2642 (ert-deftest tramp-test22-file-times ()
2643 "Check `set-file-times' and `file-newer-than-file-p'."
2644 (skip-unless (tramp--test-enabled))
2645 (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
2647 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2648 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2649 (tmp-name2 (tramp--test-make-temp-name nil quoted))
2650 (tmp-name3 (tramp--test-make-temp-name nil quoted)))
2651 (unwind-protect
2652 (progn
2653 (write-region "foo" nil tmp-name1)
2654 (should (file-exists-p tmp-name1))
2655 (should (consp (nth 5 (file-attributes tmp-name1))))
2656 ;; '(0 0) means don't know, and will be replaced by
2657 ;; `current-time'. Therefore, we use '(0 1). We skip the
2658 ;; test, if the remote handler is not able to set the
2659 ;; correct time.
2660 (skip-unless (set-file-times tmp-name1 '(0 1)))
2661 ;; Dumb remote shells without perl(1) or stat(1) are not
2662 ;; able to return the date correctly. They say "don't know".
2663 (unless (equal (nth 5 (file-attributes tmp-name1)) '(0 0))
2664 (should (equal (nth 5 (file-attributes tmp-name1)) '(0 1)))
2665 (write-region "bla" nil tmp-name2)
2666 (should (file-exists-p tmp-name2))
2667 (should (file-newer-than-file-p tmp-name2 tmp-name1))
2668 ;; `tmp-name3' does not exist.
2669 (should (file-newer-than-file-p tmp-name2 tmp-name3))
2670 (should-not (file-newer-than-file-p tmp-name3 tmp-name1))))
2672 ;; Cleanup.
2673 (ignore-errors
2674 (delete-file tmp-name1)
2675 (delete-file tmp-name2))))))
2677 (ert-deftest tramp-test23-visited-file-modtime ()
2678 "Check `set-visited-file-modtime' and `verify-visited-file-modtime'."
2679 (skip-unless (tramp--test-enabled))
2681 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2682 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
2683 (unwind-protect
2684 (progn
2685 (write-region "foo" nil tmp-name)
2686 (should (file-exists-p tmp-name))
2687 (with-temp-buffer
2688 (insert-file-contents tmp-name)
2689 (should (verify-visited-file-modtime))
2690 (set-visited-file-modtime '(0 1))
2691 (should (verify-visited-file-modtime))
2692 (should (equal (visited-file-modtime) '(0 1 0 0)))))
2694 ;; Cleanup.
2695 (ignore-errors (delete-file tmp-name))))))
2697 (ert-deftest tramp-test24-file-name-completion ()
2698 "Check `file-name-completion' and `file-name-all-completions'."
2699 (skip-unless (tramp--test-enabled))
2701 ;; Method and host name in completion mode. This kind of completion
2702 ;; does not work on MS Windows.
2703 (when (not (memq system-type '(cygwin windows-nt)))
2704 (let ((method (file-remote-p tramp-test-temporary-file-directory 'method))
2705 (host (file-remote-p tramp-test-temporary-file-directory 'host))
2706 (orig-syntax tramp-syntax))
2707 (when (and (stringp host) (string-match tramp-host-with-port-regexp host))
2708 (setq host (match-string 1 host)))
2710 (unwind-protect
2711 (dolist
2712 (syntax
2713 (if tramp--test-expensive-test
2714 (tramp-syntax-values) `(,orig-syntax)))
2715 (tramp-change-syntax syntax)
2716 (let ;; This is needed for the `simplified' syntax.
2717 ((method-marker
2718 (if (zerop (length (tramp-method-regexp)))
2719 "" tramp-default-method-marker))
2720 ;; This is needed for the `separate' syntax.
2721 (prefix-format (substring (tramp-prefix-format) 1)))
2722 ;; Complete method name.
2723 (unless (or (zerop (length method))
2724 (zerop (length (tramp-method-regexp))))
2725 (should
2726 (member
2727 (concat prefix-format method (tramp-postfix-method-format))
2728 (file-name-all-completions
2729 (concat prefix-format (substring method 0 1)) "/"))))
2730 ;; Complete host name for default method. With gvfs
2731 ;; based methods, host name will be determined as
2732 ;; host.local, so we omit the test.
2733 (let ((tramp-default-method (or method tramp-default-method)))
2734 (unless (or (zerop (length host))
2735 (tramp--test-gvfs-p tramp-default-method))
2736 (should
2737 (member
2738 (concat
2739 prefix-format method-marker (tramp-postfix-method-format)
2740 host (tramp-postfix-host-format))
2741 (file-name-all-completions
2742 (concat
2743 prefix-format method-marker (tramp-postfix-method-format)
2744 (substring host 0 1))
2745 "/")))))
2746 ;; Complete host name.
2747 (unless (or (zerop (length method))
2748 (zerop (length (tramp-method-regexp)))
2749 (zerop (length host))
2750 (tramp--test-gvfs-p method))
2751 (should
2752 (member
2753 (concat
2754 prefix-format method (tramp-postfix-method-format)
2755 host (tramp-postfix-host-format))
2756 (file-name-all-completions
2757 (concat prefix-format method (tramp-postfix-method-format))
2758 "/"))))))
2760 ;; Cleanup.
2761 (tramp-change-syntax orig-syntax))))
2763 (dolist (n-e '(nil t))
2764 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2765 (let ((non-essential n-e)
2766 (tmp-name (tramp--test-make-temp-name nil quoted)))
2768 (unwind-protect
2769 (progn
2770 ;; Local files.
2771 (make-directory tmp-name)
2772 (should (file-directory-p tmp-name))
2773 (write-region "foo" nil (expand-file-name "foo" tmp-name))
2774 (should (file-exists-p (expand-file-name "foo" tmp-name)))
2775 (write-region "bar" nil (expand-file-name "bold" tmp-name))
2776 (should (file-exists-p (expand-file-name "bold" tmp-name)))
2777 (make-directory (expand-file-name "boz" tmp-name))
2778 (should (file-directory-p (expand-file-name "boz" tmp-name)))
2779 (should (equal (file-name-completion "fo" tmp-name) "foo"))
2780 (should (equal (file-name-completion "foo" tmp-name) t))
2781 (should (equal (file-name-completion "b" tmp-name) "bo"))
2782 (should-not (file-name-completion "a" tmp-name))
2783 (should
2784 (equal
2785 (file-name-completion "b" tmp-name 'file-directory-p) "boz/"))
2786 (should
2787 (equal (file-name-all-completions "fo" tmp-name) '("foo")))
2788 (should
2789 (equal
2790 (sort (file-name-all-completions "b" tmp-name) 'string-lessp)
2791 '("bold" "boz/")))
2792 (should-not (file-name-all-completions "a" tmp-name))
2793 ;; `completion-regexp-list' restricts the completion to
2794 ;; files which match all expressions in this list.
2795 (let ((completion-regexp-list
2796 `(,directory-files-no-dot-files-regexp "b")))
2797 (should
2798 (equal (file-name-completion "" tmp-name) "bo"))
2799 (should
2800 (equal
2801 (sort (file-name-all-completions "" tmp-name) 'string-lessp)
2802 '("bold" "boz/"))))
2803 ;; `file-name-completion' ignores file names that end in
2804 ;; any string in `completion-ignored-extensions'.
2805 (let ((completion-ignored-extensions '(".ext")))
2806 (write-region "foo" nil (expand-file-name "foo.ext" tmp-name))
2807 (should (file-exists-p (expand-file-name "foo.ext" tmp-name)))
2808 (should (equal (file-name-completion "fo" tmp-name) "foo"))
2809 (should (equal (file-name-completion "foo" tmp-name) t))
2810 (should
2811 (equal (file-name-completion "foo." tmp-name) "foo.ext"))
2812 (should (equal (file-name-completion "foo.ext" tmp-name) t))
2813 ;; `file-name-all-completions' is not affected.
2814 (should
2815 (equal
2816 (sort (file-name-all-completions "" tmp-name) 'string-lessp)
2817 '("../" "./" "bold" "boz/" "foo" "foo.ext")))))
2819 ;; Cleanup.
2820 (ignore-errors (delete-directory tmp-name 'recursive)))))))
2822 (ert-deftest tramp-test25-load ()
2823 "Check `load'."
2824 (skip-unless (tramp--test-enabled))
2826 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2827 (let ((tmp-name (tramp--test-make-temp-name nil quoted)))
2828 (unwind-protect
2829 (progn
2830 (load tmp-name 'noerror 'nomessage)
2831 (should-not (featurep 'tramp-test-load))
2832 (write-region "(provide 'tramp-test-load)" nil tmp-name)
2833 ;; `load' in lread.c does not pass `must-suffix'. Why?
2834 ;;(should-error
2835 ;; (load tmp-name nil 'nomessage 'nosuffix 'must-suffix))
2836 (load tmp-name nil 'nomessage 'nosuffix)
2837 (should (featurep 'tramp-test-load)))
2839 ;; Cleanup.
2840 (ignore-errors
2841 (and (featurep 'tramp-test-load) (unload-feature 'tramp-test-load))
2842 (delete-file tmp-name))))))
2844 (ert-deftest tramp-test26-process-file ()
2845 "Check `process-file'."
2846 :tags '(:expensive-test)
2847 (skip-unless (tramp--test-enabled))
2848 (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
2850 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2851 (let* ((tmp-name (tramp--test-make-temp-name nil quoted))
2852 (fnnd (file-name-nondirectory tmp-name))
2853 (default-directory tramp-test-temporary-file-directory)
2854 kill-buffer-query-functions)
2855 (unwind-protect
2856 (progn
2857 ;; We cannot use "/bin/true" and "/bin/false"; those paths
2858 ;; do not exist on hydra.
2859 (should (zerop (process-file "true")))
2860 (should-not (zerop (process-file "false")))
2861 (should-not (zerop (process-file "binary-does-not-exist")))
2862 (with-temp-buffer
2863 (write-region "foo" nil tmp-name)
2864 (should (file-exists-p tmp-name))
2865 (should (zerop (process-file "ls" nil t nil fnnd)))
2866 ;; `ls' could produce colorized output.
2867 (goto-char (point-min))
2868 (while
2869 (re-search-forward tramp-display-escape-sequence-regexp nil t)
2870 (replace-match "" nil nil))
2871 (should (string-equal (format "%s\n" fnnd) (buffer-string)))
2872 (should-not (get-buffer-window (current-buffer) t))
2874 ;; Second run. The output must be appended.
2875 (goto-char (point-max))
2876 (should (zerop (process-file "ls" nil t t fnnd)))
2877 ;; `ls' could produce colorized output.
2878 (goto-char (point-min))
2879 (while
2880 (re-search-forward tramp-display-escape-sequence-regexp nil t)
2881 (replace-match "" nil nil))
2882 (should
2883 (string-equal (format "%s\n%s\n" fnnd fnnd) (buffer-string)))
2884 ;; A non-nil DISPLAY must not raise the buffer.
2885 (should-not (get-buffer-window (current-buffer) t))))
2887 ;; Cleanup.
2888 (ignore-errors (delete-file tmp-name))))))
2890 (ert-deftest tramp-test27-start-file-process ()
2891 "Check `start-file-process'."
2892 :tags '(:expensive-test)
2893 (skip-unless (tramp--test-enabled))
2894 (skip-unless (tramp--test-sh-p))
2896 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2897 (let ((default-directory tramp-test-temporary-file-directory)
2898 (tmp-name (tramp--test-make-temp-name nil quoted))
2899 kill-buffer-query-functions proc)
2900 (unwind-protect
2901 (with-temp-buffer
2902 (setq proc (start-file-process "test1" (current-buffer) "cat"))
2903 (should (processp proc))
2904 (should (equal (process-status proc) 'run))
2905 (process-send-string proc "foo")
2906 (process-send-eof proc)
2907 ;; Read output.
2908 (with-timeout (10 (ert-fail "`start-file-process' timed out"))
2909 (while (< (- (point-max) (point-min)) (length "foo"))
2910 (accept-process-output proc 0.1)))
2911 (should (string-equal (buffer-string) "foo")))
2913 ;; Cleanup.
2914 (ignore-errors (delete-process proc)))
2916 (unwind-protect
2917 (with-temp-buffer
2918 (write-region "foo" nil tmp-name)
2919 (should (file-exists-p tmp-name))
2920 (setq proc
2921 (start-file-process
2922 "test2" (current-buffer)
2923 "cat" (file-name-nondirectory tmp-name)))
2924 (should (processp proc))
2925 ;; Read output.
2926 (with-timeout (10 (ert-fail "`start-file-process' timed out"))
2927 (while (< (- (point-max) (point-min)) (length "foo"))
2928 (accept-process-output proc 0.1)))
2929 (should (string-equal (buffer-string) "foo")))
2931 ;; Cleanup.
2932 (ignore-errors
2933 (delete-process proc)
2934 (delete-file tmp-name)))
2936 (unwind-protect
2937 (with-temp-buffer
2938 (setq proc (start-file-process "test3" (current-buffer) "cat"))
2939 (should (processp proc))
2940 (should (equal (process-status proc) 'run))
2941 (set-process-filter
2942 proc
2943 (lambda (p s) (with-current-buffer (process-buffer p) (insert s))))
2944 (process-send-string proc "foo")
2945 (process-send-eof proc)
2946 ;; Read output.
2947 (with-timeout (10 (ert-fail "`start-file-process' timed out"))
2948 (while (< (- (point-max) (point-min)) (length "foo"))
2949 (accept-process-output proc 0.1)))
2950 (should (string-equal (buffer-string) "foo")))
2952 ;; Cleanup.
2953 (ignore-errors (delete-process proc))))))
2955 (ert-deftest tramp-test28-interrupt-process ()
2956 "Check `interrupt-process'."
2957 :tags '(:expensive-test)
2958 (skip-unless (tramp--test-enabled))
2959 (skip-unless (tramp--test-sh-p))
2960 ;; Since Emacs 26.1.
2961 (skip-unless (boundp 'interrupt-process-functions))
2963 (let ((default-directory tramp-test-temporary-file-directory)
2964 kill-buffer-query-functions proc)
2965 (unwind-protect
2966 (with-temp-buffer
2967 (setq proc (start-file-process "test" (current-buffer) "sleep" "10"))
2968 (should (processp proc))
2969 (should (process-live-p proc))
2970 (should (equal (process-status proc) 'run))
2971 (should (interrupt-process proc))
2972 ;; Let the process accept the interrupt.
2973 (accept-process-output proc 1 nil 0)
2974 (should-not (process-live-p proc))
2975 (should (equal (process-status proc) 'signal))
2976 ;; An interrupted process cannot be interrupted, again.
2977 ;; Does not work reliable.
2978 ;; (should-error (interrupt-process proc)))
2981 ;; Cleanup.
2982 (ignore-errors (delete-process proc)))))
2984 (ert-deftest tramp-test29-shell-command ()
2985 "Check `shell-command'."
2986 :tags '(:expensive-test)
2987 (skip-unless (tramp--test-enabled))
2988 (skip-unless (tramp--test-sh-p))
2990 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2991 (let ((tmp-name (tramp--test-make-temp-name nil quoted))
2992 (default-directory tramp-test-temporary-file-directory)
2993 ;; Suppress nasty messages.
2994 (inhibit-message t)
2995 kill-buffer-query-functions)
2996 (unwind-protect
2997 (with-temp-buffer
2998 (write-region "foo" nil tmp-name)
2999 (should (file-exists-p tmp-name))
3000 (shell-command
3001 (format "ls %s" (file-name-nondirectory tmp-name))
3002 (current-buffer))
3003 ;; `ls' could produce colorized output.
3004 (goto-char (point-min))
3005 (while
3006 (re-search-forward tramp-display-escape-sequence-regexp nil t)
3007 (replace-match "" nil nil))
3008 (should
3009 (string-equal
3010 (format "%s\n" (file-name-nondirectory tmp-name))
3011 (buffer-string))))
3013 ;; Cleanup.
3014 (ignore-errors (delete-file tmp-name)))
3016 (unwind-protect
3017 (with-temp-buffer
3018 (write-region "foo" nil tmp-name)
3019 (should (file-exists-p tmp-name))
3020 (async-shell-command
3021 (format "ls %s" (file-name-nondirectory tmp-name))
3022 (current-buffer))
3023 ;; Read output.
3024 (with-timeout (10 (ert-fail "`async-shell-command' timed out"))
3025 (while (< (- (point-max) (point-min))
3026 (1+ (length (file-name-nondirectory tmp-name))))
3027 (accept-process-output
3028 (get-buffer-process (current-buffer)) 0.1)))
3029 ;; `ls' could produce colorized output.
3030 (goto-char (point-min))
3031 (while
3032 (re-search-forward tramp-display-escape-sequence-regexp nil t)
3033 (replace-match "" nil nil))
3034 ;; There might be a nasty "Process *Async Shell* finished" message.
3035 (goto-char (point-min))
3036 (forward-line)
3037 (narrow-to-region (point-min) (point))
3038 (should
3039 (string-equal
3040 (format "%s\n" (file-name-nondirectory tmp-name))
3041 (buffer-string))))
3043 ;; Cleanup.
3044 (ignore-errors (delete-file tmp-name)))
3046 (unwind-protect
3047 (with-temp-buffer
3048 (write-region "foo" nil tmp-name)
3049 (should (file-exists-p tmp-name))
3050 (async-shell-command "read line; ls $line" (current-buffer))
3051 (process-send-string
3052 (get-buffer-process (current-buffer))
3053 (format "%s\n" (file-name-nondirectory tmp-name)))
3054 ;; Read output.
3055 (with-timeout (10 (ert-fail "`async-shell-command' timed out"))
3056 (while (< (- (point-max) (point-min))
3057 (1+ (length (file-name-nondirectory tmp-name))))
3058 (accept-process-output
3059 (get-buffer-process (current-buffer)) 0.1)))
3060 ;; `ls' could produce colorized output.
3061 (goto-char (point-min))
3062 (while
3063 (re-search-forward tramp-display-escape-sequence-regexp nil t)
3064 (replace-match "" nil nil))
3065 ;; There might be a nasty "Process *Async Shell* finished" message.
3066 (goto-char (point-min))
3067 (forward-line)
3068 (narrow-to-region (point-min) (point))
3069 (should
3070 (string-equal
3071 (format "%s\n" (file-name-nondirectory tmp-name))
3072 (buffer-string))))
3074 ;; Cleanup.
3075 (ignore-errors (delete-file tmp-name))))))
3077 (defun tramp--test-shell-command-to-string-asynchronously (command)
3078 "Like `shell-command-to-string', but for asynchronous processes."
3079 (with-temp-buffer
3080 (async-shell-command command (current-buffer))
3081 (with-timeout (10)
3082 (while (get-buffer-process (current-buffer))
3083 (accept-process-output (get-buffer-process (current-buffer)) 0.1)))
3084 (accept-process-output nil 0.1)
3085 (buffer-substring-no-properties (point-min) (point-max))))
3087 ;; This test is inspired by Bug#23952.
3088 (ert-deftest tramp-test30-environment-variables ()
3089 "Check that remote processes set / unset environment variables properly."
3090 :tags '(:expensive-test)
3091 (skip-unless (tramp--test-enabled))
3092 (skip-unless (tramp--test-sh-p))
3094 (dolist (this-shell-command-to-string
3095 '(;; Synchronously.
3096 shell-command-to-string
3097 ;; Asynchronously.
3098 tramp--test-shell-command-to-string-asynchronously))
3100 (let ((default-directory tramp-test-temporary-file-directory)
3101 (shell-file-name "/bin/sh")
3102 (envvar (concat "VAR_" (upcase (md5 (current-time-string)))))
3103 kill-buffer-query-functions)
3105 (unwind-protect
3106 ;; Set a value.
3107 (let ((process-environment
3108 (cons (concat envvar "=foo") process-environment)))
3109 ;; Default value.
3110 (should
3111 (string-match
3112 "foo"
3113 (funcall
3114 this-shell-command-to-string
3115 (format "echo -n ${%s:?bla}" envvar))))))
3117 (unwind-protect
3118 ;; Set the empty value.
3119 (let ((process-environment
3120 (cons (concat envvar "=") process-environment)))
3121 ;; Value is null.
3122 (should
3123 (string-match
3124 "bla"
3125 (funcall
3126 this-shell-command-to-string
3127 (format "echo -n ${%s:?bla}" envvar))))
3128 ;; Variable is set.
3129 (should
3130 (string-match
3131 (regexp-quote envvar)
3132 (funcall this-shell-command-to-string "set")))))
3134 ;; We force a reconnect, in order to have a clean environment.
3135 (tramp-cleanup-connection
3136 (tramp-dissect-file-name tramp-test-temporary-file-directory)
3137 'keep-debug 'keep-password)
3138 (unwind-protect
3139 ;; Unset the variable.
3140 (let ((tramp-remote-process-environment
3141 (cons (concat envvar "=foo")
3142 tramp-remote-process-environment)))
3143 ;; Set the initial value, we want to unset below.
3144 (should
3145 (string-match
3146 "foo"
3147 (funcall
3148 this-shell-command-to-string
3149 (format "echo -n ${%s:?bla}" envvar))))
3150 (let ((process-environment
3151 (cons envvar process-environment)))
3152 ;; Variable is unset.
3153 (should
3154 (string-match
3155 "bla"
3156 (funcall
3157 this-shell-command-to-string
3158 (format "echo -n ${%s:?bla}" envvar))))
3159 ;; Variable is unset.
3160 (should-not
3161 (string-match
3162 (regexp-quote envvar)
3163 (funcall this-shell-command-to-string "set")))))))))
3165 ;; This test is inspired by Bug#27009.
3166 (ert-deftest tramp-test30-environment-variables-and-port-numbers ()
3167 "Check that two connections with separate ports are different."
3168 (skip-unless (tramp--test-enabled))
3169 ;; We test it only for the mock-up connection; otherwise there might
3170 ;; be problems with the used ports.
3171 (skip-unless
3172 (and
3173 (eq tramp-syntax 'default)
3174 (string-equal
3175 "mock" (file-remote-p tramp-test-temporary-file-directory 'method))))
3177 ;; We force a reconnect, in order to have a clean environment.
3178 (dolist (dir `(,tramp-test-temporary-file-directory
3179 "/mock:localhost#11111:" "/mock:localhost#22222:"))
3180 (tramp-cleanup-connection
3181 (tramp-dissect-file-name dir) 'keep-debug 'keep-password))
3183 (unwind-protect
3184 (dolist (port '(11111 22222))
3185 (let* ((default-directory
3186 (format "/mock:localhost#%d:%s" port temporary-file-directory))
3187 (shell-file-name "/bin/sh")
3188 (envvar (concat "VAR_" (upcase (md5 (current-time-string)))))
3189 ;; We cannot use `process-environment', because this
3190 ;; would be applied in `process-file'.
3191 (tramp-remote-process-environment
3192 (cons
3193 (format "%s=%d" envvar port)
3194 tramp-remote-process-environment)))
3195 (should
3196 (string-equal
3197 (number-to-string port)
3198 (shell-command-to-string (format "echo -n $%s" envvar))))))
3200 ;; Cleanup.
3201 (dolist (dir '("/mock:localhost#11111:" "/mock:localhost#22222:"))
3202 (tramp-cleanup-connection (tramp-dissect-file-name dir)))))
3204 ;; The functions were introduced in Emacs 26.1.
3205 (ert-deftest tramp-test31-explicit-shell-file-name ()
3206 "Check that connection-local `explicit-shell-file-name' is set."
3207 :tags '(:expensive-test)
3208 (skip-unless (tramp--test-enabled))
3209 (skip-unless (tramp--test-sh-p))
3210 ;; Since Emacs 26.1.
3211 (skip-unless (and (fboundp 'connection-local-set-profile-variables)
3212 (fboundp 'connection-local-set-profiles)))
3214 ;; `connection-local-set-profile-variables' and
3215 ;; `connection-local-set-profiles' exists since Emacs 26. We don't
3216 ;; want to see compiler warnings for older Emacsen.
3217 (let ((default-directory tramp-test-temporary-file-directory)
3218 explicit-shell-file-name kill-buffer-query-functions)
3219 (unwind-protect
3220 (progn
3221 ;; `shell-mode' would ruin our test, because it deletes all
3222 ;; buffer local variables.
3223 (put 'explicit-shell-file-name 'permanent-local t)
3224 ;; Declare connection-local variable `explicit-shell-file-name'.
3225 (with-no-warnings
3226 (connection-local-set-profile-variables
3227 'remote-sh
3228 '((explicit-shell-file-name . "/bin/sh")
3229 (explicit-sh-args . ("-i"))))
3230 (connection-local-set-profiles
3231 `(:application tramp
3232 :protocol ,(file-remote-p default-directory 'method)
3233 :user ,(file-remote-p default-directory 'user)
3234 :machine ,(file-remote-p default-directory 'host))
3235 'remote-sh))
3237 ;; Run interactive shell. Since the default directory is
3238 ;; remote, `explicit-shell-file-name' shall be set in order
3239 ;; to avoid a question.
3240 (with-current-buffer (get-buffer-create "*shell*")
3241 (ignore-errors (kill-process (current-buffer)))
3242 (should-not explicit-shell-file-name)
3243 (call-interactively 'shell)
3244 (should explicit-shell-file-name)))
3246 (put 'explicit-shell-file-name 'permanent-local nil)
3247 (kill-buffer "*shell*"))))
3249 (ert-deftest tramp-test32-vc-registered ()
3250 "Check `vc-registered'."
3251 :tags '(:expensive-test)
3252 (skip-unless (tramp--test-enabled))
3253 (skip-unless (tramp--test-sh-p))
3255 ;; TODO: This test fails.
3256 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
3257 (let* ((default-directory tramp-test-temporary-file-directory)
3258 (tmp-name1 (tramp--test-make-temp-name nil quoted))
3259 (tmp-name2 (expand-file-name "foo" tmp-name1))
3260 (tramp-remote-process-environment tramp-remote-process-environment)
3261 (vc-handled-backends
3262 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
3263 (cond
3264 ((tramp-find-executable
3265 v vc-git-program (tramp-get-remote-path v))
3266 '(Git))
3267 ((tramp-find-executable
3268 v vc-hg-program (tramp-get-remote-path v))
3269 '(Hg))
3270 ((tramp-find-executable
3271 v vc-bzr-program (tramp-get-remote-path v))
3272 (setq tramp-remote-process-environment
3273 (cons (format "BZR_HOME=%s"
3274 (file-remote-p tmp-name1 'localname))
3275 tramp-remote-process-environment))
3276 ;; We must force a reconnect, in order to activate $BZR_HOME.
3277 (tramp-cleanup-connection
3278 (tramp-dissect-file-name tramp-test-temporary-file-directory)
3279 'keep-debug 'keep-password)
3280 '(Bzr))
3281 (t nil))))
3282 ;; Suppress nasty messages.
3283 (inhibit-message t))
3284 (skip-unless vc-handled-backends)
3285 (unless quoted (tramp--test-message "%s" vc-handled-backends))
3287 (unwind-protect
3288 (progn
3289 (make-directory tmp-name1)
3290 (write-region "foo" nil tmp-name2)
3291 (should (file-directory-p tmp-name1))
3292 (should (file-exists-p tmp-name2))
3293 (should-not (vc-registered tmp-name1))
3294 (should-not (vc-registered tmp-name2))
3296 (let ((default-directory tmp-name1))
3297 ;; Create empty repository, and register the file.
3298 ;; Sometimes, creation of repository fails (bzr!); we
3299 ;; skip the test then.
3300 (condition-case nil
3301 (vc-create-repo (car vc-handled-backends))
3302 (error (skip-unless nil)))
3303 ;; The structure of VC-FILESET is not documented. Let's
3304 ;; hope it won't change.
3305 (condition-case nil
3306 (vc-register
3307 (list (car vc-handled-backends)
3308 (list (file-name-nondirectory tmp-name2))))
3309 ;; `vc-register' has changed its arguments in Emacs 25.1.
3310 (error
3311 (vc-register
3312 nil (list (car vc-handled-backends)
3313 (list (file-name-nondirectory tmp-name2))))))
3314 ;; vc-git uses an own process sentinel, Tramp's sentinel
3315 ;; for flushing the cache isn't used.
3316 (dired-uncache (concat (file-remote-p default-directory) "/"))
3317 (should (vc-registered (file-name-nondirectory tmp-name2)))))
3319 ;; Cleanup.
3320 (ignore-errors (delete-directory tmp-name1 'recursive))))))
3322 (ert-deftest tramp-test33-make-auto-save-file-name ()
3323 "Check `make-auto-save-file-name'."
3324 (skip-unless (tramp--test-enabled))
3326 (dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
3327 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
3328 (tmp-name2 (tramp--test-make-temp-name nil quoted)))
3330 (unwind-protect
3331 (progn
3332 ;; Use default `auto-save-file-name-transforms' mechanism.
3333 (let (tramp-auto-save-directory)
3334 (with-temp-buffer
3335 (setq buffer-file-name tmp-name1)
3336 (should
3337 (string-equal
3338 (make-auto-save-file-name)
3339 ;; This is taken from original `make-auto-save-file-name'.
3340 ;; We call `convert-standard-filename', because on
3341 ;; MS Windows the (local) colons must be replaced by
3342 ;; exclamation marks.
3343 (convert-standard-filename
3344 (expand-file-name
3345 (format
3346 "#%s#"
3347 (subst-char-in-string
3348 ?/ ?! (replace-regexp-in-string "!" "!!" tmp-name1)))
3349 temporary-file-directory))))))
3351 ;; No mapping.
3352 (let (tramp-auto-save-directory auto-save-file-name-transforms)
3353 (with-temp-buffer
3354 (setq buffer-file-name tmp-name1)
3355 (should
3356 (string-equal
3357 (make-auto-save-file-name)
3358 (funcall
3359 (if quoted 'tramp-compat-file-name-quote 'identity)
3360 (expand-file-name
3361 (format "#%s#" (file-name-nondirectory tmp-name1))
3362 tramp-test-temporary-file-directory))))))
3364 ;; TODO: The following two cases don't work yet.
3365 (when nil
3366 ;; Use default `tramp-auto-save-directory' mechanism.
3367 (let ((tramp-auto-save-directory tmp-name2))
3368 (with-temp-buffer
3369 (setq buffer-file-name tmp-name1)
3370 (should
3371 (string-equal
3372 (make-auto-save-file-name)
3373 ;; This is taken from Tramp.
3374 (expand-file-name
3375 (format
3376 "#%s#"
3377 (tramp-subst-strs-in-string
3378 '(("_" . "|")
3379 ("/" . "_a")
3380 (":" . "_b")
3381 ("|" . "__")
3382 ("[" . "_l")
3383 ("]" . "_r"))
3384 (tramp-compat-file-name-unquote tmp-name1)))
3385 tmp-name2)))
3386 (should (file-directory-p tmp-name2))))
3388 ;; Relative file names shall work, too.
3389 (let ((tramp-auto-save-directory "."))
3390 (with-temp-buffer
3391 (setq buffer-file-name tmp-name1
3392 default-directory tmp-name2)
3393 (should
3394 (string-equal
3395 (make-auto-save-file-name)
3396 ;; This is taken from Tramp.
3397 (expand-file-name
3398 (format
3399 "#%s#"
3400 (tramp-subst-strs-in-string
3401 '(("_" . "|")
3402 ("/" . "_a")
3403 (":" . "_b")
3404 ("|" . "__")
3405 ("[" . "_l")
3406 ("]" . "_r"))
3407 (tramp-compat-file-name-unquote tmp-name1)))
3408 tmp-name2)))
3409 (should (file-directory-p tmp-name2)))))
3410 ) ;; TODO
3412 ;; Cleanup.
3413 (ignore-errors (delete-file tmp-name1))
3414 (ignore-errors (delete-directory tmp-name2 'recursive))))))
3416 ;; The functions were introduced in Emacs 26.1.
3417 (ert-deftest tramp-test34-make-nearby-temp-file ()
3418 "Check `make-nearby-temp-file' and `temporary-file-directory'."
3419 (skip-unless (tramp--test-enabled))
3420 ;; Since Emacs 26.1.
3421 (skip-unless
3422 (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
3424 ;; `make-nearby-temp-file' and `temporary-file-directory' exists
3425 ;; since Emacs 26. We don't want to see compiler warnings for older
3426 ;; Emacsen.
3427 (let ((default-directory tramp-test-temporary-file-directory)
3428 tmp-file)
3429 ;; The remote host shall know a temporary file directory.
3430 (should (stringp (with-no-warnings (temporary-file-directory))))
3431 (should
3432 (string-equal
3433 (file-remote-p default-directory)
3434 (file-remote-p (with-no-warnings (temporary-file-directory)))))
3436 ;; The temporary file shall be located on the remote host.
3437 (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test")))
3438 (should (file-exists-p tmp-file))
3439 (should (file-regular-p tmp-file))
3440 (should
3441 (string-equal
3442 (file-remote-p default-directory)
3443 (file-remote-p tmp-file)))
3444 (delete-file tmp-file)
3445 (should-not (file-exists-p tmp-file))
3447 (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test" 'dir)))
3448 (should (file-exists-p tmp-file))
3449 (should (file-directory-p tmp-file))
3450 (delete-directory tmp-file)
3451 (should-not (file-exists-p tmp-file))))
3453 (defun tramp--test-adb-p ()
3454 "Check, whether the remote host runs Android.
3455 This requires restrictions of file name syntax."
3456 (tramp-adb-file-name-p tramp-test-temporary-file-directory))
3458 (defun tramp--test-docker-p ()
3459 "Check, whether the docker method is used.
3460 This does not support some special file names."
3461 (string-equal
3462 "docker" (file-remote-p tramp-test-temporary-file-directory 'method)))
3464 (defun tramp--test-ftp-p ()
3465 "Check, whether an FTP-like method is used.
3466 This does not support globbing characters in file names (yet)."
3467 ;; Globbing characters are ??, ?* and ?\[.
3468 (string-match
3469 "ftp$" (file-remote-p tramp-test-temporary-file-directory 'method)))
3471 (defun tramp--test-gvfs-p (&optional method)
3472 "Check, whether the remote host runs a GVFS based method.
3473 This requires restrictions of file name syntax."
3474 (or (member method tramp-gvfs-methods)
3475 (tramp-gvfs-file-name-p tramp-test-temporary-file-directory)))
3477 (defun tramp--test-hpux-p ()
3478 "Check, whether the remote host runs HP-UX.
3479 Several special characters do not work properly there."
3480 ;; We must refill the cache. `file-truename' does it.
3481 (with-parsed-tramp-file-name
3482 (file-truename tramp-test-temporary-file-directory) nil
3483 (string-match "^HP-UX" (tramp-get-connection-property v "uname" ""))))
3485 (defun tramp--test-rsync-p ()
3486 "Check, whether the rsync method is used.
3487 This does not support special file names."
3488 (string-equal
3489 "rsync" (file-remote-p tramp-test-temporary-file-directory 'method)))
3491 (defun tramp--test-sh-p ()
3492 "Check, whether the remote host runs a based method from tramp-sh.el."
3494 (tramp-find-foreign-file-name-handler tramp-test-temporary-file-directory)
3495 'tramp-sh-file-name-handler))
3497 (defun tramp--test-windows-nt-and-batch ()
3498 "Check, whether the locale host runs MS Windows in batch mode.
3499 This does not support special characters."
3500 (and (eq system-type 'windows-nt) noninteractive))
3502 (defun tramp--test-windows-nt-and-pscp-psftp-p ()
3503 "Check, whether the locale host runs MS Windows, and ps{cp,ftp} is used.
3504 This does not support utf8 based file transfer."
3505 (and (eq system-type 'windows-nt)
3506 (string-match
3507 (regexp-opt '("pscp" "psftp"))
3508 (file-remote-p tramp-test-temporary-file-directory 'method))))
3510 (defun tramp--test-windows-nt-or-smb-p ()
3511 "Check, whether the locale or remote host runs MS Windows.
3512 This requires restrictions of file name syntax."
3513 (or (eq system-type 'windows-nt)
3514 (tramp-smb-file-name-p tramp-test-temporary-file-directory)))
3516 (defun tramp--test-check-files (&rest files)
3517 "Run a simple but comprehensive test over every file in FILES."
3518 ;; TODO: The quoted case does not work.
3519 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
3520 (let (quoted)
3521 ;; We must use `file-truename' for the temporary directory,
3522 ;; because it could be located on a symlinked directory. This
3523 ;; would let the test fail.
3524 (let* ((tramp-test-temporary-file-directory
3525 (file-truename tramp-test-temporary-file-directory))
3526 (tmp-name1 (tramp--test-make-temp-name nil quoted))
3527 (tmp-name2 (tramp--test-make-temp-name 'local quoted))
3528 (files (delq nil files))
3529 (process-environment process-environment))
3530 (unwind-protect
3531 (progn
3532 (make-directory tmp-name1)
3533 (make-directory tmp-name2)
3535 (dolist (elt files)
3536 (let* ((file1 (expand-file-name elt tmp-name1))
3537 (file2 (expand-file-name elt tmp-name2))
3538 (file3 (expand-file-name (concat elt "foo") tmp-name1)))
3539 (write-region elt nil file1)
3540 (should (file-exists-p file1))
3542 ;; Check file contents.
3543 (with-temp-buffer
3544 (insert-file-contents file1)
3545 (should (string-equal (buffer-string) elt)))
3547 ;; Copy file both directions.
3548 (copy-file file1 tmp-name2)
3549 (should (file-exists-p file2))
3550 (delete-file file1)
3551 (should-not (file-exists-p file1))
3552 (copy-file file2 tmp-name1)
3553 (should (file-exists-p file1))
3555 ;; Method "smb" supports `make-symbolic-link' only if the
3556 ;; remote host has CIFS capabilities. tramp-adb.el and
3557 ;; tramp-gvfs.el do not support symbolic links at all.
3558 (condition-case err
3559 (progn
3560 (make-symbolic-link file1 file3)
3561 (should (file-symlink-p file3))
3562 (should
3563 (string-equal
3564 (expand-file-name file1) (file-truename file3)))
3565 (should
3566 (string-equal
3567 (funcall
3568 (if quoted 'tramp-compat-file-name-quote 'identity)
3569 (car (file-attributes file3)))
3570 (file-remote-p (file-truename file1) 'localname)))
3571 ;; Check file contents.
3572 (with-temp-buffer
3573 (insert-file-contents file3)
3574 (should (string-equal (buffer-string) elt)))
3575 (delete-file file3))
3576 (file-error
3577 (should
3578 (string-equal (error-message-string err)
3579 "make-symbolic-link not supported"))))))
3581 ;; Check file names.
3582 (should (equal (directory-files
3583 tmp-name1 nil directory-files-no-dot-files-regexp)
3584 (sort (copy-sequence files) 'string-lessp)))
3585 (should (equal (directory-files
3586 tmp-name2 nil directory-files-no-dot-files-regexp)
3587 (sort (copy-sequence files) 'string-lessp)))
3589 ;; `substitute-in-file-name' could return different
3590 ;; values. For `adb', there could be strange file
3591 ;; permissions preventing overwriting a file. We don't
3592 ;; care in this testcase.
3593 (dolist (elt files)
3594 (let ((file1
3595 (substitute-in-file-name (expand-file-name elt tmp-name1)))
3596 (file2
3597 (substitute-in-file-name
3598 (expand-file-name elt tmp-name2))))
3599 (ignore-errors (write-region elt nil file1))
3600 (should (file-exists-p file1))
3601 (ignore-errors (write-region elt nil file2 nil 'nomessage))
3602 (should (file-exists-p file2))))
3604 (should (equal (directory-files
3605 tmp-name1 nil directory-files-no-dot-files-regexp)
3606 (directory-files
3607 tmp-name2 nil directory-files-no-dot-files-regexp)))
3609 ;; Check directory creation. We use a subdirectory "foo"
3610 ;; in order to avoid conflicts with previous file name tests.
3611 (dolist (elt files)
3612 (let* ((elt1 (concat elt "foo"))
3613 (file1 (expand-file-name (concat "foo/" elt) tmp-name1))
3614 (file2 (expand-file-name elt file1))
3615 (file3 (expand-file-name elt1 file1)))
3616 (make-directory file1 'parents)
3617 (should (file-directory-p file1))
3618 (write-region elt nil file2)
3619 (should (file-exists-p file2))
3620 (should
3621 (equal
3622 (directory-files
3623 file1 nil directory-files-no-dot-files-regexp)
3624 `(,elt)))
3625 (should
3626 (equal
3627 (caar (directory-files-and-attributes
3628 file1 nil directory-files-no-dot-files-regexp))
3629 elt))
3631 ;; Check symlink in `directory-files-and-attributes'.
3632 (condition-case err
3633 (progn
3634 (make-symbolic-link file2 file3)
3635 (should (file-symlink-p file3))
3636 (should
3637 (string-equal
3638 (caar (directory-files-and-attributes
3639 file1 nil (regexp-quote elt1)))
3640 elt1))
3641 (should
3642 (string-equal
3643 (funcall
3644 (if quoted 'tramp-compat-file-name-quote 'identity)
3645 (cadr (car (directory-files-and-attributes
3646 file1 nil (regexp-quote elt1)))))
3647 (file-remote-p (file-truename file2) 'localname)))
3648 (delete-file file3)
3649 (should-not (file-exists-p file3)))
3650 (file-error
3651 (should (string-equal (error-message-string err)
3652 "make-symbolic-link not supported"))))
3654 (delete-file file2)
3655 (should-not (file-exists-p file2))
3656 (delete-directory file1)
3657 (should-not (file-exists-p file1))))
3659 ;; Check, that environment variables are set correctly.
3660 (when (and tramp--test-expensive-test (tramp--test-sh-p))
3661 (dolist (elt files)
3662 (let ((envvar (concat "VAR_" (upcase (md5 elt))))
3663 (default-directory tramp-test-temporary-file-directory)
3664 (process-environment process-environment))
3665 (setenv envvar elt)
3666 ;; The value of PS1 could confuse Tramp's detection
3667 ;; of process output. So we unset it temporarily.
3668 (setenv "PS1")
3669 (with-temp-buffer
3670 (should (zerop (process-file "env" nil t nil)))
3671 (goto-char (point-min))
3672 (should
3673 (re-search-forward
3674 (format
3675 "^%s=%s$"
3676 (regexp-quote envvar)
3677 (regexp-quote (getenv envvar))))))))))
3679 ;; Cleanup.
3680 (ignore-errors (delete-directory tmp-name1 'recursive))
3681 (ignore-errors (delete-directory tmp-name2 'recursive))))))
3683 (defun tramp--test-special-characters ()
3684 "Perform the test in `tramp-test35-special-characters*'."
3685 ;; Newlines, slashes and backslashes in file names are not
3686 ;; supported. So we don't test. And we don't test the tab
3687 ;; character on Windows or Cygwin, because the backslash is
3688 ;; interpreted as a path separator, preventing "\t" from being
3689 ;; expanded to <TAB>.
3690 (tramp--test-check-files
3691 (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
3692 "foo bar baz"
3693 (if (or (tramp--test-adb-p)
3694 (tramp--test-docker-p)
3695 (eq system-type 'cygwin))
3696 " foo bar baz "
3697 " foo\tbar baz\t"))
3698 "$foo$bar$$baz$"
3699 "-foo-bar-baz-"
3700 "%foo%bar%baz%"
3701 "&foo&bar&baz&"
3702 (unless (or (tramp--test-ftp-p)
3703 (tramp--test-gvfs-p)
3704 (tramp--test-windows-nt-or-smb-p))
3705 "?foo?bar?baz?")
3706 (unless (or (tramp--test-ftp-p)
3707 (tramp--test-gvfs-p)
3708 (tramp--test-windows-nt-or-smb-p))
3709 "*foo*bar*baz*")
3710 (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
3711 "'foo'bar'baz'"
3712 "'foo\"bar'baz\"")
3713 "#foo~bar#baz~"
3714 (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
3715 "!foo!bar!baz!"
3716 "!foo|bar!baz|")
3717 (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
3718 ";foo;bar;baz;"
3719 ":foo;bar:baz;")
3720 (unless (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
3721 "<foo>bar<baz>")
3722 "(foo)bar(baz)"
3723 (unless (or (tramp--test-ftp-p) (tramp--test-gvfs-p)) "[foo]bar[baz]")
3724 "{foo}bar{baz}"))
3726 ;; These tests are inspired by Bug#17238.
3727 (ert-deftest tramp-test35-special-characters ()
3728 "Check special characters in file names."
3729 (skip-unless (tramp--test-enabled))
3730 (skip-unless (not (tramp--test-rsync-p)))
3731 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3733 (tramp--test-special-characters))
3735 (ert-deftest tramp-test35-special-characters-with-stat ()
3736 "Check special characters in file names.
3737 Use the `stat' command."
3738 :tags '(:expensive-test)
3739 (skip-unless (tramp--test-enabled))
3740 (skip-unless (tramp--test-sh-p))
3741 (skip-unless (not (tramp--test-rsync-p)))
3742 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3743 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
3744 (skip-unless (tramp-get-remote-stat v)))
3746 (let ((tramp-connection-properties
3747 (append
3748 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3749 "perl" nil))
3750 tramp-connection-properties)))
3751 (tramp--test-special-characters)))
3753 (ert-deftest tramp-test35-special-characters-with-perl ()
3754 "Check special characters in file names.
3755 Use the `perl' command."
3756 :tags '(:expensive-test)
3757 (skip-unless (tramp--test-enabled))
3758 (skip-unless (tramp--test-sh-p))
3759 (skip-unless (not (tramp--test-rsync-p)))
3760 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3761 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
3762 (skip-unless (tramp-get-remote-perl v)))
3764 (let ((tramp-connection-properties
3765 (append
3766 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3767 "stat" nil)
3768 ;; See `tramp-sh-handle-file-truename'.
3769 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3770 "readlink" nil))
3771 tramp-connection-properties)))
3772 (tramp--test-special-characters)))
3774 (ert-deftest tramp-test35-special-characters-with-ls ()
3775 "Check special characters in file names.
3776 Use the `ls' command."
3777 :tags '(:expensive-test)
3778 (skip-unless (tramp--test-enabled))
3779 (skip-unless (tramp--test-sh-p))
3780 (skip-unless (not (tramp--test-rsync-p)))
3781 (skip-unless (not (tramp--test-windows-nt-and-batch)))
3782 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3784 (let ((tramp-connection-properties
3785 (append
3786 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3787 "perl" nil)
3788 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3789 "stat" nil)
3790 ;; See `tramp-sh-handle-file-truename'.
3791 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3792 "readlink" nil))
3793 tramp-connection-properties)))
3794 (tramp--test-special-characters)))
3796 (defun tramp--test-utf8 ()
3797 "Perform the test in `tramp-test36-utf8*'."
3798 (let* ((utf8 (if (and (eq system-type 'darwin)
3799 (memq 'utf-8-hfs (coding-system-list)))
3800 'utf-8-hfs 'utf-8))
3801 (coding-system-for-read utf8)
3802 (coding-system-for-write utf8)
3803 (file-name-coding-system
3804 (coding-system-change-eol-conversion utf8 'unix)))
3805 (tramp--test-check-files
3806 (unless (tramp--test-hpux-p) "Γυρίστε το Γαλαξία με Ώτο Στοπ")
3807 (unless (tramp--test-hpux-p)
3808 "أصبح بوسعك الآن تنزيل نسخة كاملة من موسوعة ويكيبيديا العربية لتصفحها بلا اتصال بالإنترنت")
3809 "银河系漫游指南系列"
3810 "Автостопом по гала́ктике")))
3812 (ert-deftest tramp-test36-utf8 ()
3813 "Check UTF8 encoding in file names and file contents."
3814 (skip-unless (tramp--test-enabled))
3815 (skip-unless (not (tramp--test-docker-p)))
3816 (skip-unless (not (tramp--test-rsync-p)))
3817 (skip-unless (not (tramp--test-windows-nt-and-batch)))
3818 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3820 (tramp--test-utf8))
3822 (ert-deftest tramp-test36-utf8-with-stat ()
3823 "Check UTF8 encoding in file names and file contents.
3824 Use the `stat' command."
3825 :tags '(:expensive-test)
3826 (skip-unless (tramp--test-enabled))
3827 (skip-unless (tramp--test-sh-p))
3828 (skip-unless (not (tramp--test-docker-p)))
3829 (skip-unless (not (tramp--test-rsync-p)))
3830 (skip-unless (not (tramp--test-windows-nt-and-batch)))
3831 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3832 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
3833 (skip-unless (tramp-get-remote-stat v)))
3835 (let ((tramp-connection-properties
3836 (append
3837 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3838 "perl" nil))
3839 tramp-connection-properties)))
3840 (tramp--test-utf8)))
3842 (ert-deftest tramp-test36-utf8-with-perl ()
3843 "Check UTF8 encoding in file names and file contents.
3844 Use the `perl' command."
3845 :tags '(:expensive-test)
3846 (skip-unless (tramp--test-enabled))
3847 (skip-unless (tramp--test-sh-p))
3848 (skip-unless (not (tramp--test-docker-p)))
3849 (skip-unless (not (tramp--test-rsync-p)))
3850 (skip-unless (not (tramp--test-windows-nt-and-batch)))
3851 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3852 (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
3853 (skip-unless (tramp-get-remote-perl v)))
3855 (let ((tramp-connection-properties
3856 (append
3857 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3858 "stat" nil)
3859 ;; See `tramp-sh-handle-file-truename'.
3860 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3861 "readlink" nil))
3862 tramp-connection-properties)))
3863 (tramp--test-utf8)))
3865 (ert-deftest tramp-test36-utf8-with-ls ()
3866 "Check UTF8 encoding in file names and file contents.
3867 Use the `ls' command."
3868 :tags '(:expensive-test)
3869 (skip-unless (tramp--test-enabled))
3870 (skip-unless (tramp--test-sh-p))
3871 (skip-unless (not (tramp--test-docker-p)))
3872 (skip-unless (not (tramp--test-rsync-p)))
3873 (skip-unless (not (tramp--test-windows-nt-and-batch)))
3874 (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
3876 (let ((tramp-connection-properties
3877 (append
3878 `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3879 "perl" nil)
3880 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3881 "stat" nil)
3882 ;; See `tramp-sh-handle-file-truename'.
3883 (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
3884 "readlink" nil))
3885 tramp-connection-properties)))
3886 (tramp--test-utf8)))
3888 (defun tramp--test-timeout-handler ()
3889 (interactive)
3890 (ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test)))))
3892 ;; This test is inspired by Bug#16928.
3893 (ert-deftest tramp-test37-asynchronous-requests ()
3894 "Check parallel asynchronous requests.
3895 Such requests could arrive from timers, process filters and
3896 process sentinels. They shall not disturb each other."
3897 :tags '(:expensive-test)
3898 (skip-unless (tramp--test-enabled))
3899 (skip-unless (tramp--test-sh-p))
3901 ;; This test could be blocked on hydra. So we set a timeout of 300
3902 ;; seconds, and we send a SIGUSR1 signal after 300 seconds.
3903 (with-timeout (300 (tramp--test-timeout-handler))
3904 (define-key special-event-map [sigusr1] 'tramp--test-timeout-handler)
3905 (tramp--test-instrument-test-case (if (getenv "EMACS_HYDRA_CI") 10 0)
3906 (let* (;; For the watchdog.
3907 (default-directory (expand-file-name temporary-file-directory))
3908 (watchdog
3909 (start-process
3910 "*watchdog*" nil shell-file-name shell-command-switch
3911 (format "sleep 300; kill -USR1 %d" (emacs-pid))))
3912 (tmp-name (tramp--test-make-temp-name))
3913 (default-directory tmp-name)
3914 ;; Do not cache Tramp properties.
3915 (remote-file-name-inhibit-cache t)
3916 (process-file-side-effects t)
3917 ;; Suppress nasty messages.
3918 (inhibit-message t)
3919 ;; Do not run delayed timers.
3920 (timer-max-repeats 0)
3921 ;; Number of asynchronous processes for test.
3922 (number-proc 10)
3923 ;; On hydra, timings are bad.
3924 (timer-repeat
3925 (cond
3926 ((getenv "EMACS_HYDRA_CI") 10)
3927 (t 1)))
3928 ;; We must distinguish due to performance reasons.
3929 (timer-operation
3930 (cond
3931 ((string-equal "mock" (file-remote-p tmp-name 'method))
3932 'vc-registered)
3933 (t 'file-attributes)))
3934 timer buffers kill-buffer-query-functions)
3936 (unwind-protect
3937 (progn
3938 (make-directory tmp-name)
3940 ;; Setup a timer in order to raise an ordinary command
3941 ;; again and again. `vc-registered' is well suited,
3942 ;; because there are many checks.
3943 (setq
3944 timer
3945 (run-at-time
3946 0 timer-repeat
3947 (lambda ()
3948 (when buffers
3949 (let ((time (float-time))
3950 (default-directory tmp-name)
3951 (file
3952 (buffer-name (nth (random (length buffers)) buffers))))
3953 (tramp--test-message
3954 "Start timer %s %s" file (current-time-string))
3955 (funcall timer-operation file)
3956 ;; Adjust timer if it takes too much time.
3957 (when (> (- (float-time) time) timer-repeat)
3958 (setq timer-repeat (* 1.5 timer-repeat))
3959 (setf (timer--repeat-delay timer) timer-repeat)
3960 (tramp--test-message "Increase timer %s" timer-repeat))
3961 (tramp--test-message
3962 "Stop timer %s %s" file (current-time-string)))))))
3964 ;; Create temporary buffers. The number of buffers
3965 ;; corresponds to the number of processes; it could be
3966 ;; increased in order to make pressure on Tramp.
3967 (dotimes (_i number-proc)
3968 (setq buffers (cons (generate-new-buffer "foo") buffers)))
3970 ;; Open asynchronous processes. Set process filter and sentinel.
3971 (dolist (buf buffers)
3972 ;; Activate timer.
3973 (sit-for 0.01 'nodisp)
3974 (let ((proc
3975 (start-file-process-shell-command
3976 (buffer-name buf) buf
3977 (concat
3978 "(read line && echo $line >$line);"
3979 "(read line && cat $line);"
3980 "(read line && rm $line)")))
3981 (file (expand-file-name (buffer-name buf))))
3982 ;; Remember the file name. Add counter.
3983 (process-put proc 'foo file)
3984 (process-put proc 'bar 0)
3985 ;; Add process filter.
3986 (set-process-filter
3987 proc
3988 (lambda (proc string)
3989 (with-current-buffer (process-buffer proc)
3990 (insert string))
3991 (unless (zerop (length string))
3992 (should (file-attributes (process-get proc 'foo))))))
3993 ;; Add process sentinel.
3994 (set-process-sentinel
3995 proc
3996 (lambda (proc _state)
3997 (should-not (file-attributes (process-get proc 'foo)))))))
3999 ;; Send a string. Use a random order of the buffers. Mix
4000 ;; with regular operation.
4001 (let ((buffers (copy-sequence buffers)))
4002 (while buffers
4003 ;; Activate timer.
4004 (sit-for 0.01 'nodisp)
4005 (let* ((buf (nth (random (length buffers)) buffers))
4006 (proc (get-buffer-process buf))
4007 (file (process-get proc 'foo))
4008 (count (process-get proc 'bar)))
4009 (tramp--test-message
4010 "Start action %d %s %s" count buf (current-time-string))
4011 ;; Regular operation prior process action.
4012 (if (= count 0)
4013 (should-not (file-attributes file))
4014 (should (file-attributes file)))
4015 ;; Send string to process.
4016 (process-send-string proc (format "%s\n" (buffer-name buf)))
4017 (accept-process-output proc 0.1 nil 0)
4018 ;; Give the watchdog a chance.
4019 (read-event nil nil 0.01)
4020 ;; Regular operation post process action.
4021 (if (= count 2)
4022 (should-not (file-attributes file))
4023 (should (file-attributes file)))
4024 (tramp--test-message
4025 "Stop action %d %s %s" count buf (current-time-string))
4026 (process-put proc 'bar (1+ count))
4027 (unless (process-live-p proc)
4028 (setq buffers (delq buf buffers))))))
4030 ;; Checks. All process output shall exists in the
4031 ;; respective buffers. All created files shall be
4032 ;; deleted.
4033 (tramp--test-message "Check %s" (current-time-string))
4034 (dolist (buf buffers)
4035 (with-current-buffer buf
4036 (should (string-equal (format "%s\n" buf) (buffer-string)))))
4037 (should-not
4038 (directory-files
4039 tmp-name nil directory-files-no-dot-files-regexp)))
4041 ;; Cleanup.
4042 (define-key special-event-map [sigusr1] 'ignore)
4043 (ignore-errors (quit-process watchdog))
4044 (dolist (buf buffers)
4045 (ignore-errors (delete-process (get-buffer-process buf)))
4046 (ignore-errors (kill-buffer buf)))
4047 (ignore-errors (cancel-timer timer))
4048 (ignore-errors (delete-directory tmp-name 'recursive)))))))
4050 (ert-deftest tramp-test38-recursive-load ()
4051 "Check that Tramp does not fail due to recursive load."
4052 (skip-unless (tramp--test-enabled))
4054 (let ((default-directory (expand-file-name temporary-file-directory)))
4055 (dolist (code
4056 (list
4057 (format
4058 "(expand-file-name %S)" tramp-test-temporary-file-directory)
4059 (format
4060 "(let ((default-directory %S)) (expand-file-name %S))"
4061 tramp-test-temporary-file-directory
4062 temporary-file-directory)))
4063 (should-not
4064 (string-match
4065 "Recursive load"
4066 (shell-command-to-string
4067 (format
4068 "%s -batch -Q -L %s --eval %s"
4069 (expand-file-name invocation-name invocation-directory)
4070 (mapconcat 'shell-quote-argument load-path " -L ")
4071 (shell-quote-argument code))))))))
4073 (ert-deftest tramp-test39-remote-load-path ()
4074 "Check that Tramp autoloads its packages with remote `load-path'."
4075 ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
4076 ;; It shall still work, when a remote file name is in the
4077 ;; `load-path'.
4078 (let ((default-directory (expand-file-name temporary-file-directory))
4079 (code
4080 "(let ((force-load-messages t) \
4081 (load-path (cons \"/foo:bar:\" load-path))) \
4082 (tramp-cleanup-all-connections))"))
4083 (should
4084 (string-match
4085 (format
4086 "Loading %s"
4087 (expand-file-name
4088 "tramp-cmds" (file-name-directory (locate-library "tramp"))))
4089 (shell-command-to-string
4090 (format
4091 "%s -batch -Q -L %s -l tramp-sh --eval %s"
4092 (expand-file-name invocation-name invocation-directory)
4093 (mapconcat 'shell-quote-argument load-path " -L ")
4094 (shell-quote-argument code)))))))
4096 (ert-deftest tramp-test40-unload ()
4097 "Check that Tramp and its subpackages unload completely.
4098 Since it unloads Tramp, it shall be the last test to run."
4099 :tags '(:expensive-test)
4100 (skip-unless noninteractive)
4102 (when (featurep 'tramp)
4103 (unload-feature 'tramp 'force)
4104 ;; No Tramp feature must be left.
4105 (should-not (featurep 'tramp))
4106 (should-not (all-completions "tramp" (delq 'tramp-tests features)))
4107 ;; `file-name-handler-alist' must be clean.
4108 (should-not (all-completions "tramp" (mapcar 'cdr file-name-handler-alist)))
4109 ;; There shouldn't be left a bound symbol, except buffer-local
4110 ;; variables, and autoload functions. We do not regard our test
4111 ;; symbols, and the Tramp unload hooks.
4112 (mapatoms
4113 (lambda (x)
4114 (and (or (and (boundp x) (null (local-variable-if-set-p x)))
4115 (and (functionp x) (null (autoloadp (symbol-function x)))))
4116 (string-match "^tramp" (symbol-name x))
4117 (not (string-match "^tramp--?test" (symbol-name x)))
4118 (not (string-match "unload-hook$" (symbol-name x)))
4119 (ert-fail (format "`%s' still bound" x)))))
4120 ;; The defstruct `tramp-file-name' and all its internal functions
4121 ;; shall be purged.
4122 (should-not (cl--find-class 'tramp-file-name))
4123 (mapatoms
4124 (lambda (x)
4125 (and (functionp x)
4126 (string-match "tramp-file-name" (symbol-name x))
4127 (ert-fail (format "Structure function `%s' still exists" x)))))
4128 ;; There shouldn't be left a hook function containing a Tramp
4129 ;; function. We do not regard the Tramp unload hooks.
4130 (mapatoms
4131 (lambda (x)
4132 (and (boundp x)
4133 (string-match "-\\(hook\\|function\\)s?$" (symbol-name x))
4134 (not (string-match "unload-hook$" (symbol-name x)))
4135 (consp (symbol-value x))
4136 (ignore-errors (all-completions "tramp" (symbol-value x)))
4137 (ert-fail (format "Hook `%s' still contains Tramp function" x)))))))
4139 ;; TODO:
4141 ;; * dired-compress-file
4142 ;; * dired-uncache
4143 ;; * file-acl
4144 ;; * file-name-case-insensitive-p
4145 ;; * file-selinux-context
4146 ;; * find-backup-file-name
4147 ;; * set-file-acl
4148 ;; * set-file-selinux-context
4150 ;; * Work on skipped tests. Make a comment, when it is impossible.
4151 ;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'.
4152 ;; * Fix `tramp-test06-directory-file-name' for `ftp'.
4153 ;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?).
4154 ;; * Fix Bug#16928 in `tramp-test37-asynchronous-requests'.
4156 (defun tramp-test-all (&optional interactive)
4157 "Run all tests for \\[tramp]."
4158 (interactive "p")
4159 (funcall
4160 (if interactive 'ert-run-tests-interactively 'ert-run-tests-batch) "^tramp"))
4162 (provide 'tramp-tests)
4163 ;;; tramp-tests.el ends here