void DeployScript(Script script, string name = null) { var scriptName = name ?? new FileInfo(script.Options.FilePath).Name ?? Guid.NewGuid().ToString(); if (scripts.ContainsKey(scriptName)) { scripts[scriptName] = script; } else { scripts.Add(scriptName, script); } var gc = script.GetCompilation(); var errors = gc.GetDiagnostics(); var job = new JobMetadata(scriptName) { DisplayName = scriptName, Category = "Scripts", MethodInfo = this.GetType().GetMethod("ScriptRunner") }; job.DefaultArguments.Add("scriptName", scriptName); Hangfire.Scripting.GlobalConfigurationExtension.Jobs.Add(job); }
private IJobDetail CreateJob(JobMetadata jobMetadata) { return(JobBuilder.Create(jobMetadata.JobType) .WithIdentity(jobMetadata.JobId.ToString()) .WithDescription(jobMetadata.JobName) .Build()); }
internal static void GetAllJobs(Assembly assembly) { foreach (Type ti in assembly.GetTypes().Where(x => !x.IsInterface && typeof(IJob).IsAssignableFrom(x) && x.Name != (typeof(IJob).Name))) { if (ti.GetCustomAttributes(true).OfType <ManagementPageAttribute>().Any()) { var attr = ti.GetCustomAttribute <ManagementPageAttribute>(); if (!Pages.Any(p => p.Category == attr.Category)) { Pages.Add(attr); } foreach (var methodInfo in ti.GetMethods().Where(m => m.DeclaringType == ti && m.GetCustomAttributes(true).OfType <DisplayNameAttribute>().Any())) { var meta = new JobMetadata { Type = ti, Queue = attr.Queue, Category = attr.Category }; meta.MethodInfo = methodInfo; meta.DisplayName = methodInfo.GetCustomAttribute <DisplayNameAttribute>().DisplayName; if (methodInfo.GetCustomAttributes(true).OfType <DescriptionAttribute>().Any()) { meta.Description = methodInfo.GetCustomAttribute <DescriptionAttribute>().Description; } Metadata.Add(meta); } } } }
public async Task AddNewRecurrentJob_Success() { // Arrange var jobRepositoryMock = new Mock <IJobRepository>(); var jobsAdder = new AdderJobs(jobRepositoryMock.Object, new JsonSerializerSettings()); var job = new JobMetadata { Cron = Cron.SecondInterval(15), ObsoleteInterval = TimeSpan.FromMinutes(5), JobType = typeof(TestReccurrentJob), JobKey = nameof(TestReccurrentJob), Status = JobStatus.Ready, JobId = Guid.NewGuid().ToString("N"), StartAt = DateTime.UtcNow + TimeSpan.FromSeconds(10), CountStarted = 0 }; // Act await jobsAdder.AddRecurrentJob(job); // Assert jobRepositoryMock.Verify(x => x.AddRecurrentJob(It.Is <JobDb>(j => j.Status == job.Status && j.CountStarted == job.CountStarted && j.JobKey == job.JobKey && j.Cron == job.Cron && j.JobId == job.JobId )), Times.Once); }
public void splitJob(JobMetadata jobMetadata) { Common.Logger().LogInfo("splitting job", string.Empty, string.Empty); long totalBytes = jobMetadata.TotalByteCount; long splits = jobMetadata.SplitCount; for (int i = 0; i < splits; i++) { long start = i * totalBytes / splits; long end = start + totalBytes / splits; FileSplitMetadata metadata = new FileSplitMetadata(i, start, end, jobMetadata.ClientUrl, Worker.JOBTRACKER_URL); Task task = new Task(i, metadata, StatusType.NOT_SEND_TO_WORKER); taskList.Add(i, task); FileSplitMetadata metadataOrig = new FileSplitMetadata(i, start, end, jobMetadata.ClientUrl, Worker.JOBTRACKER_URL); Task taskOrig = new Task(i, metadataOrig, StatusType.NOT_SEND_TO_WORKER); originalTaskList.Add(i, taskOrig); } if (existingWorkerMap.Count > 1) { string bkpUrl = GetBackupTrackerUrl(); communicator.SendTaskCopyToBackupTracker(bkpUrl, originalTaskList, clientURL); communicator.notifyBackupJobtrackerUrl(bkpUrl, existingWorkerMap); } distributeTasks(); }
protected BaseScheduler(SchedulerSettings settings, JobMetadata metadataManager, IJobDetailService jobDetailService) { JobDetailService = jobDetailService; Metadata = metadataManager; Init(settings); }
private async Task HandleFailed(JobMetadata jobMetadata, Exception ex, dynamic jobImplementation) { _settings.Logger.Debug(ex); var maxRepeatCount = jobMetadata.MaxRepeatCount != 0 ? jobMetadata.MaxRepeatCount : _settings.MaxRepeatCount; if (jobMetadata.CountStarted >= maxRepeatCount) { if (jobImplementation != null && jobImplementation is IAllRepeatesIsFailed) { try { await jobImplementation.FailedEvent((dynamic)jobMetadata.JobParam, ex); } catch (Exception failedEventException) { _settings.Logger.Error($"{jobMetadata.JobType}'s .FailedEvent threw", failedEventException); } } await _jobRepository.FailedJob(jobMetadata.JobId, ex); _settings.Logger.Debug("jobMetadata saved failed"); } else { await _jobRepository.RepeatJob(jobMetadata.JobId, GetNextStartFailedJobTime(jobMetadata), ex); _settings.Logger.Debug("jobMetadata saved repeat"); } }
private ITrigger CreateTrigger(JobMetadata jobMetadata) { return(TriggerBuilder.Create() .WithIdentity(jobMetadata.JobId.ToString()) .WithCronSchedule(jobMetadata.CronExpression) .WithDescription(jobMetadata.JobName) .Build()); }
private async Task ScheduleRecurrentNextTime(JobMetadata metadata) { var cron = await _jobRepository.GetCronForRecurrentJob(metadata.JobKey); await new RecurrentJobBuilder(_adderJobs, cron, metadata.JobType, metadata.ObsoleteInterval) .WithKey(metadata.JobKey) .Schedule(); }
private void FillWithDefaultIfNecessary(JobMetadata job) { job.Delay = job.Delay ?? TimeSpan.Zero; job.StartAt = DateTime.UtcNow + job.Delay.Value; job.ObsoleteInterval = job.ObsoleteInterval == default(TimeSpan) ? _globalObsoleteInterval : job.ObsoleteInterval; }
public QuartzHostedService(ISchedulerFactory schedulerFactory, JobMetadata jobMetadata, IJobFactory jobFactory) { this.schedulerFactory = schedulerFactory; this.jobMetadata = jobMetadata; this.jobFactory = jobFactory; }
public QuartzScheduler(SchedulerSettings settings, JobMetadata metadataManager, IJobDetailService jobDetailService) : base(settings, metadataManager, jobDetailService) { JobListener.ToBeExecuted += (s, e) => OnBeforeJobExecution(e.Job); JobListener.Executed += (s, e) => OnJobTriggered(e.Job); JobListener.ExecutionVetoed += (s, e) => OnJobSkipped(e.Job); JobListener.ExecutionSucceeded += (s, e) => OnJobSucceeded(e.Job); JobListener.ExecutionFailed += (s, e) => OnJobFailed(e.Job); }
public Task Execute(JobMetadata jobMetadata) { if (jobMetadata.JobType.GetTypeInfo().GetInterfaces().Contains(typeof(IJobRecurrent))) { return(ExecuteJobRecurrent(jobMetadata)); } return(ExecuteJob(jobMetadata)); }
private void GenerateNewJob(Type jobType) { Job = new JobMetadata { JobId = Guid.NewGuid().ToString("N"), JobType = jobType, Status = JobStatus.Ready, CountStarted = 0 }; }
internal static void GetAllJobs(Assembly assembly) { Jobs = new List <JobMetadata>(); Pages = new List <ManagementPageNavigation>(); foreach (Type ti in assembly.GetTypes().Where(x => !x.IsInterface && typeof(IJob).IsAssignableFrom(x) && x.Name != (typeof(IJob).Name))) { var q = "default"; // if (ti.GetCustomAttributes(true).OfType<ManagementPageAttribute>().Any()) // { // var attr = ti.GetCustomAttribute<ManagementPageAttribute>(); // q = attr.Queue; // if (!Pages.Any(x => x.MenuName == attr.MenuName)) Pages.Add(attr); // } foreach (var methodInfo in ti.GetMethods().Where(m => m.DeclaringType == ti && m.GetCustomAttributes(true).OfType <ManagementPageSectionAttribute>().Any())) { var jobData = new JobMetadata { Type = ti, Queue = q //Defaulted to value from Class, can be override at method level }; jobData.MethodInfo = methodInfo; if (methodInfo.GetCustomAttributes(true).OfType <DescriptionAttribute>().Any()) { jobData.Description = methodInfo.GetCustomAttribute <DescriptionAttribute>().Description; } if (methodInfo.GetCustomAttributes(true).OfType <ManagementPageSectionAttribute>().Any()) { jobData.ManagementPageSection = methodInfo.GetCustomAttribute <ManagementPageSectionAttribute>().Section; } if (methodInfo.GetCustomAttributes(true).OfType <DisplayNameAttribute>().Any()) { jobData.DisplayName = methodInfo.GetCustomAttribute <DisplayNameAttribute>().DisplayName; } else { jobData.DisplayName = methodInfo.Name; } if (methodInfo.GetCustomAttributes(true).OfType <QueueAttribute>().Any()) { jobData.Queue = methodInfo.GetCustomAttribute <QueueAttribute>().Queue; } Jobs.Add(jobData); } } }
public void SnowballDescribeJob() { #region to-describe-a-job-youve-created-for-aws-snowball-1482539500180 var response = client.DescribeJob(new DescribeJobRequest { JobId = "JID123e4567-e89b-12d3-a456-426655440000" }); JobMetadata jobMetadata = response.JobMetadata; #endregion }
internal static void GetAllJobs(Assembly assembly) { foreach (Type ti in assembly.GetTypes().Where(x => typeof(IJob).IsAssignableFrom(x) && x.Name != (typeof(IJob).Name))) { var q = "default"; var title = "Default"; var menuName = "Default"; if (ti.GetCustomAttributes(true).OfType <ManagementPageAttribute>().Any()) { var mgmtPageAttr = ti.GetCustomAttribute <ManagementPageAttribute>(); title = mgmtPageAttr.Title; menuName = mgmtPageAttr.MenuName; if (!Pages.Any(x => x.MenuName == menuName)) { Pages.Add(mgmtPageAttr); } } foreach (var methodInfo in ti.GetMethods().Where(m => m.DeclaringType == ti)) { var meta = new JobMetadata { Type = ti, Queue = q, SectionTitle = title, MenuName = menuName }; meta.MethodInfo = methodInfo; if (methodInfo.GetCustomAttributes(true).OfType <QueueAttribute>().Any()) { meta.Queue = methodInfo.GetCustomAttribute <QueueAttribute>().Queue; } if (methodInfo.GetCustomAttributes(true).OfType <DescriptionAttribute>().Any()) { meta.Description = methodInfo.GetCustomAttribute <DescriptionAttribute>().Description; } if (methodInfo.GetCustomAttributes(true).OfType <DisplayNameAttribute>().Any()) { meta.DisplayName = methodInfo.GetCustomAttribute <DisplayNameAttribute>().DisplayName; } if (methodInfo.GetCustomAttributes(true).OfType <AllowMultipleAttribute>().Any()) { meta.AllowMultiple = methodInfo.GetCustomAttribute <AllowMultipleAttribute>().AllowMultiple; } Metadata.Add(meta); } } }
public void ToJobDb() { var job = new JobMetadata() { JobType = typeof(TestJob), JobParam = "test" }; var jobDb = JobDb.CreatedJobDb(job, new JsonSerializerSettings()); Assert.Equal(jobDb.JobType, _strJobType); Assert.Equal(jobDb.JobParamType, _strJobParamType); Assert.Equal(jobDb.JobParam, _strJobParam); }
private DateTime GetNextStartFailedJobTime(JobMetadata jobMetadata) { IFailedRepeatStrategy strategy; if (jobMetadata.RepeatStrategy != null) { strategy = (IFailedRepeatStrategy)Activator.CreateInstance(jobMetadata.RepeatStrategy); } else { strategy = _settings.FailedRepeatStrategy; } return(DateTime.UtcNow + strategy.GetNextStartInterval(jobMetadata.CountStarted)); }
internal static (List <JobMetadata>, List <JobCategory>) GetAllJobs(Assembly assembly) { var Metadata = new List <JobMetadata>(); var Pages = new List <JobCategory>(); var jobMethods = assembly.GetTypes().Where(x => !x.IsInterface && typeof(IJob).IsAssignableFrom(x) && x.Name != (typeof(IJob).Name)); foreach (Type ti in jobMethods) { var q = "default"; var title = "Default"; if (ti.GetCustomAttributes(true).OfType <JobCategoryAttribute>().Any()) { JobCategory attr = new JobCategory(ti.GetCustomAttribute <JobCategoryAttribute>()); //q = attr.Queue; title = attr.Title; if (!Pages.Any(x => x.Title == title)) { Pages.Add(attr); } } foreach (MethodInfo methodInfo in ti.GetMethods().Where(m => m.DeclaringType == ti)) { string jobName = methodInfo.Name; var meta = new JobMetadata(jobName) { MethodInfo = methodInfo, Queue = q, Category = title }; meta.MethodInfo = methodInfo; if (methodInfo.GetCustomAttributes(true).OfType <DescriptionAttribute>().Any()) { meta.Description = methodInfo.GetCustomAttribute <DescriptionAttribute>().Description; } if (methodInfo.GetCustomAttributes(true).OfType <DisplayNameAttribute>().Any()) { meta.DisplayName = methodInfo.GetCustomAttribute <DisplayNameAttribute>().DisplayName; } Metadata.Add(meta); } } return(Metadata, Pages); }
private async Task ExecuteJob(JobMetadata jobMetadata) { dynamic jobImplementation = null; try { using (var scope = _settings.JobScopeFactory.Create()) { try { jobImplementation = scope.CreateJob(jobMetadata.JobType); } catch (Exception ex) { //Дополнительное логирование ошибки, когда джоб не может быть создан _settings.Logger.Error($"Ошибка создания джоба {jobMetadata.JobType}", ex); throw; } _settings.Logger.Debug("got jobImplementation -" + jobImplementation.GetType()); _settings.Logger.Debug("got JobParam -" + jobMetadata.JobParam.GetType()); await jobImplementation.Execute((dynamic)jobMetadata.JobParam); _settings.Logger.Debug("jobMetadata excecuted"); if (jobMetadata.NextJob != null) { jobMetadata.NextJob.StartAt = DateTime.UtcNow + jobMetadata.NextJob.Delay.GetValueOrDefault(); await _jobRepository.AddJob(JobDb.CreatedJobDb(jobMetadata.NextJob, _settings.JsonSerializerSettings)); _settings.Logger.Debug("next jobMetadata added"); } await _jobRepository.RemoveJob(jobMetadata.JobId); _settings.Logger.Debug("jobMetadata saved success"); } } catch (Exception ex) { await HandleFailed(jobMetadata, ex, jobImplementation); } }
public async Task Schedule_ManyJobs_ShouldScheduleCorrectly() { // Arrange var builder = new ParameterizedJobBuilder <TestJob, string>(_jobsAdderMock.Object, "HALLO", _globalObsoleteInterval); var scheduledJob = new JobMetadata(); var secondJobDelay = TimeSpan.FromSeconds(27); var thirdJobDelay = TimeSpan.FromMinutes(20); _jobsAdderMock.Setup(a => a.AddEnqueueJob(It.IsAny <JobMetadata>())) .Returns(Task.CompletedTask) .Callback((JobMetadata job) => scheduledJob = job); // Act await builder .Next <TestJob, string>("HALLO2") .WithDelay(secondJobDelay) .Next <TestJob, string>("HALLO3") .WithDelay(thirdJobDelay) .Schedule(); // Assert var firstJob = scheduledJob; Assert.Equal(firstJob.ObsoleteInterval, _globalObsoleteInterval); Assert.Equal(firstJob.Delay, TimeSpan.Zero); Assert.NotNull(firstJob.NextJob); var secondJob = firstJob.NextJob; Assert.Equal(secondJob.ObsoleteInterval, _globalObsoleteInterval); Assert.Equal(secondJob.Delay, secondJobDelay); Assert.NotNull(secondJob.NextJob); var thirdJob = secondJob.NextJob; Assert.Equal(thirdJob.ObsoleteInterval, _globalObsoleteInterval); Assert.Equal(thirdJob.Delay, thirdJobDelay); Assert.Null(thirdJob.NextJob); _jobsAdderMock.Verify(a => a.AddEnqueueJob(It.IsAny <JobMetadata>()), Times.Once); _jobsAdderMock.VerifyNoOtherCalls(); }
public async Task Schedule_NoPropertiesHaveBeenPassed_ShouldScheduleWithDefault() { // Arrange var builder = new ParameterizedJobBuilder <TestJob, string>(_jobsAdderMock.Object, "HALLO", _globalObsoleteInterval); var scheduledJob = new JobMetadata(); _jobsAdderMock.Setup(a => a.AddEnqueueJob(It.IsAny <JobMetadata>())) .Returns(Task.CompletedTask) .Callback((JobMetadata job) => scheduledJob = job); // Act await builder.Schedule(); // Assert Assert.Equal(scheduledJob.StartAt, DateTime.UtcNow, TimeSpan.FromMilliseconds(500)); _jobsAdderMock.Verify(a => a.AddEnqueueJob(It.IsAny <JobMetadata>()), Times.Once); _jobsAdderMock.VerifyNoOtherCalls(); }
public Hotbar(long gameOptionsId, Job job) { Slots = new QuickSlot[MaxSlots]; for (int i = 0; i < MaxSlots; i++) { Slots[i] = new(); } AddDefaultSkills(); Id = DatabaseManager.Hotbars.Insert(this, gameOptionsId); void AddDefaultSkills() { JobMetadata jobMetadata = JobMetadataStorage.GetJobMetadata(job); if (jobMetadata is null) { return; } List <int> skillIds = new(); jobMetadata.LearnedSkills.ForEach(x => skillIds.AddRange(x.SkillIds)); List <(int skillId, byte slotPriority)> hotbarSkills = new(); foreach (int skillId in skillIds) { JobSkillMetadata jobSkillMetadata = jobMetadata.Skills.First(x => x.SkillId == skillId); if (jobSkillMetadata.QuickSlotPriority != 99 && jobSkillMetadata.SubJobCode == 0) { hotbarSkills.Add((skillId, jobSkillMetadata.QuickSlotPriority)); } } foreach ((int skillId, byte _) in hotbarSkills.OrderBy(x => x.slotPriority)) { AddToFirstSlot(QuickSlot.From(skillId)); } } }
public async Task Schedule_NoPropertiesHaveBeenSet_ShouldSetDefaultAndSchedule() { // Arrange var builder = new RecurrentJobBuilder(_jobsAdderMock.Object, JobsCron, typeof(TestReccurrentJob), _globalObsoleteInterval); var scheduledJob = new JobMetadata(); _jobsAdderMock.Setup(a => a.AddRecurrentJob(It.IsAny <JobMetadata>())) .Returns(Task.CompletedTask) .Callback((JobMetadata job) => scheduledJob = job); // Act await builder.Schedule(); // Assert Assert.Equal(scheduledJob.JobKey, typeof(TestReccurrentJob).Name); _jobsAdderMock.Verify(a => a.AddRecurrentJob(It.IsAny <JobMetadata>()), Times.Once); _jobsAdderMock.VerifyNoOtherCalls(); }
internal static void GetAllJobs(Assembly assembly) { Metadata = new List <JobMetadata>(); Pages = new List <ManagementPageAttribute>(); foreach (Type ti in assembly.GetTypes().Where(x => !x.IsInterface && typeof(IJob).IsAssignableFrom(x) && x.Name != (typeof(IJob).Name))) { var q = "default"; var title = "Default"; if (ti.GetCustomAttributes(true).OfType <ManagementPageAttribute>().Any()) { var attr = ti.GetCustomAttribute <ManagementPageAttribute>(); q = attr.Queue; title = attr.Title; if (!Pages.Any(x => x.Title == title)) { Pages.Add(attr); } } foreach (var methodInfo in ti.GetMethods().Where(m => m.DeclaringType == ti)) { var meta = new JobMetadata { Type = ti, Queue = q, PageTitle = title }; meta.MethodInfo = methodInfo; if (methodInfo.GetCustomAttributes(true).OfType <DescriptionAttribute>().Any()) { meta.Description = methodInfo.GetCustomAttribute <DescriptionAttribute>().Description; } if (methodInfo.GetCustomAttributes(true).OfType <DisplayNameAttribute>().Any()) { meta.DisplayName = methodInfo.GetCustomAttribute <DisplayNameAttribute>().DisplayName; } Metadata.Add(meta); } } }
public async Task RecurrentJob_ThrowException_AddRecurrentJobNextStart() { // Arrange var jobRepositoryMock = new Mock <IJobRepository>(); var(jobScopeFactoryMock, jobScopeMock) = CreateScopeMock(); var jobAdderJob = new Mock <IAdderJobs>(); const string cron = "*/15 * * * * *"; jobScopeMock.Setup(x => x.CreateJob(It.IsAny <Type>())) .Returns(() => throw new Exception()); jobRepositoryMock.Setup(x => x.GetCronForRecurrentJob(It.IsAny <string>())) .ReturnsAsync(cron); var executorJob = new ExecutorJob( jobRepositoryMock.Object, jobAdderJob.Object, new HorariumSettings { JobScopeFactory = jobScopeFactoryMock.Object }); var job = new JobMetadata() { JobParam = null, JobKey = nameof(TestReccurrentJob), JobType = typeof(TestReccurrentJob), CountStarted = 1, Cron = cron }; // Act await executorJob.Execute(job); // Assert jobRepositoryMock.Verify(x => x.GetCronForRecurrentJob(It.IsAny <string>()), Times.Once); jobAdderJob.Verify(x => x.AddRecurrentJob(It.Is <JobMetadata>(j => j.JobType == job.JobType && j.JobKey == job.JobKey && j.Cron == job.Cron))); }
public static JobDb CreatedJobDb(JobMetadata jobMetadata, JsonSerializerSettings jsonSerializerSettings) { return(new JobDb { JobKey = jobMetadata.JobKey, JobId = jobMetadata.JobId, Status = jobMetadata.Status, JobType = jobMetadata.JobType.AssemblyQualifiedNameWithoutVersion(), JobParamType = jobMetadata.JobParam?.GetType().AssemblyQualifiedNameWithoutVersion(), JobParam = jobMetadata.JobParam?.ToJson(jobMetadata.JobParam.GetType(), jsonSerializerSettings), CountStarted = jobMetadata.CountStarted, StartedExecuting = jobMetadata.StartedExecuting, ExecutedMachine = jobMetadata.ExecutedMachine, StartAt = jobMetadata.StartAt, NextJob = jobMetadata.NextJob != null?CreatedJobDb(jobMetadata.NextJob, jsonSerializerSettings) : null, Cron = jobMetadata.Cron, Delay = jobMetadata.Delay, ObsoleteInterval = jobMetadata.ObsoleteInterval }); }
private async Task HandleFailed(JobMetadata jobMetadata, Exception ex, dynamic jobImplementation) { _horariumLogger.Debug(ex); if (jobMetadata.CountStarted >= _maxCountRepeat) { if (jobImplementation != null && jobImplementation is IAllRepeatesIsFailed) { await jobImplementation.FailedEvent((dynamic)jobMetadata.JobParam, ex); } await _jobRepository.FailedJob(jobMetadata.JobId, ex); _horariumLogger.Debug("jobMetadata saved failed"); } else { await _jobRepository.RepeatJob(jobMetadata.JobId, GetNextStartFailedJobTime(jobMetadata), ex); _horariumLogger.Debug("jobMetadata saved repeat"); } }
public async Task Schedule_CorrectCronPassed_ShouldSetRightStartAtAndSchedule() { // Arrange var builder = new RecurrentJobBuilder(_jobsAdderMock.Object, JobsCron, typeof(TestReccurrentJob), _globalObsoleteInterval); var scheduledJob = new JobMetadata(); var parsedCron = CronExpression.Parse(JobsCron, CronFormat.IncludeSeconds); var expectedStartAt = parsedCron.GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local); _jobsAdderMock.Setup(a => a.AddRecurrentJob(It.IsAny <JobMetadata>())) .Returns(Task.CompletedTask) .Callback((JobMetadata job) => scheduledJob = job); // Act await builder.Schedule(); // Assert Assert.Equal(scheduledJob.StartAt, expectedStartAt); _jobsAdderMock.Verify(a => a.AddRecurrentJob(It.IsAny <JobMetadata>()), Times.Once); _jobsAdderMock.VerifyNoOtherCalls(); }