This renames unreachableInactiveAfter and
unreachbleExpungeAfter to inactiveAfter and expungeAfter to avoid
API stutter such as unreachableStrategy.unreachableInactiveAfter.
Closes #4794.
jdef | |
meichstedt |
This renames unreachableInactiveAfter and
unreachbleExpungeAfter to inactiveAfter and expungeAfter to avoid
API stutter such as unreachableStrategy.unreachableInactiveAfter.
Closes #4794.
unit-test
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Can't run Marathon with this commit due to flood of following exception:
Caused by: play.api.libs.json.JsResultException: JsResultException(errors:List((/unreachableStrategy/inactiveAfter,List(ValidationError(List(error.path.missing),WrappedArray()))), (/unreachableStrategy/expungeAfter,List(ValidationError(List(error.path.missing),WrappedArray())))))
@janisz Your marathon state seems to contain instances with an unreachableStrategy including the previous Json representation (different property names). Instances are serialized to JSON and stored as a byte string; Unfortunately, we do not have a migration from snapshot to snapshot in place so a state that was created with a snapshot previous to this one cannot be used :|
Commit | Tree | Parents | Author | Summary | Date |
---|---|---|---|---|---|
7d746c929bea | 9cdd31242439 | ef6a71d2b50d | jeschkies | Rename unreachable strategy parameters to avoid API stutter. (Show More…) | Dec 8 2016, 2:20 PM |
Show First 20 Lines • Show All 745 Lines • ▼ Show 20 Line(s) | |||
746 | 746 | "killSelection": { | |
---|---|---|---|
747 | 747 | "type": "string", | |
748 | 748 | "enum": ["YoungestFirst", "OldestFirst"], | |
749 | 749 | "default": "YoungestFirst", | |
750 | 750 | "description": "Defines which instance should be killed first in case of e.g. rescaling." | |
751 | 751 | }, | |
752 | 752 | "unreachableStrategy": { | |
753 | 753 | "type": "object", | |
754 | "description": "Define handling for unreachable instances. Given `unreachableInactiveAfter = 60` and `unreachableExpungeAfter = 120`, an instance will be expunged if it has been unreachable for more than 120 seconds or a second instance is started if it has been unreachable for more than 60 seconds.", | ||
754 | "description": "Define handling for unreachable instances. Given `inactiveAfter = 60` and `expungeAfter = 120`, an instance will be expunged if it has been unreachable for more than 120 seconds or a second instance is started if it has been unreachable for more than 60 seconds.", | ||
755 | 755 | "additionalProperties": false, | |
756 | 756 | "properties": { | |
757 | "unreachableInactiveAfterSeconds": { | ||
757 | "inactiveAfterSeconds": { | ||
758 | 758 | "type": "integer", | |
759 | "description": "If an instance is unreachable for longer than unreachableInactiveAfter seconds it is marked as inactive. This will trigger a new instance launch. The original task is not expunged yet.", | ||
759 | "description": "If an instance is unreachable for longer than inactiveAfter seconds it is marked as inactive. This will trigger a new instance launch. The original task is not expunged yet.", | ||
760 | 760 | "minimum": 1 | |
761 | 761 | }, | |
762 | "unreachableExpungeAfterSeconds": { | ||
762 | "expungeAfterSeconds": { | ||
763 | 763 | "type": "number", | |
764 | "description": "If an instance is unreachable for longer than unreachableExpungeAfter seconds it will be expunged. That means it will be killed if it ever comes back. Instances are usually marked as unreachable before they are expunged but they don't have to.", | ||
764 | "description": "If an instance is unreachable for longer than expungeAfter seconds it will be expunged. That means it will be killed if it ever comes back. Instances are usually marked as unreachable before they are expunged but they don't have to.", | ||
765 | 765 | "minimum": 2 | |
766 | 766 | } | |
767 | 767 | } | |
768 | 768 | } | |
769 | 769 | }, | |
770 | 770 | "required": [ | |
771 | 771 | "id" | |
772 | 772 | ], | |
773 | 773 | "type": "object" | |
774 | 774 | } |
1 | 1 | #%RAML 1.0 Library | |
---|---|---|---|
2 | 2 | types: | |
3 | 3 | UnreachableStrategy: | |
4 | 4 | type: object | |
5 | 5 | properties: | |
6 | unreachableInactiveAfterSeconds?: | ||
6 | inactiveAfterSeconds?: | ||
7 | 7 | type: integer | |
8 | 8 | format: int64 | |
9 | 9 | default: 300 | |
10 | 10 | minimum: 1 | |
11 | 11 | description: | | |
12 | If an instance is unreachable for longer than unreachableInactiveAfter seconds it is marked | ||
12 | If an instance is unreachable for longer than inactiveAfter seconds it is marked | ||
13 | 13 | as inactive. This will trigger a new instance launch. The original task is not | |
14 | 14 | expunged yet. | |
15 | unreachableExpungeAfterSeconds?: | ||
15 | expungeAfterSeconds?: | ||
16 | 16 | type: integer | |
17 | 17 | format: int64 | |
18 | 18 | default: 600 | |
19 | 19 | minimum: 1 | |
20 | 20 | description: | | |
21 | 21 | If an instance is unreachable for longer than unreachableExpungeAfter seconds it will be expunged. | |
22 | 22 | That means it will be killed if it ever comes back. Instances are usually marked as | |
23 | 23 | unreachable before they are expunged but they don't have to. |
Show First 20 Lines • Show All 162 Lines • ▼ Show 20 Line(s) | |||
163 | 163 | override def version: Timestamp = runSpecVersion | |
---|---|---|---|
164 | 164 | ||
165 | 165 | override def hostname: String = agentInfo.host | |
166 | 166 | ||
167 | 167 | override def attributes: Seq[Attribute] = agentInfo.attributes | |
168 | 168 | ||
169 | 169 | private[instance] def updatedInstance(updatedTask: Task, now: Timestamp): Instance = { | |
170 | 170 | val updatedTasks = tasksMap.updated(updatedTask.taskId, updatedTask) | |
171 | copy(tasksMap = updatedTasks, state = Instance.InstanceState(Some(state), updatedTasks, now, unreachableStrategy.unreachableInactiveAfter)) | ||
171 | copy(tasksMap = updatedTasks, state = Instance.InstanceState(Some(state), updatedTasks, now, unreachableStrategy.inactiveAfter)) | ||
172 | 172 | } | |
173 | 173 | } | |
174 | 174 | ||
175 | 175 | @SuppressWarnings(Array("DuplicateImport")) | |
176 | 176 | object Instance { | |
177 | 177 | ||
178 | 178 | import mesosphere.marathon.api.v2.json.Formats.TimestampFormat | |
179 | 179 | ||
▲ Show 20 Lines • Show All 311 Lines • Show Last 20 Lines |
Show All 33 Lines | |||
34 | 34 | ||
---|---|---|---|
35 | 35 | /** | |
36 | 36 | * @return instances that have been UnreachableInactive for more than half of [[mesosphere.marathon.core.task.jobs.TaskJobsConfig.taskLostExpungeGC]] millis. | |
37 | 37 | */ | |
38 | 38 | def filterOverdueUnreachableInactive(instances: Map[PathId, SpecInstances], now: Timestamp) = | |
39 | 39 | instances.values.flatMap(_.instances) | |
40 | 40 | .withFilter(_.isUnreachableInactive) | |
41 | 41 | .withFilter { instance => | |
42 | val unreachableExpungeAfter = instance.unreachableStrategy.unreachableExpungeAfter | ||
42 | val unreachableExpungeAfter = instance.unreachableStrategy.expungeAfter | ||
43 | 43 | instance.tasksMap.valuesIterator.exists(_.isUnreachableExpired(now, unreachableExpungeAfter)) | |
44 | 44 | } | |
45 | 45 | } | |
46 | 46 | ||
47 | 47 | class ExpungeOverdueLostTasksActor( | |
48 | 48 | val clock: Clock, | |
49 | 49 | val config: TaskJobsConfig, | |
50 | 50 | instanceTracker: InstanceTracker, | |
Show All 35 Lines |
1 | 1 | package mesosphere.marathon | |
---|---|---|---|
2 | 2 | package raml | |
3 | 3 | ||
4 | 4 | import scala.concurrent.duration._ | |
5 | 5 | ||
6 | 6 | /** | |
7 | 7 | * Conversion from [[mesosphere.marathon.state.UnreachableStrategy]] to [[mesosphere.marathon.raml.UnreachableStrategy]]. | |
8 | 8 | */ | |
9 | 9 | trait UnreachableStrategyConversion { | |
10 | 10 | ||
11 | implicit val ramlUnreachableStrategyRead = Reads[UnreachableStrategy, state.UnreachableStrategy] { handling => | ||
11 | implicit val ramlUnreachableStrategyRead = Reads[UnreachableStrategy, state.UnreachableStrategy] { strategy => | ||
12 | 12 | state.UnreachableStrategy( | |
13 | unreachableInactiveAfter = handling.unreachableInactiveAfterSeconds.seconds, | ||
14 | unreachableExpungeAfter = handling.unreachableExpungeAfterSeconds.seconds) | ||
13 | inactiveAfter = strategy.inactiveAfterSeconds.seconds, | ||
14 | expungeAfter = strategy.expungeAfterSeconds.seconds) | ||
15 | 15 | } | |
16 | 16 | ||
17 | implicit val ramlUnreachableStrategyWrite = Writes[state.UnreachableStrategy, UnreachableStrategy]{ handling => | ||
17 | implicit val ramlUnreachableStrategyWrite = Writes[state.UnreachableStrategy, UnreachableStrategy]{ strategy => | ||
18 | 18 | UnreachableStrategy( | |
19 | unreachableInactiveAfterSeconds = handling.unreachableInactiveAfter.toSeconds, | ||
20 | unreachableExpungeAfterSeconds = handling.unreachableExpungeAfter.toSeconds) | ||
19 | inactiveAfterSeconds = strategy.inactiveAfter.toSeconds, | ||
20 | expungeAfterSeconds = strategy.expungeAfter.toSeconds) | ||
21 | 21 | } | |
22 | 22 | } | |
23 | 23 | ||
24 | 24 | object UnreachableStrategyConversion extends UnreachableStrategyConversion |
1 | 1 | package mesosphere.marathon | |
---|---|---|---|
2 | 2 | package state | |
3 | 3 | ||
4 | 4 | import com.wix.accord.dsl._ | |
5 | 5 | ||
6 | 6 | import scala.concurrent.duration._ | |
7 | 7 | ||
8 | 8 | /** | |
9 | 9 | * Defines the time outs for unreachable tasks. | |
10 | 10 | */ | |
11 | 11 | case class UnreachableStrategy( | |
12 | unreachableInactiveAfter: FiniteDuration = UnreachableStrategy.DefaultTimeUntilInactive, | ||
13 | unreachableExpungeAfter: FiniteDuration = UnreachableStrategy.DefaultTimeUntilExpunge) | ||
12 | inactiveAfter: FiniteDuration = UnreachableStrategy.DefaultTimeUntilInactive, | ||
13 | expungeAfter: FiniteDuration = UnreachableStrategy.DefaultTimeUntilExpunge) | ||
14 | 14 | ||
15 | 15 | object UnreachableStrategy { | |
16 | 16 | val DefaultTimeUntilInactive = 3.minutes | |
17 | 17 | val DefaultTimeUntilExpunge = 6.minutes | |
18 | 18 | ||
19 | 19 | implicit val unreachableStrategyValidator = validator[UnreachableStrategy] { strategy => | |
20 | strategy.unreachableInactiveAfter should be >= 1.second | ||
21 | strategy.unreachableInactiveAfter should be < strategy.unreachableExpungeAfter | ||
20 | strategy.inactiveAfter should be >= 1.second | ||
21 | strategy.inactiveAfter should be < strategy.expungeAfter | ||
22 | 22 | } | |
23 | 23 | } |
Show First 20 Lines • Show All 443 Lines • ▼ Show 20 Line(s) | |||
444 | 444 | (json \ "secrets" \ "secret3" \ "source").as[String] should equal("/foo2") | |
---|---|---|---|
445 | 445 | } | |
446 | 446 | ||
447 | 447 | test("FromJSON should parse unreachable instance strategy") { | |
448 | 448 | val appDef = Json.parse( | |
449 | 449 | """{ | |
450 | 450 | | "id": "test", | |
451 | 451 | | "unreachableStrategy": { | |
452 | | "unreachableInactiveAfterSeconds": 600, | ||
453 | | "unreachableExpungeAfterSeconds": 1200 | ||
452 | | "inactiveAfterSeconds": 600, | ||
453 | | "expungeAfterSeconds": 1200 | ||
454 | 454 | | } | |
455 | 455 | |}""".stripMargin).as[AppDefinition] | |
456 | 456 | ||
457 | appDef.unreachableStrategy.unreachableInactiveAfter should be(10.minutes) | ||
458 | appDef.unreachableStrategy.unreachableExpungeAfter should be(20.minutes) | ||
457 | appDef.unreachableStrategy.inactiveAfter should be(10.minutes) | ||
458 | appDef.unreachableStrategy.expungeAfter should be(20.minutes) | ||
459 | 459 | } | |
460 | 460 | ||
461 | 461 | test("ToJSON should serialize unreachable instance strategy") { | |
462 | 462 | val strategy = UnreachableStrategy(6.minutes, 12.minutes) | |
463 | 463 | val appDef = AppDefinition(id = PathId("test"), unreachableStrategy = strategy) | |
464 | 464 | ||
465 | 465 | val json = Json.toJson(appDef) | |
466 | 466 | ||
467 | (json \ "unreachableStrategy" \ "unreachableInactiveAfterSeconds").as[Long] should be(360) | ||
468 | (json \ "unreachableStrategy" \ "unreachableExpungeAfterSeconds").as[Long] should be(720) | ||
467 | (json \ "unreachableStrategy" \ "inactiveAfterSeconds").as[Long] should be(360) | ||
468 | (json \ "unreachableStrategy" \ "expungeAfterSeconds").as[Long] should be(720) | ||
469 | 469 | } | |
470 | 470 | ||
471 | 471 | test("FromJSON should parse kill selection") { | |
472 | 472 | val appDef = Json.parse( | |
473 | 473 | """{ | |
474 | 474 | | "id": "test", | |
475 | 475 | | "killSelection": "YoungestFirst" | |
476 | 476 | |}""".stripMargin).as[AppDefinition] | |
Show All 23 Lines |
1 | 1 | package mesosphere.marathon | |
---|---|---|---|
2 | 2 | package core.instance | |
3 | 3 | ||
4 | 4 | import mesosphere.UnitTest | |
5 | 5 | import mesosphere.marathon.state.UnreachableStrategy | |
6 | 6 | import play.api.libs.json._ | |
7 | 7 | ||
8 | 8 | import scala.concurrent.duration._ | |
9 | 9 | ||
10 | 10 | class InstanceFormatTest extends UnitTest { | |
11 | 11 | ||
12 | 12 | import Instance._ | |
13 | 13 | ||
14 | 14 | "Instance.unreachableStrategyFormat" should { | |
15 | 15 | "parse a proper JSON" in { | |
16 | val json = Json.parse("""{ "unreachableInactiveAfter": 1, "unreachableExpungeAfter": 2 }""") | ||
17 | json.as[UnreachableStrategy].unreachableInactiveAfter should be(1.second) | ||
18 | json.as[UnreachableStrategy].unreachableExpungeAfter should be(2.seconds) | ||
16 | val json = Json.parse("""{ "inactiveAfter": 1, "expungeAfter": 2 }""") | ||
17 | json.as[UnreachableStrategy].inactiveAfter should be(1.second) | ||
18 | json.as[UnreachableStrategy].expungeAfter should be(2.seconds) | ||
19 | 19 | } | |
20 | 20 | ||
21 | 21 | "not parse a JSON with empty fields" in { | |
22 | 22 | val json = Json.parse("""{ "unreachableExpungeAfter": 2 }""") | |
23 | 23 | a[JsResultException] should be thrownBy { json.as[UnreachableStrategy] } | |
24 | 24 | } | |
25 | 25 | ||
26 | 26 | } | |
27 | 27 | ||
28 | 28 | "Instance.instanceFormat" should { | |
29 | 29 | "fill UnreachableStrategy with defaults if empty" in { | |
30 | 30 | val json = Json.parse( | |
31 | 31 | """{ "instanceId": { "idString": "app.instance-1337" }, | |
32 | 32 | | "tasksMap": {}, | |
33 | 33 | | "runSpecVersion": "2015-01-01", | |
34 | 34 | | "agentInfo": { "host": "localhost", "attributes": [] }, | |
35 | 35 | | "state": { "since": "2015-01-01", "condition": { "str": "Running" } } | |
36 | 36 | |}""".stripMargin) | |
37 | 37 | val instance = json.as[Instance] | |
38 | 38 | ||
39 | instance.unreachableStrategy.unreachableInactiveAfter should be(UnreachableStrategy.DefaultTimeUntilInactive) | ||
40 | instance.unreachableStrategy.unreachableExpungeAfter should be(UnreachableStrategy.DefaultTimeUntilExpunge) | ||
39 | instance.unreachableStrategy.inactiveAfter should be(UnreachableStrategy.DefaultTimeUntilInactive) | ||
40 | instance.unreachableStrategy.expungeAfter should be(UnreachableStrategy.DefaultTimeUntilExpunge) | ||
41 | 41 | } | |
42 | 42 | } | |
43 | 43 | } |
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Line(s) | |||
65 | 65 | } | |
---|---|---|---|
66 | 66 | ||
67 | 67 | } | |
68 | 68 | ||
69 | 69 | "updated to an expired unreachable" should { | |
70 | 70 | ||
71 | 71 | val f = new Fixture | |
72 | 72 | ||
73 | val unreachableInactiveAfter = f.instance.unreachableStrategy.unreachableInactiveAfter | ||
73 | val unreachableInactiveAfter = f.instance.unreachableStrategy.inactiveAfter | ||
74 | 74 | val newMesosStatus = MesosTaskStatusTestHelper.unreachable(f.taskId, since = f.clock.now()) | |
75 | 75 | ||
76 | 76 | // Forward time to expire unreachable status | |
77 | 77 | f.clock += unreachableInactiveAfter + 1.minute | |
78 | 78 | ||
79 | 79 | val operation = InstanceUpdateOperation.MesosUpdate(f.instance, newMesosStatus, f.clock.now()) | |
80 | 80 | ||
81 | 81 | val result = f.instance.update(operation) | |
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Line(s) | |||
204 | 204 | ||
205 | 205 | val f = new Fixture | |
206 | 206 | ||
207 | 207 | // Setup unreachable instance with a unreachable task | |
208 | 208 | val mesosTaskStatus = MesosTaskStatusTestHelper.unreachable(f.taskId, since = f.clock.now()) | |
209 | 209 | val unreachableStatus = f.taskStatus.copy(startedAt = None, condition = Condition.Unreachable, mesosStatus = Some(mesosTaskStatus)) | |
210 | 210 | val unreachableTask = f.task.copy(status = unreachableStatus) | |
211 | 211 | val unreachableState = f.instanceState.copy(condition = Condition.Unreachable) | |
212 | val unreachableStrategy = UnreachableStrategy(unreachableInactiveAfter = 30.minutes, unreachableExpungeAfter = 1.hour) | ||
212 | val unreachableStrategy = UnreachableStrategy(inactiveAfter = 30.minutes, expungeAfter = 1.hour) | ||
213 | 213 | val unreachableInstance = f.instance.copy( | |
214 | 214 | tasksMap = Map(f.taskId -> unreachableTask), | |
215 | 215 | state = unreachableState, | |
216 | 216 | unreachableStrategy = unreachableStrategy) | |
217 | 217 | ||
218 | 218 | // Move time forward | |
219 | 219 | f.clock += 5.minutes | |
220 | 220 | ||
Show All 11 Lines | |||
232 | 232 | ||
233 | 233 | val f = new Fixture | |
234 | 234 | ||
235 | 235 | // Setup unreachable instance with a unreachable task | |
236 | 236 | val mesosTaskStatus = MesosTaskStatusTestHelper.unreachable(f.taskId, since = f.clock.now()) | |
237 | 237 | val unreachableStatus = f.taskStatus.copy(startedAt = None, condition = Condition.Unreachable, mesosStatus = Some(mesosTaskStatus)) | |
238 | 238 | val unreachableTask = f.task.copy(status = unreachableStatus) | |
239 | 239 | val unreachableInactiveState = f.instanceState.copy(condition = Condition.UnreachableInactive) | |
240 | val unreachableStrategy = UnreachableStrategy(unreachableInactiveAfter = 1.minute, unreachableExpungeAfter = 1.hour) | ||
240 | val unreachableStrategy = UnreachableStrategy(inactiveAfter = 1.minute, expungeAfter = 1.hour) | ||
241 | 241 | val unreachableInactiveInstance = f.instance.copy( | |
242 | 242 | tasksMap = Map(f.taskId -> unreachableTask), | |
243 | 243 | state = unreachableInactiveState, | |
244 | 244 | unreachableStrategy = unreachableStrategy) | |
245 | 245 | ||
246 | 246 | // Move time forward | |
247 | 247 | f.clock += 5.minutes | |
248 | 248 | ||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | |||
58 | 58 | } | |
---|---|---|---|
59 | 59 | ||
60 | 60 | // format: OFF | |
61 | 61 | // Different task configuration with startedAt, status since and condition values. Expunge indicates whether an | |
62 | 62 | // expunge is expected or not. | |
63 | 63 | val taskCases = Table( | |
64 | 64 | ("name", "startedAt", "since", "condition", "expunge"), | |
65 | 65 | ("running", Timestamp.zero, Timestamp.zero, Condition.Running, false ), | |
66 | ("expired inactive", Timestamp.zero, f.clock.now - f.strategy.unreachableExpungeAfter - 1.minute, Condition.UnreachableInactive, true ), | ||
67 | ("unreachable", Timestamp.zero, f.clock.now - f.strategy.unreachableInactiveAfter, Condition.Unreachable, false ) | ||
66 | ("expired inactive", Timestamp.zero, f.clock.now - f.strategy.expungeAfter - 1.minute, Condition.UnreachableInactive, true ), | ||
67 | ("unreachable", Timestamp.zero, f.clock.now - f.strategy.inactiveAfter, Condition.Unreachable, false ) | ||
68 | 68 | ) | |
69 | 69 | // format: ON | |
70 | 70 | ||
71 | 71 | forAll(taskCases) { (name: String, startedAt: Timestamp, since: Timestamp, condition: Condition, expunge: Boolean) => | |
72 | 72 | s"filtering $name task since $since" should { | |
73 | 73 | val instance: Instance = (condition match { | |
74 | 74 | case Condition.Unreachable => TestInstanceBuilder.newBuilder("/unreachable".toPath).addTaskUnreachable(since = since).getInstance() | |
75 | 75 | case Condition.UnreachableInactive => TestInstanceBuilder.newBuilder("/unreachable".toPath).addTaskUnreachableInactive(since = since).getInstance() | |
▲ Show 20 Lines • Show All 121 Lines • Show Last 20 Lines |
1 | 1 | package mesosphere.marathon | |
---|---|---|---|
2 | 2 | package raml | |
3 | 3 | ||
4 | 4 | import mesosphere.marathon.state | |
5 | 5 | import mesosphere.UnitTest | |
6 | 6 | ||
7 | 7 | import scala.concurrent.duration._ | |
8 | 8 | ||
9 | 9 | class UnreachableStrategyConversionTest extends UnitTest { | |
10 | 10 | ||
11 | 11 | "UnreachableStrategyConversion" should { | |
12 | 12 | "read from RAML" in { | |
13 | 13 | val raml = UnreachableStrategy() | |
14 | 14 | ||
15 | 15 | val result: state.UnreachableStrategy = UnreachableStrategyConversion.ramlUnreachableStrategyRead(raml) | |
16 | 16 | ||
17 | result.unreachableInactiveAfter should be(5.minutes) | ||
18 | result.unreachableExpungeAfter should be(10.minutes) | ||
17 | result.inactiveAfter should be(5.minutes) | ||
18 | result.expungeAfter should be(10.minutes) | ||
19 | 19 | } | |
20 | 20 | } | |
21 | 21 | ||
22 | 22 | it should { | |
23 | 23 | "write to RAML" in { | |
24 | 24 | val strategy = state.UnreachableStrategy(10.minutes, 20.minutes) | |
25 | 25 | ||
26 | 26 | val raml: UnreachableStrategy = UnreachableStrategyConversion.ramlUnreachableStrategyWrite(strategy) | |
27 | 27 | ||
28 | raml.unreachableInactiveAfterSeconds should be(600) | ||
29 | raml.unreachableExpungeAfterSeconds should be(1200) | ||
28 | raml.inactiveAfterSeconds should be(600) | ||
29 | raml.expungeAfterSeconds should be(1200) | ||
30 | 30 | } | |
31 | 31 | } | |
32 | 32 | } |
1 | 1 | package mesosphere.marathon | |
---|---|---|---|
2 | 2 | package state | |
3 | 3 | ||
4 | 4 | import mesosphere.UnitTest | |
5 | 5 | import com.wix.accord.scalatest.ResultMatchers | |
6 | 6 | ||
7 | 7 | import scala.concurrent.duration._ | |
8 | 8 | ||
9 | 9 | class UnreachableStrategyTest extends UnitTest with ResultMatchers { | |
10 | 10 | ||
11 | 11 | "UnreachableStrategy.unreachableStrategyValidator" should { | |
12 | 12 | "validate default strategy" in { | |
13 | 13 | val strategy = UnreachableStrategy() | |
14 | 14 | UnreachableStrategy.unreachableStrategyValidator(strategy) shouldBe aSuccess | |
15 | 15 | } | |
16 | 16 | ||
17 | "validate with other paramters successfully" in { | ||
17 | "validate with other parameters successfully" in { | ||
18 | 18 | val strategy = UnreachableStrategy(13.minutes, 37.minutes) | |
19 | 19 | UnreachableStrategy.unreachableStrategyValidator(strategy) shouldBe aSuccess | |
20 | 20 | } | |
21 | 21 | ||
22 | 22 | "fail with invalid time until inactive" in { | |
23 | val strategy = UnreachableStrategy(unreachableInactiveAfter = 0.second) | ||
24 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("unreachableInactiveAfter" -> "got 0 seconds, expected 1 second or more") | ||
23 | val strategy = UnreachableStrategy(inactiveAfter = 0.second) | ||
24 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("inactiveAfter" -> "got 0 seconds, expected 1 second or more") | ||
25 | 25 | } | |
26 | 26 | ||
27 | 27 | "fail when time until expunge is smaller" in { | |
28 | val strategy = UnreachableStrategy(unreachableInactiveAfter = 2.seconds, unreachableExpungeAfter = 1.second) | ||
29 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("unreachableInactiveAfter" -> "got 2 seconds, expected less than 1 second") | ||
28 | val strategy = UnreachableStrategy(inactiveAfter = 2.seconds, expungeAfter = 1.second) | ||
29 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("inactiveAfter" -> "got 2 seconds, expected less than 1 second") | ||
30 | 30 | } | |
31 | 31 | ||
32 | 32 | "fail when time until expunge is equal to time until inactive" in { | |
33 | val strategy = UnreachableStrategy(unreachableInactiveAfter = 2.seconds, unreachableExpungeAfter = 2.seconds) | ||
34 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("unreachableInactiveAfter" -> "got 2 seconds, expected less than 2 seconds") | ||
33 | val strategy = UnreachableStrategy(inactiveAfter = 2.seconds, expungeAfter = 2.seconds) | ||
34 | UnreachableStrategy.unreachableStrategyValidator(strategy) should failWith("inactiveAfter" -> "got 2 seconds, expected less than 2 seconds") | ||
35 | 35 | } | |
36 | 36 | } | |
37 | 37 | } |