Repository: conda/conda-build

Issue:
Moar bugs in copying test files
```
Traceback (most recent call last):
  File "/opt/conda/bin/conda-build", line 11, in <module>
    sys.exit(main())
  File "/opt/conda/lib/python3.6/site-packages/conda_build/cli/main_build.py", line 420, in main
    execute(sys.argv[1:])
  File "/opt/conda/lib/python3.6/site-packages/conda_build/cli/main_build.py", line 411, in execute
    verify=args.verify)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/api.py", line 200, in build
    notest=notest, need_source_download=need_source_download, variants=variants)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/build.py", line 2181, in build_tree
    test(pkg, config=metadata.config.copy(), stats=stats)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/build.py", line 1834, in test
    copy_test_source_files(metadata, metadata.config.test_dir)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/build.py", line 405, in copy_test_source_files
    timeout=m.config.timeout, locking=m.config.locking, clobber=True)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/utils.py", line 466, in copy_into
    _copy_with_shell_fallback(src, dst_fn)
  File "/opt/conda/lib/python3.6/site-packages/conda_build/utils.py", line 399, in _copy_with_shell_fallback
    raise OSError("Failed to copy {} to {}.  Error was: {}".format(src, dst, e))
OSError: Failed to copy /tmp/tmp26g4707g/info/recipe/test_data to /tmp/build/80754af9/gdal-split_1527879568885/test_tmp/test_data/test_data.  Error was: Command 'cp -a /tmp/tmp26g4707g/info/recipe/test_data /tmp/build/80754af9/gdal-split_1527879568885/test_tmp/test_data/test_data' returned non-zero exit status 1.
```

Looks to me like it is duplicating the folder name somehow.


Discussion:

Resolving patch:
diff --git a/conda_build/build.py b/conda_build/build.py
--- a/conda_build/build.py
+++ b/conda_build/build.py
@@ -400,9 +400,11 @@ def copy_test_source_files(m, destination):
     recipe_test_files = m.get_value('test/files')
     if recipe_test_files:
         orig_recipe_dir = m.path or m.meta.get('extra', {}).get('parent_recipe', {}).get('path')
-        for f in recipe_test_files:
-            utils.copy_into(os.path.join(orig_recipe_dir, f), os.path.join(destination, f),
-                            timeout=m.config.timeout, locking=m.config.locking, clobber=True)
+        for pattern in recipe_test_files:
+            files = glob(join(orig_recipe_dir, pattern))
+            for f in files:
+                utils.copy_into(f, f.replace(orig_recipe_dir, destination),
+                                timeout=m.config.timeout, locking=m.config.locking, clobber=True)
 
 
 def write_hash_input(m):


Test patch:
diff --git a/conda_build/create_test.py b/conda_build/create_test.py
--- a/conda_build/create_test.py
+++ b/conda_build/create_test.py
@@ -8,7 +8,7 @@
 from os.path import join, exists
 import sys
 
-from conda_build.utils import copy_into, on_win, ensure_list
+from conda_build.utils import copy_into, on_win, ensure_list, glob
 
 
 def create_files(m, test_dir=None):
@@ -27,14 +27,12 @@ def create_files(m, test_dir=None):
 
     recipe_dir = m.path or m.meta.get('extra', {}).get('parent_recipe', {}).get('path')
 
-    for fn in ensure_list(m.get_value('test/files', [])):
+    for pattern in ensure_list(m.get_value('test/files', [])):
         has_files = True
-        path = join(recipe_dir, fn)
-        if not os.path.isdir(os.path.dirname(path)):
-            os.makedirs(os.path.dirname(path))
-        # disable locking to avoid locking a temporary directory (the extracted test folder)
-        copy_into(path, join(test_dir, fn), m.config.timeout, locking=False,
-                  clobber=True)
+        files = glob(join(recipe_dir, pattern))
+        for f in files:
+            copy_into(f, f.replace(recipe_dir, test_dir), m.config.timeout, locking=False,
+                    clobber=True)
     return has_files
 
 
diff --git a/tests/test-recipes/metadata/_test_test_source_files/conda-recipe/meta.yaml b/tests/test-recipes/metadata/_test_test_source_files/conda-recipe/meta.yaml
--- a/tests/test-recipes/metadata/_test_test_source_files/conda-recipe/meta.yaml
+++ b/tests/test-recipes/metadata/_test_test_source_files/conda-recipe/meta.yaml
@@ -7,12 +7,12 @@ source:
 
 test:
   source_files:
-    - test
+    - test_files_folder
   files:
     - recipe_file
 
   commands:
-    - test -e test/text.txt   # [unix]
+    - test -e test_files_folder/text.txt   # [unix]
     - test -e recipe_file     # [unix]
-    - if not exist test\text.txt exit 1  # [win]
+    - if not exist test_files_folder\text.txt exit 1  # [win]
     - if not exist recipe_file exit 1    # [win]
diff --git a/tests/test-recipes/metadata/_test_test_source_files/test/text.txt b/tests/test-recipes/metadata/_test_test_source_files/test/text.txt
deleted file mode 100644
--- a/tests/test-recipes/metadata/_test_test_source_files/test/text.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is test data.
diff --git a/tests/test-recipes/metadata/_test_test_source_files/test_files_folder/text.txt b/tests/test-recipes/metadata/_test_test_source_files/test_files_folder/text.txt
new file mode 100644
diff --git a/tests/test-recipes/split-packages/test_files_copying/folder/file2 b/tests/test-recipes/split-packages/test_files_copying/folder/file2
new file mode 100644
diff --git a/tests/test-recipes/split-packages/test_files_copying/meta.yaml b/tests/test-recipes/split-packages/test_files_copying/meta.yaml
--- a/tests/test-recipes/split-packages/test_files_copying/meta.yaml
+++ b/tests/test-recipes/split-packages/test_files_copying/meta.yaml
@@ -12,8 +12,16 @@ outputs:
     test:
       files:
         - file
+        - folder
       source_files:
         - source_file
+        - source_folder
       commands:
-        - test -e file
-        - test -e source_file
+        - test -e file                           # [unix]
+        - test -e folder/file2                   # [unix]
+        - test -e source_file                    # [unix]
+        - test -e source_folder/file3            # [unix]
+        - if not exist file exit 1               # [win]
+        - if not exist folder/file2 exit 1       # [win]
+        - if not exist source_file exit 1        # [win]
+        - if not exist source_folder/file3 exit  # [win]
diff --git a/tests/test-recipes/split-packages/test_files_copying/source_folder/file3 b/tests/test-recipes/split-packages/test_files_copying/source_folder/file3
new file mode 100644
diff --git a/tests/test_api_build.py b/tests/test_api_build.py
--- a/tests/test_api_build.py
+++ b/tests/test_api_build.py
@@ -1171,18 +1171,18 @@ def test_copy_test_source_files(testing_config):
             # nesting of test/test here is because info/test is the main folder
             # for test files, then test is the source_files folder we specify,
             # and text.txt is within that.
-            if f.name == 'info/test/test/text.txt':
+            if f.name == 'info/test/test_files_folder/text.txt':
                 found = True
                 break
         if found:
-            assert copy, "'info/test/test/text.txt' found in tar.bz2 but not copying test source files"
+            assert copy, "'info/test/test_files_folder/text.txt' found in tar.bz2 but not copying test source files"
             if copy:
                 api.test(outputs[0])
             else:
                 with pytest.raises(RuntimeError):
                     api.test(outputs[0])
         else:
-            assert not copy, "'info/test/test/text.txt' not found in tar.bz2 but copying test source files. File list: %r" % files
+            assert not copy, "'info/test/test_files_folder/text.txt' not found in tar.bz2 but copying test source files. File list: %r" % files
 
 
 def test_pin_depends(testing_config):