Update tosca lib to version 0.5
[parser.git] / tosca2heat / heat-translator / translator / tests / test_shell.py
1 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
2 #    not use this file except in compliance with the License. You may obtain
3 #    a copy of the License at
4 #
5 #         http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #    Unless required by applicable law or agreed to in writing, software
8 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 #    License for the specific language governing permissions and limitations
11 #    under the License.
12
13 import ast
14 import json
15 import os
16 import shutil
17 import tempfile
18
19 from mock import patch
20 from toscaparser.common import exception
21 from toscaparser.utils.gettextutils import _
22 import translator.shell as shell
23 from translator.tests.base import TestCase
24
25
26 class ShellTest(TestCase):
27     tosca_helloworld = os.path.join(
28         os.path.dirname(os.path.abspath(__file__)),
29         "data/tosca_helloworld.yaml")
30     template_file = '--template-file=' + tosca_helloworld
31     template_type = '--template-type=tosca'
32     template_validation = "--validate-only=true"
33     failure_msg = _('The program raised an exception unexpectedly.')
34
35     def test_missing_arg(self):
36         error = self.assertRaises(ValueError, shell.main, '')
37         err_msg = _('The program requires minimum two arguments. '
38                     'Please refer to the usage documentation.')
39         self.assertEqual(err_msg, str(error))
40
41     def test_invalid_file_arg(self):
42         error = self.assertRaises(ValueError, shell.main, 'translate me')
43         err_msg = _('The program expects --template-file as first '
44                     'argument. Please refer to the usage documentation.')
45         self.assertEqual(err_msg, str(error))
46
47     def test_invalid_type_arg(self):
48         error = self.assertRaises(ValueError,
49                                   shell.main, ('--template-file=', 'xyz'))
50         err_msg = _('The program expects --template-type as second argument. '
51                     'Please refer to the usage documentation.')
52         self.assertEqual(err_msg, str(error))
53
54     def test_invalid_file_value(self):
55         error = self.assertRaises(ValueError,
56                                   shell.main, ('--template-file=template.txt',
57                                                self.template_type))
58         err_msg = _('The path template.txt is not a valid file or URL.')
59         self.assertEqual(err_msg, str(error))
60
61     def test_invalid_type_value(self):
62         error = self.assertRaises(ValueError, shell.main,
63                                   (self.template_file, '--template-type=xyz'))
64         err_msg = _('xyz is not a valid template type.')
65         self.assertEqual(err_msg, str(error))
66
67     def test_invalid_parameters(self):
68         error = self.assertRaises(ValueError, shell.main,
69                                   (self.template_file, self.template_type,
70                                    '--parameters=key'))
71         err_msg = _("'key' is not a well-formed parameter.")
72         self.assertEqual(err_msg, str(error))
73
74     def test_valid_template(self):
75         try:
76             shell.main([self.template_file, self.template_type])
77         except Exception:
78             self.fail(self.failure_msg)
79
80     def test_valid_template_with_parameters(self):
81         tosca_single_instance_wordpress = os.path.join(
82             os.path.dirname(os.path.abspath(__file__)),
83             "data/tosca_single_instance_wordpress.yaml")
84         parameters = '--parameters="cpus=2;db_name=wpdb;db_user=test;'\
85                      'db_port=2000;db_root_pwd=fun2test;db_pwd=fun2test"'
86         template = '--template-file=' + tosca_single_instance_wordpress
87         try:
88             shell.main([template, self.template_type, parameters])
89         except Exception:
90             self.fail(self.failure_msg)
91
92     def test_validate_only(self):
93         try:
94             shell.main([self.template_file, self.template_type,
95                         self.template_validation])
96         except Exception:
97             self.fail(self.failure_msg)
98
99         template = os.path.join(
100             os.path.dirname(os.path.abspath(__file__)),
101             "data/tosca_helloworld_invalid.yaml")
102         invalid_template = '--template-file=' + template
103         self.assertRaises(exception.ValidationError, shell.main,
104                           [invalid_template, self.template_type,
105                            self.template_validation])
106
107     def test_output_file(self):
108         temp_dir = tempfile.mkdtemp()
109         temp_file = "/test_translation_output.txt"
110         output_file = "--output-file=" + temp_dir + temp_file
111         try:
112             shell.main([self.template_file, self.template_type, output_file])
113         except Exception:
114             self.fail(self.failure_msg)
115         finally:
116             if temp_dir:
117                 shutil.rmtree(temp_dir)
118                 self.assertTrue(temp_dir is None or
119                                 not os.path.exists(temp_dir))
120
121     @patch('uuid.uuid4')
122     @patch('translator.common.utils.check_for_env_variables')
123     @patch('requests.post')
124     @patch('translator.common.utils.get_url_for')
125     @patch('translator.common.utils.get_token_id')
126     @patch('os.getenv')
127     @patch('translator.hot.tosca.tosca_compute.'
128            'ToscaCompute._create_nova_flavor_dict')
129     def test_template_deploy_with_credentials(self, mock_flavor_dict,
130                                               mock_os_getenv,
131                                               mock_token,
132                                               mock_url, mock_post,
133                                               mock_env,
134                                               mock_uuid):
135         mock_uuid.return_value = 'abcXXX-abcXXX'
136         mock_env.return_value = True
137         mock_flavor_dict.return_value = {
138             'm1.medium': {'mem_size': 4096, 'disk_size': 40, 'num_cpus': 2}
139         }
140         mock_url.return_value = 'http://abc.com'
141         mock_token.return_value = 'mock_token'
142         mock_os_getenv.side_effect = ['demo', 'demo',
143                                       'demo', 'http://www.abc.com']
144         try:
145             data = {
146                 'stack_name': 'heat_abcXXX',
147                 'parameters': {},
148                 'template': {
149                     'outputs': {},
150                     'heat_template_version': '2013-05-23',
151                     'description': 'Template for deploying a single server '
152                                    'with predefined properties.\n',
153                     'parameters': {},
154                     'resources': {
155                         'my_server': {
156                             'type': 'OS::Nova::Server',
157                             'properties': {
158                                 'flavor': 'm1.medium',
159                                 'user_data_format': 'SOFTWARE_CONFIG',
160                                 'image': 'rhel-6.5-test-image'
161                             }
162                         }
163                     }
164                 }
165             }
166
167             mock_heat_res = {
168                 "stack": {
169                     "id": 1234
170                 }
171             }
172             headers = {
173                 'Content-Type': 'application/json',
174                 'X-Auth-Token': 'mock_token'
175             }
176
177             class mock_response(object):
178                 def __init__(self, status_code, _content):
179                     self.status_code = status_code
180                     self._content = _content
181
182             mock_response_obj = mock_response(201, json.dumps(mock_heat_res))
183             mock_post.return_value = mock_response_obj
184             shell.main([self.template_file, self.template_type,
185                         "--deploy"])
186             args, kwargs = mock_post.call_args
187             self.assertEqual(args[0], 'http://abc.com/stacks')
188             self.assertEqual(ast.literal_eval(kwargs['data']), data)
189             self.assertEqual(kwargs['headers'], headers)
190         except Exception:
191             self.fail(self.failure_msg)