예제 #1
0
        protected async Task DoWorkAsync(IQueueEntry <SimpleWorkItem> w, AsyncCountdownEvent countdown, WorkInfo info)
        {
            _logger.Trace($"Starting: {w.Value.Id}");
            Assert.Equal("Hello", w.Value.Data);

            try {
                // randomly complete, abandon or blowup.
                if (RandomData.GetBool())
                {
                    _logger.Trace($"Completing: {w.Value.Id}");
                    await w.CompleteAsync();

                    info.IncrementCompletedCount();
                }
                else if (RandomData.GetBool())
                {
                    _logger.Trace($"Abandoning: {w.Value.Id}");
                    await w.AbandonAsync();

                    info.IncrementAbandonCount();
                }
                else
                {
                    _logger.Trace($"Erroring: {w.Value.Id}");
                    info.IncrementErrorCount();
                    throw new Exception();
                }
            } finally {
                _logger.Trace($"Signal {countdown.CurrentCount}");
                countdown.Signal();
            }
        }
예제 #2
0
        private void DoWork(QueueEntry <SimpleWorkItem> w, CountdownEvent latch, WorkInfo info)
        {
            Debug.WriteLine("Starting: {0}", w.Value.Id);
            Assert.Equal("Hello", w.Value.Data);

            try {
                // randomly complete, abandon or blowup.
                if (RandomData.GetBool())
                {
                    Debug.WriteLine("Completing: {0}", w.Value.Id);
                    w.Complete();
                    info.IncrementCompletedCount();
                }
                else if (RandomData.GetBool())
                {
                    Debug.WriteLine("Abandoning: {0}", w.Value.Id);
                    w.Abandon();
                    info.IncrementAbandonCount();
                }
                else
                {
                    Debug.WriteLine("Erroring: {0}", w.Value.Id);
                    info.IncrementErrorCount();
                    throw new ApplicationException();
                }
            } finally {
                latch.Signal();
            }
        }
예제 #3
0
    public SimpleError GenerateSimpleError(int maxErrorNestingLevel = 3, bool generateData = true, int currentNestingLevel = 0)
    {
        var error = new SimpleError {
            Message = @"Generated exception message.", Type = ExceptionTypes.Random()
        };

        if (generateData)
        {
            for (int i = 0; i < RandomData.GetInt(1, 5); i++)
            {
                string key = RandomData.GetWord();
                while (error.Data.ContainsKey(key) || key == Event.KnownDataKeys.Error)
                {
                    key = RandomData.GetWord();
                }

                error.Data.Add(key, RandomData.GetString());
            }
        }

        error.StackTrace = RandomData.GetString();

        if (currentNestingLevel < maxErrorNestingLevel && RandomData.GetBool())
        {
            error.Inner = GenerateSimpleError(maxErrorNestingLevel, generateData, currentNestingLevel + 1);
        }

        return(error);
    }
        private Event CreateSimpleEvent()
        {
            var ev = new Event {
                Date    = DateTime.Now,
                Message = "Testing",
                Type    = Event.KnownTypes.Log,
                Source  = "StorageSerializer"
            };

            if (RandomData.GetBool(80))
            {
                ev.Geo = RandomData.GetCoordinate();
            }
            if (RandomData.GetBool(20))
            {
                ev.Value = RandomData.GetDecimal();
            }
            if (RandomData.GetBool(20))
            {
                ev.Count = RandomData.GetInt();
            }
            if (RandomData.GetBool(80))
            {
                ev.ReferenceId = RandomData.GetAlphaNumericString(0, 10);
            }
            return(ev);
        }
예제 #5
0
        public object GenerateValue(BuilderContext context)
        {
            var value = RandomData.GetBool();

            return(TypeManager.IsNullableType <bool>(context.CurrentValueGeneratorType)
                       ? (bool?)value
                       : value);
        }
        private static IEnumerable <LocationReader> GenerateLocations()
        {
            A.Configure <LocationReader>()
            .Fill(a => a.Name).AsCity()
            .Fill(b => b.IsHotel, RandomData.GetBool(80));

            return(A.ListOf <LocationReader>(RandomData.GetInt(10, 30)));
        }
예제 #7
0
        public virtual async Task CanConcurrentlyManageFilesAsync()
        {
            await ResetAsync();

            var storage = GetStorage();

            if (storage == null)
            {
                return;
            }

            using (storage) {
                const string queueFolder = "q";
                var          queueItems  = new BlockingCollection <int>();

                var info = await storage.GetFileInfoAsync("nope");

                Assert.Null(info);

                await Run.InParallelAsync(10, async i => {
                    var ev = new PostInfo {
                        ApiVersion      = 2,
                        CharSet         = "utf8",
                        ContentEncoding = "application/json",
                        Data            = Encoding.UTF8.GetBytes("{}"),
                        IpAddress       = "127.0.0.1",
                        MediaType       = "gzip",
                        ProjectId       = i.ToString(),
                        UserAgent       = "test"
                    };

                    await storage.SaveObjectAsync(Path.Combine(queueFolder, i + ".json"), ev);
                    queueItems.Add(i);
                });

                Assert.Equal(10, (await storage.GetFileListAsync()).Count());

                await Run.InParallelAsync(10, async i => {
                    string path   = Path.Combine(queueFolder, queueItems.Random() + ".json");
                    var eventPost = await storage.GetEventPostAndSetActiveAsync(Path.Combine(queueFolder, RandomData.GetInt(0, 25) + ".json"), _logger);
                    if (eventPost == null)
                    {
                        return;
                    }

                    if (RandomData.GetBool())
                    {
                        await storage.CompleteEventPostAsync(path, eventPost.ProjectId, SystemClock.UtcNow, true, _logger);
                    }
                    else
                    {
                        await storage.SetNotActiveAsync(path, _logger);
                    }
                });
            }
        }
예제 #8
0
        private async Task SendEventNoticeAsync(PersistentEvent ev)
        {
            ev.Id             = TestConstants.EventId;
            ev.OrganizationId = TestConstants.OrganizationId;
            ev.ProjectId      = TestConstants.ProjectId;
            ev.StackId        = TestConstants.StackId;
            ev.Date           = SystemClock.OffsetUtcNow;

            await _slackService.SendEventNoticeAsync(ev, _project, RandomData.GetBool(), RandomData.GetBool());

            await RunWebHookJobAsync();
        }
예제 #9
0
        public async Task MeasureThroughputWithRandomFailures()
        {
            var queue = GetQueue(retries: 3, workItemTimeout: TimeSpan.FromSeconds(2), retryDelay: TimeSpan.Zero);

            if (queue == null)
            {
                return;
            }

            FlushAll();

            using (queue) {
                await queue.DeleteQueueAsync();

                const int workItemCount = 1000;
                for (int i = 0; i < workItemCount; i++)
                {
                    await queue.EnqueueAsync(new SimpleWorkItem {
                        Data = "Hello"
                    });
                }
                Assert.Equal(workItemCount, (await queue.GetQueueStatsAsync()).Queued);

                var metrics  = new InMemoryMetricsClient();
                var workItem = await queue.DequeueAsync(TimeSpan.Zero);

                while (workItem != null)
                {
                    Assert.Equal("Hello", workItem.Value.Data);
                    if (RandomData.GetBool(10))
                    {
                        await workItem.AbandonAsync();
                    }
                    else
                    {
                        await workItem.CompleteAsync();
                    }

                    await metrics.CounterAsync("work");

                    workItem = await queue.DequeueAsync(TimeSpan.FromMilliseconds(100));
                }
                _logger.Trace((await metrics.GetCounterStatsAsync("work")).ToString());

                var stats = await queue.GetQueueStatsAsync();

                Assert.True(stats.Dequeued >= workItemCount);
                Assert.Equal(workItemCount, stats.Completed + stats.Deadletter);
                Assert.Equal(0, stats.Queued);

                Trace.WriteLine(CountAllKeys());
            }
        }
예제 #10
0
        private async Task SendEventNoticeAsync(PersistentEvent ev) {
            var user = UserData.GenerateSampleUser();
            var project = ProjectData.GenerateSampleProject();

            ev.Id = TestConstants.EventId;
            ev.OrganizationId = TestConstants.OrganizationId;
            ev.ProjectId = TestConstants.ProjectId;
            ev.StackId = TestConstants.StackId;

            await _mailer.SendEventNoticeAsync(user, ev, project, RandomData.GetBool(), RandomData.GetBool(), 1);
            await RunMailJobAsync();
        }
예제 #11
0
        public virtual void CanConcurrentlyManageFiles()
        {
            Reset();

            IFileStorage storage = GetStorage();

            if (storage == null)
            {
                return;
            }

            using (storage) {
                const string queueFolder = "q";
                var          queueItems  = new BlockingCollection <int>();

                var info = storage.GetFileInfo("nope");
                Assert.Null(info);

                Parallel.For(0, 10, i => {
                    var ev = new PostInfo {
                        ApiVersion      = 2,
                        CharSet         = "utf8",
                        ContentEncoding = "application/json",
                        Data            = Encoding.UTF8.GetBytes("{}"),
                        IpAddress       = "127.0.0.1",
                        MediaType       = "gzip",
                        ProjectId       = i.ToString(),
                        UserAgent       = "test"
                    };
                    storage.SaveObject(Path.Combine(queueFolder, i + ".json"), ev);
                    queueItems.Add(i);
                });
                Assert.Equal(10, storage.GetFileList().Count());

                Parallel.For(0, 10, i => {
                    string path   = Path.Combine(queueFolder, queueItems.Random() + ".json");
                    var eventPost = storage.GetEventPostAndSetActive(Path.Combine(queueFolder, RandomData.GetInt(0, 25) + ".json"));
                    if (eventPost == null)
                    {
                        return;
                    }

                    if (RandomData.GetBool())
                    {
                        storage.CompleteEventPost(path, eventPost.ProjectId, DateTime.UtcNow, true);
                    }
                    else
                    {
                        storage.SetNotActive(path);
                    }
                });
            }
        }
예제 #12
0
        protected override Task <JobResult> ProcessQueueEntryAsync(JobQueueEntryContext <PingRequest> context)
        {
            RunCount++;

            _logger.Info(() => $"Got {RunCount.ToOrdinal()} ping. Sending pong!");

            if (RandomData.GetBool(1))
            {
                throw new ApplicationException("Boom!");
            }

            return(Task.FromResult(JobResult.Success));
        }
예제 #13
0
        protected override async Task <JobResult> ProcessQueueEntryAsync(QueueEntryContext <PingRequest> context)
        {
            Interlocked.Increment(ref _runCount);

            _logger.Info(() => $"Got {RunCount.ToOrdinal()} ping. Sending pong!");
            await SystemClock.SleepAsync(TimeSpan.FromMilliseconds(1)).AnyContext();

            if (RandomData.GetBool(context.QueueEntry.Value.PercentChanceOfException))
            {
                throw new ApplicationException("Boom!");
            }

            return(JobResult.Success);
        }
예제 #14
0
        public void MeasureThroughputWithRandomFailures()
        {
            var queue = GetQueue(retries: 3, workItemTimeout: TimeSpan.FromSeconds(2), retryDelay: TimeSpan.Zero);

            if (queue == null)
            {
                return;
            }

            FlushAll();

            using (queue) {
                queue.DeleteQueue();

                const int workItemCount = 10000;
                for (int i = 0; i < workItemCount; i++)
                {
                    queue.Enqueue(new SimpleWorkItem {
                        Data = "Hello"
                    });
                }
                Assert.Equal(workItemCount, queue.GetQueueCount());

                var metrics  = new InMemoryMetricsClient();
                var workItem = queue.Dequeue(TimeSpan.Zero);
                while (workItem != null)
                {
                    Assert.Equal("Hello", workItem.Value.Data);
                    if (RandomData.GetBool(10))
                    {
                        workItem.Abandon();
                    }
                    else
                    {
                        workItem.Complete();
                    }
                    metrics.Counter("work");

                    workItem = queue.Dequeue(TimeSpan.FromMilliseconds(100));
                }
                metrics.DisplayStats();

                Assert.True(queue.DequeuedCount >= workItemCount);
                Assert.Equal(workItemCount, queue.CompletedCount + queue.GetDeadletterCount());
                Assert.Equal(0, queue.GetQueueCount());

                Trace.WriteLine(CountAllKeys());
            }
        }
예제 #15
0
        protected override async Task <JobResult> ProcessQueueEntryAsync(JobQueueEntryContext <PingRequest> context)
        {
            RunCount++;

            Console.WriteLine("Pong!");

            if (RandomData.GetBool(80))
            {
                await context.QueueEntry.CompleteAsync().AnyContext();
            }
            else if (RandomData.GetBool(80))
            {
                await context.QueueEntry.AbandonAsync().AnyContext();
            }

            return(JobResult.Success);
        }
예제 #16
0
        public void CanConcurrentlyManageFiles()
        {
            Reset();

            IObjectStorage  storage    = GetStorage();
            IJsonSerializer serializer = new DefaultJsonSerializer();
            const string    queueName  = "test";

            Parallel.For(0, 25, i => {
                var ev = new Event {
                    Type    = Event.KnownTypes.Log,
                    Message = "test" + i
                };
                storage.Enqueue(queueName, ev);
            });
            Assert.Equal(25, storage.GetObjectList().Count());
            var working = new ConcurrentDictionary <string, object>();

            Parallel.For(0, 50, i => {
                var fileBatch = storage.GetEventBatch(queueName, serializer, 2);
                foreach (var f in fileBatch)
                {
                    if (working.ContainsKey(f.Item1.Path))
                    {
                        Debug.WriteLine(f.Item1.Path);
                    }
                    Assert.False(working.ContainsKey(f.Item1.Path));
                    working.TryAdd(f.Item1.Path, null);
                }

                if (RandomData.GetBool())
                {
                    object o;
                    foreach (var f in fileBatch)
                    {
                        working.TryRemove(f.Item1.Path, out o);
                    }
                    storage.ReleaseBatch(fileBatch);
                }
                else
                {
                    storage.DeleteBatch(fileBatch);
                }
            });
            Assert.Equal(25, working.Count + storage.GetQueueFiles(queueName).Count);
        }
예제 #17
0
        protected override Task <JobResult> ProcessQueueEntryAsync(QueueEntryContext <SampleQueueWorkItem> context)
        {
            _metrics.Counter("dequeued");

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("errors");
                throw new Exception("Boom!");
            }

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("abandoned");
                return(Task.FromResult(JobResult.FailedWithMessage("Abandoned")));
            }

            _metrics.Counter("completed");
            return(Task.FromResult(JobResult.Success));
        }
예제 #18
0
        protected override Task <JobResult> RunInternalAsync(JobContext context)
        {
            _metrics.Counter("runs");

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("errors");
                throw new Exception("Boom!");
            }

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("failed");
                return(Task.FromResult(JobResult.FailedWithMessage("Failed")));
            }

            _metrics.Counter("completed");
            return(Task.FromResult(JobResult.Success));
        }
예제 #19
0
        protected override object MutateGene(PropertyInfo gene, int index, object originalValue, object suggestedRandomValue)
        {
            if (NumberHelper.TryGetValue(originalValue, out var value))
            {
                var addValue  = (value * ADD_RATE) * (decimal)RandomData.GetDouble(); // something around 10% (ADD_RATE), then a random fraction of it
                var shouldAdd = RandomData.GetBool();                                 // add or subtract

                var result = shouldAdd
                    ? value + addValue
                    : value - addValue;

                return(_options.IsInRange(result)
                    ? NumberHelper.CastValueToProperType(gene.PropertyType, result)
                    : suggestedRandomValue);
            }
            else
            {
                return(suggestedRandomValue);
            }
        }
예제 #20
0
        internal static Error GenerateError(int maxErrorNestingLevel = 3, bool generateData = true, int currentNestingLevel = 0)
        {
            var error = new Error {
                Message = "Generated exception message.",
                Type    = TestConstants.ExceptionTypes.Random()
            };

            if (RandomData.GetBool())
            {
                error.Code = RandomData.GetInt(-234523453, 98690899).ToString();
            }

            if (generateData)
            {
                for (int i = 0; i < RandomData.GetInt(1, 5); i++)
                {
                    string key = RandomData.GetWord();
                    while (error.Data.ContainsKey(key) || key == Event.KnownDataKeys.Error)
                    {
                        key = RandomData.GetWord();
                    }

                    error.Data.Add(key, RandomData.GetWord());
                }
            }

            var stack = new StackFrameCollection();

            for (int i = 0; i < RandomData.GetInt(1, 10); i++)
            {
                stack.Add(GenerateStackFrame());
            }
            error.StackTrace = stack;

            if (currentNestingLevel < maxErrorNestingLevel && RandomData.GetBool())
            {
                error.Inner = GenerateError(maxErrorNestingLevel, generateData, currentNestingLevel + 1);
            }

            return(error);
        }
예제 #21
0
        protected override async Task <JobResult> ProcessQueueEntryAsync(QueueEntryContext <SampleQueueWorkItem> context)
        {
            await _metrics.CounterAsync("dequeued").AnyContext();

            if (RandomData.GetBool(10))
            {
                await _metrics.CounterAsync("errors").AnyContext();

                throw new ApplicationException("Boom!");
            }

            if (RandomData.GetBool(10))
            {
                await _metrics.CounterAsync("abandoned").AnyContext();

                return(JobResult.FailedWithMessage("Abandoned"));
            }

            await _metrics.CounterAsync("completed").AnyContext();

            return(JobResult.Success);
        }
예제 #22
0
        protected override async Task <JobResult> RunInternalAsync(JobContext context)
        {
            await _metrics.CounterAsync("runs").AnyContext();

            if (RandomData.GetBool(10))
            {
                await _metrics.CounterAsync("errors").AnyContext();

                throw new Exception("Boom!");
            }

            if (RandomData.GetBool(10))
            {
                await _metrics.CounterAsync("failed").AnyContext();

                return(JobResult.FailedWithMessage("Failed"));
            }

            await _metrics.CounterAsync("completed").AnyContext();

            return(JobResult.Success);
        }
예제 #23
0
        protected override Task <JobResult> ProcessQueueItem(QueueEntry <SampleQueueWorkItem> queueEntry)
        {
            _metrics.Counter("dequeued");

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("errors");
                throw new ApplicationException("Boom!");
            }

            if (RandomData.GetBool(10))
            {
                _metrics.Counter("abandoned");
                queueEntry.Abandon();
                return(Task.FromResult(JobResult.FailedWithMessage("Abandoned")));
            }

            queueEntry.Complete();
            _metrics.Counter("completed");

            return(Task.FromResult(JobResult.Success));
        }
예제 #24
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            var metrics = new InMemoryMetricsClient();
            var queue   = new InMemoryQueue <WorkItemData>(retries: 0, retryDelay: TimeSpan.Zero);

            queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics));
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var j1     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j2     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j3     = new WorkItemJob(queue, messageBus, handlerRegistry);
            int errors = 0;

            var jobIds = new ConcurrentDictionary <string, int>();

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                var jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                Logger.Trace().Message($"Job {ctx.JobId} processing work item #: {jobWorkTotal}").Write();

                for (int i = 0; i < 10; i++)
                {
                    await ctx.ReportProgressAsync(10 * i);
                }

                if (RandomData.GetBool(1))
                {
                    Interlocked.Increment(ref errors);
                    throw new ApplicationException("Boom!");
                }
            });

            for (int i = 0; i < workItemCount; i++)
            {
                await queue.EnqueueAsync(new MyWorkItem {
                    SomeData = "Test",
                    Index    = i
                }, true);
            }

            var    completedItems     = new List <string>();
            object completedItemsLock = new object();

            messageBus.Subscribe <WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                if (status.Progress < 100)
                {
                    return;
                }

                lock (completedItemsLock)
                    completedItems.Add(status.WorkItemId);
            });

            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var tasks = new List <Task> {
                Task.Run(async() => {
                    await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token)
            };

            try {
                await Task.WhenAll(tasks);

                await Task.Delay(100);
            } catch (TaskCanceledException) {}

            Logger.Info().Message($"Completed: {completedItems.Count} Errors: {errors}").Write();
            metrics.DisplayStats(_writer);

            Assert.Equal(workItemCount, completedItems.Count + errors);
            Assert.Equal(3, jobIds.Count);
            Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
        }
예제 #25
0
    public void PopulateEvent(Event ev, bool setUserIdentity = true)
    {
        if (MinDate.HasValue || MaxDate.HasValue)
        {
            ev.Date = RandomData.GetDateTime(MinDate ?? DateTime.MinValue, MaxDate ?? DateTime.MaxValue);
        }

        ev.Type = new[] { Event.KnownTypes.Error, Event.KnownTypes.FeatureUsage, Event.KnownTypes.Log, Event.KnownTypes.NotFound }.Random();
        if (ev.Type == Event.KnownTypes.FeatureUsage)
        {
            ev.Source = FeatureNames.Random();
        }
        else if (ev.Type == Event.KnownTypes.NotFound)
        {
            ev.Source = PageNames.Random();
        }
        else if (ev.Type == Event.KnownTypes.Log)
        {
            ev.Source  = LogSources.Random();
            ev.Message = RandomData.GetString();

            string level = LogLevels.Random();
            if (!String.IsNullOrEmpty(level))
            {
                ev.Data[Event.KnownDataKeys.Level] = level;
            }
        }

        if (RandomData.GetBool(80))
        {
            ev.Geo = RandomData.GetCoordinate();
        }

        if (RandomData.GetBool(20))
        {
            ev.Value = RandomData.GetInt(0, 10000);
        }

        if (setUserIdentity)
        {
            ev.SetUserIdentity(Identities.Random());
        }

        ev.SetVersion(RandomData.GetVersion("2.0", "4.0"));

        ev.AddRequestInfo(new RequestInfo {
            //ClientIpAddress = ClientIpAddresses.Random(),
            Path = PageNames.Random()
        });

        ev.Data.Add(Event.KnownDataKeys.EnvironmentInfo, new EnvironmentInfo {
            IpAddress   = MachineIpAddresses.Random() + ", " + MachineIpAddresses.Random(),
            MachineName = MachineNames.Random()
        });

        for (int i = 0; i < RandomData.GetInt(1, 3); i++)
        {
            string key = RandomData.GetWord();
            while (ev.Data.ContainsKey(key) || key == Event.KnownDataKeys.Error)
            {
                key = RandomData.GetWord();
            }

            ev.Data.Add(key, RandomData.GetString());
        }

        int tagCount = RandomData.GetInt(1, 3);

        for (int i = 0; i < tagCount; i++)
        {
            string tag = EventTags.Random();
            if (!ev.Tags.Contains(tag))
            {
                ev.Tags.Add(tag);
            }
        }

        if (ev.Type == Event.KnownTypes.Error)
        {
            if (RandomData.GetBool())
            {
                // limit error variation so that stacking will occur
                if (_randomErrors == null)
                {
                    _randomErrors = new List <Error>(Enumerable.Range(1, 25).Select(i => GenerateError()));
                }

                ev.Data[Event.KnownDataKeys.Error] = _randomErrors.Random();
            }
            else
            {
                // limit error variation so that stacking will occur
                if (_randomSimpleErrors == null)
                {
                    _randomSimpleErrors = new List <SimpleError>(Enumerable.Range(1, 25).Select(i => GenerateSimpleError()));
                }

                ev.Data[Event.KnownDataKeys.SimpleError] = _randomSimpleErrors.Random();
            }
        }
    }
예제 #26
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            using (var metrics = new InMemoryMetricsClient(new InMemoryMetricsClientOptions {
                LoggerFactory = Log
            })) {
                var options = new InMemoryQueueOptions <WorkItemData> {
                    Retries = 0, RetryDelay = TimeSpan.Zero, LoggerFactory = Log
                };
                using (var queue = new InMemoryQueue <WorkItemData>(options)) {
                    queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics, loggerFactory: Log));
                    using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                        LoggerFactory = Log
                    })) {
                        var handlerRegistry = new WorkItemHandlers();
                        var j1     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j2     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j3     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        int errors = 0;

                        var jobIds = new ConcurrentDictionary <string, int>();

                        handlerRegistry.Register <MyWorkItem>(async ctx => {
                            var jobData = ctx.GetData <MyWorkItem>();
                            Assert.Equal("Test", jobData.SomeData);

                            int jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                            if (jobData.Index % 100 == 0)
                            {
                                _logger.Trace("Job {jobId} processing work item #: {jobWorkTotal}", ctx.JobId, jobWorkTotal);
                            }

                            for (int i = 0; i < 10; i++)
                            {
                                await ctx.ReportProgressAsync(10 * i);
                            }

                            if (RandomData.GetBool(1))
                            {
                                Interlocked.Increment(ref errors);
                                throw new Exception("Boom!");
                            }
                        });

                        for (int i = 0; i < workItemCount; i++)
                        {
                            await queue.EnqueueAsync(new MyWorkItem {
                                SomeData = "Test",
                                Index    = i
                            }, true);
                        }

                        var    completedItems     = new List <string>();
                        object completedItemsLock = new object();
                        await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                            if (status.Progress == 100)
                            {
                                _logger.Trace("Progress: {progress}", status.Progress);
                            }

                            if (status.Progress < 100)
                            {
                                return;
                            }

                            lock (completedItemsLock)
                                completedItems.Add(status.WorkItemId);
                        });

                        var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
                        var tasks = new List <Task> {
                            Task.Run(async() => {
                                await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token)
                        };

                        try {
                            await Task.WhenAll(tasks);
                        } catch (OperationCanceledException ex) {
                            _logger.Error(ex, $"One or more tasks were cancelled: {ex.Message}");
                        }

                        await SystemClock.SleepAsync(100);

                        _logger.Info("Completed: {completedItems} Errors: {errors}", completedItems.Count, errors);
                        Assert.Equal(workItemCount, completedItems.Count + errors);
                        Assert.Equal(3, jobIds.Count);
                        Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
                    }
                }
            }
        }
예제 #27
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private MarCard CreateMarCard()
        {
            MarCard entity = new MarCard()
            {
                CustId                 = RandomData.GetInt(),                           //商户Id
                CardId                 = Guid.NewGuid().ToString("N"),                  //卡券ID代表一类卡券
                LogoUrl                = RandomData.GetString(maxLength: 200),          //卡券的商户logo,建议像素为300*300。
                CardType               = RandomData.GetString(maxLength: 20),           //卡券类型(CASH:代金券,DISCOUNT:折扣券,GIFT:兑换券,GROUPON:团购券)
                CodeType               = RandomData.GetString(maxLength: 20),           //核销码类型(CODE_TYPE_TEXT文 本 ; "CODE_TYPE_BARCODE"一维码 "CODE_TYPE_QRCODE"二维码 "CODE_TYPE_ONLY_QRCODE",二维码无code显示; "CODE_TYPE_ONLY_BARCODE",一维码无code显示;CODE_TYPE_NONE, 不显示code和条形码类型)
                Title                  = RandomData.GetString(maxLength: 30),           //卡券名,字数上限为9个汉字。(建议涵盖卡券属性、服务及金额)。
                SubTitle               = RandomData.GetString(maxLength: 30),           //显示在入口下方的提示语 ,仅在卡券状态正常(可以核销)时显示。
                Color                  = RandomData.GetString(maxLength: 16),           //券颜色。按色彩规范标注填写Color010-Color100。
                Notice                 = RandomData.GetString(maxLength: 50),           //卡券使用提醒,字数上限为16个汉字。
                Description            = RandomData.GetString(maxLength: 1024),         //卡券使用说明,字数上限为1024个汉字。
                Quantity               = RandomData.GetInt(),                           //卡券库存的数量,上限为100000000。
                DateType               = RandomData.GetString(maxLength: 20),           //有效期类型(DATE_TYPE_FIX _TIME_RANGE 表示固定日期区间,DATE_TYPE_FIX_TERM表示 X天后生效,X天内有效)
                DateBeginTime          = RandomData.GetDateTime(),                      //DateType为DATE_TYPE_FIX_TIME_RANGE时专用,表示起用时间
                DateEndTime            = RandomData.GetDateTime(),                      //DateType为DATE_TYPE_FIX_TIME_RANGE时专用,表示结束时间 , 建议设置为截止日期的23:59:59过期
                DateFixedTerm          = RandomData.GetInt(),                           //DateType为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天内有效,不支持填写0。
                DateFixedBeginTerm     = RandomData.GetInt(),                           //DateType为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天开始生效,领取后当天生效填写0。(单位为天)
                BindOpenid             = RandomData.GetBool(),                          //是否指定用户领取,填写true或false 。默认为false。通常指定特殊用户群体 投放卡券或防止刷券时选择指定用户领取。
                ServicePhone           = RandomData.GetString(maxLength: 20),           //客服电话。
                GetLimit               = RandomData.GetInt(),                           //每人可领券的数量限制,不填写默认为50。
                UseLimit               = RandomData.GetInt(),                           //每人可核销的数量限制,不填写默认为50。
                CanShare               = RandomData.GetBool(),                          //卡券领取页面是否可分享。
                CanGiveFriend          = RandomData.GetBool(),                          //卡券是否可转赠
                AcceptCategory         = RandomData.GetString(),                        //指定可用的商品类目
                RejectCategory         = RandomData.GetString(),                        //指定不可用的商品类目,仅用于代金券类型 ,填入后将在券面拼写不适用于xxxx
                AcceptProduct          = RandomData.GetString(),                        //指定可用的商品
                RejecProduct           = RandomData.GetString(),                        //指定不可用的商品
                ReduceCost             = RandomData.GetDecimal(0, (int)Math.Pow(2, 6)), //代金券专用,表示减免金额
                LeastCost              = RandomData.GetDecimal(0, (int)Math.Pow(2, 6)), //满减门槛字段,可用于兑换券和代金券 ,填入后将在全面拼写消费满xx元可用。
                Discount               = RandomData.GetDecimal(0, (int)Math.Pow(2, 6)), //折扣券专用,表示打折额度(百分比)
                CanUseWithOtheDiscount = RandomData.GetBool(),                          //不可以与其他类型共享门槛 ,填写false时系统将在使用须知里 拼写“不可与其他优惠共享”, 填写true时系统将在使用须知里 拼写“可与其他优惠共享”, 默认为true
                BusinessService        = RandomData.GetString(maxLength: 200),          //Arry类型 商家服务类型: BIZ_SERVICE_DELIVER 外卖服务; BIZ_SERVICE_FREE_PARK 停车位; BIZ_SERVICE_WITH_PET 可带宠物; BIZ_SERVICE_FREE_WIFI 免费wifi, 可多选

                /*
                 * {
                 *  type    否   string(24 )	限制类型枚举值:支持填入 MONDAY 周一 TUESDAY 周二 WEDNESDAY 周三 THURSDAY 周四 FRIDAY 周五 SATURDAY 周六 SUNDAY 周日 此处只控制显示, 不控制实际使用逻辑,不填默认不显示
                 *  begin_hour   否   int 当前type类型下的起始时间(小时) ,如当前结构体内填写了MONDAY, 此处填写了10,则此处表示周一 10:00可用
                 *  begin_minute 否   int 当前type类型下的起始时间(分钟) ,如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59可用
                 *  end_hour 否   int 当前type类型下的结束时间(小时) ,如当前结构体内填写了MONDAY, 此处填写了20, 则此处表示周一 10:00 - 20:00可用
                 *      end_minute   否   int 当前type类型下的结束时间(分钟) ,如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59 - 00:59可用
                 * }
                 */
                TimeLimit               = @"[{""type"": ""MONDAY"", ""begin_hour"": 0,""end_hour"": 10,""begin_minute"": 10,""end_minute"": 59 }]", //JSON结构	使用时段限制,包含以下字段
                AbstractIntro           = RandomData.GetString(maxLength: 24),                                                                      //封面摘要简介
                AbstractIconUrlList     = RandomData.GetString(maxLength: 200),                                                                     //封面图片列表,仅支持填入一 个封面图片链接, 上传图片接口 上传获取图片获得链接,填写 非CDN链接会报错,并在此填入。 建议图片尺寸像素850*350
                ConsumeType             = default(byte?),                                                                                           //核销方式(1:自助买单,2:自助核销,3:用扫码核销--二维码_条形码_仅卡券号)
                ConsumeNeedVerifyCode   = RandomData.GetBool(),                                                                                     //自助核销是否启用验证码(消费者持券到店,须输入验证码才能核销卡券)
                ConsumeVerifyCode       = RandomData.GetString(maxLength: 3),                                                                       //自助核销验证码(消费者持券到店,须输入验证码才能核销卡券)
                ConsumeNeedRemarkAmount = RandomData.GetBool(),                                                                                     //自助核销是否启用备注交易金额(商户选择备注交易金额后,用户持券到店,须备注本次交易的金额才能成功销券,用于对账。)
                BranchNo                       = RandomData.GetString(),                                                                            //适应的门店编号如:1234,5678
                Status                         = default(byte),                                                                                     //卡券状态(0:待审核,1:审核中,2:审核通过(待投放),3:审核未通过,4:已投放,5:下架)
                SendNum                        = RandomData.GetInt(),                                                                               //投放数量
                UseNum                         = RandomData.GetInt(),                                                                               //核销数量
                QuantityThreshold              = RandomData.GetInt(),                                                                               //库存阈值(当库存少于X提醒)
                QuantityThresholdNotificCount  = RandomData.GetInt(),                                                                               //库存阈值提醒次数
                QuantityThresholdNotificStatus = default(byte),                                                                                     //库存阈值提醒状态(0:禁用,1:启用)
                CreateTime                     = DateTime.Now,                                                                                      //创建时间
                CreateUser                     = RandomData.GetInt(),                                                                               //创建用户
                UpdateTime                     = RandomData.GetDateTime(),                                                                          //修改时间
                UpdateUser                     = RandomData.GetInt(),                                                                               //修改用户
                DeleteFlag                     = false,                                                                                             //删除标志 1删除
                DeleteUser                     = RandomData.GetInt(),                                                                               //删除用户
                DeleteTime                     = RandomData.GetDateTime(),                                                                          //删除时间
            };

            return(entity);
        }
예제 #28
0
 protected override T ChooseGeneGiver(PropertyInfo gene, int index, T parentA, T parentB)
 {
     return(RandomData.GetBool() ? parentA : parentB);
 }