blob: 25b8ae554ea3fcf7f66627a94227c88b54732cc4 [file] [log] [blame]
Scott Baker1a2ee302018-08-27 16:16:19 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import json
17import os
18import sys
19import unittest
20from mock import patch, PropertyMock, ANY, MagicMock, Mock
21from unit_test_common import setup_sync_unit_test
22
23class ApiException(Exception):
24 def __init__(self, status, *args, **kwargs):
25 super(ApiException, self).__init__(*args, **kwargs)
26 self.status = status
27
28def fake_init_kubernetes_client(self):
29 self.kubernetes_client = MagicMock()
30 self.v1core = MagicMock()
31 self.ApiException = ApiException
32
33class TestSyncKubernetesResourceInstance(unittest.TestCase):
34
35 def setUp(self):
36 self.unittest_setup = setup_sync_unit_test(os.path.abspath(os.path.dirname(os.path.realpath(__file__))),
37 globals(),
Scott Bakera30fae72019-02-01 16:14:43 -080038 [("kubernetes-service", "kubernetes.xproto")] )
Scott Baker1a2ee302018-08-27 16:16:19 -070039
40 self.MockObjectList = self.unittest_setup["MockObjectList"]
Scott Bakera30fae72019-02-01 16:14:43 -080041 self.model_accessor = self.unittest_setup["model_accessor"]
Scott Baker1a2ee302018-08-27 16:16:19 -070042
43 sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.realpath(__file__))), "../steps"))
44
45 from sync_kubernetesresourceinstance import SyncKubernetesResourceInstance
46 self.step_class = SyncKubernetesResourceInstance
47
48 self.service = KubernetesService()
49
50 def tearDown(self):
51 sys.path = self.unittest_setup["sys_path_save"]
52
53 @patch('subprocess.Popen')
54 def test_run_kubectl(self, mock_popen):
55 proc = Mock()
56 proc.communicate.return_value = ('output', 'error')
57 proc.returncode = 0
58
59 mock_popen.return_value = proc
60
Scott Bakera30fae72019-02-01 16:14:43 -080061 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -070062 step.run_kubectl("create", "foo")
63
64 mock_popen.assert_called()
65
66 @patch('subprocess.Popen')
67 def test_run_kubectl_fail(self, mock_popen):
68 proc = Mock()
69 proc.communicate.return_value = ('output', 'error')
70 proc.returncode = 1
71
72 mock_popen.return_value = proc
73
Scott Bakera30fae72019-02-01 16:14:43 -080074 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -070075 with self.assertRaises(Exception) as e:
76 step.run_kubectl("create", "foo")
77
78 self.assertEqual(e.exception.message, "Process failed with returncode 1")
79
80 def test_sync_record_create(self):
81 with patch.object(self.step_class, "run_kubectl") as run_kubectl:
82 xos_ri = KubernetesResourceInstance(name="test-instance", owner=self.service, resource_definition="foo")
83
84 run_kubectl.return_value = None
85
Scott Bakera30fae72019-02-01 16:14:43 -080086 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -070087 step.sync_record(xos_ri)
88
89 run_kubectl.assert_called_with("apply", "foo")
90
91 self.assertEqual(xos_ri.kubectl_state, "created")
92
93 def test_sync_record_update(self):
94 with patch.object(self.step_class, "run_kubectl") as run_kubectl:
95 xos_ri = KubernetesResourceInstance(name="test-instance", owner=self.service, resource_definition="foo", kubectl_state="created")
96
97 run_kubectl.return_value = None
98
Scott Bakera30fae72019-02-01 16:14:43 -080099 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -0700100 step.sync_record(xos_ri)
101
102 run_kubectl.assert_called_with("apply", "foo")
103
104 self.assertEqual(xos_ri.kubectl_state, "updated")
105
106 def test_sync_record_delete(self):
107 with patch.object(self.step_class, "run_kubectl") as run_kubectl:
108 xos_ri = KubernetesResourceInstance(name="test-instance", owner=self.service, resource_definition="foo", kubectl_state="created")
109
110 run_kubectl.return_value = None
111
Scott Bakera30fae72019-02-01 16:14:43 -0800112 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -0700113 step.delete_record(xos_ri)
114
115 run_kubectl.assert_called_with("delete", "foo")
116
117 self.assertEqual(xos_ri.kubectl_state, "deleted")
118
119 def test_sync_record_delete_never_created(self):
120 """ If the object was never saved, then we shouldn't try to delete it """
121 with patch.object(self.step_class, "run_kubectl") as run_kubectl:
122 xos_ri = KubernetesResourceInstance(name="test-instance", owner=self.service, resource_definition="foo")
123
124 run_kubectl.return_value = None
125
Scott Bakera30fae72019-02-01 16:14:43 -0800126 step = self.step_class(model_accessor = self.model_accessor)
Scott Baker1a2ee302018-08-27 16:16:19 -0700127 step.delete_record(xos_ri)
128
129 run_kubectl.assert_not_called()
130
131
132if __name__ == '__main__':
133 unittest.main()