Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs @ 6743

Last change on this file since 6743 was 6743, checked in by ascheibe, 13 years ago

#1233

  • fixed a bug in the Slave UI
  • finished renaming Webservice and Dao methods to be consistent with Job/Task naming
  • some cosmetic changes and project dependencies cleanups
File size: 15.8 KB
RevLine 
[5156]1#region License Information
2/* HeuristicLab
[6372]3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[5156]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[5106]23using System.Collections.Generic;
24using System.Linq;
[6717]25using HeuristicLab.Clients.Hive;
[6457]26using HeuristicLab.Services.Hive.Tests.Mocks;
[5156]27using Microsoft.VisualStudio.TestTools.UnitTesting;
[6717]28using DT = HeuristicLab.Services.Hive.DataTransfer;
[5106]29
30namespace HeuristicLab.Services.Hive.Tests {
31  [TestClass]
32  public class ServiceTests {
[6457]33    // use the mock service locator to modify service properties (such as current user)
34    private static MockServiceLocator mockServiceLocator;
[5106]35
36    [ClassInitialize]
37    public static void MyClassInitialize(TestContext testContext) {
[6457]38      mockServiceLocator = new MockServiceLocator(ServiceLocator.Instance);
39      ServiceLocator.Instance = mockServiceLocator;
[5106]40    }
41
[6717]42    private HeuristicLab.Services.Hive.ServiceContracts.IHiveService GetLocalService() {
43      return new HeuristicLab.Services.Hive.HiveService();
[5106]44    }
45
46    [TestMethod]
47    public void TestJobs() {
48      var service = GetLocalService();
49
[5511]50      // create hive experiment
[6723]51      DT.Job experiment = new DT.Job() { Name = "TestExperiment", Description = "" };
[5106]52
[6725]53      // create task
[6721]54      DT.Task job = new DT.Task() { CoresNeeded = 1, MemoryNeeded = 0, Priority = 0 };
55      job.State = DT.TaskState.Offline;
56      job.StateLog.Add(new DT.StateLog { State = DT.TaskState.Offline, DateTime = DateTime.Now });
[5106]57
[6721]58      DT.TaskData jobData = new DT.TaskData() {
[5511]59        //Data = PersistenceUtil.Serialize(new MockJob(500, true))
[5526]60        Data = new byte[10000]
[5106]61      };
62
[6452]63      // delete plugin first (otherwise the system would not allow it because of the same hash code
64      var hash = new byte[] { 1, 2, 3 };
65      var p = service.GetPluginByHash(hash);
66      if (p != null) service.DeletePlugin(p.Id);
67
[5511]68      // create plugin
[5404]69      DT.Plugin plugin1 = new DT.Plugin();
70      plugin1.Name = "Tests.MyPlugin";
71      plugin1.Version = new Version("1.0.0.0");
72      plugin1.UserId = Guid.Empty;
73      plugin1.DateCreated = DateTime.Now;
[6452]74      plugin1.Hash = hash;
[6457]75
[5404]76      DT.PluginData pluginData1 = new DT.PluginData();
77      pluginData1.FileName = "Tests.MyPlugin-1.0.dll";
78      pluginData1.Data = new byte[] { 0, 1, 2, 3, 4, 5 };
79
[6717]80      plugin1.Id = service.AddPlugin(plugin1, new List<DT.PluginData> { pluginData1 });
[5511]81      pluginData1.PluginId = plugin1.Id;
82
83      // add plugin
[5404]84      job.PluginsNeededIds.Add(plugin1.Id);
85
[5511]86      // create slave
[6717]87      DT.Slave slave = new DT.Slave();
[5511]88      slave.Id = Guid.NewGuid();
89      slave.Name = "TestSlave";
90      slave.Memory = 1024;
91      slave.Cores = 4;
92      slave.CpuSpeed = 2800;
93      slave.OperatingSystem = "Windows 3.11";
[6717]94      slave.CpuArchitecture = DT.CpuArchitecture.x64;
[5511]95
96      // add slave
97      service.AddSlave(slave);
98
99      // add hive experiment
[6743]100      experiment.Id = service.AddJob(experiment);
[5511]101
[6725]102      // add task
[6723]103      job.JobId = experiment.Id;
[6743]104      job.Id = service.AddTask(job, jobData, new List<Guid> { slave.Id });
[6369]105
[6725]106      // test task
[6743]107      DT.Task jobLoaded = service.GetTask(job.Id);
[5106]108      Assert.AreEqual(job.Id, jobLoaded.Id);
109      Assert.AreEqual(job.CoresNeeded, jobLoaded.CoresNeeded);
110      Assert.AreEqual(job.MemoryNeeded, jobLoaded.MemoryNeeded);
111      Assert.AreEqual(job.Priority, jobLoaded.Priority);
[6721]112      Assert.AreEqual(DT.TaskState.Waiting, jobLoaded.State);
[5404]113      Assert.IsTrue(job.PluginsNeededIds.SequenceEqual(jobLoaded.PluginsNeededIds));
[6723]114      Assert.AreEqual(job.JobId, jobLoaded.JobId);
[5526]115
[6743]116      DT.TaskData jobDataLoaded = service.GetTaskData(job.Id);
[6721]117      Assert.AreEqual(job.Id, jobDataLoaded.TaskId);
[5106]118      Assert.IsTrue(jobData.Data.SequenceEqual(jobDataLoaded.Data));
119
[5511]120      // test hive experiment
[6743]121      DT.Job experimentLoaded = service.GetJob(experiment.Id);
[5106]122      Assert.AreEqual(experiment.Id, experimentLoaded.Id);
123      Assert.AreEqual(experiment.Name, experimentLoaded.Name);
124      Assert.AreEqual(experiment.Description, experimentLoaded.Description);
125
[5511]126      // test assigned ressources
[6717]127      var actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
[5511]128      Assert.AreEqual(1, actions.Count);
[6725]129      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
[6721]130      Assert.AreEqual(job.Id, actions[0].TaskId);
[5511]131
[6743]132      jobLoaded = service.GetTask(job.Id);
[6721]133      Assert.AreEqual(TaskState.Transferring, jobLoaded.State);
[5511]134
[5636]135      // slave is responsible for updating state to 'Calculating'
[6743]136      service.UpdateTaskState(jobLoaded.Id, DT.TaskState.Calculating, slave.Id, null, null);
[5636]137
[5511]138      // send progress
139      var progress = new Dictionary<Guid, TimeSpan>();
140      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
[6717]141      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
[5511]142      Assert.AreEqual(0, actions.Count);
143
[6725]144      // the task should be in state 'Calculating' now
[6743]145      jobLoaded = service.GetTask(job.Id);
[6721]146      Assert.AreEqual(TaskState.Calculating, jobLoaded.State);
[6267]147      Assert.AreEqual(new TimeSpan(1, 5, 10, 20, 30), jobLoaded.ExecutionTime);
[5511]148
[6725]149      // test if the task is returned for the resource
[6743]150      var jobsBySlave = service.GetTasksByResourceId(slave.Id);
[6267]151      Assert.AreEqual(1, jobsBySlave.Count());
152      Assert.AreEqual(job.Id, jobsBySlave.Single().Id);
[6369]153
[6267]154      // set it to finished
[6743]155      service.UpdateTaskState(jobLoaded.Id, DT.TaskState.Finished, slave.Id, null, null);
[6267]156
[6725]157      // test if the task is returned for the resource (it should not be)
[6743]158      var jobsBySlave2 = service.GetTasksByResourceId(slave.Id);
[6267]159      Assert.AreEqual(0, jobsBySlave2.Count());
160
[6725]161      // set task waiting again
[6743]162      service.UpdateTaskState(job.Id, DT.TaskState.Waiting, null, null, string.Empty);
[6369]163
[6725]164      // get task again
[6717]165      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
[6369]166      Assert.AreEqual(1, actions.Count);
[6725]167      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
[6721]168      Assert.AreEqual(job.Id, actions[0].TaskId);
[6369]169
[6452]170      // create downtime which should make slave unavailable for calculation
[6717]171      Guid downtimeId = service.AddDowntime(new DT.Downtime { ResourceId = slave.Id, StartDate = DateTime.Now - TimeSpan.FromMinutes(1), EndDate = DateTime.Now + TimeSpan.FromMinutes(1), Recurring = false });
[6369]172
173      progress.Clear();
174      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
[6717]175      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
[6369]176      Assert.AreEqual(1, actions.Count);
177      Assert.AreEqual(MessageContainer.MessageType.PauseAll, actions[0].Message);
[6721]178      Assert.AreEqual(Guid.Empty, actions[0].TaskId);
[6369]179
[6452]180      service.DeleteDowntime(downtimeId);
[6369]181
[5511]182      // delete
[6743]183      service.DeleteJob(experiment.Id);
184      Assert.AreEqual(null, service.GetJob(experiment.Id));
185      Assert.AreEqual(null, service.GetTask(job.Id));
186      Assert.AreEqual(null, service.GetTaskData(job.Id));
[5511]187
[6725]188      // send another heartbeat with the deleted task; the server should command the abortion of the task
[6717]189      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
[5511]190      Assert.AreEqual(1, actions.Count);
[6725]191      Assert.AreEqual(MessageContainer.MessageType.AbortTask, actions[0].Message);
[6721]192      Assert.AreEqual(job.Id, actions[0].TaskId);
[5511]193
194      // delete slave
195      service.DeleteSlave(slave.Id);
[5106]196    }
197
198    [TestMethod]
[5526]199    public void TestParentJobs() {
[5106]200      var service = GetLocalService();
[5404]201
[5526]202      // create hive experiment
[6723]203      DT.Job experiment = new DT.Job() { Name = "TestExperiment", Description = "" };
[5106]204
[6725]205      // create parent task
[6721]206      DT.Task parentJob = new DT.Task() {
[5526]207        CoresNeeded = 1,
208        MemoryNeeded = 0,
209        Priority = 0,
[6725]210        IsParentTask = true,
[5526]211        FinishWhenChildJobsFinished = true
212      };
[6721]213      parentJob.State = DT.TaskState.Offline;
214      parentJob.StateLog.Add(new DT.StateLog { State = DT.TaskState.Offline, DateTime = DateTime.Now });
[5404]215
[6721]216      DT.TaskData parentJobData = new DT.TaskData() { Data = new byte[0] };
[5106]217
[6725]218      // create child task
[6721]219      DT.Task childJob = new DT.Task() {
[5526]220        CoresNeeded = 1,
221        MemoryNeeded = 0,
222        Priority = 0
223      };
[6721]224      childJob.State = DT.TaskState.Offline;
225      childJob.StateLog.Add(new DT.StateLog { State = DT.TaskState.Offline, DateTime = DateTime.Now });
[5404]226
[6721]227      DT.TaskData childJobData = new DT.TaskData() { Data = new byte[1000] };
[5404]228
[5526]229      // create slave
[6717]230      DT.Slave slave = new DT.Slave();
[5526]231      slave.Id = Guid.NewGuid();
232      slave.Name = "TestSlave";
233      slave.Memory = 1024;
234      slave.Cores = 4;
235      slave.CpuSpeed = 2800;
236      slave.OperatingSystem = "Windows 3.11";
[6717]237      slave.CpuArchitecture = DT.CpuArchitecture.x64;
[5404]238
[5526]239      // add slave
240      service.AddSlave(slave);
[5106]241
[6006]242      // add hive experiment
[6743]243      experiment.Id = service.AddJob(experiment);
[6006]244
[6725]245      // add parent task
[6723]246      parentJob.JobId = experiment.Id;
[6743]247      parentJob.Id = service.AddTask(parentJob, parentJobData, new List<Guid> { slave.Id });
[5106]248
[6725]249      // add child task
[6723]250      childJob.JobId = experiment.Id;
[6743]251      childJob.Id = service.AddChildTask(parentJob.Id, childJob, childJobData);
[6721]252      childJob.ParentTaskId = parentJob.Id;
[5106]253
[6725]254      // test child task
[6743]255      var childJobLoaded = service.GetTask(childJob.Id);
[6721]256      Assert.AreEqual(childJob.ParentTaskId, childJobLoaded.ParentTaskId);
[6723]257      Assert.AreEqual(childJob.JobId, childJobLoaded.JobId);
[6721]258      Assert.AreEqual(DT.TaskState.Waiting, childJobLoaded.State);
[5526]259      Assert.AreEqual(false, childJobLoaded.FinishWhenChildJobsFinished);
[6725]260      Assert.AreEqual(false, childJobLoaded.IsParentTask);
[5404]261
[6725]262      // test parent task
[6743]263      var parentJobLoaded = service.GetTask(parentJob.Id);
[6723]264      Assert.AreEqual(parentJob.JobId, parentJobLoaded.JobId);
[6721]265      Assert.AreEqual(TaskState.Waiting, parentJobLoaded.State);
[5526]266      Assert.AreEqual(true, parentJobLoaded.FinishWhenChildJobsFinished);
[6725]267      Assert.AreEqual(true, parentJobLoaded.IsParentTask);
[5526]268
269      // test heartbeat
[6717]270      var actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
[6725]271      Assert.AreEqual(1, actions.Count); // only the child task should be assigned
272      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
[6721]273      Assert.AreEqual(childJob.Id, actions[0].TaskId);
[5526]274
[6725]275      // lifecycle - let it process one server-heartbeat; the parent task must NOT be set to finished
[6698]276      service.TriggerEventManager(true);
[5526]277
[6743]278      parentJobLoaded = service.GetTask(parentJob.Id);
[6721]279      Assert.AreEqual(TaskState.Waiting, parentJobLoaded.State);
[5526]280
[6725]281      // set child task to finished
[6743]282      childJobLoaded = service.UpdateTaskState(childJobLoaded.Id, DT.TaskState.Finished, slave.Id, null, null);
[5526]283
[6725]284      // lifecycle - let it process one server-heartbeat; this should set the parent task to finished
[6698]285      service.TriggerEventManager(true);
[5526]286
[6725]287      // test if parent task is finished
[6743]288      parentJobLoaded = service.GetTask(parentJob.Id);
[6721]289      Assert.AreEqual(TaskState.Finished, parentJobLoaded.State);
[5526]290
291      // delete experiment
[6743]292      service.DeleteJob(experiment.Id);
293      Assert.AreEqual(null, service.GetTask(parentJob.Id));
294      Assert.AreEqual(null, service.GetTask(childJob.Id));
[5526]295
296      service.DeleteSlave(slave.Id);
[5106]297    }
[6457]298
299
300    [TestMethod]
301    public void TestHiveExperimentPermissions() {
302      var service = GetLocalService();
[6463]303      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6457]304
305      // create hive experiment
[6723]306      DT.Job e1 = new DT.Job() { Name = "TestExperiment", Description = "" };
[6743]307      e1.Id = service.AddJob(e1);
[6717]308
[6743]309      var e1loaded = service.GetJob(e1.Id);
[6457]310      Assert.AreEqual(Permission.Full, e1loaded.Permission);
[6743]311      var allExp = service.GetJobs();
[6463]312      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
[6717]313
[6457]314      // change to user2
[6463]315      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
316      try {
[6743]317        e1loaded = service.GetJob(e1.Id);
[6463]318        Assert.Fail("Access should not be possible");
[6717]319      }
320      catch { /* ok, cool */ }
[6743]321      allExp = service.GetJobs();
[6463]322      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
[6457]323
324      // user2 should not be able to grant permissions
325      try {
[6717]326        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
[6457]327        Assert.Fail("Should not be possible to grant permission due to missing permission for User2");
328      }
329      catch { /* ok, cool */ }
330
331      // switch back to user1 (owner) and grant user2 permissions
[6463]332      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6717]333      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
[6457]334
335      // back to user2
[6463]336      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
[6743]337      e1loaded = service.GetJob(e1.Id);
[6463]338      Assert.AreEqual(Permission.Read, e1loaded.Permission);
[6743]339      allExp = service.GetJobs();
[6463]340      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
[6457]341
342      // user2 should still not be able to grant permissions
343      try {
[6717]344        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
[6457]345        Assert.Fail("Should not be possible to grant permission due to missing permission for User2");
346      }
347      catch { /* ok, cool */ }
348
349      // back to user1
[6463]350      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6717]351      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Full);
[6457]352
353      // back to user2
[6463]354      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
[6743]355      e1loaded = service.GetJob(e1.Id);
[6457]356      Assert.AreEqual(Permission.Full, e1loaded.Permission);
[6743]357      allExp = service.GetJobs();
[6463]358      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
[6717]359
[6457]360      // grant rights to user3, now this should be possible due to full permissions
[6717]361      service.GrantPermission(e1.Id, MockUserManager.MockUserId3, DT.Permission.Read);
[6457]362
363      // back to user1 and revoke rights for user2
[6463]364      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
365      service.RevokePermission(e1.Id, MockUserManager.MockUserId2);
[6457]366
367      // back to user2
[6463]368      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
369      try {
[6743]370        e1loaded = service.GetJob(e1.Id);
[6463]371        Assert.Fail("Access should not be possible");
372      }
373      catch { /* ok, cool */ }
[6743]374      allExp = service.GetJobs();
[6463]375      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
[6457]376
[6463]377      // back to user1
378      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6743]379      service.DeleteJob(e1.Id);
[6457]380    }
[5106]381  }
382}
Note: See TracBrowser for help on using the repository browser.