Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flow instantiation fails silently in some conditions #1809

Closed
smithdtyler opened this issue May 16, 2019 · 9 comments

Comments

@smithdtyler
Copy link

commented May 16, 2019

Summary

When a flow path through a subcomponent is included as part of an end to
end flow, but that flow path is not implemented through the
subcomponents of that component, the end to end flow is not included in
the instance model with no warning to the user.

We discussed this with @joeseibel, who agreed it is a problem.

Environment

  • OSATE Version: 2.4.x
  • Operating System: Windows

@lwrage lwrage added the info needed label May 17, 2019

@lwrage

This comment has been minimized.

Copy link
Contributor

commented May 17, 2019

Could you include an example model, please?

@smithdtyler

This comment has been minimized.

Copy link
Author

commented May 28, 2019

Example below:

package Flow_Demo
public
	system Top
		
	end Top;
	
	system implementation Top.impl
		subcomponents
			one: abstract Thing.one;
			two: abstract Thing.two;
			three: abstract Thing.three;
		connections
			Top_impl_new_connection: feature one.output -> three.input;
			Top_impl_new_connection2: feature three.output -> two.input;
		flows
			ETE: end to end flow one.Thing_new_flow_spec -> Top_impl_new_connection -> three.Thing_new_flow_spec3 -> Top_impl_new_connection2 -> two.Thing_new_flow_spec2;
	end Top.impl;
	
	abstract Thing
		features
			input: in feature;
			output: out feature;
		flows
			Thing_new_flow_spec: flow source output;
			Thing_new_flow_spec2: flow sink input;
			Thing_new_flow_spec3: flow path input -> output;
	end Thing;
	
	abstract implementation Thing.one
		
	end Thing.one;
	
	abstract implementation Thing.two
		
	end Thing.two;
	
	abstract implementation Thing.three
		subcomponents
			stub: abstract sub;
		connections
			Thing_three_new_connection: feature input -> stub.input;
			Thing_three_new_connection2: feature stub.output -> output;
	end Thing.three;
	
	abstract sub
		features
			input: in feature;
			output: out feature;
	end sub;
	
	abstract implementation sub.impl
		
	end sub.impl;
end Flow_Demo;
@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2019

Just tried the above example:

  • No end to end flow is generated in the instance model.
  • No error/warning message is generated

If you add

    	flows
    		Thing_new_flow_spec3: flow path input -> Thing_three_new_connection -> stub.xxx -> Thing_three_new_connection2 -> output;

to Thing.three and

    	flows
    		xxx: flow path input -> output;

to sub

then the end to end flow is generated.

Removing the flow implementation again from Thing.three causes the end to end flow to not be generated.

@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2019

Okay, it seems that many errors messages are still being reported on the end to end flow instance, even though that instance is later removed.

@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2019

I commented out the code that actually removed the (partially built) end to end flow instances to see if the instance has an error reported on it. Surprisingly, it does not.

The end to end flow instance is added to the remove list in processFlowStep:

			if (connis.isEmpty()) {
				connections.clear();
				removeETEI.add(etei);

				if (!lastFlowImpl.isEmpty()) {
					FlowImplementation flowFilter = lastFlowImpl.peek();
					if (flowFilter != null) {
						error(etei.getContainingComponentInstance(),
								"Cannot create end to end flow '" + etei.getName()
								+ "' because there are no semantic connections that continue the flow '"
								+ flowFilter.getSpecification().getName() + "' from feature '"
								+ flowFilter.getOutEnd().getFeature().getName() + "'");
					}
				}
			} else {

There is an attempt to create an error message, but in this case it is not generated because the stack referenced by lastFlowImpl contains to null values. Not sure yet what this means.

@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2019

To be clear, the main issue in the above model is that Thing.three contains connections to a subcomponent but no flow implementations.

if you remove the connections, the end to end flow is generated just fine using only the flow specification.

@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2019

The actual problem in the above example, by which I mean the thing that causes undesirable OSATE behavior, is the fact that sub is abstract. The end to end flow instantiation code checks for the case of "missing flow implementation" and generates a warning message. This is in processSubcomponentFlow:

		if (flowImpls.isEmpty()) {
			// we are at a leaf
			processFlowStep(ci, etei, fs, iter);
			if (subImpl != null && AadlUtil.hasPortComponents(subImpl)) {
				warning(etei, "End-to-end flow " + etei.getName() + " contains component " + ci.getName()
				+ " with subcomponents, but no flow implementation " + fs.getName() + " to them");
			}
		} else {

The problem is AadlUtil.hasPortComponents because it does not consider abstract component types:

	public static boolean hasPortComponents(ComponentImplementation compimpl) {
		if (compimpl == null) {
			return false;
		}
		EList<Subcomponent> sl = compimpl.getAllSubcomponents();
		if (sl == null) {
			return false;
		}
		for (Subcomponent o : sl) {
			if (o instanceof SystemSubcomponent || o instanceof ProcessSubcomponent
					|| o instanceof ThreadGroupSubcomponent || o instanceof ThreadSubcomponent
					|| o instanceof DeviceSubcomponent || o instanceof ProcessorSubcomponent) {
				return true;
			}
		}
		return false;
	}

If you change sub (and the references to it) to be system, then when the model is instantiated

  1. the end to end flow ETE is not generated, but
  2. the warning message is: "End-to-end flow ETE contains component three with subcomponents, but no flow implementation Thing_new_flow_spec3 to them"

Interesting note: The warning message is originally places on the end to end flow instance node. Even though this node is removed from the model, the warning marker persists on the resource. This is good to know because some of the warnings/errors creating during this process are placed on the end to end flow instance and some are placed on the containing component. I was wondering what happened to the errors if the ETEI is removed from the model. Now we know the marker will still persist.

@AaronGreenhouse

This comment has been minimized.

Copy link
Contributor

commented Aug 12, 2019

So the fix for this issue is to update hasPortComponents to also consider abstract subcomponents to be things that can have ports.

I will update this and create a new JUnit test.

@lwrage

This comment has been minimized.

Copy link
Contributor

commented Aug 14, 2019

Fixed via PR #1943

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.