dbfit / dbfit Goto Github PK
View Code? Open in Web Editor NEWDbFit is a database testing framework that supports easy test-driven development of your database code.
Home Page: http://dbfit.github.io/dbfit
License: GNU General Public License v2.0
DbFit is a database testing framework that supports easy test-driven development of your database code.
Home Page: http://dbfit.github.io/dbfit
License: GNU General Public License v2.0
This is blocker for #28.
Example of failing snipped is described in #28.
The problem with NCLOB is that there is oracle.sql.NCLOB data type in JDBC 11.2 which didn't exist in earlier version of JDBC.
Some ideas for workarounds:
Git tagging syntax:
git tag -a v2.0.0-RC4 -m "release 2.0.0 RC4"
In DbFit.AcceptanceTests.JavaTests.DerbyTests.FlowMode.BulkInsert, create table Test_DBFit
is called but select * from Test_DBFit
doesn't work.
Suggestions by @MMatten:
I guess more of a tutorial than the dbfit acceptance tests. But in particular:
!|dbfit.OracleTest|
!|Connect|localhost:1521|dftest|dftest|XE|
|set parameter|threshold|10|
!|query|select TO_CHAR(SYSTIMESTAMP, 'SSSSS') AS start_time FROM DUAL|
|start_time? |
|>>start_time |
!|execute procedure|ConcatenateStrings |
|firstString |secondString|concatenated?|
|a |b |a b |
!|query|SELECT (TO_CHAR(SYSTIMESTAMP, 'SSSSS') - :start_time) AS duration FROM DUAL|
|duration? |
|>>duration |
!|query stats|
|query|is empty?|
|SELECT :duration FROM DUAL WHERE :duration > :threshold|yes|
Latest version of FitLibrary seems to be 2.0 (from year 2011) while dbfit is still based on an older release from 2008. Maybe would be good to bump it up in dbfit.
(I've been using dbfit 1.1 with FitLibrary 2.0 past year - I haven't faced issues)
For MySQL, this is allowed:
|Execute procedure|abc|
however for Postgres, the above doesn't work and is instead:
|Execute procedure|abc()|
The following should work for all DBs:
|Execute procedure|abc|
When building the postgre module I have a bit of an anomoly. If I run mvn package
from dbfit/dbfit-java
then the dbdeploy plugin fails as it cannot find the org.postgres.Driver
class.
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 2 source files to C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre\target\classes
[INFO] [dbdeploy:update {execution: default}]
dbdeploy 3.0M3
[ERROR]
java.lang.ClassNotFoundException: org.postgresql.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(RealmClassLoader.java:195)
at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:255)
at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:274)
at org.codehaus.classworlds.RealmClassLoader.loadClass(RealmClassLoader.java:214)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
However if I run it from the postgre directory it works
C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre>mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building DBFit PostGreSQL engine
[INFO] task-segment: [package]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre\src\main\resources
Downloading: http://repo1.maven.org/maven2/org/fitnesse/fitlibrary/20081102/fitlibrary-20081102.pom
[INFO] Unable to find resource 'org.fitnesse:fitlibrary:pom:20081102' in repository maven-central (http://repo1.maven.org/maven2)
Downloading: http://repo1.maven.org/maven2/org/fitnesse/fitlibrary/20081102/fitlibrary-20081102.pom
[INFO] Unable to find resource 'org.fitnesse:fitlibrary:pom:20081102' in repository central (http://repo1.maven.org/maven2)
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [dbdeploy:update {execution: default}]
dbdeploy 3.0M3
Reading change scripts from directory C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre\src\test\resources...
Changes currently applied to database:
1
Scripts available:
1
To be applied:
(none)
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre\target\test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: C:\Users\Mark\Documents\GitHub\dbfit\dbfit-java\postgre\target\surefire-reports
Do you also see this behaviour or is it just me?
Allow specifying timeout for tests. (Individually; and if possible - at larger scope). I.e. something similar to JUnit's timeout https://github.com/junit-team/junit/wiki/Timeout-for-tests
The desired behaviour is the given test to be aborted if a query takes too long.
Seems like the dotnet version does support it:
https://github.com/benilovj/dbfit/blob/master/dbfit-dotnet/oracle/OracleEnvironment.cs
but the java version doesn't:
https://github.com/benilovj/dbfit/blob/master/dbfit-java/oracle/src/main/java/dbfit/environment/OracleEnvironment.java
e.g. for Oracle, if the ojdbc jar is missing, the following occurs:
java.lang.NoClassDefFoundError: oracle/sql/TIMESTAMP
at dbfit.environment.OracleEnvironment.(OracleEnvironment.java:86)
at dbfit.OracleTest.(OracleTest.java:7)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at fit.FixtureClass.newInstance(FixtureClass.java:24)
at fit.FixtureLoader.instantiateFixture(FixtureLoader.java:62)
at fit.FixtureLoader.instantiateFirstValidFixtureClass(FixtureLoader.java:84)
at fit.FixtureLoader.disgraceThenLoad(FixtureLoader.java:44)
at fit.Fixture.loadFixture(Fixture.java:141)
at fit.Fixture.getLinkedFixtureWithArgs(Fixture.java:133)
at fit.Fixture.doTables(Fixture.java:78)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
Caused by: java.lang.ClassNotFoundException: oracle.sql.TIMESTAMP
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 18 more
It might be good to have a self-test of some kind which checks the presence of the driver and falls over if it's unavailable.
Currently, as the name would suggest, DbFit only supports the Fit test system for FitNesse. This feature is about adding Slim test system (note that we don't want to drop Fit support any time soon).
The main complexity of this feature will come from having to untangle the Fit-specific table and data type parsing from the test-framework part of the DbFit core.
Another current unknown is how DbFit's flow mode will translate to Slim; flow mode makes sure that the test automatically executes in a transaction, so that the user doesn't have to worry about it.
This is a substancial piece of work to do cleanly, involving the following:
core
component (currently, there's quite tight coupling in a few places) - this is Java refactoring work.This feature will involve touching most of the core of DbFit. I would like to use this opportunity to pay back a lot of tech debt, specifically:
I would like to apply an acceptance-test-driven approach:
I'm getting this error in versions RC2 and RC3 when running an Oracle test that works fine in RC1:
dbfit.OracleTest
java.lang.NoClassDefFoundError: oracle/sql/TIMESTAMP
at dbfit.environment.OracleEnvironment.(OracleEnvironment.java:86)
at dbfit.OracleTest.(OracleTest.java:7)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at fit.FixtureClass.newInstance(FixtureClass.java:24)
at fit.FixtureLoader.instantiateFixture(FixtureLoader.java:62)
at fit.FixtureLoader.instantiateFirstValidFixtureClass(FixtureLoader.java:84)
at fit.FixtureLoader.disgraceThenLoad(FixtureLoader.java:44)
at fit.Fixture.loadFixture(Fixture.java:141)
at fit.Fixture.getLinkedFixtureWithArgs(Fixture.java:133)
at fit.Fixture.doTables(Fixture.java:78)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
Caused by: java.lang.ClassNotFoundException: oracle.sql.TIMESTAMP
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 18 more
dbfit 1.1 used to provide dbfit-java-binaries-20080822.zip binary package which easily integrates with FitLibraryWeb. Would be good to have one for 2.x too.
Users have (justifiably, IMHO), asking which is the appropriate DbFit implementation for them. This isn't really explained anywhere, as far as I can see, which I would like to correct.
I am thinking to post something along these lines:
I want to only test database code:
I want to combine database and application interaction in the same test:
I want to test databases and application code, but not in the same test:
I want to combine database and application fixtures in the same test:
cc @jediwhale @MMatten @gojko : does that look sensible? Any corrections?
Discussed (with example code) here:
Suggestions from @MMatten:
another using symbols and additional queries to avoid conflicts with existing data.
This is currently possible, but somewhat clunky (connections need to be opened and closed serially in standalone mode).
This is valuable when:
From discussion on groups.dbfit:
# Let's say t1 and t2 are different transactions/connections to db. How to declare and initiate them is out for scope for now
t1: start
t2: start
t1: |execute procedure|p1|
t1: wait
t2: |execute procedure|p1|
t2: commit
t1: continue
t1: commit
# and here we add some other tests to check if data in db looks OK. E.g. - expected balance account in a table is 110.
and
So basically, being able to name connections/transactions and being able to switch which is the active one them is the idea.
Then this could be used to test interactions/isolation/contention between multiple concurrent transactions.
I guess also for things like 2-phase commits (across different DBs).
FitLibrary has some kind of similar construct to switch between different flow mode fixtures on the page. I think it's 'select' to choose the active one.
This could all be done using stand alone mode but may be more elegant with a 'select' type of mechanism....?
The stacktrace:
java.lang.Error: java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'BY_REGION'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at dbfit.fixture.DbObjectExecutionFixture.doRows(DbObjectExecutionFixture.java:72)
at fit.Fixture.doTable(Fixture.java:154)
at fitlibrary.traverse.AlienTraverseHandler.doTable(AlienTraverseHandler.java:18)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:99)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:87)
at fitlibrary.DoFixture.interpretWholeTable(DoFixture.java:69)
at fitlibrary.suite.InFlowPageRunner.run(InFlowPageRunner.java:34)
at fitlibrary.DoFixture.interpretTables(DoFixture.java:42)
at dbfit.DatabaseTest.interpretTables(DatabaseTest.java:25)
at fit.Fixture.doTables(Fixture.java:80)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
Caused by: java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'BY_REGION'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:218)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:969)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1190)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3476)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4400)
at dbfit.fixture.DbObjectExecutionFixture.doRows(DbObjectExecutionFixture.java:59)
... 12 more
I am trying to test some tables that use a geography datatype in several columns. The first column is a simple geography column and two (latitude and longitude) are computed columns that use the .Lat and .Long functions of the geography object. I am unable to use INSERT or a simple QUERY statement in DbFit without generating errors. The QUERY statement produces this error:
System.ApplicationException: Can't parse Microsoft.SqlServer.Types.SqlGeography because it doesn't have a static Parse() method
at fit.TypeAdapter.Parse(String theInput, Type theType)
at fitnesse.handlers.AbstractCellHandler.HandleEvaluate(Fixture fixture, Parse cell, Accessor accessor)
at dbfit.AbstractDataTableFixture.FindMatchingTableRow(Parse row, DataTable table) in D:\work\dbfit\impl\dotnet\src\fixture\AbstractDataTableFixture.cs:line 77
at dbfit.AbstractDataTableFixture.DoRows(Parse rows) in D:\work\dbfit\impl\dotnet\src\fixture\AbstractDataTableFixture.cs:line 54
at fit.Fixture.DoTables(Parse theTables)
The INSERT statement produces this error:
System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
at System.Data.SqlClient.SqlBuffer.get_String()
at dbfit.SqlServerEnvironment.ReadIntoParams(String objname, String query) in D:\work\dbfit\impl\dotnet\src\environment\SqlServerEnvironment.cs:line 85
at dbfit.fixture.Insert.InitParameters(Parse headerCells) in D:\work\dbfit\impl\dotnet\src\fixture\Insert.cs:line 96
at dbfit.fixture.Insert.DoRows(Parse rows) in D:\work\dbfit\impl\dotnet\src\fixture\Insert.cs:line 48
at fit.Fixture.DoTables(Parse theTables)
I can work around the INSERT not working as I use EXECUTE with a SQL Insert statement, but I'd like to be able to use the built in DbFit Fixtures.
From #7:
"From looking at TeradataEnvironment.java it seems like it's using the wrong authorization mechanism - the default is TD and we're using LDAP. According to http://terahelp.blogspot.no/2009/08/connecting-to-database-using-teradata.html this is a simple parameter you can add to the JDBC connection string. I tried specifying the database parameter as "databasename,LOGMECH=LDAP" and then it connected perfectly."
This should be handled in code and/or documented.
Would be good if we can express tests for database calls (something like JUnit's @test (expected=...). This could be useful for many statements:
Matching exception by various attributes (error code, message, etc) would be useful so that we can clarify specifics of the expected exception. (http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html)
Right now, the barrier to contribution is too high because of setting up a VM with all the databases in it. It's possible to avoid this by having a "fast build" that:
This could also allow running the fast build on Travis CI
I see current README is still referring to 10g version of JDBC drivers.
I would suggest using latest version (currently for 11.2.0.3) - jar file name is ojdbc6.jar. The 10g one had some issue/limitation with Date fields containing non-zero time part (FAQ page as Why does DbFit not see the time portion of my Date fields?)
(The 11.2 JDBC used to work fine for me with the previous version of dbfit in a setup config as I posted on dbfit google group: https://groups.google.com/d/topic/dbfit/mHjSDTKWGcg/discussion. I haven' tried it with dbfit 2.0 though - I'll try and give a feedback here soon).
The exception:
java.lang.NullPointerException
at dbfit.api.DbTable.getDbParameterAccessor(DbTable.java:32)
at dbfit.fixture.DbObjectExecutionFixture.getAccessors(DbObjectExecutionFixture.java:87)
at dbfit.fixture.DbObjectExecutionFixture.doRows(DbObjectExecutionFixture.java:62)
at fit.Fixture.doTable(Fixture.java:154)
at fitlibrary.traverse.AlienTraverseHandler.doTable(AlienTraverseHandler.java:18)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:99)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:87)
at fitlibrary.DoFixture.interpretWholeTable(DoFixture.java:69)
at fitlibrary.suite.InFlowPageRunner.run(InFlowPageRunner.java:34)
at fitlibrary.DoFixture.interpretTables(DoFixture.java:42)
at dbfit.DatabaseTest.interpretTables(DatabaseTest.java:25)
at fit.Fixture.doTables(Fixture.java:80)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
There is STDERR output in this case:
java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1049)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1154)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3415)
at dbfit.fixture.Query.getDataTable(Query.java:42)
at dbfit.fixture.RowSetFixture.doRows(RowSetFixture.java:78)
at fit.Fixture.doTable(Fixture.java:154)
at fitlibrary.traverse.AlienTraverseHandler.doTable(AlienTraverseHandler.java:18)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:99)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:87)
at fitlibrary.DoFixture.interpretWholeTable(DoFixture.java:69)
at fitlibrary.suite.InFlowPageRunner.run(InFlowPageRunner.java:34)
at fitlibrary.DoFixture.interpretTables(DoFixture.java:42)
at dbfit.DatabaseTest.interpretTables(DatabaseTest.java:25)
at fit.Fixture.doTables(Fixture.java:80)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
I feel sometimes it's better to re-generate Cheffile.lock - so maybe it's better to move the postgresql recipe source (github) to Cheffile. (I'm not sure though - it's my first play with Chef).
It's possible to use a Teradata Express VM image to set up a test instance.
This is the first step on the way to slim support (#31).
When working through synonyms (in Oracle db) - attempt to work with them results in errors. E.g. - in following example DEMOTABLE is synonym to table in another schema:
|insert|DEMOTABLE|
|ID |STATUS|
|1 |Success|
It fails:
java.sql.SQLException: Cannot retrieve list of columns for DEMOTABLE - check spelling and access rights
at dbfit.api.DbTable.(DbTable.java:19)
at dbfit.fixture.Insert.getTargetDbObject(Insert.java:33)
at dbfit.fixture.DbObjectExecutionFixture.doRows(DbObjectExecutionFixture.java:56)
at fit.Fixture.doTable(Fixture.java:154)
at fitlibrary.traverse.AlienTraverseHandler.doTable(AlienTraverseHandler.java:18)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:99)
at fitlibrary.traverse.workflow.DoTraverseInterpreter.interpretWholeTable(DoTraverseInterpreter.java:87)
at fitlibrary.DoFixture.interpretWholeTable(DoFixture.java:69)
at fitlibrary.suite.InFlowPageRunner.run(InFlowPageRunner.java:34)
at fitlibrary.DoFixture.interpretTables(DoFixture.java:42)
at dbfit.DatabaseTest.interpretTables(DatabaseTest.java:25)
at fit.Fixture.doTables(Fixture.java:80)
at fit.FitServer.process(FitServer.java:81)
at fit.FitServer.run(FitServer.java:56)
at fit.FitServer.main(FitServer.java:41)
CompareStoredQueries
more efficient than O(nĀ²): solved in case of comparing sorted setsSince the .NET implementation is provided by fitsharp, there's little point having .NET tests there...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ššš
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ā¤ļø Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.