PlanLoadException in OpenTap 9.24 with Unassigned Instruments

We have two versions of our software: one uses OpenTap version 9.13 and the other uses 9.24.

In our test plan, we have steps that use instruments. In OpenTap version 9.13, I can open the test plan even if the instrument is not available, allowing customers to open the test plan and reassign the instruments between testers.

However, in version 9.24, it throws a PlanLoadException if the instrument is not created or assigned, preventing me from opening the test plan. Is there any workaround for this?
I need to be able to open the test plan even if the instrument is unassigned or not created.

Question posted regarding : Ratheesh

1 Like

Hi @justin_c_i,

Have you developed a custom GUI around OpenTAP?

In 9.23, a UI pops up which asks the user to decide between continue and abort when a test plan with errors are loaded.
Unfortunately, it seems that if there is no handler for the event, it will just assume to abort loading the test plan. This sounds a bit like a breaking change, so theoretically we might need to fix it.

However, since this was added a while ago, I am not sure what the right approach would be.

What you can do is to create an IUserInputInterface instance, and added it with UserInput.SetInterface.

But this only applies if you are indeed creating your own user interface. Is that the case?

1 Like

Hi @rolf_madsen,

Yes, we are using our own user interface, which is inherited from IUserInputInterface , and we are calling UserInput.SetInterface to set our custom implementation.

Ok, in that case, you can intercept the user input request and select the correct option.

This is a bit difficult to do since the object to intercept is not a public API. However you can do it like this as a workaround:

        class InterceptLoadErrorUserInterface : IUserInputInterface
        {
            void InterceptAndFixTestPlanLoadError(object dataObject)
            {
                var annotation = AnnotationCollection.Annotate(dataObject);
                var members = annotation.Get<MembersAnnotation>().Members?.ToArray();
                if (members == null) return;
                var responseMemberAnnotation = members.FirstOrDefault(member => member.Get<IMemberAnnotation>()?.Member.Name == "Response");
                if (responseMemberAnnotation == null) return;
                var sca = responseMemberAnnotation.Get<IStringValueAnnotation>();
                sca.Value = "Ignore";
                responseMemberAnnotation.Write();
            }
            public void RequestUserInput(object dataObject, TimeSpan Timeout, bool modal)
            {
                InterceptAndFixTestPlanLoadError(dataObject);
            }
        }

   // In my test it worked:
        [Test]
        public void InterceptTestPlanLoadErrors()
        {
            using var session = Session.Create();
            var intercept = new InterceptLoadErrorUserInterface();
            UserInput.SetInterface(intercept);
            var xml = "<TestPlan><Asd Type=\"adsasd.asdasd\"/> </TestPlan>";
            // this throws an exception unless we intercept the error and ignore it.
            TestPlan.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml)), "test.TapPlan");
        }