Completed
Push — master ( 24da64...15c423 )
by Gonzalo
65:23
created

NewIntegrationTests.test_non_existent_file()   A

Complexity

Conditions 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
1
import json
2
import os
3
from os.path import join
4
from shlex import split
5
import tempfile
6
import unittest
7
8
import pytest
9
10
from conda.base.constants import ROOT_ENV_NAME
11
from conda.base.context import context
12
from conda.cli.conda_argparse import do_call
13
from conda.cli.main import generate_parser
14
from conda.common.io import captured
15
from conda.core.envs_manager import list_all_known_prefixes
16
from conda.exceptions import EnvironmentLocationNotFound
17
from conda.install import rm_rf
18
from conda_env.cli.main import create_parser, do_call as do_call_conda_env
19
from conda_env.exceptions import EnvironmentFileExtensionNotValid, EnvironmentFileNotFound
20
from conda_env.yaml import load as yaml_load
21
22
from . import support_file
23
24
environment_1 = '''
25
name: env-1
26
dependencies:
27
  - python
28
channels:
29
  - malev
30
'''
31
32
environment_2 = '''
33
name: env-1
34
dependencies:
35
  - python
36
  - flask
37
channels:
38
  - malev
39
'''
40
41
environment_3_invalid = '''
42
name: env-1
43
dependecies:
44
  - python
45
  - flask
46
channels:
47
  - malev
48
foo: bar
49
'''
50
51
test_env_name_1 = "env-1"
52
test_env_name_2 = "snowflakes"
53
test_env_name_3 = "env_foo"
54
55
56
def escape_for_winpath(p):
57
    if p:
58
        return p.replace('\\', '\\\\')
59
60
61
class Commands:
62
    ENV_CREATE = "create"
63
    ENV_REMOVE = "remove"
64
    ENV_EXPORT = "export"
65
    ENV_UPDATE = "update"
66
    LIST = "list"
67
    CREATE = "create"
68
    INFO = "info"
69
    INSTALL = "install"
70
71
72
def run_env_command(command, prefix, *arguments):
73
    """
74
        Run conda env commands
75
    Args:
76
        command: The command, create, remove, export
77
        prefix: The prefix, for remove and create
78
        *arguments: The extra arguments
79
    """
80
    p = create_parser()
81
    prefix = escape_for_winpath(prefix)
82
83
    if arguments:
84
        arguments = list(map(escape_for_winpath, arguments))
85
86
    if command is Commands.ENV_EXPORT:
87
        command_line = "{0} -n {1} {2}".format(command, prefix, " ".join(arguments))
88
    elif command is Commands.ENV_CREATE: # CREATE
89
        if prefix :
90
            command_line = "{0} -f {1}  {2}".format(command, prefix, " ".join(arguments))
91
        else:
92
            command_line = "{0} ".format(command)
93
    elif command is Commands.ENV_REMOVE:  # REMOVE
94
        command_line = "{0} --yes -n {1} {2}".format(command, prefix, " ".join(arguments))
95
    elif command is Commands.ENV_UPDATE:
96
        command_line = "{0} -n {1} {2}".format(command, prefix, " ".join(arguments))
97
    else:
98
        command_line = " --help "
99
100
    args = p.parse_args(split(command_line))
101
    context._set_argparse_args(args)
102
103
    with captured() as c:
104
        do_call_conda_env(args, p)
105
106
    return c.stdout, c.stderr
107
108
109
def run_conda_command(command, prefix, *arguments):
110
    """
111
        Run conda command,
112
    Args:
113
        command: conda create , list, info
114
        prefix: The prefix or the name of environment
115
        *arguments: Extra arguments
116
    """
117
    p = generate_parser()
118
119
    prefix = escape_for_winpath(prefix)
120
    if arguments:
121
        arguments = list(map(escape_for_winpath, arguments))
122
    if command is Commands.INFO:    # INFO
123
        command_line = "{0} {1}".format(command, " ".join(arguments))
124
    elif command is Commands.LIST:  # LIST
125
        command_line = "{0} -n {1} {2}".format(command, prefix, " ".join(arguments))
126
    else:  # CREATE
127
        command_line = "{0} -y -q -n {1} {2}".format(command, prefix, " ".join(arguments))
128
129
    args = p.parse_args(split(command_line))
130
    context._set_argparse_args(args)
131
    with captured() as c:
132
        do_call(args, p)
133
134
    return c.stdout, c.stderr
135
136
137
def create_env(content, filename='environment.yml'):
138
    with open(filename, 'w') as fenv:
139
        fenv.write(content)
140
141
142
def remove_env_file(filename='environment.yml'):
143
    os.remove(filename)
144
145
146
@pytest.mark.integration
147
class IntegrationTests(unittest.TestCase):
148
149
    def setUp(self):
150
        rm_rf("environment.yml")
151
        if env_is_created(test_env_name_1):
152
            run_env_command(Commands.ENV_REMOVE, test_env_name_1)
153
154
    def tearDown(self):
155
        rm_rf("environment.yml")
156
        if env_is_created(test_env_name_1):
157
            run_env_command(Commands.ENV_REMOVE, test_env_name_1)
158
159
    def test_conda_env_create_no_file(self):
160
        '''
161
        Test `conda env create` without an environment.yml file
162
        Should fail
163
        '''
164
        try:
165
            run_env_command(Commands.ENV_CREATE, None)
166
        except Exception as e:
167
            self.assertIsInstance(e, EnvironmentFileNotFound)
168
169
    def test_conda_env_create_no_existent_file(self):
170
        '''
171
        Test `conda env create --file=not_a_file.txt` with a file that does not
172
        exist.
173
        '''
174
        try:
175
            run_env_command(Commands.ENV_CREATE, None, '--file not_a_file.txt')
176
        except Exception as e:
177
            self.assertIsInstance(e, EnvironmentFileNotFound)
178
179
    def test_create_valid_env(self):
180
        '''
181
        Creates an environment.yml file and
182
        creates and environment with it
183
        '''
184
185
        create_env(environment_1)
186
        run_env_command(Commands.ENV_CREATE, None)
187
        self.assertTrue(env_is_created(test_env_name_1))
188
189
        o, e = run_conda_command(Commands.INFO, None, "--json")
190
        parsed = json.loads(o)
191
        self.assertNotEqual(
192
            len([env for env in parsed['envs'] if env.endswith(test_env_name_1)]), 0
193
        )
194
195
    def test_update(self):
196
        create_env(environment_1)
197
        run_env_command(Commands.ENV_CREATE, None)
198
        create_env(environment_2)
199
200
        run_env_command(Commands.ENV_UPDATE, test_env_name_1)
201
202
        o, e = run_conda_command(Commands.LIST, test_env_name_1, "flask", "--json")
203
        parsed = json.loads(o)
204
        self.assertNotEqual(len(parsed), 0)
205
206
    def test_name(self):
207
        # smoke test for gh-254
208
        create_env(environment_1)
209
        try:
210
            run_env_command(Commands.ENV_CREATE, test_env_name_1, "create")
211
        except Exception as e:
212
            self.assertIsInstance(e, EnvironmentFileNotFound, str(e))
213
214
215
def env_is_created(env_name):
216
    """
217
        Assert an environment is created
218
    Args:
219
        env_name: the environment name
220
    Returns: True if created
221
             False otherwise
222
    """
223
    from os.path import basename
224
225
    for prefix in list_all_known_prefixes():
226
        name = (ROOT_ENV_NAME if prefix == context.root_dir else
227
                basename(prefix))
228
        if name == env_name:
229
            return True
230
231
    return False
232
233
234
@pytest.mark.integration
235
class NewIntegrationTests(unittest.TestCase):
236
    """
237
        This is integration test for conda env
238
        make sure all instruction on online documentation works
239
        Please refer to link below
240
        http://conda.pydata.org/docs/using/envs.html#export-the-environment-file
241
    """
242
243
    def setUp(self):
244
        if env_is_created(test_env_name_2):
245
            run_env_command(Commands.ENV_REMOVE, test_env_name_2)
246
        if env_is_created(test_env_name_3):
247
            run_env_command(Commands.ENV_REMOVE, test_env_name_3)
248
249
    def tearDown(self):
250
        if env_is_created(test_env_name_2):
251
            run_env_command(Commands.ENV_REMOVE, test_env_name_2)
252
        if env_is_created(test_env_name_3):
253
            run_env_command(Commands.ENV_REMOVE, test_env_name_3)
254
255
    def test_create_remove_env(self):
256
        """
257
            Test conda create and remove env
258
        """
259
260
        run_conda_command(Commands.CREATE, test_env_name_3)
261
        self.assertTrue(env_is_created(test_env_name_3))
262
263
        run_env_command(Commands.ENV_REMOVE, test_env_name_3)
264
        self.assertFalse(env_is_created(test_env_name_3))
265
266
        with pytest.raises(EnvironmentLocationNotFound) as execinfo:
267
            run_env_command(Commands.ENV_REMOVE, 'does-not-exist')
268
269
    def test_env_export(self):
270
        """
271
            Test conda env export
272
        """
273
274
        run_conda_command(Commands.CREATE, test_env_name_2, "flask")
275
        self.assertTrue(env_is_created(test_env_name_2))
276
277
        snowflake, e,  = run_env_command(Commands.ENV_EXPORT, test_env_name_2)
278
279
        with tempfile.NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_yaml:
280
            env_yaml.write(snowflake)
281
            env_yaml.flush()
282
            env_yaml.close()
283
284
            run_env_command(Commands.ENV_REMOVE, test_env_name_2)
285
            self.assertFalse(env_is_created(test_env_name_2))
286
            run_env_command(Commands.ENV_CREATE, env_yaml.name)
287
            self.assertTrue(env_is_created(test_env_name_2))
288
289
            # regression test for #6220
290
            snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2, '--no-builds')
291
            assert not e.strip()
292
            env_description = yaml_load(snowflake)
293
            assert len(env_description['dependencies'])
294
            for spec_str in env_description['dependencies']:
295
                assert spec_str.count('=') == 1
296
297
    def test_list(self):
298
        """
299
            Test conda list -e and conda create from txt
300
        """
301
302
        run_conda_command(Commands.CREATE, test_env_name_2)
303
        self.assertTrue(env_is_created(test_env_name_2))
304
305
        snowflake, e = run_conda_command(Commands.LIST, test_env_name_2, "-e")
306
307
        with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as env_txt:
308
            env_txt.write(snowflake)
309
            env_txt.flush()
310
            env_txt.close()
311
            run_env_command(Commands.ENV_REMOVE, test_env_name_2)
312
            self.assertFalse(env_is_created(test_env_name_2))
313
            run_conda_command(Commands.CREATE, test_env_name_2, "--file " + env_txt.name)
314
            self.assertTrue(env_is_created(test_env_name_2))
315
316
        snowflake2, e = run_conda_command(Commands.LIST, test_env_name_2, "-e")
317
        self.assertEqual(snowflake, snowflake2)
318
319
    def test_export_muti_channel(self):
320
        """
321
            Test conda env export
322
        """
323
        from conda.core.prefix_data import PrefixData
324
        PrefixData._cache_.clear()
325
        run_conda_command(Commands.CREATE, test_env_name_2, "python=3.5")
326
        self.assertTrue(env_is_created(test_env_name_2))
327
328
        # install something from other channel not in config file
329
        run_conda_command(Commands.INSTALL, test_env_name_2, "-c", "numba", "llvmlite")
330
        snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2)
331
        assert 'numba' in snowflake
332
333
        check1, e = run_conda_command(Commands.LIST, test_env_name_2, "--explicit")
334
335
        with tempfile.NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_yaml:
336
            env_yaml.write(snowflake)
337
            env_yaml.flush()
338
            env_yaml.close()
339
            run_env_command(Commands.ENV_REMOVE, test_env_name_2)
340
            self.assertFalse(env_is_created(test_env_name_2))
341
            run_env_command(Commands.ENV_CREATE, env_yaml.name)
342
            self.assertTrue(env_is_created(test_env_name_2))
343
344
        # check explicit that we have same file
345
        check2, e = run_conda_command(Commands.LIST, test_env_name_2, "--explicit")
346
        self.assertEqual(check1, check2)
347
348
    def test_non_existent_file(self):
349
        with self.assertRaises(EnvironmentFileNotFound):
350
            run_env_command(Commands.ENV_CREATE, 'i_do_not_exist.yml')
351
352
    def test_invalid_extensions(self):
353
        with tempfile.NamedTemporaryFile(mode="w", suffix=".ymla", delete=False) as env_yaml:
354
            with self.assertRaises(EnvironmentFileExtensionNotValid):
355
                run_env_command(Commands.ENV_CREATE, env_yaml.name)
356
357
358
359
if __name__ == '__main__':
360
    unittest.main()
361