# Copyright 2022 The Kubeflow Authors # # 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. """Contains tests for kfp.components.placeholders.""" from typing import List import unittest from absl.testing import parameterized from kfp.components import placeholders from kfp.components import structures class TestExecutorInputPlaceholder(parameterized.TestCase): @parameterized.parameters([ ('{{$}}', placeholders.ExecutorInputPlaceholder()), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.ExecutorInputPlaceholder): self.assertEqual( placeholders.ExecutorInputPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestInputValuePlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.inputs.parameters['input1']}}", placeholders.InputValuePlaceholder('input1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.InputValuePlaceholder): self.assertEqual( placeholders.InputValuePlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) @parameterized.parameters([ ("{{$.inputs.parameters[''input1'']}}", placeholders.InputValuePlaceholder('input1')), ('{{$.inputs.parameters["input1"]}}', placeholders.InputValuePlaceholder('input1')), ]) def test_from_placeholder_special_quote_case( self, placeholder_string: str, placeholder_obj: placeholders.InputValuePlaceholder): self.assertEqual( placeholders.InputValuePlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) class TestInputPathPlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.inputs.artifacts['input1'].path}}", placeholders.InputPathPlaceholder('input1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.InputPathPlaceholder): self.assertEqual( placeholders.InputPathPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestInputUriPlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.inputs.artifacts['input1'].uri}}", placeholders.InputUriPlaceholder('input1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.InputUriPlaceholder): self.assertEqual( placeholders.InputUriPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestOutputPathPlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.outputs.artifacts['output1'].path}}", placeholders.OutputPathPlaceholder('output1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.OutputPathPlaceholder): self.assertEqual( placeholders.OutputPathPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestOutputParameterPlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.outputs.parameters['output1'].output_file}}", placeholders.OutputParameterPlaceholder('output1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.OutputParameterPlaceholder): self.assertEqual( placeholders.OutputParameterPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestOutputUriPlaceholder(parameterized.TestCase): @parameterized.parameters([ ("{{$.outputs.artifacts['output1'].uri}}", placeholders.OutputUriPlaceholder('output1')), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.OutputUriPlaceholder): self.assertEqual( placeholders.OutputUriPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestIfPresentPlaceholderStructure(parameterized.TestCase): def test_else_transform(self): obj = placeholders.IfPresentPlaceholder( then='then', input_name='input_name', else_=['something']) self.assertEqual(obj.else_, ['something']) obj = placeholders.IfPresentPlaceholder( then='then', input_name='input_name', else_=[]) self.assertEqual(obj.else_, None) @parameterized.parameters([ ('{"IfPresent": {"InputName": "output1", "Then": "then", "Else": "something"}}', placeholders.IfPresentPlaceholder( input_name='output1', then='then', else_='something')), ('{"IfPresent": {"InputName": "output1", "Then": "then"}}', placeholders.IfPresentPlaceholder(input_name='output1', then='then')), ('{"IfPresent": {"InputName": "output1", "Then": "then"}}', placeholders.IfPresentPlaceholder('output1', 'then')), ('{"IfPresent": {"InputName": "output1", "Then": ["then"], "Else": ["something"]}}', placeholders.IfPresentPlaceholder( input_name='output1', then=['then'], else_=['something'])), ('{"IfPresent": {"InputName": "output1", "Then": ["then", {"IfPresent": {"InputName": "output1", "Then": ["then"], "Else": ["something"]}}], "Else": ["something"]}}', placeholders.IfPresentPlaceholder( input_name='output1', then=[ 'then', placeholders.IfPresentPlaceholder( input_name='output1', then=['then'], else_=['something']) ], else_=['something'])), ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.ConcatPlaceholder): self.assertEqual( placeholders.IfPresentPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) class TestConcatPlaceholder(parameterized.TestCase): @parameterized.parameters([ ('{"Concat": ["a", "b"]}', placeholders.ConcatPlaceholder(['a', 'b'])), ('{"Concat": ["a", {"Concat": ["b", "c"]}]}', placeholders.ConcatPlaceholder( ['a', placeholders.ConcatPlaceholder(['b', 'c'])])), ('{"Concat": ["a", {"Concat": ["b", {"IfPresent": {"InputName": "output1", "Then": ["then"], "Else": ["something"]}}]}]}', placeholders.ConcatPlaceholder([ 'a', placeholders.ConcatPlaceholder([ 'b', placeholders.IfPresentPlaceholder( input_name='output1', then=['then'], else_=['something']) ]) ])) ]) def test_to_from_placeholder( self, placeholder_string: str, placeholder_obj: placeholders.ConcatPlaceholder): self.assertEqual( placeholders.ConcatPlaceholder.from_placeholder_string( placeholder_string), placeholder_obj) self.assertEqual(placeholder_obj.to_placeholder_string(), placeholder_string) @parameterized.parameters([ "{{$.inputs.parameters[''input1'']}}+{{$.inputs.parameters[''input2'']}}", '{"Concat": ["a", "b"]}', '{"Concat": ["a", {"Concat": ["b", "c"]}]}', "{{$.inputs.parameters[''input1'']}}something{{$.inputs.parameters[''input2'']}}", "{{$.inputs.parameters[''input_prefix'']}}some value", "some value{{$.inputs.parameters[''input_suffix'']}}", "some value{{$.inputs.parameters[''input_infix'']}}some value" ]) def test_is_match(self, placeholder: str): self.assertTrue(placeholders.ConcatPlaceholder.is_match(placeholder)) @parameterized.parameters([ ("{{$.inputs.parameters[''input1'']}}something{{$.inputs.parameters[''input2'']}}", [ "{{$.inputs.parameters[''input1'']}}", 'something', "{{$.inputs.parameters[''input2'']}}" ]), ("{{$.inputs.parameters[''input_prefix'']}}some value", ["{{$.inputs.parameters[''input_prefix'']}}", 'some value']), ("some value{{$.inputs.parameters[''input_suffix'']}}", ['some value', "{{$.inputs.parameters[''input_suffix'']}}"]), ("some value{{$.inputs.parameters[''input_infix'']}}some value", [ 'some value', "{{$.inputs.parameters[''input_infix'']}}", 'some value' ]), ("{{$.inputs.parameters[''input1'']}}+{{$.inputs.parameters[''input2'']}}", [ "{{$.inputs.parameters[''input1'']}}", "{{$.inputs.parameters[''input2'']}}" ]) ]) def test_split_cel_concat_string(self, placeholder: str, expected: List[str]): self.assertEqual( placeholders.ConcatPlaceholder.split_cel_concat_string(placeholder), expected) class TestProcessCommandArg(unittest.TestCase): def test_string(self): arg = 'test' struct = placeholders.maybe_convert_placeholder_string_to_placeholder( arg) self.assertEqual(struct, arg) def test_input_value_placeholder(self): arg = "{{$.inputs.parameters['input1']}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( arg) expected = placeholders.InputValuePlaceholder(input_name='input1') self.assertEqual(actual, expected) def test_input_path_placeholder(self): arg = "{{$.inputs.artifacts['input1'].path}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( arg) expected = placeholders.InputPathPlaceholder('input1') self.assertEqual(actual, expected) def test_input_uri_placeholder(self): arg = "{{$.inputs.artifacts['input1'].uri}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( arg) expected = placeholders.InputUriPlaceholder('input1') self.assertEqual(actual, expected) def test_output_path_placeholder(self): arg = "{{$.outputs.artifacts['output1'].path}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( arg) expected = placeholders.OutputPathPlaceholder('output1') self.assertEqual(actual, expected) def test_output_uri_placeholder(self): placeholder = "{{$.outputs.artifacts['output1'].uri}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( placeholder) expected = placeholders.OutputUriPlaceholder('output1') self.assertEqual(actual, expected) def test_output_parameter_placeholder(self): placeholder = "{{$.outputs.parameters['output1'].output_file}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( placeholder) expected = placeholders.OutputParameterPlaceholder('output1') self.assertEqual(actual, expected) def test_concat_placeholder(self): placeholder = "{{$.inputs.parameters[''input1'']}}+{{$.inputs.parameters[''input2'']}}" actual = placeholders.maybe_convert_placeholder_string_to_placeholder( placeholder) expected = placeholders.ConcatPlaceholder(items=[ placeholders.InputValuePlaceholder(input_name='input1'), placeholders.InputValuePlaceholder(input_name='input2') ]) self.assertEqual(actual, expected)