public void ScpShallComposeSingleJobFromMultipleAssociations()
        {
            var testCase              = "3-single-study-multi-series";
            var jobs                  = new List <Job>();
            var jobCreatedEvent       = new CountdownEvent(1);
            var instanceStoredCounter = new MockedStoredInstanceObserver();

            _dicomAdapterFixture.GetIInstanceStoredNotificationService().Subscribe(instanceStoredCounter);

            _dicomAdapterFixture.Jobs.Setup(p => p.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <JobPriority>(), It.IsAny <IDictionary <string, string> >()))
            .Callback((string pipelineId, string jobName, JobPriority jobPriority, IDictionary <string, string> metadata) =>
            {
                Console.WriteLine(">>>>> Job.Create {0} - {1} - {2}", pipelineId, jobName, jobPriority);
                jobCreatedEvent.Signal();
            })
            .Returns((string pipelineId, string jobName, JobPriority jobPriority, IDictionary <string, string> metadata) => Task.FromResult(new Job
            {
                JobId     = Guid.NewGuid().ToString(),
                PayloadId = Guid.NewGuid().ToString()
            }));

            var outputs   = new List <StringBuilder>();
            var processes = new List <Tuple <Process, ManualResetEvent> >();
            var paths     = new List <string>();

            var rootPath = Path.Combine(TestFileSetsFixture.ApplicationEntryDirectory, testCase);

            for (var i = 0; i < 5; i++)
            {
                var path = Path.Combine(rootPath, i.ToString());
                paths.Add(path);
                var output1 = new StringBuilder();
                var proc1   = DcmtkLauncher.StoreScuNoWait(path, $"-xb", $"-v -aet PACS1 -aec {DicomAdapterFixture.AET_CLARA1}", output1);
                outputs.Add(output1);
                processes.Add(proc1);
            }

            var totalInstanceSent = 0;

            for (var i = 0; i < processes.Count; i++)
            {
                processes[i].Item1.WaitForExit();
                processes[i].Item2.WaitOne(3000);
                Console.WriteLine(">>>>> Association #{0}", i);
                if (processes[i].Item1.ExitCode != 0)
                {
                    Console.WriteLine(">>>>> {0}", outputs[i].ToString());
                }
                Assert.Equal(0, processes[i].Item1.ExitCode);
                // Console.WriteLine(outputs[i].ToString());

                // make sure we are sending correct number of files
                var instanceSent = Directory.GetFiles(paths[i]).Count();
                totalInstanceSent += instanceSent;
                Thread.Sleep(750);
                var receivedStoreCount = outputs[i].ToString().Split(Environment.NewLine)
                                         .Count(p => p.Contains("I: Received Store Response (Success)"));

                var sendingStoreCount = outputs[i].ToString().Split(Environment.NewLine)
                                        .Count(p => p.Contains("I: Sending Store Request"));

                // Since receivedStoreCount can sometime be off by 1, we'll relax the check here
                Assert.InRange(receivedStoreCount + sendingStoreCount, instanceSent * 2 - 1, instanceSent * 2);
            }
            Assert.True(jobCreatedEvent.Wait(TimeSpan.FromSeconds(30)));
            Assert.Equal(totalInstanceSent, instanceStoredCounter.InstanceCount);
        }
        public void ScpShallAcceptMultipleAssociationsOverMultipleAetitles()
        {
            var testCase = "2-2-patients-2-studies";
            // Clara1 with 4 studies launched
            // Clara2 with 2 patients * 2 pipelines launched
            var jobCreatedEvent       = new CountdownEvent(8);
            var jobs                  = new List <Job>();
            var instanceStoredCounter = new MockedStoredInstanceObserver();

            _dicomAdapterFixture.GetIInstanceStoredNotificationService().Subscribe(instanceStoredCounter);

            _dicomAdapterFixture.Jobs.Setup(p => p.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <JobPriority>(), It.IsAny <IDictionary <string, string> >()))
            .Callback((string pipelineId, string jobName, JobPriority jobPriority, IDictionary <string, string> metadata) =>
            {
                jobCreatedEvent.Signal();
                Console.WriteLine(">>>>> Job.Create {0} - {1} - {2}", pipelineId, jobName, jobPriority);
            })
            .Returns((string pipelineId, string jobName, JobPriority jobPriority, IDictionary <string, string> metadata) => Task.FromResult(new Job
            {
                JobId     = Guid.NewGuid().ToString(),
                PayloadId = Guid.NewGuid().ToString()
            }));

            var outputs   = new List <StringBuilder>();
            var processes = new List <Tuple <Process, ManualResetEvent> >();
            var paths     = new List <string>();

            var rootPath = Path.Combine(TestFileSetsFixture.ApplicationEntryDirectory, testCase);

            foreach (var patient in new[] { "P0", "P1" })
            {
                foreach (var study in new[] { "S0", "S1" })
                {
                    var path = Path.Combine(rootPath, patient, study);
                    paths.Add(path);
                    paths.Add(path);

                    var output1 = new StringBuilder();
                    var proc1   = DcmtkLauncher.StoreScuNoWait(path, $"-xb", $"-v -aet PACS1 -aec {DicomAdapterFixture.AET_CLARA1}", output1);
                    outputs.Add(output1);
                    processes.Add(proc1);

                    var output2 = new StringBuilder();
                    var proc2   = DcmtkLauncher.StoreScuNoWait(path, $"-xb", $"-v -aet PACS1 -aec {DicomAdapterFixture.AET_CLARA2}", output2);
                    outputs.Add(output2);
                    processes.Add(proc2);
                }
            }

            int totalInstanceSent = 0;
            int threadSleep       = 2000;

            for (var i = 0; i < processes.Count; i++)
            {
                processes[i].Item1.WaitForExit();
                processes[i].Item2.WaitOne(3000);
                Console.WriteLine(">>>>> Association #{0}", i);
                // if (processes[i].ExitCode != 0)
                //     Console.WriteLine(">>>>> {0}", outputs[i].ToString());
                Assert.Equal(0, processes[i].Item1.ExitCode);
                // Console.WriteLine(outputs[i].ToString());

                // make sure we are sending correct number of files
                var instanceSent = Directory.GetFiles(paths[i]).Count();
                totalInstanceSent += instanceSent;
                Thread.Sleep(threadSleep);
                outputs[i].ToString().Split(Environment.NewLine)
                .Where(p => p.Contains("I: Received Store Response (Success)"))
                .Should()
                .HaveCount(instanceSent, outputs[i].ToString());
                threadSleep -= 125;
            }
            Assert.True(jobCreatedEvent.Wait(TimeSpan.FromSeconds(60)));
            Assert.Equal(totalInstanceSent, instanceStoredCounter.InstanceCount);
        }
        public void ScpShallComposeSingleJobFromMultipleAssociations()
        {
            var testCase              = "3-single-study-multi-series";
            var jobs                  = new List <Job>();
            var jobCreatedEvent       = new CountdownEvent(1);
            var jobStoredEvent        = new CountdownEvent(1);
            var instanceStoredCounter = new MockedStoredInstanceObserver();
            var jobStoreInstanceCount = 0;

            _dicomAdapterFixture.GetIInstanceStoredNotificationService().Subscribe(instanceStoredCounter);

            _dicomAdapterFixture.Jobs.Setup(p => p.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <JobPriority>()))
            .Callback((string pipelineId, string jobName, JobPriority jobPriority) =>
            {
                Console.WriteLine(">>>>> Job.Create {0} - {1} - {2}", pipelineId, jobName, jobPriority);
                jobCreatedEvent.Signal();
            })
            .Returns((string pipelineId, string jobName, JobPriority jobPriority) => Task.FromResult(new Job
            {
                JobId     = Guid.NewGuid().ToString(),
                PayloadId = Guid.NewGuid().ToString()
            }));

            _dicomAdapterFixture.JobStore.Setup(p => p.Add(It.IsAny <Job>(), It.IsAny <string>(), It.IsAny <IList <InstanceStorageInfo> >()))
            .Callback((Job job, string jobName, IList <InstanceStorageInfo> instances) =>
            {
                jobStoredEvent.Signal();
                jobStoreInstanceCount = instances.Count();
            });

            var outputs   = new List <StringBuilder>();
            var processes = new List <Process>();
            var paths     = new List <string>();

            var rootPath = Path.Combine(TestFileSetsFixture.ApplicationEntryDirectory, testCase);

            for (var i = 0; i < 5; i++)
            {
                var path = Path.Combine(rootPath, i.ToString());
                paths.Add(path);
                var output1 = new StringBuilder();
                var proc1   = DcmtkLauncher.StoreScuNoWait(path, $"-xb", $"-v -aet PACS1 -aec {AE1}", output1);
                outputs.Add(output1);
                processes.Add(proc1);
            }

            var totalInstanceSent = 0;

            for (var i = 0; i < processes.Count; i++)
            {
                processes[i].WaitForExit();
                Console.WriteLine(">>>>> Association #{0}", i);
                if (processes[i].ExitCode != 0)
                {
                    Console.WriteLine(">>>>> {0}", outputs[i].ToString());
                }
                Assert.Equal(0, processes[i].ExitCode);
                // Console.WriteLine(outputs[i].ToString());

                // make sure we are sending correct number of files
                var instanceSent = Directory.GetFiles(paths[i]).Count();
                totalInstanceSent += instanceSent;
                Thread.Sleep(750);
                outputs[i].ToString().Split(Environment.NewLine)
                .Where(p => p.Contains("I: Received Store Response (Success)"))
                .Should()
                .HaveCount(instanceSent, outputs[i].ToString());
            }
            Assert.True(jobCreatedEvent.Wait(TimeSpan.FromSeconds(30)));
            Assert.True(jobStoredEvent.Wait(TimeSpan.FromSeconds(30)));
            Assert.Equal(totalInstanceSent, instanceStoredCounter.InstanceCount);
            Assert.Equal(totalInstanceSent, jobStoreInstanceCount);
            _dicomAdapterFixture.JobStore.Verify(p => p.Add(It.IsAny <Job>(), It.IsAny <string>(), It.IsAny <IList <InstanceStorageInfo> >()), Times.Once());
        }