Пример #1
0
        public void Should_publish_pasta_price_as_soon_as_all_needed_RawMaterialMarketData_are_received()
        {
            // spaghetti(eggs-flour)
            // Prepares the marketdata mocks
            var eggsMarketDataMock = Substitute.For<IRawMaterialMarketData>();
            eggsMarketDataMock.RawMaterialName.Returns("eggs");

            var flourMarketDataMock = Substitute.For<IRawMaterialMarketData>();
            flourMarketDataMock.RawMaterialName.Returns("flour");
            
            // setup the pricing agent
            var sequencer = new Sequencer(new DirectDispatcher());
            var pricingAgent = new PastaPricingAgent(sequencer, "spaghetti");
            pricingAgent.SubscribeToMarketData(new List<IRawMaterialMarketData>() { eggsMarketDataMock, flourMarketDataMock });
            var pastaPriceHasChanged = false;
            pricingAgent.PastaPriceChanged += (o, args) => { pastaPriceHasChanged = true; };

            Check.That(pastaPriceHasChanged).IsFalse();

            // Raises event for "eggs"
            eggsMarketDataMock.PriceChanged += Raise.EventWith(new object(), new RawMaterialPriceChangedEventArgs("eggs", 0));
            Check.That(pastaPriceHasChanged).IsFalse();

            // Raises event for "flour" => all needed market data has been received, the price must have been published now
            flourMarketDataMock.PriceChanged += Raise.EventWith(new object(), new RawMaterialPriceChangedEventArgs("flour", 0));
            Check.That(pastaPriceHasChanged).IsTrue();
        }
Пример #2
0
        public void DoesNotLoseAnyTaskWithTwoWriterThreadsOnTheSameSequencer()
        {
            var rootDispatcher = new DotNetThreadPoolUnitOfExecution();
            var sequencer = new Sequencer(rootDispatcher);
            const int NumberOfWritesPerThread = 10000;
            var tasksOutput = new List<int>();

            using (var unleashThreadsEvent = new AutoResetEvent(false))
            using (var firstWriterFinishedEvent = new AutoResetEvent(false))
            using (var secondWriterFinishedEvent = new AutoResetEvent(false))
            {
                var firstWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, firstWriterFinishedEvent));
                firstWriter.Start();

                var secondWriter = new Thread(() => this.WriterRoutine(sequencer, unleashThreadsEvent, 0, NumberOfWritesPerThread, tasksOutput, secondWriterFinishedEvent));
                secondWriter.Start();

                // ready, set, mark
                unleashThreadsEvent.Set();

                // Waits until the two writers have finished their writes
                Check.That(firstWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax) && secondWriterFinishedEvent.WaitOne(2 * ThreeSecondsMax)).IsTrue();

                // Checks that no write has been missing
                Check.That(tasksOutput).HasSize(2 * NumberOfWritesPerThread);
            }
        }
Пример #3
0
        public void SequencerExecutesTasksInTheOrderOfTheirDispatch()
        {
            var rootDispatcher = new DotNetThreadPoolUnitOfExecution();
            var sequencer = new Sequencer(rootDispatcher);
            const int TasksNumber = 100000;
            var tasksOutput = new List<int>();

            using (var dispatchingFinishedEvent = new AutoResetEvent(false))
            {
                // Dispatches tasks to the sequencer
                for (int i = 0; i < TasksNumber; i++)
                {
                    int antiClosureSideEffectNumber = i;
                    sequencer.Dispatch(() => tasksOutput.Add(antiClosureSideEffectNumber));
                }

                // Indicates the end of the sequence with a final task
                sequencer.Dispatch(() => dispatchingFinishedEvent.Set());

                // Waits for sequence completion
                Check.That(dispatchingFinishedEvent.WaitOne(ThreeSecondsMax)).IsTrue();

                // Checks that everything was properly processed in sequence
                for (int k = 0; k < TasksNumber; k++)
                {
                    Check.That(tasksOutput[k]).IsEqualTo(k);
                }
            }
        }
Пример #4
0
        public void Should_Compute_expected_price_from_known_market_data_inputs()
        {
            // Check.That(pastaCalculator.Compute(flourPrice: 1.3m, eggsPrice: 2.4m, flavorPrice: 1.2m)).IsEqualTo(2.52m);

            // spaghetti(eggs-flour)
            // Prepares the marketdata mocks
            var eggsMarketDataMock = Substitute.For<IRawMaterialMarketData>();
            eggsMarketDataMock.RawMaterialName.Returns("eggs");

            var flourMarketDataMock = Substitute.For<IRawMaterialMarketData>();
            flourMarketDataMock.RawMaterialName.Returns("flour");
            
            var tomatoMarketDataMock = Substitute.For<IRawMaterialMarketData>();
            tomatoMarketDataMock.RawMaterialName.Returns("tomato");

            // setup the pricing agent
            var sequencer = new Sequencer(new DirectDispatcher());
            var pricingAgent = new PastaPricingAgent(sequencer, "tomato spaghetti");
            pricingAgent.SubscribeToMarketData(new List<IRawMaterialMarketData>() { eggsMarketDataMock, flourMarketDataMock, tomatoMarketDataMock });
            var publishedPastaPrice = 0m;
            pricingAgent.PastaPriceChanged += (o, args) => { publishedPastaPrice = args.Price; };

            Check.That(publishedPastaPrice).IsEqualTo(0);

            // Raises event for "eggs"
            eggsMarketDataMock.PriceChanged += Raise.EventWith(new object(), new RawMaterialPriceChangedEventArgs("eggs", 2.4m));
            Check.That(publishedPastaPrice).IsEqualTo(0);

            // Raises event for "tomato"
            tomatoMarketDataMock.PriceChanged += Raise.EventWith(new object(), new RawMaterialPriceChangedEventArgs("tomato", 1.2m));
            Check.That(publishedPastaPrice).IsEqualTo(0);

            // Raises event for "flour" => all needed market data has been received, the price must have been published now
            flourMarketDataMock.PriceChanged += Raise.EventWith(new object(), new RawMaterialPriceChangedEventArgs("flour", 1.3m));

            const decimal ExpectedPastaPrice = 2.52m;
            Check.That(publishedPastaPrice).IsEqualTo(ExpectedPastaPrice);
        }
Пример #5
0
        private void WriterRoutine(Sequencer sequencer, AutoResetEvent readySetMarkEvent, int firstIndex, int lastIndex, List<int> tasksOutput, AutoResetEvent lastTaskEvent)
        {
            readySetMarkEvent.WaitOne(ThreeSecondsMax);

            for (int i = firstIndex; i < lastIndex; i++)
            {
                int antiClosureSideEffectNumber = i;
                sequencer.Dispatch(() => tasksOutput.Add(antiClosureSideEffectNumber));
            }

            // Indicates the end of the sequence with a final task
            sequencer.Dispatch(() => lastTaskEvent.Set());
        }