Skip to content
This repository has been archived by the owner on Aug 16, 2021. It is now read-only.

Commit

Permalink
Merge pull request #173 from Neurosploit/xunittovisualstudioframework
Browse files Browse the repository at this point in the history
Move from xUnit to MsTest
  • Loading branch information
bokobza authored Jun 20, 2017
2 parents 89446ee + 2a85aef commit cd809fc
Show file tree
Hide file tree
Showing 71 changed files with 1,684 additions and 1,707 deletions.
17 changes: 14 additions & 3 deletions Documentation/testing-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Test Guidelines

Unit Testing
------------
For unit testing we use Xunit and Moq.
For unit testing we use the Visual Studio Unit Testing Framework and Moq.

Unit test preparations
1. If a class contains multiple classes try to see if you can move them to separate files inside the same folder. Ideally we have 1 file per class.
Expand Down Expand Up @@ -71,9 +71,20 @@ General testing rules:
}
}

[TestClass]
public class BaseRepositoryTest
{
[Fact]
[TestInitialize]
public void Initialize() {
// optional: initialize code that has to be run before each test.
}

[TestCleanup]
public void Cleanup() {
// optional: cleanup the initialized code after each test has run.
}

[TestMethod]
public void GetContextReturnsContext()
{
var connection = new DbConnection();
Expand All @@ -84,7 +95,7 @@ General testing rules:
var repository = new BaseRepositoryStub(dbConnectionMock.Object);
var result = repository.GetContext();

Assert.Equal(connection, result);
Assert.AreEqual(connection, result);
}

private class BaseRepositoryStub : BaseRepository
Expand Down
24 changes: 24 additions & 0 deletions Stratis.Bitcoin.IntegrationTests/AssemblyInitialize.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ο»Ώusing Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NBitcoin;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Stratis.Bitcoin.IntegrationTests
{
public static class AssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize()
{
Logs.Configure(new LoggerFactory().AddConsole(LogLevel.Trace, false));
}
}
}
35 changes: 18 additions & 17 deletions Stratis.Bitcoin.IntegrationTests/BlockStoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.MemoryPool;
using Xunit;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Stratis.Bitcoin.IntegrationTests
{
[TestClass]
public class BlockStoreTests
{

//[Fact]
//[TestMethod]
public void BlockRepositoryBench()
{
using (var dir = TestDirectory.Create())
Expand Down Expand Up @@ -65,7 +66,7 @@ public void BlockRepositoryBench()
}
}

[Fact]
[TestMethod]
public void BlockRepositoryPutBatch()
{
using (var dir = TestDirectory.Create())
Expand Down Expand Up @@ -96,24 +97,24 @@ public void BlockRepositoryPutBatch()
foreach (var block in lst)
{
var received = blockRepo.GetAsync(block.GetHash()).GetAwaiter().GetResult();
Assert.True(block.ToBytes().SequenceEqual(received.ToBytes()));
Assert.IsTrue(block.ToBytes().SequenceEqual(received.ToBytes()));

foreach (var transaction in block.Transactions)
{
var trx = blockRepo.GetTrxAsync(transaction.GetHash()).GetAwaiter().GetResult();
Assert.True(trx.ToBytes().SequenceEqual(transaction.ToBytes()));
Assert.IsTrue(trx.ToBytes().SequenceEqual(transaction.ToBytes()));
}
}

// delete
blockRepo.DeleteAsync(lst.ElementAt(2).GetHash(), new[] {lst.ElementAt(2).GetHash()}.ToList());
var deleted = blockRepo.GetAsync(lst.ElementAt(2).GetHash()).GetAwaiter().GetResult();
Assert.Null(deleted);
Assert.IsNull(deleted);
}
}
}

[Fact]
[TestMethod]
public void BlockRepositoryBlockHash()
{
using (var dir = TestDirectory.Create())
Expand All @@ -122,15 +123,15 @@ public void BlockRepositoryBlockHash()
{
blockRepo.Initialize().GetAwaiter().GetResult();

Assert.Equal(Network.Main.GenesisHash, blockRepo.BlockHash);
Assert.AreEqual(Network.Main.GenesisHash, blockRepo.BlockHash);
var hash = new Block().GetHash();
blockRepo.SetBlockHash(hash).GetAwaiter().GetResult();
Assert.Equal(hash, blockRepo.BlockHash);
Assert.AreEqual(hash, blockRepo.BlockHash);
}
}
}

[Fact]
[TestMethod]
public void BlockBroadcastInv()
{
using (NodeBuilder builder = NodeBuilder.Create())
Expand Down Expand Up @@ -172,7 +173,7 @@ public void BlockBroadcastInv()
}
}

[Fact]
[TestMethod]
public void BlockStoreCanRecoverOnStartup()
{
using (NodeBuilder builder = NodeBuilder.Create())
Expand All @@ -199,12 +200,12 @@ public void BlockStoreCanRecoverOnStartup()
newNodeInstance.Start();

// check that store recovered to be the same as the best chain.
Assert.Equal(newNodeInstance.FullNode.Chain.Tip.HashBlock, newNodeInstance.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock);
Assert.AreEqual(newNodeInstance.FullNode.Chain.Tip.HashBlock, newNodeInstance.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock);
//TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisNodeSync));
}
}

[Fact]
[TestMethod]
public void BlockStoreCanReorg()
{
using (NodeBuilder builder = NodeBuilder.Create())
Expand Down Expand Up @@ -255,7 +256,7 @@ public void BlockStoreCanReorg()
}
}

[Fact]
[TestMethod]
public void BlockStoreIndexTx()
{
using (NodeBuilder builder = NodeBuilder.Create())
Expand All @@ -276,12 +277,12 @@ public void BlockStoreIndexTx()
TestHelper.WaitLoop(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNode2.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock);

var bestBlock1 = stratisNode1.FullNode.BlockStoreManager.BlockRepository.GetAsync(stratisNode1.FullNode.Chain.Tip.HashBlock).Result;
Assert.NotNull(bestBlock1);
Assert.IsNotNull(bestBlock1);

// get the block coinbase trx
var trx = stratisNode2.FullNode.BlockStoreManager.BlockRepository.GetTrxAsync(bestBlock1.Transactions.First().GetHash()).Result;
Assert.NotNull(trx);
Assert.Equal(bestBlock1.Transactions.First().GetHash(), trx.GetHash());
Assert.IsNotNull(trx);
Assert.AreEqual(bestBlock1.Transactions.First().GetHash(), trx.GetHash());
}
}
}
Expand Down
42 changes: 21 additions & 21 deletions Stratis.Bitcoin.IntegrationTests/ChainBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ public class ChainBuilder
public ChainBuilder(Network network)
{
Guard.NotNull(network, nameof(network));
_Network = network;
_Chain = new ConcurrentChain(_Network);
MinerKey = new Key();
MinerScriptPubKey = MinerKey.PubKey.Hash.ScriptPubKey;

this._Network = network;
this._Chain = new ConcurrentChain(this._Network);
this.MinerKey = new Key();
this.MinerScriptPubKey = this.MinerKey.PubKey.Hash.ScriptPubKey;
}

public ConcurrentChain Chain
{
get
{
return _Chain;
return this._Chain;
}
}

Expand All @@ -47,24 +47,24 @@ public Transaction Spend(ICoin[] coins, Money amount)
{
TransactionBuilder builder = new TransactionBuilder();
builder.AddCoins(coins);
builder.AddKeys(MinerKey);
builder.Send(MinerScriptPubKey, amount);
builder.AddKeys(this.MinerKey);
builder.Send(this.MinerScriptPubKey, amount);
builder.SendFees(Money.Coins(0.01m));
builder.SetChange(MinerScriptPubKey);
builder.SetChange(this.MinerScriptPubKey);
var tx = builder.BuildTransaction(true);
return tx;
}

public ICoin[] GetSpendableCoins()
{
return _Blocks
return this._Blocks
.Select(b => b.Value)
.SelectMany(b => b.Transactions.Select(t => new
{
Tx = t,
Block = b
}))
.Where(b => !b.Tx.IsCoinBase || (_Chain.Height + 1) - _Chain.GetBlock(b.Block.GetHash()).Height >= 100)
.Where(b => !b.Tx.IsCoinBase || (this._Chain.Height + 1) - this._Chain.GetBlock(b.Block.GetHash()).Height >= 100)
.Select(b => b.Tx)
.SelectMany(b => b.Outputs.AsIndexedOutputs())
.Where(o => o.TxOut.ScriptPubKey == this.MinerScriptPubKey)
Expand All @@ -80,14 +80,14 @@ public void Mine(int blockCount)
{
uint nonce = 0;
Block block = new Block();
block.Header.HashPrevBlock = _Chain.Tip.HashBlock;
block.Header.Bits = block.Header.GetWorkRequired(_Network, _Chain.Tip);
block.Header.UpdateTime(now, _Network, _Chain.Tip);
block.Header.HashPrevBlock = this._Chain.Tip.HashBlock;
block.Header.Bits = block.Header.GetWorkRequired(this._Network, this._Chain.Tip);
block.Header.UpdateTime(now, this._Network, this._Chain.Tip);
var coinbase = new Transaction();
coinbase.AddInput(TxIn.CreateCoinbase(_Chain.Height + 1));
coinbase.AddOutput(new TxOut(_Network.GetReward(_Chain.Height + 1), MinerScriptPubKey));
coinbase.AddInput(TxIn.CreateCoinbase(this._Chain.Height + 1));
coinbase.AddOutput(new TxOut(this._Network.GetReward(this._Chain.Height + 1), this.MinerScriptPubKey));
block.AddTransaction(coinbase);
foreach(var tx in _Transactions)
foreach(var tx in this._Transactions)
{
block.AddTransaction(tx);
}
Expand All @@ -96,21 +96,21 @@ public void Mine(int blockCount)
block.Header.Nonce = ++nonce;
block.Header.CacheHashes();
blocks.Add(block);
_Transactions.Clear();
_Chain.SetTip(block.Header);
this._Transactions.Clear();
this._Chain.SetTip(block.Header);
}

foreach(var b in blocks)
{
_Blocks.Add(b.GetHash(), b);
this._Blocks.Add(b.GetHash(), b);
}
}

internal Dictionary<uint256, Block> _Blocks = new Dictionary<uint256, Block>();
private List<Transaction> _Transactions = new List<Transaction>();
public void Broadcast(Transaction tx)
{
_Transactions.Add(tx);
this._Transactions.Add(tx);
}
}
}
26 changes: 13 additions & 13 deletions Stratis.Bitcoin.IntegrationTests/CoinViewTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class SpendableCoin
public CoinViewTester(CoinView coinView)
{
this.coinView = coinView;
_Hash = coinView.GetBlockHashAsync().Result;
this._Hash = coinView.GetBlockHashAsync().Result;
}

List<UnspentOutputs> _PendingCoins = new List<UnspentOutputs>();
Expand All @@ -28,14 +28,14 @@ public Coin[] CreateCoins(int coinCount)
.Select(t => new TxOut(Money.Zero, new Key()))
.ToArray());
var output = new UnspentOutputs(1, tx);
_PendingCoins.Add(output);
this._PendingCoins.Add(output);
return tx.Outputs.AsCoins().ToArray();
}

public bool Exists(Coin c)
{
var result = coinView.FetchCoinsAsync(new[] { c.Outpoint.Hash }).Result;
if(result.BlockHash != _Hash)
var result = this.coinView.FetchCoinsAsync(new[] { c.Outpoint.Hash }).Result;
if(result.BlockHash != this._Hash)
throw new InvalidOperationException("Unexepected hash");
if(result.UnspentOutputs[0] == null)
return false;
Expand All @@ -44,18 +44,18 @@ public bool Exists(Coin c)

public void Spend(Coin c)
{
var coin = _PendingCoins.FirstOrDefault(u => u.TransactionId == c.Outpoint.Hash);
var coin = this._PendingCoins.FirstOrDefault(u => u.TransactionId == c.Outpoint.Hash);
if(coin == null)
{
var result = coinView.FetchCoinsAsync(new[] { c.Outpoint.Hash }).Result;
if(result.BlockHash != _Hash)
var result = this.coinView.FetchCoinsAsync(new[] { c.Outpoint.Hash }).Result;
if(result.BlockHash != this._Hash)
throw new InvalidOperationException("Unexepected hash");
if(result.UnspentOutputs[0] == null)
throw new InvalidOperationException("Coin unavailable");

if(!result.UnspentOutputs[0].Spend(c.Outpoint.N))
throw new InvalidOperationException("Coin unspendable");
_PendingCoins.Add(result.UnspentOutputs[0]);
this._PendingCoins.Add(result.UnspentOutputs[0]);
}
else
{
Expand All @@ -68,16 +68,16 @@ public void Spend(Coin c)
public uint256 NewBlock()
{
var newHash = new uint256(RandomUtils.GetBytes(32));
coinView.SaveChangesAsync(_PendingCoins, null, _Hash, newHash).Wait();
_PendingCoins.Clear();
_Hash = newHash;
this.coinView.SaveChangesAsync(this._PendingCoins, null, this._Hash, newHash).Wait();
this._PendingCoins.Clear();
this._Hash = newHash;
return newHash;
}

public uint256 Rewind()
{
_Hash = coinView.Rewind().Result;
return _Hash;
this._Hash = this.coinView.Rewind().Result;
return this._Hash;
}
}
}
Loading

8 comments on commit cd809fc

@detroitpro
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um....why?

Is there an open issue that I could read that talks about such a change? Seems like a really big change and moving towards VSTest is not how we often seen OSS projects move.

Does this allow more a more inclusive ecosystem? Does VSTest work with VSCode?

@dangershony
Copy link
Contributor

@dangershony dangershony commented on cd809fc Jun 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems yes MSTest can run on VSCode dotnet/vscode-csharp#1482
I wasn't aware this will be an issue OSS is full of surprises, I am ready to role this back if we can agree with @Neurosploit and @bokobza
XUint was giving me trouble with the integration tests (so perhaps giving MSTest a try is worth a shot)

@Neurosploit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware of this either. If you run into major issues roll it back.

@detroitpro
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only real problem will be that VSTest will hurt adoption. I can't think of a single OSS project that would move towards VSTest.

Even ASP.NET MVC uses xunit.
https://github.com/aspnet/Mvc/blob/dev/test/Microsoft.AspNetCore.Mvc.Test/Microsoft.AspNetCore.Mvc.Test.csproj

@detroitpro
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to being OSS and getting some traction. πŸ‘

@dangershony
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha yeah, I have a feeling I will never go back.. πŸ‘

@dangershony
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After digging around it seems fairly easy to switch back, so @Neurosploit will have a look at nunit as well and we then decide.
It seems many people agree xunit and nunit are more extendable then mstest.

@Neurosploit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@detroitpro I have reverted this change see #179

Please sign in to comment.