<commit_before>﻿//-----------------------------------------------------------------------
// <copyright file="BitcoinDatabaseGeneratorTest.cs">
// Copyright © <NAME>. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace BitcoinDatabaseGeneratorIntegrationTest.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using BitcoinBlockchain.Data;
    using BitcoinDatabaseGenerator;
    using BitcoinDatabaseGeneratorIntegrationTest.Helpers;
    using BitcoinDataLayerAdoNet;
    using BitcoinDataLayerAdoNet.DataSets;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class BitcoinDatabaseGeneratorTest
    {
        [TestMethod]
        public async Task SimpleCaseTest()
        {
            FakeDatabaseGeneratorParameters parameters = new FakeDatabaseGeneratorParameters(true, FakeDatabaseGeneratorParameters.AutoThreads);
            DatabaseConnection databaseConnection = DatabaseConnection.CreateLocalDbConnection(parameters.DatabaseName);

            DatabaseGenerator databaseGenerator = new DatabaseGenerator(
                parameters,
                databaseConnection,
                () => new FakeBlockchainParser(this.GetBlocksForSimpleScenario()));

            await databaseGenerator.GenerateAndPopulateDatabase();

            using (BitcoinDataLayer bitcoinDataLayer = new BitcoinDataLayer(databaseConnection.ConnectionString))
            {
                // ValidationBlockchainDataSet will give us the aggregate values per the entire blockchain.
                ValidationBlockchainDataSet validationBlockchainDataSet = bitcoinDataLayer.GetValidationBlockchainDataSet(100);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain.Count);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].BlockCount);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionCount);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionInputCount);
                Assert.AreEqual(50, validationBlockchainDataSet.ValidationBlockchain[0].TotalInputBtc);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionOutputCount);
                Assert.AreEqual(99, validationBlockchainDataSet.ValidationBlockchain[0].TotalOutputBtc);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain[0].TransactionFeeBtc);
                Assert.AreEqual(49, validationBlockchainDataSet.ValidationBlockchain[0].TotalUnspentOutputBtc);

                // @@@ Implement these.
                // bitcoinDataLayer.GetValidationBlockFilesDataSet(100);
                // bitcoinDataLayer.GetValidationBlockSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionInputSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionOutputSampleDataSet(100, 1);
            }
        }

        /// <summary>
        /// Simulates a case where there are two transactions with the same transaction hash value.
        /// The first transaction becomes is spent and then the second transaction with the same hash
        /// is placed in the blockchain and spent.
        /// The test makes sure that transaction inputs that refers to the duplicated hash will point
        /// to the correct output of the correct transaction.
        /// </summary>
        [TestMethod]
        public async Task DuplicateTransactionHashTest()
        {
            ByteArray duplicateTransactionHash = SampleByteArray.GetSampleByteArray(100);

            FakeDatabaseGeneratorParameters parameters = new FakeDatabaseGeneratorParameters(true, 1);
            DatabaseConnection databaseConnection = DatabaseConnection.CreateLocalDbConnection(parameters.DatabaseName);

            DatabaseGenerator databaseGenerator = new DatabaseGenerator(
                parameters,
                databaseConnection,
                () => new FakeBlockchainParser(this.GetBlocksForDuplicateTransactionHashScenario(duplicateTransactionHash)));

            await databaseGenerator.GenerateAndPopulateDatabase();

            using (BitcoinDataLayer bitcoinDataLayer = new BitcoinDataLayer(databaseConnection.ConnectionString))
            {
                // ValidationBlockchainDataSet will give us the aggregate values per the entire blockchain.
                ValidationBlockchainDataSet validationBlockchainDataSet = bitcoinDataLayer.GetValidationBlockchainDataSet(100);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain.Count);

                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].BlockCount);
                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].TransactionCount);
                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].TransactionInputCount);
                Assert.AreEqual(29, validationBlockchainDataSet.ValidationBlockchain[0].TotalInputBtc);
                Assert.AreEqual(8, validationBlockchainDataSet.ValidationBlockchain[0].TransactionOutputCount);
                Assert.AreEqual(49, validationBlockchainDataSet.ValidationBlockchain[0].TotalOutputBtc);
                Assert.AreEqual(0, validationBlockchainDataSet.ValidationBlockchain[0].TransactionFeeBtc);
                Assert.AreEqual(21, validationBlockchainDataSet.ValidationBlockchain[0].TotalUnspentOutputBtc);

                // ValidationBlockFilesDataSet will give us the aggregate values per block files. 
                // In this setup we have one block per block file. 
                ValidationBlockFilesDataSet validationBlockFilesDataSet = bitcoinDataLayer.GetValidationBlockFilesDataSet(100);
                Assert.AreEqual(6, validationBlockFilesDataSet.ValidationBlockFiles.Count);

                ValidationBlockFilesDataSet.ValidationBlockFilesRow blockFile0 = validationBlockFilesDataSet.ValidationBlockFiles[0];
                Assert.AreEqual(0, blockFile0.BlockFileId);
                Assert.AreEqual("blk00000.dat", blockFile0.FileName);
                Assert.AreEqual(1, blockFile0.BlockCount);
                Assert.AreEqual(1, blockFile0.TransactionCount);
                Assert.AreEqual(1, blockFile0.TransactionInputCount);
                Assert.AreEqual(true, blockFile0.IsTotalInputBtcNull());
                Assert.AreEqual(1, blockFile0.TransactionOutputCount);
                Assert.AreEqual(10, blockFile0.TotalOutputBtc);
                Assert.AreEqual(0, blockFile0.TransactionFeeBtc);
                Assert.AreEqual(7, blockFile0.TotalUnspentOutputBtc);
<commit_msg>Fix bugs in a test automation method.<commit_after>﻿//-----------------------------------------------------------------------
// <copyright file="BitcoinDatabaseGeneratorTest.cs">
// Copyright © <NAME>. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace BitcoinDatabaseGeneratorIntegrationTest.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using BitcoinBlockchain.Data;
    using BitcoinDatabaseGenerator;
    using BitcoinDatabaseGeneratorIntegrationTest.Helpers;
    using BitcoinDataLayerAdoNet;
    using BitcoinDataLayerAdoNet.DataSets;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class BitcoinDatabaseGeneratorTest
    {
        [TestMethod]
        public async Task SimpleCaseTest()
        {
            FakeDatabaseGeneratorParameters parameters = new FakeDatabaseGeneratorParameters(true, FakeDatabaseGeneratorParameters.AutoThreads);
            DatabaseConnection databaseConnection = DatabaseConnection.CreateLocalDbConnection(parameters.DatabaseName);

            DatabaseGenerator databaseGenerator = new DatabaseGenerator(
                parameters,
                databaseConnection,
                () => new FakeBlockchainParser(this.GetBlocksForSimpleScenario()));

            await databaseGenerator.GenerateAndPopulateDatabase();

            using (BitcoinDataLayer bitcoinDataLayer = new BitcoinDataLayer(databaseConnection.ConnectionString))
            {
                // ValidationBlockchainDataSet will give us the aggregate values per the entire blockchain.
                ValidationBlockchainDataSet validationBlockchainDataSet = bitcoinDataLayer.GetValidationBlockchainDataSet(100);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain.Count);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].BlockCount);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionCount);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionInputCount);
                Assert.AreEqual(50, validationBlockchainDataSet.ValidationBlockchain[0].TotalInputBtc);
                Assert.AreEqual(2, validationBlockchainDataSet.ValidationBlockchain[0].TransactionOutputCount);
                Assert.AreEqual(99, validationBlockchainDataSet.ValidationBlockchain[0].TotalOutputBtc);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain[0].TransactionFeeBtc);
                Assert.AreEqual(49, validationBlockchainDataSet.ValidationBlockchain[0].TotalUnspentOutputBtc);

                // @@@ Implement these.
                // bitcoinDataLayer.GetValidationBlockFilesDataSet(100);
                // bitcoinDataLayer.GetValidationBlockSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionInputSampleDataSet(100, 1);
                // bitcoinDataLayer.GetValidationTransactionOutputSampleDataSet(100, 1);
            }
        }

        /// <summary>
        /// Simulates a case where there are two transactions with the same transaction hash value.
        /// The first transaction becomes is spent and then the second transaction with the same hash
        /// is placed in the blockchain and spent.
        /// The test makes sure that transaction inputs that refers to the duplicated hash will point
        /// to the correct output of the correct transaction.
        /// </summary>
        [TestMethod]
        public async Task DuplicateTransactionHashTest()
        {
            ByteArray duplicateTransactionHash = SampleByteArray.GetSampleByteArray(100);

            FakeDatabaseGeneratorParameters parameters = new FakeDatabaseGeneratorParameters(true, 1);
            DatabaseConnection databaseConnection = DatabaseConnection.CreateLocalDbConnection(parameters.DatabaseName);

            DatabaseGenerator databaseGenerator = new DatabaseGenerator(
                parameters,
                databaseConnection,
                () => new FakeBlockchainParser(this.GetBlocksForDuplicateTransactionHashScenario(duplicateTransactionHash)));

            await databaseGenerator.GenerateAndPopulateDatabase();

            using (BitcoinDataLayer bitcoinDataLayer = new BitcoinDataLayer(databaseConnection.ConnectionString))
            {
                // ValidationBlockchainDataSet will give us the aggregate values per the entire blockchain.
                ValidationBlockchainDataSet validationBlockchainDataSet = bitcoinDataLayer.GetValidationBlockchainDataSet(100);
                Assert.AreEqual(1, validationBlockchainDataSet.ValidationBlockchain.Count);

                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].BlockCount);
                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].TransactionCount);
                Assert.AreEqual(6, validationBlockchainDataSet.ValidationBlockchain[0].TransactionInputCount);
                Assert.AreEqual(29, validationBlockchainDataSet.ValidationBlockchain[0].TotalInputBtc);
                Assert.AreEqual(8, validationBlockchainDataSet.ValidationBlockchain[0].TransactionOutputCount);
                Assert.AreEqual(49, validationBlockchainDataSet.ValidationBlockchain[0].TotalOutputBtc);
                Assert.AreEqual(0, validationBlockchainDataSet.ValidationBlockchain[0].TransactionFeeBtc);
                Assert.AreEqual(20, validationBlockchainDataSet.ValidationBlockchain[0].TotalUnspentOutputBtc);

                // ValidationBlockFilesDataSet will give us the aggregate values per block files. 
                // In this setup we have one block per block file. 
                ValidationBlockFilesDataSet validationBlockFilesDataSet = bitcoinDataLayer.GetValidationBlockFilesDataSet(100);
                Assert.AreEqual(6, validationBlockFilesDataSet.ValidationBlockFiles.Count);

                ValidationBlockFilesDataSet.ValidationBlockFilesRow blockFile0 = validationBlockFilesDataSet.ValidationBlockFiles[0];
                Assert.AreEqual(0, blockFile0.BlockFileId);
                Assert.AreEqual("blk00000.dat", blockFile0.FileName);
                Assert.AreEqual(1, blockFile0.BlockCount);
                Assert.AreEqual(1, blockFile0.TransactionCount);
                Assert.AreEqual(1, blockFile0.TransactionInputCount);
                Assert.AreEqual(true, blockFile0.IsTotalInputBtcNull());
                Assert.AreEqual(1, blockFile0.TransactionOutputCount);
                Assert.AreEqual(10, blockFile0.TotalOutputBtc);
                Assert.AreEqual(0, blockFile0.TransactionFeeBtc);
                Assert.AreEqual(0, blockFile0.TotalUnspentOutputBtc);

{'fraction_non_alphanumeric': 0.089572773352643, 'fraction_numerical': 0.014337436640115858, 'mean_word_length': 2.894811054709532, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1094151', 'n_tokens_mistral': 3164, 'n_tokens_neox': 3004, 'n_words': 560}