Skip to content

Latest commit

 

History

History
323 lines (262 loc) · 13.6 KB

CONTRIBUTING.md

File metadata and controls

323 lines (262 loc) · 13.6 KB
uid
contributing

Contributing guide

Project structure

Solution and folder structure

Folder Description
.\Build Build and CI files, check readme.md in that folder
.\Data Databases and database creation scripts for tests
.\NuGet LINQ to DB NuGet packages build files
.\Redist Binaries, unavailable officially at NuGet, used by tests and nugets
.\Source\LinqToDB LINQ to DB source code
.\Source\LinqToDB.AspNet LINQ to DB ASP.NET Core integration library source code
.\Source\LinqToDB.CLI LINQ to DB CLI scaffold tool source code
.\Source\LinqToDB.Remote.Grpc LINQ to DB Remote Context GRPC client/server source code
.\Source\LinqToDB.Remote.Wcf LINQ to DB Remote Context WCF client/server source code
.\Source\LinqToDB.Templates LINQ to DB t4models source code
.\Source\LinqToDB.Tools LINQ to DB Tools source code
.\Tests Unit test projects folder
.\Tests\Base LINQ to DB testing framework
.\Tests\FSharp F# models and tests
.\Tests\Linq Main project for LINQ to DB unit tests
.\Tests\Model Model classes for tests
.\Tests\Tests.T4 T4 templates test project
.\Tests\Tests.Benchmarks Benchmarks
.\Tests\Tests.PLayground Test project for use with linq2db.playground.sln lite test solution
Used for work on specific test without full solution load
.\Tests\VisualBasic Visual Basic models and tests support

Solutions

  • .\linq2db.sln - full linq2db solution
  • .\linq2db.playground.slnf - ligthweight linq2db test solution. Used to work on specific test without loading of all payload of full solution
  • .\linq2db.Benchmarks.slnf - ligthweight linq2db benchmarks solution. Used to work on benchmarks without loading of all payload of full solution

Source projects

Preferred target defines:

  • NETFRAMEWORK - net45, net46 and net472 target ifdef
  • NETSTANDARD2_1PLUS - targets with netstandard2.1 support (netstandard2.1, netcoreapp3.1, net6.0, net7.0). Don't use this define in test projects!
  • NATIVE_ASYNC - ifdef with native support for ValueTask, IAsyncEnumerable<T> and IAsyncDisposable types

Other allowed target defines:

  • NETSTANDARD2_1 - netstandard2.1 target ifdef
  • NETCOREAPP3_1 - netcoreapp3.1 target ifdef
  • NETSTANDARD2_0 - netstandard2.0 target ifdef
  • NET6_0 - net6.0 target ifdef
  • NET7_0 - net7.0 target ifdef
  • NET45 - net45 target ifdef
  • NET46 - net46 target ifdef
  • NET472 - net472 target ifdef

Allowed debugging defines:

  • TRACK_BUILD - ???
  • DEBUG - for debug code in debug build. To disable debug code use DEBUG1 rename
  • OVERRIDETOSTRING - enables ToString() overrides for AST model (must be enabled in LinqToDB.csproj by renaming existing OVERRIDETOSTRING1 define)

Test projects

Tests targets: net472, netcoreapp31, net6.0, net7.0

Allowed target defines:

  • NETCOREAPP3_1 - netcoreapp3.1 target ifdef
  • NET6_0 - net6.0 target ifdef
  • NET7_0 - net7.0 target ifdef
  • NET472 - net472 target ifdef
  • AZURE - for Azure Pipelines CI builds

Build

You can use solution to build and run tests. Also you can build whole solution or library using the following batch files:

  • .\Build.cmd - builds all the projects in the solution for Debug, Release and Azure configurations
  • .\Compile.cmd - builds LinqToDB project for Debug and Release configurations
  • .\Clean.cmd - cleanups solution projects for Debug, Release and Azure configurations
  • .\Test.cmd - build Debug configuration and run tests for net472, netcoreapp3.1, net6.0 and net7.0 targets. You can set other configuration by passing it as first parameter, disable test targets by passing 0 to second (for net472), third (for netcoreapp3.1), fourth (for net6.0) or fifth (for net7.0) parameter and format (default:html) as 7th parameter.

Example of running Release build tests for netcoreapp3.1 only with trx as output:

test.cmd Release 0 1 0 0 0 trx

Different platforms support

Because we target different TFMs, we use:

  • Conditional compilation. See supported defines above
  • Implementation of missing runtime functionality (usually copied from dotnet/runtime repository). Should be placed to Source\Shared folder with proper TFM #ifdefs (it will be picked by all projects automatically) and made explicitly internal to avoid conflicts.

Branches

  • master - main development branch, contains code for next release
  • release - branch with the latest released version

Run tests

NUnit3 is used as unit-testing framework. Most of tests are run for all supported databases and written in same pattern:

// TestBase - base class for all our tests
// provides required testing infrastructure
[TestFixture]
public class Test: TestBase
{
    // DataSourcesAttribute - custom attribute to feed test with enabled database configurations
    [Test]
    public void Test([DataSources] string context)
    {
        // TestBase.GetDataContext - creates new IDataContext
        // also supports creation of remote client and server
        // for remote contexts
        using(var db = GetDataContext(context))
        {
            // Here is the most interesting
            // this.Person - list of persons, corresponding Person table in database (derived from TestBase)
            // db.Person - database table
            // So test checks that LINQ to Objects query produces the same result as executed database query
            AreEqual(this.Person.Where(_ => _.Name == "John"), db.Person.Where(_ => _.Name == "John"));
        }
    }

}

Configure data providers for tests

DataSourcesAttribute generates tests for each enabled data provider. Configuration is taken from .\Tests\DataProviders.json and .\Tests\UserDataProviders.json (used first, if exists).

Repository already contains pre-configured UserDataProviders.json.template configuration with basic setup for SQLite-based testing and all you need is to rename it to UserDataProviders.json, add connection string for other databases you want to test. UserDataProviders.json will be ignored by git, so you can edit it freely.

Configuration file is used to specify user-specific settings such as connection strings to test databases and list of providers to test.

The [User]DataProviders.json is a regular JSON file:

UserDataProviders.json example (with description)

{
    // .net framework 4.7.2 test configuration
    "NET472" :
    {
        // base configuration to inherit settings from
        // Inheritance rules:
        // - DefaultConfiguration, TraceLevel, Providers - use value from base configuration only if it is not defined in current configuration
        // - Connections - merge current and base connection strings
        "BasedOn"              : "LocalConnectionStrings",

        // default provider, used as a source of reference data
        // LINQ to DB uses SQLite for it and you hardly need to change it
        "DefaultConfiguration" : "SQLite.Classic",

        // (optional) contains full or relative (from test assembly location) path to test baselines directory.
        // When path is set and specified directory exists - enables baselines generation for tests.
        "BaselinesPath": "c:\\github\\linq2db.baselines",

        // logging level
        // Supported values: Off, Error, Warning, Info, Verbose
        // Default level: Info
        "TraceLevel"           : "Error",
                                
        // list of database providers, enabled for current test configuration
        "Providers"            :
        [
            "Access",
            "SqlCe",
            "SQLite.Classic",
            "SQLite.MS",
            "Northwind.SQLite",
            "Northwind.SQLite.MS",
            "SqlServer.2014",
            "SqlServer.2012",
            "SqlServer.2008",
            "SqlServer.2005",
            "SqlServer.Azure",
            "DB2",
            "Firebird",
            "Informix",
            "MySql",
            "MariaDB",
            "Oracle.Native",
            "Oracle.Managed",
            "PostgreSQL",
            "Sybase.Managed",
            "SqlServer.Northwind",
            "TestNoopProvider"
        ],

        // list of test skip categories, disabled for current test configuration
    // to set test skip category, use SkipCategoryAttribute on test method, class or whole assembly
        "Skip"                 :
    [
        "Access.12"
    ]

    },

    // .net 6.0 test configuration
    "NET60" :
    {
        "BasedOn"              : "LocalConnectionStrings",
        "Providers"            :
        [
            "SQLite.MS",
            "Northwind.SQLite.MS",
            "SqlServer.2014",
            "SqlServer.2012",
            "SqlServer.2008",
            "SqlServer.2005",
            "SqlServer.Azure",
            "Firebird",
            "MySql",
            "MariaDB",
            "PostgreSQL",
            "SqlServer.Northwind",
            "TestNoopProvider"
        ]
    },

    // .net 7.0 test configuration
    "NET70" :
    {
        "BasedOn"              : "LocalConnectionStrings",
        "Providers"            :
        [
            "SQLite.MS",
            "Northwind.SQLite.MS",
            "SqlServer.2014",
            "SqlServer.2012",
            "SqlServer.2008",
            "SqlServer.2005",
            "SqlServer.Azure",
            "Firebird",
            "MySql",
            "MariaDB",
            "PostgreSQL",
            "SqlServer.Northwind",
            "TestNoopProvider"
        ]
    },

    // list of connection strings for all providers
    "LocalConnectionStrings":
    {
        "BasedOn"           : "CommonConnectionStrings",
        "Connections"       :
        {
            // override connection string for SqlAzure provider
            // all other providers will use default inherited connection strings from CommonConnectionStrings configuration
            "SqlServer.Azure" :
            {
                 "Provider"         : "System.Data.SqlClient",
                 "ConnectionString" : "Server=tcp:xxxxxxxxx.database.windows.net,1433;Database=TestData;User ID=TestUser@zzzzzzzzz;Password=TestPassword;Trusted_Connection=False;Encrypt=True;"
            }
        }
    }
}

To define your own configurations DO NOT EDIT DataProviders.json - create .\Tests\Linq\UserDataProviders.json and define needed configurations.

Tests execution depends on _CreateData.* tests executed first. Those tests recreate test databases and populate them with test data, so if you are going to run one test be sure to run _CreateData before it manually.

Also - if your test changes database data, be sure to revert those changes (!) to avoid side effects for other tests.

Continuous Integration

We do run builds and tests with:

  • Azure Pipelines pipelines/default.yml. It builds solution, generate and publish nugets and runs tests for:
    • .Net 4.7.2
    • .Net Core 3.1 (Windows, Linux and MacOS)
    • .Net 6.0 (Windows, Linux and MacOS)
    • .Net 7.0 (Windows, Linux and MacOS) For more details check readme

CI builds are done for all branches and PRs.

  • Tests run for all branches and PRs except release branch
  • Nugets publishing to Azure feeds enabled only for branch
  • Nugets publishing to Nuget.org enabled only for release branch

Publishing packages

  • "Nightly" builds packages are published to Azure feeds for each successful build of master branch.
  • Release packages are published to Nuget.org for each successful build of release branch.

Building releases

  1. Update Release Notes and create empty entry for vNext release
  2. Create PR from master to release branch, in comments add @testers to notify all testers that we are ready to release
  3. Wait few days for feedback from testers and approval from contributors
  4. Merge PR
  5. Tag release on master branch
  6. Update versions in master branch (this will lead to publish all next master builds as new version RC):
    • in \Build\Azure\pipelines\templates\build-vars.yml set assemblyVersion and packageVersion (for release and development) parameters to next version. Always use next minor version and change it to major only before release, if it should be new major version release

Process

In general you should follow simple rules:

  • Code style should match exising code
  • There should be no compilation warnings (will fail CI builds)
  • Do not add new features without tests
  • Avoid direct pushes to master and release branches
  • To fix some issue or implement new feature create new branch and make pull request after you are ready to merge or create pull request as work-in-progress pull request. Merge your PR only after contributors' review.
  • bugfix branches must use issue/<issue_id> naming format
  • feature branches must use feature/<issue_id_or_feature_name> naming format
  • If you do have repository write access, it is recommended to use central repository instead of fork
  • Do not add new public classes, properties, methods without XML documentation on them
  • Read issues and help users
  • Do not EF :)