1<?php 2/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ 3 4namespace Tests\Icinga\Module\Setup; 5 6use Icinga\Test\BaseTestCase; 7use Icinga\Module\Setup\Requirement; 8use Icinga\Module\Setup\RequirementSet; 9 10class TrueRequirement extends Requirement 11{ 12 protected function evaluate() 13 { 14 return true; 15 } 16} 17 18class FalseRequirement extends Requirement 19{ 20 protected function evaluate() 21 { 22 return false; 23 } 24} 25 26class RequirementSetTest extends BaseTestCase 27{ 28 public function testFlatMandatoryRequirementsOfTypeAnd() 29 { 30 $emptySet = new RequirementSet(); 31 $this->assertFalse($emptySet->fulfilled(), 'A empty mandatory set of type and is fulfilled'); 32 33 $singleTrueSet = new RequirementSet(); 34 $singleTrueSet->add(new TrueRequirement()); 35 $this->assertTrue( 36 $singleTrueSet->fulfilled(), 37 'A mandatory set of type and with a single TrueRequirement is not fulfilled' 38 ); 39 40 $singleFalseSet = new RequirementSet(); 41 $singleFalseSet->add(new FalseRequirement()); 42 $this->assertFalse( 43 $singleFalseSet->fulfilled(), 44 'A mandatory set of type and with a single FalseRequirement is fulfilled' 45 ); 46 47 $mixedSet = new RequirementSet(); 48 $mixedSet->add(new TrueRequirement()); 49 $mixedSet->add(new FalseRequirement()); 50 $this->assertFalse( 51 $mixedSet->fulfilled(), 52 'A mandatory set of type and with one True- and one FalseRequirement is fulfilled' 53 ); 54 } 55 56 public function testFlatOptionalRequirementsOfTypeAnd() 57 { 58 $emptySet = new RequirementSet(true); 59 $this->assertTrue($emptySet->fulfilled(), 'A empty optional set of type and is not fulfilled'); 60 61 $singleTrueSet = new RequirementSet(true); 62 $singleTrueSet->add(new TrueRequirement()); 63 $this->assertTrue( 64 $singleTrueSet->fulfilled(), 65 'A optional set of type and with a single TrueRequirement is not fulfilled' 66 ); 67 68 $singleFalseSet = new RequirementSet(true); 69 $singleFalseSet->add(new FalseRequirement()); 70 $this->assertTrue( 71 $singleFalseSet->fulfilled(), 72 'A optional set of type and with a single FalseRequirement is not fulfilled' 73 ); 74 75 $mixedSet = new RequirementSet(true); 76 $mixedSet->add(new TrueRequirement()); 77 $mixedSet->add(new FalseRequirement()); 78 $this->assertTrue( 79 $mixedSet->fulfilled(), 80 'A optional set of type and with one True- and one FalseRequirement is not fulfilled' 81 ); 82 } 83 84 public function testFlatMixedRequirementsOfTypeAnd() 85 { 86 $mandatoryOptionalTrueSet = new RequirementSet(); 87 $mandatoryOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 88 $mandatoryOptionalTrueSet->add(new FalseRequirement()); 89 $this->assertFalse( 90 $mandatoryOptionalTrueSet->fulfilled(), 91 'A mandatory set of type and with one optional True- and one mandatory FalseRequirement is fulfilled' 92 ); 93 94 $mandatoryOptionalFalseSet = new RequirementSet(); 95 $mandatoryOptionalFalseSet->add(new TrueRequirement()); 96 $mandatoryOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 97 $this->assertTrue( 98 $mandatoryOptionalFalseSet->fulfilled(), 99 'A mandatory set of type and with one mandatory True- and one optional FalseRequirement is not fulfilled' 100 ); 101 102 $optionalOptionalTrueSet = new RequirementSet(true); 103 $optionalOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 104 $optionalOptionalTrueSet->add(new FalseRequirement()); 105 $this->assertTrue( 106 $optionalOptionalTrueSet->fulfilled(), 107 'A optional set of type and with one optional True- and one mandatory FalseRequirement is not fulfilled' 108 ); 109 110 $optionalOptionalFalseSet = new RequirementSet(true); 111 $optionalOptionalFalseSet->add(new TrueRequirement()); 112 $optionalOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 113 $this->assertTrue( 114 $optionalOptionalFalseSet->fulfilled(), 115 'A optional set of type and with one mandatory True- and one optional FalseRequirement is not fulfilled' 116 ); 117 } 118 119 public function testFlatMandatoryRequirementsOfTypeOr() 120 { 121 $emptySet = new RequirementSet(false, RequirementSet::MODE_OR); 122 $this->assertFalse($emptySet->fulfilled(), 'A empty mandatory set of type or is fulfilled'); 123 124 $singleTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 125 $singleTrueSet->add(new TrueRequirement()); 126 $this->assertTrue( 127 $singleTrueSet->fulfilled(), 128 'A mandatory set of type or with a single TrueRequirement is not fulfilled' 129 ); 130 131 $singleFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 132 $singleFalseSet->add(new FalseRequirement()); 133 $this->assertFalse( 134 $singleFalseSet->fulfilled(), 135 'A mandatory set of type or with a single FalseRequirement is fulfilled' 136 ); 137 138 $mixedSet = new RequirementSet(false, RequirementSet::MODE_OR); 139 $mixedSet->add(new TrueRequirement()); 140 $mixedSet->add(new FalseRequirement()); 141 $this->assertTrue( 142 $mixedSet->fulfilled(), 143 'A mandatory set of type or with one True- and one FalseRequirement is not fulfilled' 144 ); 145 } 146 147 public function testFlatOptionalRequirementsOfTypeOr() 148 { 149 $emptySet = new RequirementSet(true, RequirementSet::MODE_OR); 150 $this->assertTrue($emptySet->fulfilled(), 'A empty optional set of type or is not fulfilled'); 151 152 $singleTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 153 $singleTrueSet->add(new TrueRequirement()); 154 $this->assertTrue( 155 $singleTrueSet->fulfilled(), 156 'A optional set of type or with a single TrueRequirement is not fulfilled' 157 ); 158 159 $singleFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 160 $singleFalseSet->add(new FalseRequirement()); 161 $this->assertTrue( 162 $singleFalseSet->fulfilled(), 163 'A optional set of type or with a single FalseRequirement is not fulfilled' 164 ); 165 166 $mixedSet = new RequirementSet(true, RequirementSet::MODE_OR); 167 $mixedSet->add(new TrueRequirement()); 168 $mixedSet->add(new FalseRequirement()); 169 $this->assertTrue( 170 $mixedSet->fulfilled(), 171 'A optional set of type or with one True- and one FalseRequirement is not fulfilled' 172 ); 173 } 174 175 public function testFlatMixedRequirementsOfTypeOr() 176 { 177 $mandatoryOptionalTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 178 $mandatoryOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 179 $mandatoryOptionalTrueSet->add(new FalseRequirement()); 180 $this->assertTrue( 181 $mandatoryOptionalTrueSet->fulfilled(), 182 'A mandatory set of type or with one optional True- and one mandatory FalseRequirement is not fulfilled' 183 ); 184 185 $mandatoryOptionalFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 186 $mandatoryOptionalFalseSet->add(new TrueRequirement()); 187 $mandatoryOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 188 $this->assertTrue( 189 $mandatoryOptionalFalseSet->fulfilled(), 190 'A mandatory set of type or with one mandatory True- and one optional FalseRequirement is not fulfilled' 191 ); 192 193 $optionalOptionalTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 194 $optionalOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 195 $optionalOptionalTrueSet->add(new FalseRequirement()); 196 $this->assertTrue( 197 $optionalOptionalTrueSet->fulfilled(), 198 'A optional set of type or with one optional True- and one mandatory FalseRequirement is not fulfilled' 199 ); 200 201 $optionalOptionalFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 202 $optionalOptionalFalseSet->add(new TrueRequirement()); 203 $optionalOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 204 $this->assertTrue( 205 $optionalOptionalFalseSet->fulfilled(), 206 'A optional set of type or with one mandatory True- and one optional FalseRequirement is not fulfilled' 207 ); 208 } 209 210 public function testNestedMandatoryRequirementsOfTypeAnd() 211 { 212 $trueSet = new RequirementSet(); 213 $trueSet->add(new TrueRequirement()); 214 $falseSet = new RequirementSet(); 215 $falseSet->add(new FalseRequirement()); 216 217 $nestedTrueSet = new RequirementSet(); 218 $nestedTrueSet->merge($trueSet); 219 $this->assertTrue( 220 $nestedTrueSet->fulfilled(), 221 'A nested mandatory set of type and with one mandatory TrueRequirement is not fulfilled' 222 ); 223 224 $nestedFalseSet = new RequirementSet(); 225 $nestedFalseSet->merge($falseSet); 226 $this->assertFalse( 227 $nestedFalseSet->fulfilled(), 228 'A nested mandatory set of type and with one mandatory FalseRequirement is fulfilled' 229 ); 230 231 $nestedMixedSet = new RequirementSet(); 232 $nestedMixedSet->merge($trueSet); 233 $nestedMixedSet->merge($falseSet); 234 $this->assertFalse( 235 $nestedMixedSet->fulfilled(), 236 'Two nested mandatory sets of type and with one mandatory True- and' 237 . ' one mandatory FalseRequirement respectively are fulfilled' 238 ); 239 } 240 241 public function testNestedOptionalRequirementsOfTypeAnd() 242 { 243 $trueSet = new RequirementSet(true); 244 $trueSet->add(new TrueRequirement()); 245 $falseSet = new RequirementSet(true); 246 $falseSet->add(new FalseRequirement()); 247 248 $nestedTrueSet = new RequirementSet(true); 249 $nestedTrueSet->merge($trueSet); 250 $this->assertTrue( 251 $nestedTrueSet->fulfilled(), 252 'A nested optional set of type and with one mandatory TrueRequirement is not fulfilled' 253 ); 254 255 $nestedFalseSet = new RequirementSet(true); 256 $nestedFalseSet->merge($falseSet); 257 $this->assertTrue( 258 $nestedFalseSet->fulfilled(), 259 'A nested optional set of type and with one mandatory FalseRequirement is not fulfilled' 260 ); 261 262 $nestedMixedSet = new RequirementSet(true); 263 $nestedMixedSet->merge($trueSet); 264 $nestedMixedSet->merge($falseSet); 265 $this->assertTrue( 266 $nestedMixedSet->fulfilled(), 267 'Two nested optional sets of type and with one mandatory True- and' 268 . ' one mandatory FalseRequirement respectively are not fulfilled' 269 ); 270 } 271 272 public function testNestedMixedRequirementsOfTypeAnd() 273 { 274 $mandatoryMandatoryTrueSet = new RequirementSet(); 275 $mandatoryMandatoryTrueSet->add(new TrueRequirement()); 276 $mandatoryOptionalTrueSet = new RequirementSet(); 277 $mandatoryOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 278 $mandatoryMandatoryFalseSet = new RequirementSet(); 279 $mandatoryMandatoryFalseSet->add(new FalseRequirement()); 280 $mandatoryOptionalFalseSet = new RequirementSet(); 281 $mandatoryOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 282 $optionalMandatoryTrueSet = new RequirementSet(true); 283 $optionalMandatoryTrueSet->add(new TrueRequirement()); 284 $optionalOptionalTrueSet = new RequirementSet(true); 285 $optionalOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 286 $optionalMandatoryFalseSet = new RequirementSet(true); 287 $optionalMandatoryFalseSet->add(new FalseRequirement()); 288 $optionalOptionalFalseSet = new RequirementSet(true); 289 $optionalOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 290 291 $mandatoryMandatoryOptionalTrueSet = new RequirementSet(); 292 $mandatoryMandatoryOptionalTrueSet->merge($mandatoryOptionalTrueSet); 293 $mandatoryMandatoryOptionalTrueSet->merge($mandatoryMandatoryFalseSet); 294 $this->assertFalse( 295 $mandatoryMandatoryOptionalTrueSet->fulfilled(), 296 'A mandatory set of type and with two nested mandatory sets of type and where one has a optional' 297 . ' TrueRequirement and the other one has a mandatory FalseRequirement is fulfilled' 298 ); 299 300 $mandatoryMandatoryOptionalFalseSet = new RequirementSet(); 301 $mandatoryMandatoryOptionalFalseSet->merge($mandatoryOptionalFalseSet); 302 $mandatoryMandatoryOptionalFalseSet->merge($mandatoryMandatoryTrueSet); 303 $this->assertTrue( 304 $mandatoryMandatoryOptionalFalseSet->fulfilled(), 305 'A mandatory set of type and with two nested mandatory sets of type and where one has a mandatory' 306 . ' TrueRequirement and the other one has a optional FalseRequirement is not fulfilled' 307 ); 308 309 $optionalOptionalOptionalTrueSet = new RequirementSet(true); 310 $optionalOptionalOptionalTrueSet->merge($optionalOptionalTrueSet); 311 $optionalOptionalOptionalTrueSet->merge($optionalMandatoryFalseSet); 312 $this->assertTrue( 313 $optionalOptionalOptionalTrueSet->fulfilled(), 314 'A optional set of type and with two nested optional sets of type and where one has a optional' 315 . ' TrueRequirement and the other one has a mandatory FalseRequirement is not fulfilled' 316 ); 317 318 $optionalOptionalOptionalFalseSet = new RequirementSet(true); 319 $optionalOptionalOptionalFalseSet->merge($optionalOptionalFalseSet); 320 $optionalOptionalOptionalFalseSet->merge($optionalMandatoryTrueSet); 321 $this->assertTrue( 322 $optionalOptionalOptionalFalseSet->fulfilled(), 323 'A optional set of type and with two nested optional sets of type and where one has a mandatory' 324 . ' TrueRequirement and the other one has a optional FalseRequirement is not fulfilled' 325 ); 326 } 327 328 public function testNestedMandatoryRequirementsOfTypeOr() 329 { 330 $trueSet = new RequirementSet(false, RequirementSet::MODE_OR); 331 $trueSet->add(new TrueRequirement()); 332 $falseSet = new RequirementSet(false, RequirementSet::MODE_OR); 333 $falseSet->add(new FalseRequirement()); 334 335 $nestedTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 336 $nestedTrueSet->merge($trueSet); 337 $this->assertTrue( 338 $nestedTrueSet->fulfilled(), 339 'A nested mandatory set of type or with one mandatory TrueRequirement is not fulfilled' 340 ); 341 342 $nestedFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 343 $nestedFalseSet->merge($falseSet); 344 $this->assertFalse( 345 $nestedFalseSet->fulfilled(), 346 'A nested mandatory set of type or with one mandatory FalseRequirement is fulfilled' 347 ); 348 349 $nestedMixedSet = new RequirementSet(false, RequirementSet::MODE_OR); 350 $nestedMixedSet->merge($trueSet); 351 $nestedMixedSet->merge($falseSet); 352 $this->assertTrue( 353 $nestedMixedSet->fulfilled(), 354 'Two nested mandatory sets of type or with one mandatory True- and' 355 . ' one mandatory FalseRequirement respectively are not fulfilled' 356 ); 357 } 358 359 public function testNestedOptionalRequirementsOfTypeOr() 360 { 361 $trueSet = new RequirementSet(true, RequirementSet::MODE_OR); 362 $trueSet->add(new TrueRequirement()); 363 $falseSet = new RequirementSet(true, RequirementSet::MODE_OR); 364 $falseSet->add(new FalseRequirement()); 365 366 $nestedTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 367 $nestedTrueSet->merge($trueSet); 368 $this->assertTrue( 369 $nestedTrueSet->fulfilled(), 370 'A nested optional set of type or with one mandatory TrueRequirement is not fulfilled' 371 ); 372 373 $nestedFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 374 $nestedFalseSet->merge($falseSet); 375 $this->assertTrue( 376 $nestedFalseSet->fulfilled(), 377 'A nested optional set of type or with one mandatory FalseRequirement is not fulfilled' 378 ); 379 380 $nestedMixedSet = new RequirementSet(true, RequirementSet::MODE_OR); 381 $nestedMixedSet->merge($trueSet); 382 $nestedMixedSet->merge($falseSet); 383 $this->assertTrue( 384 $nestedMixedSet->fulfilled(), 385 'Two nested optional sets of type or with one mandatory True- and' 386 . ' one mandatory FalseRequirement respectively are not fulfilled' 387 ); 388 } 389 390 public function testNestedMixedRequirementsOfTypeOr() 391 { 392 $mandatoryMandatoryTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 393 $mandatoryMandatoryTrueSet->add(new TrueRequirement()); 394 $mandatoryOptionalTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 395 $mandatoryOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 396 $mandatoryMandatoryFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 397 $mandatoryMandatoryFalseSet->add(new FalseRequirement()); 398 $mandatoryOptionalFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 399 $mandatoryOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 400 $optionalMandatoryTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 401 $optionalMandatoryTrueSet->add(new TrueRequirement()); 402 $optionalOptionalTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 403 $optionalOptionalTrueSet->add(new TrueRequirement(array('optional' => true))); 404 $optionalMandatoryFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 405 $optionalMandatoryFalseSet->add(new FalseRequirement()); 406 $optionalOptionalFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 407 $optionalOptionalFalseSet->add(new FalseRequirement(array('optional' => true))); 408 409 $mandatoryMandatoryOptionalTrueSet = new RequirementSet(false, RequirementSet::MODE_OR); 410 $mandatoryMandatoryOptionalTrueSet->merge($mandatoryOptionalTrueSet); 411 $mandatoryMandatoryOptionalTrueSet->merge($mandatoryMandatoryFalseSet); 412 $this->assertTrue($mandatoryMandatoryOptionalTrueSet->fulfilled()); 413 414 $mandatoryMandatoryOptionalFalseSet = new RequirementSet(false, RequirementSet::MODE_OR); 415 $mandatoryMandatoryOptionalFalseSet->merge($mandatoryOptionalFalseSet); 416 $mandatoryMandatoryOptionalFalseSet->merge($mandatoryMandatoryTrueSet); 417 $this->assertTrue($mandatoryMandatoryOptionalFalseSet->fulfilled()); 418 419 $optionalOptionalOptionalTrueSet = new RequirementSet(true, RequirementSet::MODE_OR); 420 $optionalOptionalOptionalTrueSet->merge($optionalOptionalTrueSet); 421 $optionalOptionalOptionalTrueSet->merge($optionalMandatoryFalseSet); 422 $this->assertTrue($optionalOptionalOptionalTrueSet->fulfilled()); 423 424 $optionalOptionalOptionalFalseSet = new RequirementSet(true, RequirementSet::MODE_OR); 425 $optionalOptionalOptionalFalseSet->merge($optionalOptionalFalseSet); 426 $optionalOptionalOptionalFalseSet->merge($optionalMandatoryTrueSet); 427 $this->assertTrue($optionalOptionalOptionalFalseSet->fulfilled()); 428 } 429 430 public function testNestedMandatoryRequirementsOfDifferentTypes() 431 { 432 $true = new TrueRequirement(); 433 $false = new FalseRequirement(); 434 435 $level1And = new RequirementSet(); 436 $level2FirstOr = new RequirementSet(false, RequirementSet::MODE_OR); 437 $level2SecondOr = new RequirementSet(false, RequirementSet::MODE_OR); 438 $level1And->merge($level2FirstOr)->merge($level2SecondOr); 439 $level3FirstAnd = new RequirementSet(); 440 $level3SecondAnd = new RequirementSet(); 441 $level2FirstOr->merge($level3FirstAnd)->merge($level3SecondAnd); 442 $level2SecondOr->merge($level3FirstAnd)->merge($level3SecondAnd); 443 $level3FirstAnd->add($true)->add($true); 444 $level3SecondAnd->add($false)->add($true); 445 $this->assertTrue($level1And->fulfilled()); 446 447 $level1Or = new RequirementSet(false, RequirementSet::MODE_OR); 448 $level2FirstAnd = new RequirementSet(); 449 $level2SecondAnd = new RequirementSet(); 450 $level1Or->merge($level2FirstAnd)->merge($level2SecondAnd); 451 $level3FirstOr = new RequirementSet(false, RequirementSet::MODE_OR); 452 $level3SecondOr = new RequirementSet(false, RequirementSet::MODE_OR); 453 $level2FirstAnd->merge($level3FirstOr)->merge($level3SecondOr); 454 $level2SecondAnd->merge($level3FirstOr)->merge($level3SecondOr); 455 $level3FirstOr->add($false); 456 $level3SecondOr->add($true); 457 $this->assertFalse($level1Or->fulfilled()); 458 } 459 460 public function testNestedOptionalRequirementsOfDifferentTypes() 461 { 462 $true = new TrueRequirement(); 463 $false = new FalseRequirement(); 464 465 $level1And = new RequirementSet(); 466 $level2FirstAnd = new RequirementSet(true); 467 $level2SecondAnd = new RequirementSet(true); 468 $level1And->merge($level2FirstAnd)->merge($level2SecondAnd); 469 $level3FirstOr = new RequirementSet(true, RequirementSet::MODE_OR); 470 $level3SecondOr = new RequirementSet(true, RequirementSet::MODE_OR); 471 $level2FirstAnd->merge($level3FirstOr)->merge($level3SecondOr); 472 $level2SecondAnd->merge($level3FirstOr)->merge($level3SecondOr); 473 $level3FirstOr->add($false); 474 $level3SecondOr->add($false); 475 $this->assertFalse($level1And->fulfilled()); 476 $this->assertTrue($level2FirstAnd->fulfilled()); 477 $this->assertTrue($level2SecondAnd->fulfilled()); 478 479 $level1Or = new RequirementSet(false, RequirementSet::MODE_OR); 480 $level2FirstOr = new RequirementSet(true, RequirementSet::MODE_OR); 481 $level2SecondOr = new RequirementSet(true, RequirementSet::MODE_OR); 482 $level1Or->merge($level2FirstOr)->merge($level2SecondOr); 483 $level3FirstAnd = new RequirementSet(true); 484 $level3SecondAnd = new RequirementSet(true); 485 $level2FirstOr->merge($level3FirstAnd)->merge($level3SecondAnd); 486 $level2SecondOr->merge($level3FirstAnd)->merge($level3SecondAnd); 487 $level3FirstAnd->add($true)->add($true); 488 $level3SecondAnd->add($false)->add($true); 489 $this->assertTrue($level1Or->fulfilled()); 490 } 491 492 public function testNestedMixedRequirementsOfDifferentTypes() 493 { 494 $this->markTestIncomplete(); 495 } 496} 497