aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/bb/command.py25
-rw-r--r--lib/bb/data_smart.py29
-rw-r--r--lib/bb/tests/data.py128
-rw-r--r--lib/bb/tinfoil.py30
4 files changed, 192 insertions, 20 deletions
diff --git a/lib/bb/command.py b/lib/bb/command.py
index 222a76e58..78a86ac4d 100644
--- a/lib/bb/command.py
+++ b/lib/bb/command.py
@@ -505,6 +505,31 @@ class CommandsSync:
raise CommandError('dataStoreConnectorRelease: invalid index %d' % dsindex)
command.remotedatastores.release(dsindex)
+ def dataStoreConnectorSetVarFlag(self, command, params):
+ dsindex = params[0]
+ name = params[1]
+ flag = params[2]
+ value = params[3]
+ datastore = command.remotedatastores[dsindex]
+ datastore.setVarFlag(name, flag, value)
+
+ def dataStoreConnectorDelVar(self, command, params):
+ dsindex = params[0]
+ name = params[1]
+ datastore = command.remotedatastores[dsindex]
+ if len(params) > 2:
+ flag = params[2]
+ datastore.delVarFlag(name, flag)
+ else:
+ datastore.delVar(name)
+
+ def dataStoreConnectorRenameVar(self, command, params):
+ dsindex = params[0]
+ name = params[1]
+ newname = params[2]
+ datastore = command.remotedatastores[dsindex]
+ datastore.renameVar(name, newname)
+
def parseRecipeFile(self, command, params):
"""
Parse the specified recipe file (with or without bbappends)
diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
index 5777d545a..d6dd698ef 100644
--- a/lib/bb/data_smart.py
+++ b/lib/bb/data_smart.py
@@ -609,6 +609,12 @@ class DataSmart(MutableMapping):
"""
Rename the variable key to newkey
"""
+ if '_remote_data' in self.dict:
+ connector = self.dict["_remote_data"]["_content"]
+ res = connector.renameVar(key, newkey)
+ if not res:
+ return
+
val = self.getVar(key, 0, parsing=True)
if val is not None:
loginfo['variable'] = newkey
@@ -652,6 +658,12 @@ class DataSmart(MutableMapping):
self.setVar(var + "_prepend", value, ignore=True, parsing=True)
def delVar(self, var, **loginfo):
+ if '_remote_data' in self.dict:
+ connector = self.dict["_remote_data"]["_content"]
+ res = connector.delVar(var)
+ if not res:
+ return
+
loginfo['detail'] = ""
loginfo['op'] = 'del'
self.varhistory.record(**loginfo)
@@ -678,6 +690,12 @@ class DataSmart(MutableMapping):
override = None
def setVarFlag(self, var, flag, value, **loginfo):
+ if '_remote_data' in self.dict:
+ connector = self.dict["_remote_data"]["_content"]
+ res = connector.setVarFlag(var, flag, value)
+ if not res:
+ return
+
self.expand_cache = {}
if 'op' not in loginfo:
loginfo['op'] = "set"
@@ -796,6 +814,12 @@ class DataSmart(MutableMapping):
return value
def delVarFlag(self, var, flag, **loginfo):
+ if '_remote_data' in self.dict:
+ connector = self.dict["_remote_data"]["_content"]
+ res = connector.delVarFlag(var, flag)
+ if not res:
+ return
+
self.expand_cache = {}
local_var, _ = self._findVar(var)
if not local_var:
@@ -938,7 +962,10 @@ class DataSmart(MutableMapping):
if "_remote_data" in d:
connector = d["_remote_data"]["_content"]
- klist |= connector.getKeys()
+ for key in connector.getKeys():
+ if key in deleted:
+ continue
+ klist.add(key)
return klist
diff --git a/lib/bb/tests/data.py b/lib/bb/tests/data.py
index da3f4e66f..fe947f5ba 100644
--- a/lib/bb/tests/data.py
+++ b/lib/bb/tests/data.py
@@ -460,26 +460,43 @@ class Serialize(unittest.TestCase):
self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
+# Remote datastore tests
+# These really only test the interface, since in actual usage we have a
+# tinfoil connector that does everything over RPC, and this doesn't test
+# that.
+
+class TestConnector:
+ d = None
+ def __init__(self, d):
+ self.d = d
+ def getVar(self, name):
+ return self.d._findVar(name)
+ def getKeys(self):
+ return set(self.d.keys())
+ def getVarHistory(self, name):
+ return self.d.varhistory.variable(name)
+ def expandPythonRef(self, varname, expr, d):
+ localdata = self.d.createCopy()
+ for key in d.localkeys():
+ localdata.setVar(d.getVar(key))
+ varparse = bb.data_smart.VariableParse(varname, localdata)
+ return varparse.python_sub(expr)
+ def setVar(self, name, value):
+ self.d.setVar(name, value)
+ def setVarFlag(self, name, flag, value):
+ self.d.setVarFlag(name, flag, value)
+ def delVar(self, name):
+ self.d.delVar(name)
+ return False
+ def delVarFlag(self, name, flag):
+ self.d.delVarFlag(name, flag)
+ return False
+ def renameVar(self, name, newname):
+ self.d.renameVar(name, newname)
+ return False
+
class Remote(unittest.TestCase):
def test_remote(self):
- class TestConnector:
- d = None
- def __init__(self, d):
- self.d = d
- def getVar(self, name):
- return self.d._findVar(name)
- def getKeys(self):
- return self.d.localkeys()
- def getVarHistory(self, name):
- return self.d.varhistory.variable(name)
- def expandPythonRef(self, varname, expr, d):
- localdata = self.d.createCopy()
- for key in d.localkeys():
- localdata.setVar(d.getVar(key))
- varparse = bb.data_smart.VariableParse(varname, localdata)
- return varparse.python_sub(expr)
- def setVar(self, name, value):
- self.d.setVar(name, value)
d1 = bb.data.init()
d1.enableTracking()
@@ -500,6 +517,9 @@ class Remote(unittest.TestCase):
# Test setVar on client side affects server
d2.setVar('HELLO', 'other-world')
self.assertEqual(d1.getVar('HELLO'), 'other-world')
+ # Test setVarFlag on client side affects server
+ d2.setVarFlag('HELLO', 'flagname', 'flagvalue')
+ self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue')
# Test client side data is incorporated in python expansion (which is done on server)
d2.setVar('FOO', 'bar')
self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar')
@@ -507,3 +527,75 @@ class Remote(unittest.TestCase):
d1.setVar('FOO_test', 'baz')
d1.appendVar('OVERRIDES', ':test')
self.assertEqual(d2.getVar('FOO'), 'baz')
+
+
+# Remote equivalents of local test classes
+# Note that these aren't perfect since we only test in one direction
+
+class RemoteDataExpansions(DataExpansions):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1["foo"] = "value_of_foo"
+ self.d1["bar"] = "value_of_bar"
+ self.d1["value_of_foo"] = "value_of_'value_of_foo'"
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteNestedExpansions(TestNestedExpansions):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1["foo"] = "foo"
+ self.d1["bar"] = "bar"
+ self.d1["value_of_foobar"] = "187"
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteConcat(TestConcat):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1.setVar("FOO", "foo")
+ self.d1.setVar("VAL", "val")
+ self.d1.setVar("BAR", "bar")
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteConcatOverride(TestConcatOverride):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1.setVar("FOO", "foo")
+ self.d1.setVar("VAL", "val")
+ self.d1.setVar("BAR", "bar")
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteOverrides(TestOverrides):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1.setVar("OVERRIDES", "foo:bar:local")
+ self.d1.setVar("TEST", "testvalue")
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteKeyExpansion(TestKeyExpansion):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1.setVar("FOO", "foo")
+ self.d1.setVar("BAR", "foo")
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
+
+class TestRemoteFlags(TestFlags):
+ def setUp(self):
+ self.d1 = bb.data.init()
+ self.d = bb.data.init()
+ self.d1.setVar("foo", "value of foo")
+ self.d1.setVarFlag("foo", "flag1", "value of flag1")
+ self.d1.setVarFlag("foo", "flag2", "value of flag2")
+ connector = TestConnector(self.d1)
+ self.d.setVar('_remote_data', connector)
diff --git a/lib/bb/tinfoil.py b/lib/bb/tinfoil.py
index 00cec59b8..19b41be46 100644
--- a/lib/bb/tinfoil.py
+++ b/lib/bb/tinfoil.py
@@ -1,6 +1,6 @@
# tinfoil: a simple wrapper around cooker for bitbake-based command-line utilities
#
-# Copyright (C) 2012-2016 Intel Corporation
+# Copyright (C) 2012-2017 Intel Corporation
# Copyright (C) 2011 Mentor Graphics Corporation
#
# This program is free software; you can redistribute it and/or modify
@@ -84,6 +84,34 @@ class TinfoilDataStoreConnector:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
+ def setVarFlag(self, varname, flagname, value):
+ if self.dsindex is None:
+ self.tinfoil.run_command('dataStoreConnectorSetVarFlag', self.dsindex, varname, flagname, value)
+ else:
+ # Not currently implemented - indicate that setting should
+ # be redirected to local side
+ return True
+ def delVar(self, varname):
+ if self.dsindex is None:
+ self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname)
+ else:
+ # Not currently implemented - indicate that setting should
+ # be redirected to local side
+ return True
+ def delVarFlag(self, varname, flagname):
+ if self.dsindex is None:
+ self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname, flagname)
+ else:
+ # Not currently implemented - indicate that setting should
+ # be redirected to local side
+ return True
+ def renameVar(self, name, newname):
+ if self.dsindex is None:
+ self.tinfoil.run_command('dataStoreConnectorRenameVar', self.dsindex, name, newname)
+ else:
+ # Not currently implemented - indicate that setting should
+ # be redirected to local side
+ return True
class TinfoilCookerAdapter:
"""