1# Microsoft Azure Linux Agent
2#
3# Copyright 2018 Microsoft Corporation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# Requires Python 2.6+ and Openssl 1.0+
18
19import unittest
20
21from azurelinuxagent.common.protocol.imds import ImageInfoMatcher
22
23
24class TestImageInfoMatcher(unittest.TestCase):
25    def test_image_does_not_exist(self):
26        doc = '{}'
27
28        test_subject = ImageInfoMatcher(doc)
29        self.assertFalse(test_subject.is_match("Red Hat", "RHEL", "6.3", ""))
30
31    def test_image_exists_by_sku(self):
32        doc = '''{
33            "CANONICAL": {
34                "UBUNTUSERVER": {
35                    "16.04-LTS": { "Match": ".*" }
36                }
37            }
38        }'''
39
40        test_subject = ImageInfoMatcher(doc)
41        self.assertTrue(test_subject.is_match("Canonical", "UbuntuServer", "16.04-LTS", ""))
42        self.assertTrue(test_subject.is_match("Canonical", "UbuntuServer", "16.04-LTS", "16.04.201805090"))
43
44        self.assertFalse(test_subject.is_match("Canonical", "UbuntuServer", "14.04.0-LTS", "16.04.201805090"))
45
46    def test_image_exists_by_version(self):
47        doc = '''{
48            "REDHAT": {
49                "RHEL": {
50                    "Minimum": "6.3"
51                }
52            }
53        }'''
54
55        test_subject = ImageInfoMatcher(doc)
56        self.assertFalse(test_subject.is_match("RedHat", "RHEL", "6.1", ""))
57        self.assertFalse(test_subject.is_match("RedHat", "RHEL", "6.2", ""))
58
59        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "6.3", ""))
60        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "6.4", ""))
61        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "6.5", ""))
62        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "7.0", ""))
63        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "7.1", ""))
64
65    def test_image_exists_by_version01(self):
66        """
67        Test case to ensure the matcher exhaustively searches all cases.
68
69        REDHAT/RHEL have a SKU >= 6.3 is less precise than
70        REDHAT/RHEL/7-LVM have a any version.
71
72        Both should return a successful match.
73        """
74        doc = '''{
75            "REDHAT": {
76                "RHEL": {
77                    "Minimum": "6.3",
78                    "7-LVM": { "Match": ".*" }
79                }
80            }
81        }'''
82
83        test_subject = ImageInfoMatcher(doc)
84
85        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "6.3", ""))
86        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "7-LVM", ""))
87
88    def test_ignores_case(self):
89        doc = '''{
90            "CANONICAL": {
91                "UBUNTUSERVER": {
92                    "16.04-LTS": { "Match": ".*" }
93                }
94            }
95        }'''
96
97        test_subject = ImageInfoMatcher(doc)
98        self.assertTrue(test_subject.is_match("canonical", "ubuntuserver", "16.04-lts", ""))
99        self.assertFalse(test_subject.is_match("canonical", "ubuntuserver", "14.04.0-lts", "16.04.201805090"))
100
101    def test_list_operator(self):
102        doc = '''{
103            "CANONICAL": {
104                "UBUNTUSERVER": {
105                    "List": [ "14.04.0-LTS", "14.04.1-LTS" ]
106                }
107            }
108        }'''
109
110        test_subject = ImageInfoMatcher(doc)
111        self.assertTrue(test_subject.is_match("Canonical", "UbuntuServer", "14.04.0-LTS", ""))
112        self.assertTrue(test_subject.is_match("Canonical", "UbuntuServer", "14.04.1-LTS", ""))
113
114        self.assertFalse(test_subject.is_match("Canonical", "UbuntuServer", "22.04-LTS", ""))
115
116    def test_invalid_version(self):
117        doc = '''{
118            "REDHAT": {
119                "RHEL": {
120                    "Minimum": "6.3"
121                }
122            }
123        }'''
124
125        test_subject = ImageInfoMatcher(doc)
126        self.assertFalse(test_subject.is_match("RedHat", "RHEL", "16.04-LTS", ""))
127
128        # This is *expected* behavior as opposed to desirable.  The specification is
129        # controlled by the agent, so there is no reason to use these values, but if
130        # one does this is expected behavior.
131        #
132        # FlexibleVersion chops off all leading zeros.
133        self.assertTrue(test_subject.is_match("RedHat", "RHEL", "6.04", ""))
134        # FlexibleVersion coerces everything to a string
135        self.assertTrue(test_subject.is_match("RedHat", "RHEL", 6.04, ""))
136
137
138if __name__ == '__main__':
139    unittest.main()
140