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

Modular Structure of the Engine #1607

Open
CharliePoole opened this issue Jan 20, 2025 · 1 comment
Open

Modular Structure of the Engine #1607

CharliePoole opened this issue Jan 20, 2025 · 1 comment
Assignees
Labels
Design Decision Epic Needs Discussion V4 All issues related to V4 - use -label:V4 to get non-V4 issues
Milestone

Comments

@CharliePoole
Copy link
Member

CharliePoole commented Jan 20, 2025

@nunit/engine-team @nunit/core-team

We already have a number of individual issues around changing the engine's modular structure. I noticed that we don't have a single issue that incorporates an overview, so here it is. It's an Epic and some of it's individual parts are Epics in themselves. I've also labeled it as a Design Decision since should discuss and refine the plan.

Current Structure

Primary Modules

* nunit.engine
* nunit-agent-net462, nunit-agent-net80, etc.

Support Modules

* nunit.engine.core
* nunit.engine.api
* TestCentric.Metadata

Proposed Structure

Primary Modules

* nunit.engine

* nunit-agent-net462, nunit-agent-net80, etc. (now PLUGGABLE extensions)
|
>----nunit.agent.core

Support Modules

nunit.engine.api
NUnit.Extensibility
nunit.common
TestCentric.Metadata

Details

Engine

The engine is now dependent on nunit.engine.core, as are the agents. This creates an inter-dependency, which has frequently interfered with our ability to make changes. Any implementation code needed by the engine belongs in the engine. Issue #1578 deals with this.

Agents

As agents are becoming pluggable (see #909), they will need to be moved into individual projects and packaged separately. The engine and console runner will incorporate agents for .NET 4.6.2, 8.0 and 9.0 as dependencies. Depending on how soon we implement this, we may want to re-create the dropped .NET 6.0 agent as an optionally installable agent. In fact, we could, if desired, restore any of our past out-of-date agents as pluggable agents fairly easily, or we could support someone else who wanted to do so.

Agent Core

The nunit.agent.core assembly, also covered in #1578, will hold common code used by all our agents. We have the choice to either package it separately or use the source as a submodule. If separately packaged, it may either be referenced as a dependency by each agent package or used as a development-only dependency with the module distributed. There are advantages to each approach, which we should discuss in #909.

Extensibility

The new NUnit.Extensibility assembly will incorporate ExtensionManager and related classses in a separate package. ExtensionManager gives lower level access to extensions and is used by the engine's ExtensionService. The purpose of this split is to permit other modules than the engine to incorporate extensibility. Initially, the agents will make use of this, allowing extensions like the NUnit V2 Framework Driver to function. Eventually, we may use it for the console runner and it could even be used for NUnitLite, in order to avoid duplication of extension code. See issue #1049.

Metadata

At it's origins, NUnit used reflection to analyze assemblies before trying to load and run them. With NUnit 3, we switched to Mono.Cecil but eventually ran into problems for two reasons:

  1. Some users were testing code, which also used Mono.Cecil, sometimes a different version from ours.
  2. The package eliminated support for platforms we still wanted to support.

Facing the same problems with my TestCentric GUI, I created TestCentric.Metadata with some differences from the original:

  1. It has a subset of the capability of Mono.Cecil, supporting only reading of assemblies. This makes it a lot smaller.
  2. I retained support for all platforms we supported. It is currently built to target .NET Framework 2.0 and .NET Standard 2.0.
  3. Subsequently, I have made a few more changes. In particular, I changed the namespace to avoid collisions with user code when running under the .NET Framework. The package is currently at version 3.0.3.

For the present, I'm planning to keep assembly as is, only making changes as needed. The package is currently used by the ExtensionManager as well as by several engine services, so it will be referenced by nunit.engine, nunit.agent.core and NUnit.Extensibility.

NUnit Common

We currently provide internal trace facilities to our various modules by duplicating the source code. Providing logging to several new modules would increase the number of duplicate copies. I propose to create a package NUnit.InternalTrace nunit.common to centralize this facility as well as other commonly used classes. In addition to eliminating code duplication, this might eventually help us combine multiple log files into a single file. I'll create a new issue for this one.

Engine Api

In issue #770, @ChrisMaddock proposed splitting the then-existing api assembly into multiple assemblies. In my plan for that issue, I didn't include that aspect of his proposal. I think should discuss it in the context of this overall issue.

@stevenaw
Copy link
Member

Thanks for the extensive write up and organization of issues here @CharliePoole . Lots to read and catch up on past discussions

@CharliePoole CharliePoole added the V4 All issues related to V4 - use -label:V4 to get non-V4 issues label Feb 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Decision Epic Needs Discussion V4 All issues related to V4 - use -label:V4 to get non-V4 issues
Projects
None yet
Development

No branches or pull requests

2 participants