-
Feature Request
-
Resolution: Unresolved
-
Major
-
None
-
None
-
None
In many senses, Arquillian provides a component model for testing. While it's capable of providing services like injection, many times it's desirable for a client to get at the ARQ services programatically (as opposed to declaratively as is the case with compile-time metadata like annotations).
So we should be able to:
@Inject private ArquillianContext context;
...inside of the user test, and use this object to make container-specific requests of the container. This is in many ways analagous to:
@Resource private SessionContext context;
...within EJB, where a bean instance gets a hook to the container.
These requests should be fielded by the same mechanism used during test enrichment. In fact, introducing this grammar now provides us the proper separation between enrichment (scanning test fields and injecting into them) and resolution (the process of determining the instance to be injected into some target).
Taking this a step further we can now build a chain of resolvers which may be together composed; test enrichers would then delegate all resolution logic to the chain (now they're in a hierarchy).
Do the prototyping within the OpenEJB container, then extract out and review as necessary.
IRC log detailing some discussion:
(10:44:36 AM) ALR@Freenode: aslak: Let's start here: http://pastebin.com/WG6YBEM0
(10:45:32 AM) ALR@Freenode: Think of this as you think of EJB's SessionContext
(10:45:35 AM) aamonten left the room.
(10:45:44 AM) ALR@Freenode: In EJB, bean impls sometimes need to talk to the container.
(10:45:51 AM) ALR@Freenode: Here, tests need to talk to the container too.
(10:45:56 AM) ALR@Freenode: And the Container is Arquillian.
(10:46:12 AM) ALR@Freenode: Which may in turn delegate stuff to a backing container like JBossAS or GlassFish
(10:47:02 AM) ALR@Freenode: So very simply we get, for instance an OpenEJB implementation:
(10:47:03 AM) ALR@Freenode: http://pastebin.com/izMV5SaM
(10:47:36 AM) ALR@Freenode: Here the test enricher, or even the test itself, can get the OpenEJB impl of the Arquillian context.
(10:47:48 AM) ALR@Freenode: And this is the thing that resolves requested references.
(10:47:56 AM) ALR@Freenode: The test enricher would no longer resolve anything.
(10:47:57 AM) balunasj left the room (quit: Client Quit).
(10:48:12 AM) ALR@Freenode: Just scan the test class for stuff that needs to be injected.
(10:48:14 AM) balunasj balunasj@redhat/jboss/balunasj entered the room.
(10:48:28 AM) ALR@Freenode: So we extract the concerns in a typesafe, container-specific way.
(10:48:42 AM) aslak: the new core has that 'kind' of context already
(10:49:00 AM) ALR@Freenode: Now along comes my test.
(10:49:08 AM) ALR@Freenode: aslak: That Context isn't quite it.
(10:49:14 AM) aslak: and have plans for building some kind of 'create object' into it as well..
(10:49:17 AM) ALR@Freenode: That's a context for the testrunner
(10:50:03 AM) ALR@Freenode: aslak: Usage from the test class is:
(10:50:03 AM) ALR@Freenode: http://pastebin.com/kmkwMyX4
(10:50:13 AM) ALR@Freenode: We inject the ArquillianContext
(10:50:22 AM) ALR@Freenode: Then the test can request stuff of the container programatically.
(10:50:44 AM) ALR@Freenode: And using the same mechanism as done declaratively (==annotations/injection) during test enrichment
(10:50:48 AM) ALR@Freenode: But gives the user control.
(10:50:59 AM) ALR@Freenode: And can provide some more context to the process.
(10:51:09 AM) aslak: sure, but why stop with injecting a context the user can use for lookup
(10:51:10 AM) ALR@Freenode: So here I get a good naming context which does auth login.
(10:51:34 AM) ALR@Freenode: I stopped because it got to be 3AM.
(10:51:36 AM) aslak: that kinda goes against the idea of injection..
(10:51:49 AM) ALR@Freenode: aslak: It's a complement.
(10:51:56 AM) ALR@Freenode: Injection is always preferred.
(10:52:02 AM) ALR@Freenode: But you may not know at compile-time.
(10:52:05 AM) ALR@Freenode: This is for runtime.
(10:52:33 AM) aslak: ALR, if you keep the custom jndi properties out of it for now, this is what the enrichers should do
(10:52:42 AM) aslak: that we solve it via the context in the background, sure
(10:53:14 AM) ALR@Freenode: I think you're missing the overall goal.
(10:53:18 AM) ALR@Freenode: To separate concerns.
(10:53:24 AM) ALR@Freenode: And provide a context from test to Arquillian.
(10:53:31 AM) ALR@Freenode: jndi.properties isn't a factor.
(10:53:44 AM) ALR@Freenode: And also, I need many naming contexts with different auth properties.
(10:53:53 AM) ALR@Freenode: So something on the ClassPath isn't an answer.
(10:54:08 AM) ALR@Freenode: And the enrichers should not be in charge of resolving targets
(10:54:16 AM) aslak: no, but the mdb spec us eannotated properties
(10:54:17 AM) ALR@Freenode: This is why we commonly have "Resolvers"
(10:54:41 AM) ALR@Freenode: Great, we do that too.
(10:55:05 AM) ALR@Freenode: @Inject
(10:55:05 AM) ALR@Freenode: @ArquillianProps(
)
(10:55:05 AM) ALR@Freenode: private Context context;
(10:55:11 AM) aslak: yea
(10:55:17 AM) ALR@Freenode: And the enricher's job is only:
(10:55:22 AM) ALR@Freenode: Parse that shit
(10:55:30 AM) ALR@Freenode: And send along to the ArquillianContext impl.
(10:55:37 AM) ALR@Freenode: Not resolve anything.
(10:55:46 AM) ALR@Freenode: Under that scheme we get to compose enrichers together
(10:55:58 AM) ALR@Freenode: Backed by an appropriate ArquillianContext impl specific to each container
(10:56:07 AM) aslak: sure sure.. EJBEnricher only find the fields with @EJB, sends the resolve for creation in the context
(10:56:08 AM) ALR@Freenode: And the ArqContext can have many resolvers
(10:56:18 AM) ALR@Freenode: aslak: Exactly.
(10:56:26 AM) ALR@Freenode: Enrichers scan only.
(10:56:29 AM) aslak: yea
(10:56:37 AM) ALR@Freenode: Which means we can in turn make the enrichers much more generic.
(10:56:40 AM) aslak: sounds like a stratigy
(10:56:50 AM) ALR@Freenode: Woohoo!
(10:57:05 AM) aslak: i still think we can use the existing context tho
(10:57:25 AM) ALR@Freenode: Is the existing context container-specific?
(10:57:34 AM) aslak: a container would bind it's resolvers in the ClasContext
(10:57:34 AM) ALR@Freenode: It has too much support we don't want to give the usre.
(10:57:38 AM) ALR@Freenode: fireEvent and such
(10:58:01 AM) lightguard_jp lightguar@166-70-166-98.ip.xmission.com entered the room.
(10:58:04 AM) ALR@Freenode: (ArquillianContext here would go into an Arq API package)
(10:58:14 AM) aslak: hmm
(10:58:21 AM) ALR@Freenode: Which besides annotations is I think the only Arq API thus far.
(10:58:30 AM) aslak: yea
(10:58:41 AM) aslak: but why expose it
(10:58:46 AM) ALR@Freenode: aslak: To the user?
asgeirf__ aslak
(10:58:49 AM) aslak: yea
(10:58:56 AM) ALR@Freenode: aslak: Just as my last example has
(10:59:06 AM) ALR@Freenode: aslak: So we have a hook to ARQ.
(10:59:13 AM) ALR@Freenode: And can programatically get stuff.
(10:59:20 AM) ALR@Freenode: With runtime properties.
(10:59:33 AM) ALR@Freenode: Else we're chained a bit to compile-time stuff.
(10:59:46 AM) ALR@Freenode: It's like we say:
(11:00:00 AM) ALR@Freenode: Intelligent defaults and simplicity. But option to get under the covers a bit.
(11:00:21 AM) ALR@Freenode: We might have other things we later want to add to ArquillianContext too.
(11:00:28 AM) aslak: ok, i can relate it to injecting a beanmanager..
(11:00:30 AM) ALR@Freenode: Like...accessing the container configuration?
(11:01:19 AM) ALR@Freenode: Yes, exactly. SessionContext, BeanManager.
(11:01:34 AM) ALR@Freenode: Arquillian is a component model for tests.
(11:01:43 AM) ALR@Freenode: As such needs a channel to talk to the host.
(11:02:05 AM) ALR@Freenode: And we get to benefit from the design of successful models elsewhere.
(11:03:23 AM) aslak: so, we start with a simple Class->Resolver mapper as the ArquillianContext
(11:03:40 AM) ALR@Freenode: aslak: Let me hack some things in the OpenEJB impl.
(11:03:59 AM) ALR@Freenode: I'm thinking maybe a chain of eligible resolvers.
(11:04:03 AM) ALR@Freenode: Under the hood.
(11:04:19 AM) aslak: like El
(11:04:26 AM) ALR@Freenode: El?
(11:04:33 AM) aslak: The EL Factory
(11:04:38 AM) ALR@Freenode: Oh right.
(11:04:39 AM) aslak: or no tthe factory, the el context
(11:04:48 AM) ALR@Freenode: Or anything that needs pluggable resolution
(11:04:55 AM) aslak:
(11:05:58 AM) aslak: i'm not sure this should be fully controlled by the container tho.
(11:06:16 AM) aslak: the container will add it's set of Resolvers, but it's useful for other places as well
(11:07:34 AM) aslak: it should be bound in the normal Context at some level..
(11:07:39 AM) ALR@Freenode: aslak: Anyway let me see what I can throw in place. Then we'll find proper homes for everything.
asgeirf__ aslak
(11:07:46 AM) aslak: sure
(11:07:55 AM) ALR@Freenode: aslak: TBH I think that normal Context needs some work.
(11:08:16 AM) ALR@Freenode: The docs issue you know, but it encompasses even management together with an object registry.
(11:08:24 AM) ALR@Freenode: And its purpose is for the test runner.
(11:08:35 AM) ALR@Freenode: Not for a channel between client and Arquillian
(11:09:06 AM) ALR@Freenode: s/even/event
(11:09:37 AM) aslak: if you have any good names.. lemme know..
(11:10:59 AM) ALR@Freenode: Well, it's a context no doubt.
(11:11:16 AM) ALR@Freenode: But more I want to understand its intent.
(11:11:39 AM) ALR@Freenode: What does it do, aside from being the object we pass around from enricher to runner?
(11:11:58 AM) ALR@Freenode: TestContext
(11:11:58 AM) ALR@Freenode: ?
(11:12:11 AM) aslak: Session/Class/Test-Context
(11:12:51 AM) aslak: it's a chain of context that says something about the life of the obejct bound to it
(11:13:00 AM) aslak: s/Session/Suite sorry
(11:13:59 AM) aslak: it can store event handlers for specific events, and it can trigger(fire events) those handlers
(11:15:12 AM) aslak: it also acts as a 'cumminication' channel between the handlers/enrichers/containers
(11:16:36 AM) ALR@Freenode: Yep.
(11:16:46 AM) ALR@Freenode: So it's the test "session"
(11:17:00 AM) ALR@Freenode: Which starts and ends alongside Suite lifecycle.
(11:17:40 AM) aslak: as a scenario.. when @BeforeSuite is triggered, a SuiteContext is build based on a Profile. the ProfileBuilder will register a set of eventhandlers. when th eevent comes in to the session context, it will trigger the handlers, ie the DeployableContianer creator. the creator will then bind the DeployableContainer back to the context
(11:19:01 AM) aslak: then when @BeforeClass is triggered, a ClassContext with a ref to the parent SuiteContext is built and fired all the BeforeClass handlers.. one of which is the deployer which will get the DeployableContainer bound by the creator
(11:19:53 AM) aslak: session in a sens sure
(11:21:14 AM) ALR@Freenode: Yep.
- is related to
-
ARQ-153 Protocol configuration element should be separate from Container
- Closed