0

I'm testing legacy code with Microsoft Fakes and some shims. To test concurrency in the access of a shared resource I had to create some AppDomains to which I pass a fixture with their context. This couldn't be done only with threads because shims aren't thread safe. I expect also that on returning that context to the main AppDomain I can use that data for the tests expectations.

One of the properties of my fixture is a Dictionary that I update inside my shims for the legacy code. The problem I'm having is that I can't update the value for the dictionary.

In this method I shim a static class that would write to the registry:


    public static void ShimRegistry(PlafondManagerTestFixtureUser fixture)
        {
            Common.Util.Fakes.ShimRegistryHelper.SetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
                if (fixture.Registries != null)
                {
                    var quant = Decrypt(value);
                    if (fixture.Registries.ContainsKey(key))
                        fixture.Registries[key] = quant;
                    else
                        fixture.Registries.Add(key, quant);
                }

                return null;
            };
            Common.Util.Fakes.ShimRegistryHelper.GetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
                string val;
                fixture.Registries.TryGetValue(key, out val);
                return Encrypt(val);
            };
        }

When I debug this I can see that before

fixture.Registries[key] = quant;
I have "0" as the value of the dictionary entry and "2" in quant. Immediately after running that line the dictionary entry still reads "0".

I'm stuck with this and I couldn't find similar issues on stack overflow (or maybe I'm not finding the right words to describe it).

Other parts of this setup work fine. I can receive an updated string on the main thread, so I doubt that this has anything to do with me sharing instances between AppDomains.

Can anybody help me find whats wrong?

Updated: As Jon Skeet suggested, I tested this outside of the context of mstest, appdomain, shims and even right before the faulty code. In every case it's working as expected, so it might have something to do with sharing a dictionary between AppDomains in the fixture.

This is what I used to test:

Dictionary<string, string> test = new Dictionary<string, string>
{
    { "Key", "Value" }
};
test["Key"] = "Value2";

I have that feeling that I'm missing some stupid little thing, but just can't seem to find what it is.

Update 2: Managed to reduce the problem to passing the dictionary to another AppDomain.

Here's a sample console project I put on Github;

Update 3: Now that I had something more specific to search for I found this answer that helped me:Adam Ralph's answer to 'Sharing data between AppDomains'

I'll bet on serialization to string as I already have a way to do it easily, but still would like to understand why this happens the way it does.

Sérgio Azevedo
  • 313
  • 1
  • 4
  • 13
  • It would really help if you could provide a [mcve]. You should also do the appropriate diagnostic work to reduce the number of tricky aspects here - can you reproduce the problem without AppDomains being involved? Can you reproduce it without MS Test being involved? Can you reproduce it without MS Fakes being invokes? – Jon Skeet Jun 16 '17 at 16:43
  • TryGetValue returns a boolean. So check if return value is true. Either you are get a false returned or the key isn't the same when you are writing and when you are reading. – jdweng Jun 16 '17 at 17:01
  • @jdweng That shim isn't being used at this point in the test but I'll check it anyway. – Sérgio Azevedo Jun 16 '17 at 17:22

0 Answers0