Recently a colleague pointed out that our VirtualSystemManagementService's RemoveResourceSettings method (in libvirt-cim) was marked with the wrong type. This was done early on, and probably was just a mistake, given that AddResourceSettings and ModifyResourceSettings both took the same type: an EmbeddedObject. RemoveResourceSettings takes a reference, since anything you could possibly delete would be representable as a reference. It's the right way, but annoying, given that I had already built a common resource management infrastructure around the idea of having a list of resource objects to (Add,Modify,Remove).
Anyway, I coded up the change to the provider itself and set out to test it. I quickly realized that I didn't know what the CIMXML for a method call with an array of references looked like. Up to this point, I have been unit testing the method providers by just hacking up a CIMXML template and stuffing it into wbemexec or wbemcat. It sucks, but it works.
However, this time I was stuck. I didn't have an example, and some guessing didn't work in a short amount of time. I decided to try to work up something in pywbem to see if I could get not only the method call made for testing, but also a glimpse at what the CIMXML for it looked like. I ended up with this very small bit of python code that was extremely helpful:
from pywbem import WBEMConnection, CIMInstanceName
c = WBEMConnection("http://localhost", ("root", "password"), "root/virt") c.debug = True
r = CIMInstanceName("Xen_DiskResourceAllocationSettingData", keybindings={"InstanceID":"pv0/xvda"})
res = c.InvokeMethod("RemoveResourceSettings", "Xen_VirtualSystemManagementService", ResourceSettings=[r])
print c.last_request
This connects to localhost, creates a reference, and makes the method call with that reference as a single-element array. After the operation, the "last_request" field contains the CIMXML it sent to the server, but only if the "debug" property is set to True (something the documentation conveniently leaves out). The result (with the boiler-plate cut out) looks like this:
Not that I really need it at this point, given that the pywbem case was so easy to write. However, it provides a good example of how to not only use pywbem to figure out the proper CIMXML for an operation, but also debug it if it's wrong.