1*4882a593Smuzhiyun# 2*4882a593Smuzhiyun# BitBake Tests for utils.py 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# Copyright (C) 2012 Richard Purdie 5*4882a593Smuzhiyun# 6*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 7*4882a593Smuzhiyun# 8*4882a593Smuzhiyun 9*4882a593Smuzhiyunimport unittest 10*4882a593Smuzhiyunimport bb 11*4882a593Smuzhiyunimport os 12*4882a593Smuzhiyunimport tempfile 13*4882a593Smuzhiyunimport re 14*4882a593Smuzhiyun 15*4882a593Smuzhiyunclass VerCmpString(unittest.TestCase): 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun def test_vercmpstring(self): 18*4882a593Smuzhiyun result = bb.utils.vercmp_string('1', '2') 19*4882a593Smuzhiyun self.assertTrue(result < 0) 20*4882a593Smuzhiyun result = bb.utils.vercmp_string('2', '1') 21*4882a593Smuzhiyun self.assertTrue(result > 0) 22*4882a593Smuzhiyun result = bb.utils.vercmp_string('1', '1.0') 23*4882a593Smuzhiyun self.assertTrue(result < 0) 24*4882a593Smuzhiyun result = bb.utils.vercmp_string('1', '1.1') 25*4882a593Smuzhiyun self.assertTrue(result < 0) 26*4882a593Smuzhiyun result = bb.utils.vercmp_string('1.1', '1_p2') 27*4882a593Smuzhiyun self.assertTrue(result < 0) 28*4882a593Smuzhiyun result = bb.utils.vercmp_string('1.0', '1.0+1.1-beta1') 29*4882a593Smuzhiyun self.assertTrue(result < 0) 30*4882a593Smuzhiyun result = bb.utils.vercmp_string('1.1', '1.0+1.1-beta1') 31*4882a593Smuzhiyun self.assertTrue(result > 0) 32*4882a593Smuzhiyun result = bb.utils.vercmp_string('1a', '1a1') 33*4882a593Smuzhiyun self.assertTrue(result < 0) 34*4882a593Smuzhiyun result = bb.utils.vercmp_string('1a1', '1a') 35*4882a593Smuzhiyun self.assertTrue(result > 0) 36*4882a593Smuzhiyun result = bb.utils.vercmp_string('1.', '1.1') 37*4882a593Smuzhiyun self.assertTrue(result < 0) 38*4882a593Smuzhiyun result = bb.utils.vercmp_string('1.1', '1.') 39*4882a593Smuzhiyun self.assertTrue(result > 0) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun def test_explode_dep_versions(self): 42*4882a593Smuzhiyun correctresult = {"foo" : ["= 1.10"]} 43*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo (= 1.10)") 44*4882a593Smuzhiyun self.assertEqual(result, correctresult) 45*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo (=1.10)") 46*4882a593Smuzhiyun self.assertEqual(result, correctresult) 47*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo ( = 1.10)") 48*4882a593Smuzhiyun self.assertEqual(result, correctresult) 49*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo ( =1.10)") 50*4882a593Smuzhiyun self.assertEqual(result, correctresult) 51*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo ( = 1.10 )") 52*4882a593Smuzhiyun self.assertEqual(result, correctresult) 53*4882a593Smuzhiyun result = bb.utils.explode_dep_versions2("foo ( =1.10 )") 54*4882a593Smuzhiyun self.assertEqual(result, correctresult) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun def test_vercmp_string_op(self): 57*4882a593Smuzhiyun compareops = [('1', '1', '=', True), 58*4882a593Smuzhiyun ('1', '1', '==', True), 59*4882a593Smuzhiyun ('1', '1', '!=', False), 60*4882a593Smuzhiyun ('1', '1', '>', False), 61*4882a593Smuzhiyun ('1', '1', '<', False), 62*4882a593Smuzhiyun ('1', '1', '>=', True), 63*4882a593Smuzhiyun ('1', '1', '<=', True), 64*4882a593Smuzhiyun ('1', '0', '=', False), 65*4882a593Smuzhiyun ('1', '0', '==', False), 66*4882a593Smuzhiyun ('1', '0', '!=', True), 67*4882a593Smuzhiyun ('1', '0', '>', True), 68*4882a593Smuzhiyun ('1', '0', '<', False), 69*4882a593Smuzhiyun ('1', '0', '>>', True), 70*4882a593Smuzhiyun ('1', '0', '<<', False), 71*4882a593Smuzhiyun ('1', '0', '>=', True), 72*4882a593Smuzhiyun ('1', '0', '<=', False), 73*4882a593Smuzhiyun ('0', '1', '=', False), 74*4882a593Smuzhiyun ('0', '1', '==', False), 75*4882a593Smuzhiyun ('0', '1', '!=', True), 76*4882a593Smuzhiyun ('0', '1', '>', False), 77*4882a593Smuzhiyun ('0', '1', '<', True), 78*4882a593Smuzhiyun ('0', '1', '>>', False), 79*4882a593Smuzhiyun ('0', '1', '<<', True), 80*4882a593Smuzhiyun ('0', '1', '>=', False), 81*4882a593Smuzhiyun ('0', '1', '<=', True)] 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun for arg1, arg2, op, correctresult in compareops: 84*4882a593Smuzhiyun result = bb.utils.vercmp_string_op(arg1, arg2, op) 85*4882a593Smuzhiyun self.assertEqual(result, correctresult, 'vercmp_string_op("%s", "%s", "%s") != %s' % (arg1, arg2, op, correctresult)) 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun # Check that clearly invalid operator raises an exception 88*4882a593Smuzhiyun self.assertRaises(bb.utils.VersionStringException, bb.utils.vercmp_string_op, '0', '0', '$') 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun 91*4882a593Smuzhiyunclass Path(unittest.TestCase): 92*4882a593Smuzhiyun def test_unsafe_delete_path(self): 93*4882a593Smuzhiyun checkitems = [('/', True), 94*4882a593Smuzhiyun ('//', True), 95*4882a593Smuzhiyun ('///', True), 96*4882a593Smuzhiyun (os.getcwd().count(os.sep) * ('..' + os.sep), True), 97*4882a593Smuzhiyun (os.environ.get('HOME', '/home/test'), True), 98*4882a593Smuzhiyun ('/home/someone', True), 99*4882a593Smuzhiyun ('/home/other/', True), 100*4882a593Smuzhiyun ('/home/other/subdir', False), 101*4882a593Smuzhiyun ('', False)] 102*4882a593Smuzhiyun for arg1, correctresult in checkitems: 103*4882a593Smuzhiyun result = bb.utils._check_unsafe_delete_path(arg1) 104*4882a593Smuzhiyun self.assertEqual(result, correctresult, '_check_unsafe_delete_path("%s") != %s' % (arg1, correctresult)) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyunclass Checksum(unittest.TestCase): 107*4882a593Smuzhiyun filler = b"Shiver me timbers square-rigged spike Gold Road galleon bilge water boatswain wherry jack pirate. Mizzenmast rum lad Privateer jack salmagundi hang the jib piracy Pieces of Eight Corsair. Parrel marooned black spot yawl provost quarterdeck cable no prey, no pay spirits lateen sail." 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun def test_md5(self): 110*4882a593Smuzhiyun import hashlib 111*4882a593Smuzhiyun with tempfile.NamedTemporaryFile() as f: 112*4882a593Smuzhiyun f.write(self.filler) 113*4882a593Smuzhiyun f.flush() 114*4882a593Smuzhiyun checksum = bb.utils.md5_file(f.name) 115*4882a593Smuzhiyun self.assertEqual(checksum, "bd572cd5de30a785f4efcb6eaf5089e3") 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun def test_sha1(self): 118*4882a593Smuzhiyun import hashlib 119*4882a593Smuzhiyun with tempfile.NamedTemporaryFile() as f: 120*4882a593Smuzhiyun f.write(self.filler) 121*4882a593Smuzhiyun f.flush() 122*4882a593Smuzhiyun checksum = bb.utils.sha1_file(f.name) 123*4882a593Smuzhiyun self.assertEqual(checksum, "249eb8fd654732ea836d5e702d7aa567898eca71") 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun def test_sha256(self): 126*4882a593Smuzhiyun import hashlib 127*4882a593Smuzhiyun with tempfile.NamedTemporaryFile() as f: 128*4882a593Smuzhiyun f.write(self.filler) 129*4882a593Smuzhiyun f.flush() 130*4882a593Smuzhiyun checksum = bb.utils.sha256_file(f.name) 131*4882a593Smuzhiyun self.assertEqual(checksum, "fcfbae8bf6b721dbb9d2dc6a9334a58f2031a9a9b302999243f99da4d7f12d0f") 132*4882a593Smuzhiyun 133*4882a593Smuzhiyunclass EditMetadataFile(unittest.TestCase): 134*4882a593Smuzhiyun _origfile = """ 135*4882a593Smuzhiyun# A comment 136*4882a593SmuzhiyunHELLO = "oldvalue" 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunTHIS = "that" 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun# Another comment 141*4882a593SmuzhiyunNOCHANGE = "samevalue" 142*4882a593SmuzhiyunOTHER = 'anothervalue' 143*4882a593Smuzhiyun 144*4882a593SmuzhiyunMULTILINE = "a1 \\ 145*4882a593Smuzhiyun a2 \\ 146*4882a593Smuzhiyun a3" 147*4882a593Smuzhiyun 148*4882a593SmuzhiyunMULTILINE2 := " \\ 149*4882a593Smuzhiyun b1 \\ 150*4882a593Smuzhiyun b2 \\ 151*4882a593Smuzhiyun b3 \\ 152*4882a593Smuzhiyun " 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun 155*4882a593SmuzhiyunMULTILINE3 = " \\ 156*4882a593Smuzhiyun c1 \\ 157*4882a593Smuzhiyun c2 \\ 158*4882a593Smuzhiyun c3 \\ 159*4882a593Smuzhiyun" 160*4882a593Smuzhiyun 161*4882a593Smuzhiyundo_functionname() { 162*4882a593Smuzhiyun command1 ${VAL1} ${VAL2} 163*4882a593Smuzhiyun command2 ${VAL3} ${VAL4} 164*4882a593Smuzhiyun} 165*4882a593Smuzhiyun""" 166*4882a593Smuzhiyun def _testeditfile(self, varvalues, compareto, dummyvars=None): 167*4882a593Smuzhiyun if dummyvars is None: 168*4882a593Smuzhiyun dummyvars = [] 169*4882a593Smuzhiyun with tempfile.NamedTemporaryFile('w', delete=False) as tf: 170*4882a593Smuzhiyun tf.write(self._origfile) 171*4882a593Smuzhiyun tf.close() 172*4882a593Smuzhiyun try: 173*4882a593Smuzhiyun varcalls = [] 174*4882a593Smuzhiyun def handle_file(varname, origvalue, op, newlines): 175*4882a593Smuzhiyun self.assertIn(varname, varvalues, 'Callback called for variable %s not in the list!' % varname) 176*4882a593Smuzhiyun self.assertNotIn(varname, dummyvars, 'Callback called for variable %s in dummy list!' % varname) 177*4882a593Smuzhiyun varcalls.append(varname) 178*4882a593Smuzhiyun return varvalues[varname] 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun bb.utils.edit_metadata_file(tf.name, varvalues.keys(), handle_file) 181*4882a593Smuzhiyun with open(tf.name) as f: 182*4882a593Smuzhiyun modfile = f.readlines() 183*4882a593Smuzhiyun # Ensure the output matches the expected output 184*4882a593Smuzhiyun self.assertEqual(compareto.splitlines(True), modfile) 185*4882a593Smuzhiyun # Ensure the callback function was called for every variable we asked for 186*4882a593Smuzhiyun # (plus allow testing behaviour when a requested variable is not present) 187*4882a593Smuzhiyun self.assertEqual(sorted(varvalues.keys()), sorted(varcalls + dummyvars)) 188*4882a593Smuzhiyun finally: 189*4882a593Smuzhiyun os.remove(tf.name) 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun def test_edit_metadata_file_nochange(self): 193*4882a593Smuzhiyun # Test file doesn't get modified with nothing to do 194*4882a593Smuzhiyun self._testeditfile({}, self._origfile) 195*4882a593Smuzhiyun # Test file doesn't get modified with only dummy variables 196*4882a593Smuzhiyun self._testeditfile({'DUMMY1': ('should_not_set', None, 0, True), 197*4882a593Smuzhiyun 'DUMMY2': ('should_not_set_again', None, 0, True)}, self._origfile, dummyvars=['DUMMY1', 'DUMMY2']) 198*4882a593Smuzhiyun # Test file doesn't get modified with some the same values 199*4882a593Smuzhiyun self._testeditfile({'THIS': ('that', None, 0, True), 200*4882a593Smuzhiyun 'OTHER': ('anothervalue', None, 0, True), 201*4882a593Smuzhiyun 'MULTILINE3': (' c1 c2 c3 ', None, 4, False)}, self._origfile) 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun def test_edit_metadata_file_1(self): 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun newfile1 = """ 206*4882a593Smuzhiyun# A comment 207*4882a593SmuzhiyunHELLO = "newvalue" 208*4882a593Smuzhiyun 209*4882a593SmuzhiyunTHIS = "that" 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun# Another comment 212*4882a593SmuzhiyunNOCHANGE = "samevalue" 213*4882a593SmuzhiyunOTHER = 'anothervalue' 214*4882a593Smuzhiyun 215*4882a593SmuzhiyunMULTILINE = "a1 \\ 216*4882a593Smuzhiyun a2 \\ 217*4882a593Smuzhiyun a3" 218*4882a593Smuzhiyun 219*4882a593SmuzhiyunMULTILINE2 := " \\ 220*4882a593Smuzhiyun b1 \\ 221*4882a593Smuzhiyun b2 \\ 222*4882a593Smuzhiyun b3 \\ 223*4882a593Smuzhiyun " 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun 226*4882a593SmuzhiyunMULTILINE3 = " \\ 227*4882a593Smuzhiyun c1 \\ 228*4882a593Smuzhiyun c2 \\ 229*4882a593Smuzhiyun c3 \\ 230*4882a593Smuzhiyun" 231*4882a593Smuzhiyun 232*4882a593Smuzhiyundo_functionname() { 233*4882a593Smuzhiyun command1 ${VAL1} ${VAL2} 234*4882a593Smuzhiyun command2 ${VAL3} ${VAL4} 235*4882a593Smuzhiyun} 236*4882a593Smuzhiyun""" 237*4882a593Smuzhiyun self._testeditfile({'HELLO': ('newvalue', None, 4, True)}, newfile1) 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun def test_edit_metadata_file_2(self): 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun newfile2 = """ 243*4882a593Smuzhiyun# A comment 244*4882a593SmuzhiyunHELLO = "oldvalue" 245*4882a593Smuzhiyun 246*4882a593SmuzhiyunTHIS = "that" 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun# Another comment 249*4882a593SmuzhiyunNOCHANGE = "samevalue" 250*4882a593SmuzhiyunOTHER = 'anothervalue' 251*4882a593Smuzhiyun 252*4882a593SmuzhiyunMULTILINE = " \\ 253*4882a593Smuzhiyun d1 \\ 254*4882a593Smuzhiyun d2 \\ 255*4882a593Smuzhiyun d3 \\ 256*4882a593Smuzhiyun " 257*4882a593Smuzhiyun 258*4882a593SmuzhiyunMULTILINE2 := " \\ 259*4882a593Smuzhiyun b1 \\ 260*4882a593Smuzhiyun b2 \\ 261*4882a593Smuzhiyun b3 \\ 262*4882a593Smuzhiyun " 263*4882a593Smuzhiyun 264*4882a593Smuzhiyun 265*4882a593SmuzhiyunMULTILINE3 = "nowsingle" 266*4882a593Smuzhiyun 267*4882a593Smuzhiyundo_functionname() { 268*4882a593Smuzhiyun command1 ${VAL1} ${VAL2} 269*4882a593Smuzhiyun command2 ${VAL3} ${VAL4} 270*4882a593Smuzhiyun} 271*4882a593Smuzhiyun""" 272*4882a593Smuzhiyun self._testeditfile({'MULTILINE': (['d1','d2','d3'], None, 4, False), 273*4882a593Smuzhiyun 'MULTILINE3': ('nowsingle', None, 4, True), 274*4882a593Smuzhiyun 'NOTPRESENT': (['a', 'b'], None, 4, False)}, newfile2, dummyvars=['NOTPRESENT']) 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun def test_edit_metadata_file_3(self): 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun newfile3 = """ 280*4882a593Smuzhiyun# A comment 281*4882a593SmuzhiyunHELLO = "oldvalue" 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun# Another comment 284*4882a593SmuzhiyunNOCHANGE = "samevalue" 285*4882a593SmuzhiyunOTHER = "yetanothervalue" 286*4882a593Smuzhiyun 287*4882a593SmuzhiyunMULTILINE = "e1 \\ 288*4882a593Smuzhiyun e2 \\ 289*4882a593Smuzhiyun e3 \\ 290*4882a593Smuzhiyun " 291*4882a593Smuzhiyun 292*4882a593SmuzhiyunMULTILINE2 := "f1 \\ 293*4882a593Smuzhiyun\tf2 \\ 294*4882a593Smuzhiyun\t" 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun 297*4882a593SmuzhiyunMULTILINE3 = " \\ 298*4882a593Smuzhiyun c1 \\ 299*4882a593Smuzhiyun c2 \\ 300*4882a593Smuzhiyun c3 \\ 301*4882a593Smuzhiyun" 302*4882a593Smuzhiyun 303*4882a593Smuzhiyundo_functionname() { 304*4882a593Smuzhiyun othercommand_one a b c 305*4882a593Smuzhiyun othercommand_two d e f 306*4882a593Smuzhiyun} 307*4882a593Smuzhiyun""" 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun self._testeditfile({'do_functionname()': (['othercommand_one a b c', 'othercommand_two d e f'], None, 4, False), 310*4882a593Smuzhiyun 'MULTILINE2': (['f1', 'f2'], None, '\t', True), 311*4882a593Smuzhiyun 'MULTILINE': (['e1', 'e2', 'e3'], None, -1, True), 312*4882a593Smuzhiyun 'THIS': (None, None, 0, False), 313*4882a593Smuzhiyun 'OTHER': ('yetanothervalue', None, 0, True)}, newfile3) 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun def test_edit_metadata_file_4(self): 317*4882a593Smuzhiyun 318*4882a593Smuzhiyun newfile4 = """ 319*4882a593Smuzhiyun# A comment 320*4882a593SmuzhiyunHELLO = "oldvalue" 321*4882a593Smuzhiyun 322*4882a593SmuzhiyunTHIS = "that" 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun# Another comment 325*4882a593SmuzhiyunOTHER = 'anothervalue' 326*4882a593Smuzhiyun 327*4882a593SmuzhiyunMULTILINE = "a1 \\ 328*4882a593Smuzhiyun a2 \\ 329*4882a593Smuzhiyun a3" 330*4882a593Smuzhiyun 331*4882a593SmuzhiyunMULTILINE2 := " \\ 332*4882a593Smuzhiyun b1 \\ 333*4882a593Smuzhiyun b2 \\ 334*4882a593Smuzhiyun b3 \\ 335*4882a593Smuzhiyun " 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun 338*4882a593Smuzhiyun""" 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun self._testeditfile({'NOCHANGE': (None, None, 0, False), 341*4882a593Smuzhiyun 'MULTILINE3': (None, None, 0, False), 342*4882a593Smuzhiyun 'THIS': ('that', None, 0, False), 343*4882a593Smuzhiyun 'do_functionname()': (None, None, 0, False)}, newfile4) 344*4882a593Smuzhiyun 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun def test_edit_metadata(self): 347*4882a593Smuzhiyun newfile5 = """ 348*4882a593Smuzhiyun# A comment 349*4882a593SmuzhiyunHELLO = "hithere" 350*4882a593Smuzhiyun 351*4882a593Smuzhiyun# A new comment 352*4882a593SmuzhiyunTHIS += "that" 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun# Another comment 355*4882a593SmuzhiyunNOCHANGE = "samevalue" 356*4882a593SmuzhiyunOTHER = 'anothervalue' 357*4882a593Smuzhiyun 358*4882a593SmuzhiyunMULTILINE = "a1 \\ 359*4882a593Smuzhiyun a2 \\ 360*4882a593Smuzhiyun a3" 361*4882a593Smuzhiyun 362*4882a593SmuzhiyunMULTILINE2 := " \\ 363*4882a593Smuzhiyun b1 \\ 364*4882a593Smuzhiyun b2 \\ 365*4882a593Smuzhiyun b3 \\ 366*4882a593Smuzhiyun " 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun 369*4882a593SmuzhiyunMULTILINE3 = " \\ 370*4882a593Smuzhiyun c1 \\ 371*4882a593Smuzhiyun c2 \\ 372*4882a593Smuzhiyun c3 \\ 373*4882a593Smuzhiyun" 374*4882a593Smuzhiyun 375*4882a593SmuzhiyunNEWVAR = "value" 376*4882a593Smuzhiyun 377*4882a593Smuzhiyundo_functionname() { 378*4882a593Smuzhiyun command1 ${VAL1} ${VAL2} 379*4882a593Smuzhiyun command2 ${VAL3} ${VAL4} 380*4882a593Smuzhiyun} 381*4882a593Smuzhiyun""" 382*4882a593Smuzhiyun 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun def handle_var(varname, origvalue, op, newlines): 385*4882a593Smuzhiyun if varname == 'THIS': 386*4882a593Smuzhiyun newlines.append('# A new comment\n') 387*4882a593Smuzhiyun elif varname == 'do_functionname()': 388*4882a593Smuzhiyun newlines.append('NEWVAR = "value"\n') 389*4882a593Smuzhiyun newlines.append('\n') 390*4882a593Smuzhiyun valueitem = varvalues.get(varname, None) 391*4882a593Smuzhiyun if valueitem: 392*4882a593Smuzhiyun return valueitem 393*4882a593Smuzhiyun else: 394*4882a593Smuzhiyun return (origvalue, op, 0, True) 395*4882a593Smuzhiyun 396*4882a593Smuzhiyun varvalues = {'HELLO': ('hithere', None, 0, True), 'THIS': ('that', '+=', 0, True)} 397*4882a593Smuzhiyun varlist = ['HELLO', 'THIS', 'do_functionname()'] 398*4882a593Smuzhiyun (updated, newlines) = bb.utils.edit_metadata(self._origfile.splitlines(True), varlist, handle_var) 399*4882a593Smuzhiyun self.assertTrue(updated, 'List should be updated but isn\'t') 400*4882a593Smuzhiyun self.assertEqual(newlines, newfile5.splitlines(True)) 401*4882a593Smuzhiyun 402*4882a593Smuzhiyun # Make sure the orig value matches what we expect it to be 403*4882a593Smuzhiyun def test_edit_metadata_origvalue(self): 404*4882a593Smuzhiyun origfile = """ 405*4882a593SmuzhiyunMULTILINE = " stuff \\ 406*4882a593Smuzhiyun morestuff" 407*4882a593Smuzhiyun""" 408*4882a593Smuzhiyun expected_value = "stuff morestuff" 409*4882a593Smuzhiyun global value_in_callback 410*4882a593Smuzhiyun value_in_callback = "" 411*4882a593Smuzhiyun 412*4882a593Smuzhiyun def handle_var(varname, origvalue, op, newlines): 413*4882a593Smuzhiyun global value_in_callback 414*4882a593Smuzhiyun value_in_callback = origvalue 415*4882a593Smuzhiyun return (origvalue, op, -1, False) 416*4882a593Smuzhiyun 417*4882a593Smuzhiyun bb.utils.edit_metadata(origfile.splitlines(True), 418*4882a593Smuzhiyun ['MULTILINE'], 419*4882a593Smuzhiyun handle_var) 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun testvalue = re.sub(r'\s+', ' ', value_in_callback.strip()) 422*4882a593Smuzhiyun self.assertEqual(expected_value, testvalue) 423*4882a593Smuzhiyun 424*4882a593Smuzhiyunclass EditBbLayersConf(unittest.TestCase): 425*4882a593Smuzhiyun 426*4882a593Smuzhiyun def _test_bblayers_edit(self, before, after, add, remove, notadded, notremoved): 427*4882a593Smuzhiyun with tempfile.NamedTemporaryFile('w', delete=False) as tf: 428*4882a593Smuzhiyun tf.write(before) 429*4882a593Smuzhiyun tf.close() 430*4882a593Smuzhiyun try: 431*4882a593Smuzhiyun actual_notadded, actual_notremoved = bb.utils.edit_bblayers_conf(tf.name, add, remove) 432*4882a593Smuzhiyun with open(tf.name) as f: 433*4882a593Smuzhiyun actual_after = f.readlines() 434*4882a593Smuzhiyun self.assertEqual(after.splitlines(True), actual_after) 435*4882a593Smuzhiyun self.assertEqual(notadded, actual_notadded) 436*4882a593Smuzhiyun self.assertEqual(notremoved, actual_notremoved) 437*4882a593Smuzhiyun finally: 438*4882a593Smuzhiyun os.remove(tf.name) 439*4882a593Smuzhiyun 440*4882a593Smuzhiyun 441*4882a593Smuzhiyun def test_bblayers_remove(self): 442*4882a593Smuzhiyun before = r""" 443*4882a593Smuzhiyun# A comment 444*4882a593Smuzhiyun 445*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 446*4882a593SmuzhiyunBBFILES ?= "" 447*4882a593SmuzhiyunBBLAYERS = " \ 448*4882a593Smuzhiyun /home/user/path/layer1 \ 449*4882a593Smuzhiyun /home/user/path/layer2 \ 450*4882a593Smuzhiyun /home/user/path/subpath/layer3 \ 451*4882a593Smuzhiyun /home/user/path/layer4 \ 452*4882a593Smuzhiyun " 453*4882a593Smuzhiyun""" 454*4882a593Smuzhiyun after = r""" 455*4882a593Smuzhiyun# A comment 456*4882a593Smuzhiyun 457*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 458*4882a593SmuzhiyunBBFILES ?= "" 459*4882a593SmuzhiyunBBLAYERS = " \ 460*4882a593Smuzhiyun /home/user/path/layer1 \ 461*4882a593Smuzhiyun /home/user/path/subpath/layer3 \ 462*4882a593Smuzhiyun /home/user/path/layer4 \ 463*4882a593Smuzhiyun " 464*4882a593Smuzhiyun""" 465*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 466*4882a593Smuzhiyun None, 467*4882a593Smuzhiyun '/home/user/path/layer2', 468*4882a593Smuzhiyun [], 469*4882a593Smuzhiyun []) 470*4882a593Smuzhiyun 471*4882a593Smuzhiyun 472*4882a593Smuzhiyun def test_bblayers_add(self): 473*4882a593Smuzhiyun before = r""" 474*4882a593Smuzhiyun# A comment 475*4882a593Smuzhiyun 476*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 477*4882a593SmuzhiyunBBFILES ?= "" 478*4882a593SmuzhiyunBBLAYERS = " \ 479*4882a593Smuzhiyun /home/user/path/layer1 \ 480*4882a593Smuzhiyun /home/user/path/layer2 \ 481*4882a593Smuzhiyun /home/user/path/subpath/layer3 \ 482*4882a593Smuzhiyun /home/user/path/layer4 \ 483*4882a593Smuzhiyun " 484*4882a593Smuzhiyun""" 485*4882a593Smuzhiyun after = r""" 486*4882a593Smuzhiyun# A comment 487*4882a593Smuzhiyun 488*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 489*4882a593SmuzhiyunBBFILES ?= "" 490*4882a593SmuzhiyunBBLAYERS = " \ 491*4882a593Smuzhiyun /home/user/path/layer1 \ 492*4882a593Smuzhiyun /home/user/path/layer2 \ 493*4882a593Smuzhiyun /home/user/path/subpath/layer3 \ 494*4882a593Smuzhiyun /home/user/path/layer4 \ 495*4882a593Smuzhiyun /other/path/to/layer5 \ 496*4882a593Smuzhiyun " 497*4882a593Smuzhiyun""" 498*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 499*4882a593Smuzhiyun '/other/path/to/layer5/', 500*4882a593Smuzhiyun None, 501*4882a593Smuzhiyun [], 502*4882a593Smuzhiyun []) 503*4882a593Smuzhiyun 504*4882a593Smuzhiyun 505*4882a593Smuzhiyun def test_bblayers_add_remove(self): 506*4882a593Smuzhiyun before = r""" 507*4882a593Smuzhiyun# A comment 508*4882a593Smuzhiyun 509*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 510*4882a593SmuzhiyunBBFILES ?= "" 511*4882a593SmuzhiyunBBLAYERS = " \ 512*4882a593Smuzhiyun /home/user/path/layer1 \ 513*4882a593Smuzhiyun /home/user/path/layer2 \ 514*4882a593Smuzhiyun /home/user/path/subpath/layer3 \ 515*4882a593Smuzhiyun /home/user/path/layer4 \ 516*4882a593Smuzhiyun " 517*4882a593Smuzhiyun""" 518*4882a593Smuzhiyun after = r""" 519*4882a593Smuzhiyun# A comment 520*4882a593Smuzhiyun 521*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 522*4882a593SmuzhiyunBBFILES ?= "" 523*4882a593SmuzhiyunBBLAYERS = " \ 524*4882a593Smuzhiyun /home/user/path/layer1 \ 525*4882a593Smuzhiyun /home/user/path/layer2 \ 526*4882a593Smuzhiyun /home/user/path/layer4 \ 527*4882a593Smuzhiyun /other/path/to/layer5 \ 528*4882a593Smuzhiyun " 529*4882a593Smuzhiyun""" 530*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 531*4882a593Smuzhiyun ['/other/path/to/layer5', '/home/user/path/layer2/'], '/home/user/path/subpath/layer3/', 532*4882a593Smuzhiyun ['/home/user/path/layer2'], 533*4882a593Smuzhiyun []) 534*4882a593Smuzhiyun 535*4882a593Smuzhiyun 536*4882a593Smuzhiyun def test_bblayers_add_remove_home(self): 537*4882a593Smuzhiyun before = r""" 538*4882a593Smuzhiyun# A comment 539*4882a593Smuzhiyun 540*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 541*4882a593SmuzhiyunBBFILES ?= "" 542*4882a593SmuzhiyunBBLAYERS = " \ 543*4882a593Smuzhiyun ~/path/layer1 \ 544*4882a593Smuzhiyun ~/path/layer2 \ 545*4882a593Smuzhiyun ~/otherpath/layer3 \ 546*4882a593Smuzhiyun ~/path/layer4 \ 547*4882a593Smuzhiyun " 548*4882a593Smuzhiyun""" 549*4882a593Smuzhiyun after = r""" 550*4882a593Smuzhiyun# A comment 551*4882a593Smuzhiyun 552*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 553*4882a593SmuzhiyunBBFILES ?= "" 554*4882a593SmuzhiyunBBLAYERS = " \ 555*4882a593Smuzhiyun ~/path/layer2 \ 556*4882a593Smuzhiyun ~/path/layer4 \ 557*4882a593Smuzhiyun ~/path2/layer5 \ 558*4882a593Smuzhiyun " 559*4882a593Smuzhiyun""" 560*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 561*4882a593Smuzhiyun [os.environ['HOME'] + '/path/layer4', '~/path2/layer5'], 562*4882a593Smuzhiyun [os.environ['HOME'] + '/otherpath/layer3', '~/path/layer1', '~/path/notinlist'], 563*4882a593Smuzhiyun [os.environ['HOME'] + '/path/layer4'], 564*4882a593Smuzhiyun ['~/path/notinlist']) 565*4882a593Smuzhiyun 566*4882a593Smuzhiyun 567*4882a593Smuzhiyun def test_bblayers_add_remove_plusequals(self): 568*4882a593Smuzhiyun before = r""" 569*4882a593Smuzhiyun# A comment 570*4882a593Smuzhiyun 571*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 572*4882a593SmuzhiyunBBFILES ?= "" 573*4882a593SmuzhiyunBBLAYERS += " \ 574*4882a593Smuzhiyun /home/user/path/layer1 \ 575*4882a593Smuzhiyun /home/user/path/layer2 \ 576*4882a593Smuzhiyun " 577*4882a593Smuzhiyun""" 578*4882a593Smuzhiyun after = r""" 579*4882a593Smuzhiyun# A comment 580*4882a593Smuzhiyun 581*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 582*4882a593SmuzhiyunBBFILES ?= "" 583*4882a593SmuzhiyunBBLAYERS += " \ 584*4882a593Smuzhiyun /home/user/path/layer2 \ 585*4882a593Smuzhiyun /home/user/path/layer3 \ 586*4882a593Smuzhiyun " 587*4882a593Smuzhiyun""" 588*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 589*4882a593Smuzhiyun '/home/user/path/layer3', 590*4882a593Smuzhiyun '/home/user/path/layer1', 591*4882a593Smuzhiyun [], 592*4882a593Smuzhiyun []) 593*4882a593Smuzhiyun 594*4882a593Smuzhiyun 595*4882a593Smuzhiyun def test_bblayers_add_remove_plusequals2(self): 596*4882a593Smuzhiyun before = r""" 597*4882a593Smuzhiyun# A comment 598*4882a593Smuzhiyun 599*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 600*4882a593SmuzhiyunBBFILES ?= "" 601*4882a593SmuzhiyunBBLAYERS += " \ 602*4882a593Smuzhiyun /home/user/path/layer1 \ 603*4882a593Smuzhiyun /home/user/path/layer2 \ 604*4882a593Smuzhiyun /home/user/path/layer3 \ 605*4882a593Smuzhiyun " 606*4882a593SmuzhiyunBBLAYERS += "/home/user/path/layer4" 607*4882a593SmuzhiyunBBLAYERS += "/home/user/path/layer5" 608*4882a593Smuzhiyun""" 609*4882a593Smuzhiyun after = r""" 610*4882a593Smuzhiyun# A comment 611*4882a593Smuzhiyun 612*4882a593SmuzhiyunBBPATH = "${TOPDIR}" 613*4882a593SmuzhiyunBBFILES ?= "" 614*4882a593SmuzhiyunBBLAYERS += " \ 615*4882a593Smuzhiyun /home/user/path/layer2 \ 616*4882a593Smuzhiyun /home/user/path/layer3 \ 617*4882a593Smuzhiyun " 618*4882a593SmuzhiyunBBLAYERS += "/home/user/path/layer5" 619*4882a593SmuzhiyunBBLAYERS += "/home/user/otherpath/layer6" 620*4882a593Smuzhiyun""" 621*4882a593Smuzhiyun self._test_bblayers_edit(before, after, 622*4882a593Smuzhiyun ['/home/user/otherpath/layer6', '/home/user/path/layer3'], ['/home/user/path/layer1', '/home/user/path/layer4', '/home/user/path/layer7'], 623*4882a593Smuzhiyun ['/home/user/path/layer3'], 624*4882a593Smuzhiyun ['/home/user/path/layer7']) 625*4882a593Smuzhiyun 626*4882a593Smuzhiyun 627*4882a593Smuzhiyunclass GetReferencedVars(unittest.TestCase): 628*4882a593Smuzhiyun def setUp(self): 629*4882a593Smuzhiyun self.d = bb.data.init() 630*4882a593Smuzhiyun 631*4882a593Smuzhiyun def check_referenced(self, expression, expected_layers): 632*4882a593Smuzhiyun vars = bb.utils.get_referenced_vars(expression, self.d) 633*4882a593Smuzhiyun 634*4882a593Smuzhiyun # Do the easy check first - is every variable accounted for? 635*4882a593Smuzhiyun expected_vars = set.union(set(), *expected_layers) 636*4882a593Smuzhiyun got_vars = set(vars) 637*4882a593Smuzhiyun self.assertSetEqual(got_vars, expected_vars) 638*4882a593Smuzhiyun 639*4882a593Smuzhiyun # Now test the order of the layers 640*4882a593Smuzhiyun start = 0 641*4882a593Smuzhiyun for i, expected_layer in enumerate(expected_layers): 642*4882a593Smuzhiyun got_layer = set(vars[start:len(expected_layer)+start]) 643*4882a593Smuzhiyun start += len(expected_layer) 644*4882a593Smuzhiyun self.assertSetEqual(got_layer, expected_layer) 645*4882a593Smuzhiyun 646*4882a593Smuzhiyun def test_no_vars(self): 647*4882a593Smuzhiyun self.check_referenced("", []) 648*4882a593Smuzhiyun self.check_referenced(" ", []) 649*4882a593Smuzhiyun self.check_referenced(" no vars here! ", []) 650*4882a593Smuzhiyun 651*4882a593Smuzhiyun def test_single_layer(self): 652*4882a593Smuzhiyun self.check_referenced("${VAR}", [{"VAR"}]) 653*4882a593Smuzhiyun self.check_referenced("${VAR} ${VAR}", [{"VAR"}]) 654*4882a593Smuzhiyun 655*4882a593Smuzhiyun def test_two_layer(self): 656*4882a593Smuzhiyun self.d.setVar("VAR", "${B}") 657*4882a593Smuzhiyun self.check_referenced("${VAR}", [{"VAR"}, {"B"}]) 658*4882a593Smuzhiyun self.check_referenced("${@d.getVar('VAR')}", [{"VAR"}, {"B"}]) 659*4882a593Smuzhiyun 660*4882a593Smuzhiyun def test_more_complicated(self): 661*4882a593Smuzhiyun self.d["SRC_URI"] = "${QT_GIT}/${QT_MODULE}.git;name=${QT_MODULE};${QT_MODULE_BRANCH_PARAM};protocol=${QT_GIT_PROTOCOL}" 662*4882a593Smuzhiyun self.d["QT_GIT"] = "git://code.qt.io/${QT_GIT_PROJECT}" 663*4882a593Smuzhiyun self.d["QT_MODULE_BRANCH_PARAM"] = "branch=${QT_MODULE_BRANCH}" 664*4882a593Smuzhiyun self.d["QT_MODULE"] = "${BPN}" 665*4882a593Smuzhiyun self.d["BPN"] = "something to do with ${PN} and ${SPECIAL_PKGSUFFIX}" 666*4882a593Smuzhiyun 667*4882a593Smuzhiyun layers = [{"SRC_URI"}, {"QT_GIT", "QT_MODULE", "QT_MODULE_BRANCH_PARAM", "QT_GIT_PROTOCOL"}, {"QT_GIT_PROJECT", "QT_MODULE_BRANCH", "BPN"}, {"PN", "SPECIAL_PKGSUFFIX"}] 668*4882a593Smuzhiyun self.check_referenced("${SRC_URI}", layers) 669*4882a593Smuzhiyun 670*4882a593Smuzhiyun 671*4882a593Smuzhiyunclass EnvironmentTests(unittest.TestCase): 672*4882a593Smuzhiyun def test_environment(self): 673*4882a593Smuzhiyun os.environ["A"] = "this is A" 674*4882a593Smuzhiyun self.assertIn("A", os.environ) 675*4882a593Smuzhiyun self.assertEqual(os.environ["A"], "this is A") 676*4882a593Smuzhiyun self.assertNotIn("B", os.environ) 677*4882a593Smuzhiyun 678*4882a593Smuzhiyun with bb.utils.environment(B="this is B"): 679*4882a593Smuzhiyun self.assertIn("A", os.environ) 680*4882a593Smuzhiyun self.assertEqual(os.environ["A"], "this is A") 681*4882a593Smuzhiyun self.assertIn("B", os.environ) 682*4882a593Smuzhiyun self.assertEqual(os.environ["B"], "this is B") 683*4882a593Smuzhiyun 684*4882a593Smuzhiyun self.assertIn("A", os.environ) 685*4882a593Smuzhiyun self.assertEqual(os.environ["A"], "this is A") 686*4882a593Smuzhiyun self.assertNotIn("B", os.environ) 687