
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Tests for VEpcServiceInstance model policies

import base64
import json
import os
import sys
import unittest
from mock import patch, PropertyMock, ANY, MagicMock
from unit_test_common import setup_sync_unit_test


class TestVEpcServiceInstancePolicy(unittest.TestCase):

    def setUp(self):
        self.unittest_setup = setup_sync_unit_test(os.path.abspath(os.path.dirname(os.path.realpath(__file__))),
                                                   globals(),
                                                   [("vepcservice", "vepcservice.xproto"),
                                                    ("kubernetes-service", "kubernetes.xproto")] )

        self.MockObjectList = self.unittest_setup["MockObjectList"]

        sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.realpath(__file__))), "../model_policies"))

        from model_policy_vepcserviceinstance import VEpcServiceInstancePolicy
        self.policy_class = VEpcServiceInstancePolicy

        self.service = VEpcService()
        self.k8s_service = KubernetesService(id=1111)
        self.k8s_service.get_service_instance_class=MagicMock(return_value=KubernetesServiceInstance)
        self.trust_domain = TrustDomain(owner=self.k8s_service, name="test-trust")
        self.image = Image(name="test-image", tag="1.2", kind="container")
        self.slice = Slice(trust_domain=self.trust_domain, service=self.service, default_image = self.image)
        self.service.slices = self.MockObjectList([self.slice])

    def tearDown(self):
        sys.path = self.unittest_setup["sys_path_save"]

if __name__ == '__main__':
    unittest.main()
