Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 6593 was 6463, checked in by cneumuel, 14 years ago

#1233

  • created user interface for experiment sharing
  • created UserManager which provides access to the users
  • inserted a lot of security and authorization checks serverside
  • minor fixes in experiment manager
File size: 16.0 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;
[6431]25using HeuristicLab.Services.Hive.Common;
26using HeuristicLab.Services.Hive.Common.DataTransfer;
27using HeuristicLab.Services.Hive.Common.ServiceContracts;
[6457]28using HeuristicLab.Services.Hive.Tests.Mocks;
[5156]29using Microsoft.VisualStudio.TestTools.UnitTesting;
[6431]30using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
[5106]31
32namespace HeuristicLab.Services.Hive.Tests {
33  [TestClass]
34  public class ServiceTests {
[6457]35    // use the mock service locator to modify service properties (such as current user)
36    private static MockServiceLocator mockServiceLocator;
[5106]37
38    [ClassInitialize]
39    public static void MyClassInitialize(TestContext testContext) {
[6457]40      mockServiceLocator = new MockServiceLocator(ServiceLocator.Instance);
41      ServiceLocator.Instance = mockServiceLocator;
[5106]42    }
43
44    private IHiveService GetLocalService() {
45      return new HiveService();
46    }
47
48    [TestMethod]
49    public void TestJobs() {
50      var service = GetLocalService();
51
[5511]52      // create hive experiment
[6457]53      DT.HiveExperiment experiment = new DT.HiveExperiment() { Name = "TestExperiment", Description = "" };
[5106]54
[5511]55      // create job
[6457]56      DT.Job job = new DT.Job() { CoresNeeded = 1, MemoryNeeded = 0, Priority = 0 };
[5636]57      job.State = JobState.Offline;
58      job.StateLog.Add(new StateLog { State = JobState.Offline, DateTime = DateTime.Now });
[5106]59
60      DT.JobData jobData = new DT.JobData() {
[5511]61        //Data = PersistenceUtil.Serialize(new MockJob(500, true))
[5526]62        Data = new byte[10000]
[5106]63      };
64
[6452]65      // delete plugin first (otherwise the system would not allow it because of the same hash code
66      var hash = new byte[] { 1, 2, 3 };
67      var p = service.GetPluginByHash(hash);
68      if (p != null) service.DeletePlugin(p.Id);
69
[5511]70      // create plugin
[5404]71      DT.Plugin plugin1 = new DT.Plugin();
72      plugin1.Name = "Tests.MyPlugin";
73      plugin1.Version = new Version("1.0.0.0");
74      plugin1.UserId = Guid.Empty;
75      plugin1.DateCreated = DateTime.Now;
[6452]76      plugin1.Hash = hash;
[6457]77
[5404]78      DT.PluginData pluginData1 = new DT.PluginData();
79      pluginData1.FileName = "Tests.MyPlugin-1.0.dll";
80      pluginData1.Data = new byte[] { 0, 1, 2, 3, 4, 5 };
81
[5511]82      plugin1.Id = service.AddPlugin(plugin1, new List<PluginData> { pluginData1 });
83      pluginData1.PluginId = plugin1.Id;
84
85      // add plugin
[5404]86      job.PluginsNeededIds.Add(plugin1.Id);
87
[5511]88      // create slave
89      DT.Slave slave = new Slave();
90      slave.Id = Guid.NewGuid();
91      slave.Name = "TestSlave";
92      slave.Memory = 1024;
93      slave.Cores = 4;
94      slave.CpuSpeed = 2800;
95      slave.OperatingSystem = "Windows 3.11";
96      slave.CpuArchitecture = CpuArchitecture.x64;
97
98      // add slave
99      service.AddSlave(slave);
100
101      // add hive experiment
102      experiment.Id = service.AddHiveExperiment(experiment);
103
[6006]104      // add job
105      job.HiveExperimentId = experiment.Id;
106      job.Id = service.AddJob(job, jobData, new List<Guid> { slave.Id });
[6369]107
[5511]108      // test job
[5106]109      DT.Job jobLoaded = service.GetJob(job.Id);
110      Assert.AreEqual(job.Id, jobLoaded.Id);
111      Assert.AreEqual(job.CoresNeeded, jobLoaded.CoresNeeded);
112      Assert.AreEqual(job.MemoryNeeded, jobLoaded.MemoryNeeded);
113      Assert.AreEqual(job.Priority, jobLoaded.Priority);
[5511]114      Assert.AreEqual(JobState.Waiting, jobLoaded.State);
[5404]115      Assert.IsTrue(job.PluginsNeededIds.SequenceEqual(jobLoaded.PluginsNeededIds));
[6006]116      Assert.AreEqual(job.HiveExperimentId, jobLoaded.HiveExperimentId);
[5526]117
[5106]118      DT.JobData jobDataLoaded = service.GetJobData(job.Id);
119      Assert.AreEqual(job.Id, jobDataLoaded.JobId);
120      Assert.IsTrue(jobData.Data.SequenceEqual(jobDataLoaded.Data));
121
[5511]122      // test hive experiment
[5106]123      DT.HiveExperiment experimentLoaded = service.GetHiveExperiment(experiment.Id);
124      Assert.AreEqual(experiment.Id, experimentLoaded.Id);
125      Assert.AreEqual(experiment.Name, experimentLoaded.Name);
126      Assert.AreEqual(experiment.Description, experimentLoaded.Description);
127
[5511]128      // test assigned ressources
[5526]129      var actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
[5511]130      Assert.AreEqual(1, actions.Count);
131      Assert.AreEqual(MessageContainer.MessageType.CalculateJob, actions[0].Message);
132      Assert.AreEqual(job.Id, actions[0].JobId);
133
134      jobLoaded = service.GetJob(job.Id);
135      Assert.AreEqual(JobState.Transferring, jobLoaded.State);
136
[5636]137      // slave is responsible for updating state to 'Calculating'
138      service.UpdateJobState(jobLoaded.Id, JobState.Calculating, slave.Id, null, null);
139
[5511]140      // send progress
141      var progress = new Dictionary<Guid, TimeSpan>();
142      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
143      actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
144      Assert.AreEqual(0, actions.Count);
145
146      // the job should be in state 'Calculating' now
147      jobLoaded = service.GetJob(job.Id);
148      Assert.AreEqual(JobState.Calculating, jobLoaded.State);
[6267]149      Assert.AreEqual(new TimeSpan(1, 5, 10, 20, 30), jobLoaded.ExecutionTime);
[5511]150
[6267]151      // test if the job is returned for the resource
152      var jobsBySlave = service.GetJobsByResourceId(slave.Id);
153      Assert.AreEqual(1, jobsBySlave.Count());
154      Assert.AreEqual(job.Id, jobsBySlave.Single().Id);
[6369]155
[6267]156      // set it to finished
157      service.UpdateJobState(jobLoaded.Id, JobState.Finished, slave.Id, null, null);
158
[6369]159      // test if the job is returned for the resource (it should not be)
[6267]160      var jobsBySlave2 = service.GetJobsByResourceId(slave.Id);
161      Assert.AreEqual(0, jobsBySlave2.Count());
162
[6369]163      // set job waiting again
164      service.UpdateJobState(job.Id, JobState.Waiting, null, null, string.Empty);
165
166      // get job again
167      actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
168      Assert.AreEqual(1, actions.Count);
169      Assert.AreEqual(MessageContainer.MessageType.CalculateJob, actions[0].Message);
170      Assert.AreEqual(job.Id, actions[0].JobId);
171
[6452]172      // create downtime which should make slave unavailable for calculation
173      Guid downtimeId = service.AddDowntime(new Downtime { ResourceId = slave.Id, StartDate = DateTime.Now - TimeSpan.FromMinutes(1), EndDate = DateTime.Now + TimeSpan.FromMinutes(1), Recurring = false });
[6369]174
175      progress.Clear();
176      progress.Add(job.Id, new TimeSpan(1, 5, 10, 20, 30));
177      actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
178      Assert.AreEqual(1, actions.Count);
179      Assert.AreEqual(MessageContainer.MessageType.PauseAll, actions[0].Message);
180      Assert.AreEqual(Guid.Empty, actions[0].JobId);
181
[6452]182      service.DeleteDowntime(downtimeId);
[6369]183
[5511]184      // delete
[5106]185      service.DeleteHiveExperiment(experiment.Id);
186      Assert.AreEqual(null, service.GetHiveExperiment(experiment.Id));
187      Assert.AreEqual(null, service.GetJob(job.Id));
188      Assert.AreEqual(null, service.GetJobData(job.Id));
[5511]189
190      // send another heartbeat with the deleted job; the server should command the abortion of the job
191      actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 3, FreeMemory = 1024, JobProgress = progress });
192      Assert.AreEqual(1, actions.Count);
193      Assert.AreEqual(MessageContainer.MessageType.AbortJob, actions[0].Message);
194      Assert.AreEqual(job.Id, actions[0].JobId);
195
196      // delete slave
197      service.DeleteSlave(slave.Id);
[5106]198    }
199
200    [TestMethod]
[5526]201    public void TestParentJobs() {
[5106]202      var service = GetLocalService();
[5404]203
[5526]204      // create hive experiment
[6457]205      DT.HiveExperiment experiment = new DT.HiveExperiment() { Name = "TestExperiment", Description = "" };
[5106]206
[5526]207      // create parent job
208      DT.Job parentJob = new DT.Job() {
209        CoresNeeded = 1,
210        MemoryNeeded = 0,
211        Priority = 0,
212        IsParentJob = true,
213        FinishWhenChildJobsFinished = true
214      };
[5636]215      parentJob.State = JobState.Offline;
216      parentJob.StateLog.Add(new StateLog { State = JobState.Offline, DateTime = DateTime.Now });
[5404]217
[5526]218      DT.JobData parentJobData = new DT.JobData() { Data = new byte[0] };
[5106]219
[5526]220      // create child job
221      DT.Job childJob = new DT.Job() {
222        CoresNeeded = 1,
223        MemoryNeeded = 0,
224        Priority = 0
225      };
[5636]226      childJob.State = JobState.Offline;
227      childJob.StateLog.Add(new StateLog { State = JobState.Offline, DateTime = DateTime.Now });
[5404]228
[5526]229      DT.JobData childJobData = new DT.JobData() { Data = new byte[1000] };
[5404]230
[5526]231      // create slave
232      DT.Slave slave = new Slave();
233      slave.Id = Guid.NewGuid();
234      slave.Name = "TestSlave";
235      slave.Memory = 1024;
236      slave.Cores = 4;
237      slave.CpuSpeed = 2800;
238      slave.OperatingSystem = "Windows 3.11";
239      slave.CpuArchitecture = CpuArchitecture.x64;
[5404]240
[5526]241      // add slave
242      service.AddSlave(slave);
[5106]243
[6006]244      // add hive experiment
245      experiment.Id = service.AddHiveExperiment(experiment);
246
[5526]247      // add parent job
[6006]248      parentJob.HiveExperimentId = experiment.Id;
[5526]249      parentJob.Id = service.AddJob(parentJob, parentJobData, new List<Guid> { slave.Id });
[5106]250
[5526]251      // add child job
[6006]252      childJob.HiveExperimentId = experiment.Id;
[5526]253      childJob.Id = service.AddChildJob(parentJob.Id, childJob, childJobData);
254      childJob.ParentJobId = parentJob.Id;
[5106]255
[5526]256      // test child job
257      var childJobLoaded = service.GetJob(childJob.Id);
258      Assert.AreEqual(childJob.ParentJobId, childJobLoaded.ParentJobId);
[6006]259      Assert.AreEqual(childJob.HiveExperimentId, childJobLoaded.HiveExperimentId);
[5526]260      Assert.AreEqual(JobState.Waiting, childJobLoaded.State);
261      Assert.AreEqual(false, childJobLoaded.FinishWhenChildJobsFinished);
262      Assert.AreEqual(false, childJobLoaded.IsParentJob);
[5404]263
[5526]264      // test parent job
265      var parentJobLoaded = service.GetJob(parentJob.Id);
[6006]266      Assert.AreEqual(parentJob.HiveExperimentId, parentJobLoaded.HiveExperimentId);
[5526]267      Assert.AreEqual(JobState.Waiting, parentJobLoaded.State);
268      Assert.AreEqual(true, parentJobLoaded.FinishWhenChildJobsFinished);
269      Assert.AreEqual(true, parentJobLoaded.IsParentJob);
270
271      // test heartbeat
272      var actions = service.Heartbeat(new Heartbeat() { SlaveId = slave.Id, AssignJob = true, FreeCores = 4, FreeMemory = 1024, JobProgress = new Dictionary<Guid, TimeSpan>() });
273      Assert.AreEqual(1, actions.Count); // only the child job should be assigned
274      Assert.AreEqual(MessageContainer.MessageType.CalculateJob, actions[0].Message);
275      Assert.AreEqual(childJob.Id, actions[0].JobId);
276
277      // lifecycle - let it process one server-heartbeat; the parent job must NOT be set to finished
[5636]278      service.TriggerLifecycle(true);
[5526]279
280      parentJobLoaded = service.GetJob(parentJob.Id);
281      Assert.AreEqual(JobState.Waiting, parentJobLoaded.State);
282
283      // set child job to finished
[5636]284      childJobLoaded = service.UpdateJobState(childJobLoaded.Id, JobState.Finished, slave.Id, null, null);
[5526]285
286      // lifecycle - let it process one server-heartbeat; this should set the parent job to finished
[5636]287      service.TriggerLifecycle(true);
[5526]288
289      // test if parent job is finished
290      parentJobLoaded = service.GetJob(parentJob.Id);
291      Assert.AreEqual(JobState.Finished, parentJobLoaded.State);
292
293      // delete experiment
294      service.DeleteHiveExperiment(experiment.Id);
295      Assert.AreEqual(null, service.GetJob(parentJob.Id));
296      Assert.AreEqual(null, service.GetJob(childJob.Id));
297
298      service.DeleteSlave(slave.Id);
[5106]299    }
[6457]300
301
302    [TestMethod]
303    public void TestHiveExperimentPermissions() {
304      var service = GetLocalService();
[6463]305      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6457]306
307      // create hive experiment
308      DT.HiveExperiment e1 = new DT.HiveExperiment() { Name = "TestExperiment", Description = "" };
309      e1.Id = service.AddHiveExperiment(e1);
310     
311      var e1loaded = service.GetHiveExperiment(e1.Id);
312      Assert.AreEqual(Permission.Full, e1loaded.Permission);
[6463]313      var allExp = service.GetHiveExperiments();
314      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
315     
[6457]316      // change to user2
[6463]317      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
318      try {
319        e1loaded = service.GetHiveExperiment(e1.Id);
320        Assert.Fail("Access should not be possible");
321      } catch { /* ok, cool */ }
322      allExp = service.GetHiveExperiments();
323      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
[6457]324
325      // user2 should not be able to grant permissions
326      try {
[6463]327        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, Permission.Read);
[6457]328        Assert.Fail("Should not be possible to grant permission due to missing permission for User2");
329      }
330      catch { /* ok, cool */ }
331
332      // switch back to user1 (owner) and grant user2 permissions
[6463]333      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
334      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, Permission.Read);
[6457]335
336      // back to user2
[6463]337      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
[6457]338      e1loaded = service.GetHiveExperiment(e1.Id);
[6463]339      Assert.AreEqual(Permission.Read, e1loaded.Permission);
340      allExp = service.GetHiveExperiments();
341      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
[6457]342
343      // user2 should still not be able to grant permissions
344      try {
[6463]345        service.GrantPermission(e1.Id, MockUserManager.MockUserId2, Permission.Read);
[6457]346        Assert.Fail("Should not be possible to grant permission due to missing permission for User2");
347      }
348      catch { /* ok, cool */ }
349
350      // back to user1
[6463]351      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
352      service.GrantPermission(e1.Id, MockUserManager.MockUserId2, Permission.Full);
[6457]353
354      // back to user2
[6463]355      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
[6457]356      e1loaded = service.GetHiveExperiment(e1.Id);
357      Assert.AreEqual(Permission.Full, e1loaded.Permission);
[6463]358      allExp = service.GetHiveExperiments();
359      Assert.AreEqual(1, allExp.Count(x => x.Id == e1.Id));
360     
[6457]361      // grant rights to user3, now this should be possible due to full permissions
[6463]362      service.GrantPermission(e1.Id, MockUserManager.MockUserId3, Permission.Read);
[6457]363
364      // back to user1 and revoke rights for user2
[6463]365      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
366      service.RevokePermission(e1.Id, MockUserManager.MockUserId2);
[6457]367
368      // back to user2
[6463]369      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId2);
370      try {
371        e1loaded = service.GetHiveExperiment(e1.Id);
372        Assert.Fail("Access should not be possible");
373      }
374      catch { /* ok, cool */ }
375      allExp = service.GetHiveExperiments();
376      Assert.AreEqual(0, allExp.Count(x => x.Id == e1.Id));
[6457]377
[6463]378      // back to user1
379      mockServiceLocator.SetCurrentUserId(MockUserManager.MockUserId1);
[6457]380      service.DeleteHiveExperiment(e1.Id);
381    }
[5106]382  }
383}
Note: See TracBrowser for help on using the repository browser.