1*4882a593Smuzhiyun# 2*4882a593Smuzhiyun# BitBake Test for codeparser.py 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# Copyright (C) 2010 Chris Larson 5*4882a593Smuzhiyun# Copyright (C) 2012 Richard Purdie 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyun 10*4882a593Smuzhiyunimport unittest 11*4882a593Smuzhiyunimport logging 12*4882a593Smuzhiyunimport bb 13*4882a593Smuzhiyun 14*4882a593Smuzhiyunlogger = logging.getLogger('BitBake.TestCodeParser') 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun# bb.data references bb.parse but can't directly import due to circular dependencies. 17*4882a593Smuzhiyun# Hack around it for now :( 18*4882a593Smuzhiyunimport bb.parse 19*4882a593Smuzhiyunimport bb.data 20*4882a593Smuzhiyun 21*4882a593Smuzhiyunclass ReferenceTest(unittest.TestCase): 22*4882a593Smuzhiyun def setUp(self): 23*4882a593Smuzhiyun self.d = bb.data.init() 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun def setEmptyVars(self, varlist): 26*4882a593Smuzhiyun for k in varlist: 27*4882a593Smuzhiyun self.d.setVar(k, "") 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun def setValues(self, values): 30*4882a593Smuzhiyun for k, v in values.items(): 31*4882a593Smuzhiyun self.d.setVar(k, v) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun def assertReferences(self, refs): 34*4882a593Smuzhiyun self.assertEqual(self.references, refs) 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun def assertExecs(self, execs): 37*4882a593Smuzhiyun self.assertEqual(self.execs, execs) 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun def assertContains(self, contains): 40*4882a593Smuzhiyun self.assertEqual(self.contains, contains) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyunclass VariableReferenceTest(ReferenceTest): 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun def parseExpression(self, exp): 45*4882a593Smuzhiyun parsedvar = self.d.expandWithRefs(exp, None) 46*4882a593Smuzhiyun self.references = parsedvar.references 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun def test_simple_reference(self): 49*4882a593Smuzhiyun self.setEmptyVars(["FOO"]) 50*4882a593Smuzhiyun self.parseExpression("${FOO}") 51*4882a593Smuzhiyun self.assertReferences(set(["FOO"])) 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun def test_nested_reference(self): 54*4882a593Smuzhiyun self.setEmptyVars(["BAR"]) 55*4882a593Smuzhiyun self.d.setVar("FOO", "BAR") 56*4882a593Smuzhiyun self.parseExpression("${${FOO}}") 57*4882a593Smuzhiyun self.assertReferences(set(["FOO", "BAR"])) 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun def test_python_reference(self): 60*4882a593Smuzhiyun self.setEmptyVars(["BAR"]) 61*4882a593Smuzhiyun self.parseExpression("${@d.getVar('BAR') + 'foo'}") 62*4882a593Smuzhiyun self.assertReferences(set(["BAR"])) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyunclass ShellReferenceTest(ReferenceTest): 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun def parseExpression(self, exp): 67*4882a593Smuzhiyun parsedvar = self.d.expandWithRefs(exp, None) 68*4882a593Smuzhiyun parser = bb.codeparser.ShellParser("ParserTest", logger) 69*4882a593Smuzhiyun parser.parse_shell(parsedvar.value) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun self.references = parsedvar.references 72*4882a593Smuzhiyun self.execs = parser.execs 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun def test_quotes_inside_assign(self): 75*4882a593Smuzhiyun self.parseExpression('foo=foo"bar"baz') 76*4882a593Smuzhiyun self.assertReferences(set([])) 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun def test_quotes_inside_arg(self): 79*4882a593Smuzhiyun self.parseExpression('sed s#"bar baz"#"alpha beta"#g') 80*4882a593Smuzhiyun self.assertExecs(set(["sed"])) 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun def test_arg_continuation(self): 83*4882a593Smuzhiyun self.parseExpression("sed -i -e s,foo,bar,g \\\n *.pc") 84*4882a593Smuzhiyun self.assertExecs(set(["sed"])) 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun def test_dollar_in_quoted(self): 87*4882a593Smuzhiyun self.parseExpression('sed -i -e "foo$" *.pc') 88*4882a593Smuzhiyun self.assertExecs(set(["sed"])) 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun def test_quotes_inside_arg_continuation(self): 91*4882a593Smuzhiyun self.setEmptyVars(["bindir", "D", "libdir"]) 92*4882a593Smuzhiyun self.parseExpression(""" 93*4882a593Smuzhiyunsed -i -e s#"moc_location=.*$"#"moc_location=${bindir}/moc4"# \\ 94*4882a593Smuzhiyun-e s#"uic_location=.*$"#"uic_location=${bindir}/uic4"# \\ 95*4882a593Smuzhiyun${D}${libdir}/pkgconfig/*.pc 96*4882a593Smuzhiyun""") 97*4882a593Smuzhiyun self.assertReferences(set(["bindir", "D", "libdir"])) 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun def test_assign_subshell_expansion(self): 100*4882a593Smuzhiyun self.parseExpression("foo=$(echo bar)") 101*4882a593Smuzhiyun self.assertExecs(set(["echo"])) 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun def test_shell_unexpanded(self): 104*4882a593Smuzhiyun self.setEmptyVars(["QT_BASE_NAME"]) 105*4882a593Smuzhiyun self.parseExpression('echo "${QT_BASE_NAME}"') 106*4882a593Smuzhiyun self.assertExecs(set(["echo"])) 107*4882a593Smuzhiyun self.assertReferences(set(["QT_BASE_NAME"])) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun def test_incomplete_varexp_single_quotes(self): 110*4882a593Smuzhiyun self.parseExpression("sed -i -e 's:IP{:I${:g' $pc") 111*4882a593Smuzhiyun self.assertExecs(set(["sed"])) 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun def test_parameter_expansion_modifiers(self): 114*4882a593Smuzhiyun # -,+ and : are also valid modifiers for parameter expansion, but are 115*4882a593Smuzhiyun # valid characters in bitbake variable names, so are not included here 116*4882a593Smuzhiyun for i in ('=', '?', '#', '%', '##', '%%'): 117*4882a593Smuzhiyun name = "foo%sbar" % i 118*4882a593Smuzhiyun self.parseExpression("${%s}" % name) 119*4882a593Smuzhiyun self.assertNotIn(name, self.references) 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun def test_until(self): 122*4882a593Smuzhiyun self.parseExpression("until false; do echo true; done") 123*4882a593Smuzhiyun self.assertExecs(set(["false", "echo"])) 124*4882a593Smuzhiyun self.assertReferences(set()) 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun def test_case(self): 127*4882a593Smuzhiyun self.parseExpression(""" 128*4882a593Smuzhiyuncase $foo in 129*4882a593Smuzhiyun*) 130*4882a593Smuzhiyunbar 131*4882a593Smuzhiyun;; 132*4882a593Smuzhiyunesac 133*4882a593Smuzhiyun""") 134*4882a593Smuzhiyun self.assertExecs(set(["bar"])) 135*4882a593Smuzhiyun self.assertReferences(set()) 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun def test_assign_exec(self): 138*4882a593Smuzhiyun self.parseExpression("a=b c='foo bar' alpha 1 2 3") 139*4882a593Smuzhiyun self.assertExecs(set(["alpha"])) 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun def test_redirect_to_file(self): 142*4882a593Smuzhiyun self.setEmptyVars(["foo"]) 143*4882a593Smuzhiyun self.parseExpression("echo foo >${foo}/bar") 144*4882a593Smuzhiyun self.assertExecs(set(["echo"])) 145*4882a593Smuzhiyun self.assertReferences(set(["foo"])) 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun def test_heredoc(self): 148*4882a593Smuzhiyun self.setEmptyVars(["theta"]) 149*4882a593Smuzhiyun self.parseExpression(""" 150*4882a593Smuzhiyuncat <<END 151*4882a593Smuzhiyunalpha 152*4882a593Smuzhiyunbeta 153*4882a593Smuzhiyun${theta} 154*4882a593SmuzhiyunEND 155*4882a593Smuzhiyun""") 156*4882a593Smuzhiyun self.assertReferences(set(["theta"])) 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun def test_redirect_from_heredoc(self): 159*4882a593Smuzhiyun v = ["B", "SHADOW_MAILDIR", "SHADOW_MAILFILE", "SHADOW_UTMPDIR", "SHADOW_LOGDIR", "bindir"] 160*4882a593Smuzhiyun self.setEmptyVars(v) 161*4882a593Smuzhiyun self.parseExpression(""" 162*4882a593Smuzhiyuncat <<END >${B}/cachedpaths 163*4882a593Smuzhiyunshadow_cv_maildir=${SHADOW_MAILDIR} 164*4882a593Smuzhiyunshadow_cv_mailfile=${SHADOW_MAILFILE} 165*4882a593Smuzhiyunshadow_cv_utmpdir=${SHADOW_UTMPDIR} 166*4882a593Smuzhiyunshadow_cv_logdir=${SHADOW_LOGDIR} 167*4882a593Smuzhiyunshadow_cv_passwd_dir=${bindir} 168*4882a593SmuzhiyunEND 169*4882a593Smuzhiyun""") 170*4882a593Smuzhiyun self.assertReferences(set(v)) 171*4882a593Smuzhiyun self.assertExecs(set(["cat"])) 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun# def test_incomplete_command_expansion(self): 174*4882a593Smuzhiyun# self.assertRaises(reftracker.ShellSyntaxError, reftracker.execs, 175*4882a593Smuzhiyun# bbvalue.shparse("cp foo`", self.d), self.d) 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun# def test_rogue_dollarsign(self): 178*4882a593Smuzhiyun# self.setValues({"D" : "/tmp"}) 179*4882a593Smuzhiyun# self.parseExpression("install -d ${D}$") 180*4882a593Smuzhiyun# self.assertReferences(set(["D"])) 181*4882a593Smuzhiyun# self.assertExecs(set(["install"])) 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun 184*4882a593Smuzhiyunclass PythonReferenceTest(ReferenceTest): 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun def setUp(self): 187*4882a593Smuzhiyun self.d = bb.data.init() 188*4882a593Smuzhiyun if hasattr(bb.utils, "_context"): 189*4882a593Smuzhiyun self.context = bb.utils._context 190*4882a593Smuzhiyun else: 191*4882a593Smuzhiyun import builtins 192*4882a593Smuzhiyun self.context = builtins.__dict__ 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun def parseExpression(self, exp): 195*4882a593Smuzhiyun parsedvar = self.d.expandWithRefs(exp, None) 196*4882a593Smuzhiyun parser = bb.codeparser.PythonParser("ParserTest", logger) 197*4882a593Smuzhiyun parser.parse_python(parsedvar.value) 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun self.references = parsedvar.references | parser.references 200*4882a593Smuzhiyun self.execs = parser.execs 201*4882a593Smuzhiyun self.contains = parser.contains 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun @staticmethod 204*4882a593Smuzhiyun def indent(value): 205*4882a593Smuzhiyun """Python Snippets have to be indented, python values don't have to 206*4882a593Smuzhiyunbe. These unit tests are testing snippets.""" 207*4882a593Smuzhiyun return " " + value 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun def test_getvar_reference(self): 210*4882a593Smuzhiyun self.parseExpression("d.getVar('foo')") 211*4882a593Smuzhiyun self.assertReferences(set(["foo"])) 212*4882a593Smuzhiyun self.assertExecs(set()) 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun def test_getvar_computed_reference(self): 215*4882a593Smuzhiyun self.parseExpression("d.getVar('f' + 'o' + 'o')") 216*4882a593Smuzhiyun self.assertReferences(set()) 217*4882a593Smuzhiyun self.assertExecs(set()) 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun def test_getvar_exec_reference(self): 220*4882a593Smuzhiyun self.parseExpression("eval('d.getVar(\"foo\")')") 221*4882a593Smuzhiyun self.assertReferences(set()) 222*4882a593Smuzhiyun self.assertExecs(set(["eval"])) 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun def test_var_reference(self): 225*4882a593Smuzhiyun self.context["foo"] = lambda x: x 226*4882a593Smuzhiyun self.setEmptyVars(["FOO"]) 227*4882a593Smuzhiyun self.parseExpression("foo('${FOO}')") 228*4882a593Smuzhiyun self.assertReferences(set(["FOO"])) 229*4882a593Smuzhiyun self.assertExecs(set(["foo"])) 230*4882a593Smuzhiyun del self.context["foo"] 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun def test_var_exec(self): 233*4882a593Smuzhiyun for etype in ("func", "task"): 234*4882a593Smuzhiyun self.d.setVar("do_something", "echo 'hi mom! ${FOO}'") 235*4882a593Smuzhiyun self.d.setVarFlag("do_something", etype, True) 236*4882a593Smuzhiyun self.parseExpression("bb.build.exec_func('do_something', d)") 237*4882a593Smuzhiyun self.assertReferences(set([])) 238*4882a593Smuzhiyun self.assertExecs(set(["do_something"])) 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun def test_function_reference(self): 241*4882a593Smuzhiyun self.context["testfunc"] = lambda msg: bb.msg.note(1, None, msg) 242*4882a593Smuzhiyun self.d.setVar("FOO", "Hello, World!") 243*4882a593Smuzhiyun self.parseExpression("testfunc('${FOO}')") 244*4882a593Smuzhiyun self.assertReferences(set(["FOO"])) 245*4882a593Smuzhiyun self.assertExecs(set(["testfunc"])) 246*4882a593Smuzhiyun del self.context["testfunc"] 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun def test_qualified_function_reference(self): 249*4882a593Smuzhiyun self.parseExpression("time.time()") 250*4882a593Smuzhiyun self.assertExecs(set(["time.time"])) 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun def test_qualified_function_reference_2(self): 253*4882a593Smuzhiyun self.parseExpression("os.path.dirname('/foo/bar')") 254*4882a593Smuzhiyun self.assertExecs(set(["os.path.dirname"])) 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun def test_qualified_function_reference_nested(self): 257*4882a593Smuzhiyun self.parseExpression("time.strftime('%Y%m%d',time.gmtime())") 258*4882a593Smuzhiyun self.assertExecs(set(["time.strftime", "time.gmtime"])) 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun def test_function_reference_chained(self): 261*4882a593Smuzhiyun self.context["testget"] = lambda: "\tstrip me " 262*4882a593Smuzhiyun self.parseExpression("testget().strip()") 263*4882a593Smuzhiyun self.assertExecs(set(["testget"])) 264*4882a593Smuzhiyun del self.context["testget"] 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun def test_contains(self): 267*4882a593Smuzhiyun self.parseExpression('bb.utils.contains("TESTVAR", "one", "true", "false", d)') 268*4882a593Smuzhiyun self.assertContains({'TESTVAR': {'one'}}) 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun def test_contains_multi(self): 271*4882a593Smuzhiyun self.parseExpression('bb.utils.contains("TESTVAR", "one two", "true", "false", d)') 272*4882a593Smuzhiyun self.assertContains({'TESTVAR': {'one two'}}) 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun def test_contains_any(self): 275*4882a593Smuzhiyun self.parseExpression('bb.utils.contains_any("TESTVAR", "hello", "true", "false", d)') 276*4882a593Smuzhiyun self.assertContains({'TESTVAR': {'hello'}}) 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun def test_contains_any_multi(self): 279*4882a593Smuzhiyun self.parseExpression('bb.utils.contains_any("TESTVAR", "one two three", "true", "false", d)') 280*4882a593Smuzhiyun self.assertContains({'TESTVAR': {'one', 'two', 'three'}}) 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun def test_contains_filter(self): 283*4882a593Smuzhiyun self.parseExpression('bb.utils.filter("TESTVAR", "hello there world", d)') 284*4882a593Smuzhiyun self.assertContains({'TESTVAR': {'hello', 'there', 'world'}}) 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun 287*4882a593Smuzhiyunclass DependencyReferenceTest(ReferenceTest): 288*4882a593Smuzhiyun 289*4882a593Smuzhiyun pydata = """ 290*4882a593Smuzhiyund.getVar('somevar') 291*4882a593Smuzhiyundef test(d): 292*4882a593Smuzhiyun foo = 'bar %s' % 'foo' 293*4882a593Smuzhiyundef test2(d): 294*4882a593Smuzhiyun d.getVar(foo) 295*4882a593Smuzhiyun d.getVar('bar', False) 296*4882a593Smuzhiyun test2(d) 297*4882a593Smuzhiyun 298*4882a593Smuzhiyundef a(): 299*4882a593Smuzhiyun \"\"\"some 300*4882a593Smuzhiyun stuff 301*4882a593Smuzhiyun \"\"\" 302*4882a593Smuzhiyun return "heh" 303*4882a593Smuzhiyun 304*4882a593Smuzhiyuntest(d) 305*4882a593Smuzhiyun 306*4882a593Smuzhiyund.expand(d.getVar("something", False)) 307*4882a593Smuzhiyund.expand("${inexpand} somethingelse") 308*4882a593Smuzhiyund.getVar(a(), False) 309*4882a593Smuzhiyun""" 310*4882a593Smuzhiyun 311*4882a593Smuzhiyun def test_python(self): 312*4882a593Smuzhiyun self.d.setVar("FOO", self.pydata) 313*4882a593Smuzhiyun self.setEmptyVars(["inexpand", "a", "test2", "test"]) 314*4882a593Smuzhiyun self.d.setVarFlags("FOO", { 315*4882a593Smuzhiyun "func": True, 316*4882a593Smuzhiyun "python": True, 317*4882a593Smuzhiyun "lineno": 1, 318*4882a593Smuzhiyun "filename": "example.bb", 319*4882a593Smuzhiyun }) 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), self.d) 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun self.assertEqual(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"])) 324*4882a593Smuzhiyun 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun shelldata = """ 327*4882a593Smuzhiyunfoo () { 328*4882a593Smuzhiyunbar 329*4882a593Smuzhiyun} 330*4882a593Smuzhiyun{ 331*4882a593Smuzhiyunecho baz 332*4882a593Smuzhiyun$(heh) 333*4882a593Smuzhiyuneval `moo` 334*4882a593Smuzhiyun} 335*4882a593Smuzhiyuna=b 336*4882a593Smuzhiyunc=d 337*4882a593Smuzhiyun( 338*4882a593Smuzhiyuntrue && false 339*4882a593Smuzhiyuntest -f foo 340*4882a593Smuzhiyuntestval=something 341*4882a593Smuzhiyun$testval 342*4882a593Smuzhiyun) || aiee 343*4882a593Smuzhiyun! inverted 344*4882a593Smuzhiyunecho ${somevar} 345*4882a593Smuzhiyun 346*4882a593Smuzhiyuncase foo in 347*4882a593Smuzhiyunbar) 348*4882a593Smuzhiyunecho bar 349*4882a593Smuzhiyun;; 350*4882a593Smuzhiyunbaz) 351*4882a593Smuzhiyunecho baz 352*4882a593Smuzhiyun;; 353*4882a593Smuzhiyunfoo*) 354*4882a593Smuzhiyunecho foo 355*4882a593Smuzhiyun;; 356*4882a593Smuzhiyunesac 357*4882a593Smuzhiyun""" 358*4882a593Smuzhiyun 359*4882a593Smuzhiyun def test_shell(self): 360*4882a593Smuzhiyun execs = ["bar", "echo", "heh", "moo", "true", "aiee"] 361*4882a593Smuzhiyun self.d.setVar("somevar", "heh") 362*4882a593Smuzhiyun self.d.setVar("inverted", "echo inverted...") 363*4882a593Smuzhiyun self.d.setVarFlag("inverted", "func", True) 364*4882a593Smuzhiyun self.d.setVar("FOO", self.shelldata) 365*4882a593Smuzhiyun self.d.setVarFlags("FOO", {"func": True}) 366*4882a593Smuzhiyun self.setEmptyVars(execs) 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), self.d) 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun self.assertEqual(deps, set(["somevar", "inverted"] + execs)) 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun 373*4882a593Smuzhiyun def test_vardeps(self): 374*4882a593Smuzhiyun self.d.setVar("oe_libinstall", "echo test") 375*4882a593Smuzhiyun self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") 376*4882a593Smuzhiyun self.d.setVarFlag("FOO", "vardeps", "oe_libinstall") 377*4882a593Smuzhiyun 378*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), self.d) 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun self.assertEqual(deps, set(["oe_libinstall"])) 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun def test_vardeps_expand(self): 383*4882a593Smuzhiyun self.d.setVar("oe_libinstall", "echo test") 384*4882a593Smuzhiyun self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") 385*4882a593Smuzhiyun self.d.setVarFlag("FOO", "vardeps", "${@'oe_libinstall'}") 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), self.d) 388*4882a593Smuzhiyun 389*4882a593Smuzhiyun self.assertEqual(deps, set(["oe_libinstall"])) 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun def test_contains_vardeps(self): 392*4882a593Smuzhiyun expr = '${@bb.utils.filter("TESTVAR", "somevalue anothervalue", d)} \ 393*4882a593Smuzhiyun ${@bb.utils.contains("TESTVAR", "testval testval2", "yetanothervalue", "", d)} \ 394*4882a593Smuzhiyun ${@bb.utils.contains("TESTVAR", "testval2 testval3", "blah", "", d)} \ 395*4882a593Smuzhiyun ${@bb.utils.contains_any("TESTVAR", "testval2 testval3", "lastone", "", d)}' 396*4882a593Smuzhiyun parsedvar = self.d.expandWithRefs(expr, None) 397*4882a593Smuzhiyun # Check contains 398*4882a593Smuzhiyun self.assertEqual(parsedvar.contains, {'TESTVAR': {'testval2 testval3', 'anothervalue', 'somevalue', 'testval testval2', 'testval2', 'testval3'}}) 399*4882a593Smuzhiyun # Check dependencies 400*4882a593Smuzhiyun self.d.setVar('ANOTHERVAR', expr) 401*4882a593Smuzhiyun self.d.setVar('TESTVAR', 'anothervalue testval testval2') 402*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), self.d) 403*4882a593Smuzhiyun self.assertEqual(sorted(values.splitlines()), 404*4882a593Smuzhiyun sorted([expr, 405*4882a593Smuzhiyun 'TESTVAR{anothervalue} = Set', 406*4882a593Smuzhiyun 'TESTVAR{somevalue} = Unset', 407*4882a593Smuzhiyun 'TESTVAR{testval testval2} = Set', 408*4882a593Smuzhiyun 'TESTVAR{testval2 testval3} = Unset', 409*4882a593Smuzhiyun 'TESTVAR{testval2} = Set', 410*4882a593Smuzhiyun 'TESTVAR{testval3} = Unset' 411*4882a593Smuzhiyun ])) 412*4882a593Smuzhiyun # Check final value 413*4882a593Smuzhiyun self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['anothervalue', 'yetanothervalue', 'lastone']) 414*4882a593Smuzhiyun 415*4882a593Smuzhiyun def test_contains_vardeps_excluded(self): 416*4882a593Smuzhiyun # Check the ignored_vars option to build_dependencies is handled by contains functionality 417*4882a593Smuzhiyun varval = '${TESTVAR2} ${@bb.utils.filter("TESTVAR", "somevalue anothervalue", d)}' 418*4882a593Smuzhiyun self.d.setVar('ANOTHERVAR', varval) 419*4882a593Smuzhiyun self.d.setVar('TESTVAR', 'anothervalue testval testval2') 420*4882a593Smuzhiyun self.d.setVar('TESTVAR2', 'testval3') 421*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(["TESTVAR"]), self.d) 422*4882a593Smuzhiyun self.assertEqual(sorted(values.splitlines()), sorted([varval])) 423*4882a593Smuzhiyun self.assertEqual(deps, set(["TESTVAR2"])) 424*4882a593Smuzhiyun self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval3', 'anothervalue']) 425*4882a593Smuzhiyun 426*4882a593Smuzhiyun # Check the vardepsexclude flag is handled by contains functionality 427*4882a593Smuzhiyun self.d.setVarFlag('ANOTHERVAR', 'vardepsexclude', 'TESTVAR') 428*4882a593Smuzhiyun deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), self.d) 429*4882a593Smuzhiyun self.assertEqual(sorted(values.splitlines()), sorted([varval])) 430*4882a593Smuzhiyun self.assertEqual(deps, set(["TESTVAR2"])) 431*4882a593Smuzhiyun self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval3', 'anothervalue']) 432*4882a593Smuzhiyun 433*4882a593Smuzhiyun #Currently no wildcard support 434*4882a593Smuzhiyun #def test_vardeps_wildcards(self): 435*4882a593Smuzhiyun # self.d.setVar("oe_libinstall", "echo test") 436*4882a593Smuzhiyun # self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") 437*4882a593Smuzhiyun # self.d.setVarFlag("FOO", "vardeps", "oe_*") 438*4882a593Smuzhiyun # self.assertEquals(deps, set(["oe_libinstall"])) 439*4882a593Smuzhiyun 440*4882a593Smuzhiyun 441