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
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Clients.Hive;
26using HeuristicLab.Services.Hive.Tests.Mocks;
27using Microsoft.VisualStudio.TestTools.UnitTesting;
28using DT = HeuristicLab.Services.Hive.DataTransfer;
29
30namespace HeuristicLab.Services.Hive.Tests {
31  [TestClass]
32  public class ServiceTests {
33    // use the mock service locator to modify service properties (such as current user)
34    private static MockServiceLocator mockServiceLocator;
35
36    [ClassInitialize]
37    public static void MyClassInitialize(TestContext testContext) {
38      mockServiceLocator = new MockServiceLocator(ServiceLocator.Instance);
39      ServiceLocator.Instance = mockServiceLocator;
40    }
41
42    private HeuristicLab.Services.Hive.ServiceContracts.IHiveService GetLocalService() {
43      return new HeuristicLab.Services.Hive.HiveService();
44    }
45
46    [TestMethod]
47    public void TestJobs() {
48      var service = GetLocalService();
49
50      // create hive experiment
51      DT.Job experiment = new DT.Job() { Name = "TestExperiment", Description = "" };
52
53      // create task
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 });
57
58      DT.TaskData jobData = new DT.TaskData() {
59        //Data = PersistenceUtil.Serialize(new MockJob(500, true))
60        Data = new byte[10000]
61      };
62
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
68      // create plugin
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;
74      plugin1.Hash = hash;
75
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
80      plugin1.Id = service.AddPlugin(plugin1, new List<DT.PluginData> { pluginData1 });
81      pluginData1.PluginId = plugin1.Id;
82
83      // add plugin
84      job.PluginsNeededIds.Add(plugin1.Id);
85
86      // create slave
87      DT.Slave slave = new DT.Slave();
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";
94      slave.CpuArchitecture = DT.CpuArchitecture.x64;
95
96      // add slave
97      service.AddSlave(slave);
98
99      // add hive experiment
100      experiment.Id = service.AddJob(experiment);
101
102      // add task
103      job.JobId = experiment.Id;
104      job.Id = service.AddTask(job, jobData, new List<Guid> { slave.Id });
105
106      // test task
107      DT.Task jobLoaded = service.GetTask(job.Id);
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);
112      Assert.AreEqual(DT.TaskState.Waiting, jobLoaded.State);
113      Assert.IsTrue(job.PluginsNeededIds.SequenceEqual(jobLoaded.PluginsNeededIds));
114      Assert.AreEqual(job.JobId, jobLoaded.JobId);
115
116      DT.TaskData jobDataLoaded = service.GetTaskData(job.Id);
117      Assert.AreEqual(job.Id, jobDataLoaded.TaskId);
118      Assert.IsTrue(jobData.Data.SequenceEqual(jobDataLoaded.Data));
119
120      // test hive experiment
121      DT.Job experimentLoaded = service.GetJob(experiment.Id);
122      Assert.AreEqual(experiment.Id, experimentLoaded.Id);
123      Assert.AreEqual(experiment.Name, experimentLoaded.Name);
124      Assert.AreEqual(experiment.Description, experimentLoaded.Description);
125
126      // test assigned ressources
127      var actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
128      Assert.AreEqual(1, actions.Count);
129      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
130      Assert.AreEqual(job.Id, actions[0].TaskId);
131
132      jobLoaded = service.GetTask(job.Id);
133      Assert.AreEqual(TaskState.Transferring, jobLoaded.State);
134
135      // slave is responsible for updating state to 'Calculating'
136      service.UpdateTaskState(jobLoaded.Id, DT.TaskState.Calculating, slave.Id, null, null);
137
138      // send progress
139      var progress = new Dictionary<Guid, TimeSpan>();
140      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
141      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
142      Assert.AreEqual(0, actions.Count);
143
144      // the task should be in state 'Calculating' now
145      jobLoaded = service.GetTask(job.Id);
146      Assert.AreEqual(TaskState.Calculating, jobLoaded.State);
147      Assert.AreEqual(new TimeSpan(1, 5, 10, 20, 30), jobLoaded.ExecutionTime);
148
149      // test if the task is returned for the resource
150      var jobsBySlave = service.GetTasksByResourceId(slave.Id);
151      Assert.AreEqual(1, jobsBySlave.Count());
152      Assert.AreEqual(job.Id, jobsBySlave.Single().Id);
153
154      // set it to finished
155      service.UpdateTaskState(jobLoaded.Id, DT.TaskState.Finished, slave.Id, null, null);
156
157      // test if the task is returned for the resource (it should not be)
158      var jobsBySlave2 = service.GetTasksByResourceId(slave.Id);
159      Assert.AreEqual(0, jobsBySlave2.Count());
160
161      // set task waiting again
162      service.UpdateTaskState(job.Id, DT.TaskState.Waiting, null, null, string.Empty);
163
164      // get task again
165      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
166      Assert.AreEqual(1, actions.Count);
167      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
168      Assert.AreEqual(job.Id, actions[0].TaskId);
169
170      // create downtime which should make slave unavailable for calculation
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 });
172
173      progress.Clear();
174      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
175      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
176      Assert.AreEqual(1, actions.Count);
177      Assert.AreEqual(MessageContainer.MessageType.PauseAll, actions[0].Message);
178      Assert.AreEqual(Guid.Empty, actions[0].TaskId);
179
180      service.DeleteDowntime(downtimeId);
181
182      // delete
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));
187
188      // send another heartbeat with the deleted task; the server should command the abortion of the task
189      actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
190      Assert.AreEqual(1, actions.Count);
191      Assert.AreEqual(MessageContainer.MessageType.AbortTask, actions[0].Message);
192      Assert.AreEqual(job.Id, actions[0].TaskId);
193
194      // delete slave
195      service.DeleteSlave(slave.Id);
196    }
197
198    [TestMethod]
199    public void TestParentJobs() {
200      var service = GetLocalService();
201
202      // create hive experiment
203      DT.Job experiment = new DT.Job() { Name = "TestExperiment", Description = "" };
204
205      // create parent task
206      DT.Task parentJob = new DT.Task() {
207        CoresNeeded = 1,
208        MemoryNeeded = 0,
209        Priority = 0,
210        IsParentTask = true,
211        FinishWhenChildJobsFinished = true
212      };
213      parentJob.State = DT.TaskState.Offline;
214      parentJob.StateLog.Add(new DT.StateLog { State = DT.TaskState.Offline, DateTime = DateTime.Now });
215
216      DT.TaskData parentJobData = new DT.TaskData() { Data = new byte[0] };
217
218      // create child task
219      DT.Task childJob = new DT.Task() {
220        CoresNeeded = 1,
221        MemoryNeeded = 0,
222        Priority = 0
223      };
224      childJob.State = DT.TaskState.Offline;
225      childJob.StateLog.Add(new DT.StateLog { State = DT.TaskState.Offline, DateTime = DateTime.Now });
226
227      DT.TaskData childJobData = new DT.TaskData() { Data = new byte[1000] };
228
229      // create slave
230      DT.Slave slave = new DT.Slave();
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";
237      slave.CpuArchitecture = DT.CpuArchitecture.x64;
238
239      // add slave
240      service.AddSlave(slave);
241
242      // add hive experiment
243      experiment.Id = service.AddJob(experiment);
244
245      // add parent task
246      parentJob.JobId = experiment.Id;
247      parentJob.Id = service.AddTask(parentJob, parentJobData, new List<Guid> { slave.Id });
248
249      // add child task
250      childJob.JobId = experiment.Id;
251      childJob.Id = service.AddChildTask(parentJob.Id, childJob, childJobData);
252      childJob.ParentTaskId = parentJob.Id;
253
254      // test child task
255      var childJobLoaded = service.GetTask(childJob.Id);
256      Assert.AreEqual(childJob.ParentTaskId, childJobLoaded.ParentTaskId);
257      Assert.AreEqual(childJob.JobId, childJobLoaded.JobId);
258      Assert.AreEqual(DT.TaskState.Waiting, childJobLoaded.State);
259      Assert.AreEqual(false, childJobLoaded.FinishWhenChildJobsFinished);
260      Assert.AreEqual(false, childJobLoaded.IsParentTask);
261
262      // test parent task
263      var parentJobLoaded = service.GetTask(parentJob.Id);
264      Assert.AreEqual(parentJob.JobId, parentJobLoaded.JobId);
265      Assert.AreEqual(TaskState.Waiting, parentJobLoaded.State);
266      Assert.AreEqual(true, parentJobLoaded.FinishWhenChildJobsFinished);
267      Assert.AreEqual(true, parentJobLoaded.IsParentTask);
268
269      // test heartbeat
270      var actions = service.Heartbeat(new DT.Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
271      Assert.AreEqual(1, actions.Count); // only the child task should be assigned
272      Assert.AreEqual(MessageContainer.MessageType.CalculateTask, actions[0].Message);
273      Assert.AreEqual(childJob.Id, actions[0].TaskId);
274
275      // lifecycle - let it process one server-heartbeat; the parent task must NOT be set to finished
276      service.TriggerEventManager(true);
277
278      parentJobLoaded = service.GetTask(parentJob.Id);
279      Assert.AreEqual(TaskState.Waiting, parentJobLoaded.State);
280
281      // set child task to finished
282      childJobLoaded = service.UpdateTaskState(childJobLoaded.Id, DT.TaskState.Finished, slave.Id, null, null);
283
284      // lifecycle - let it process one server-heartbeat; this should set the parent task to finished
285      service.TriggerEventManager(true);
286
287      // test if parent task is finished
288      parentJobLoaded = service.GetTask(parentJob.Id);
289      Assert.AreEqual(TaskState.Finished, parentJobLoaded.State);
290
291      // delete experiment
292      service.DeleteJob(experiment.Id);
293      Assert.AreEqual(null, service.GetTask(parentJob.Id));
294      Assert.AreEqual(null, service.GetTask(childJob.Id));
295
296      service.DeleteSlave(slave.Id);
297    }
298
299
300    [TestMethod]
301    public void TestHiveExperimentPermissions() {
302      var service = GetLocalService();
303      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
304
305      // create hive experiment
306      DT.Job e1 = new DT.Job() { Name = "TestExperiment", Description = "" };
307      e1.Id = service.AddJob(e1);
308
309      var e1loaded = service.GetJob(e1.Id);
310      Assert.AreEqual(Permission.Full, e1loaded.Permission);
311      var allExp = service.GetJobs();
312      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
313
314      // change to user2
315      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
316      try {
317        e1loaded = service.GetJob(e1.Id);
318        Assert.Fail("Access should not be possible");
319      }
320      catch { /* ok, cool */ }
321      allExp = service.GetJobs();
322      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
323
324      // user2 should not be able to grant permissions
325      try {
326        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
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
332      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
333      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
334
335      // back to user2
336      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
337      e1loaded = service.GetJob(e1.Id);
338      Assert.AreEqual(Permission.Read, e1loaded.Permission);
339      allExp = service.GetJobs();
340      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
341
342      // user2 should still not be able to grant permissions
343      try {
344        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Read);
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
350      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
351      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, DT.Permission.Full);
352
353      // back to user2
354      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
355      e1loaded = service.GetJob(e1.Id);
356      Assert.AreEqual(Permission.Full, e1loaded.Permission);
357      allExp = service.GetJobs();
358      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
359
360      // grant rights to user3, now this should be possible due to full permissions
361      service.GrantPermission(e1.Id, MockUserManager.MockUserId3, DT.Permission.Read);
362
363      // back to user1 and revoke rights for user2
364      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
365      service.RevokePermission(e1.Id, MockUserManager.MockUserId2);
366
367      // back to user2
368      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
369      try {
370        e1loaded = service.GetJob(e1.Id);
371        Assert.Fail("Access should not be possible");
372      }
373      catch { /* ok, cool */ }
374      allExp = service.GetJobs();
375      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
376
377      // back to user1
378      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
379      service.DeleteJob(e1.Id);
380    }
381  }
382}
Note: See TracBrowser for help on using the repository browser.