-
Notifications
You must be signed in to change notification settings - Fork 188
/
TestUtil.java
712 lines (625 loc) · 31.6 KB
/
TestUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
/*
* Copyright (c) 2010-2019 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.test.util;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.testng.AssertJUnit;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ObjectFactory;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.TestNameHolder;
import com.evolveum.midpoint.util.JAXBUtil;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
/**
* Unit test utilities.
*
* @author Radovan Semancik
*/
public class TestUtil {
public static final int MAX_EXCEPTION_MESSAGE_LENGTH = 500;
public static final String TEST_LOG_PREFIX = "=====[ ";
public static final String TEST_LOG_SUFFIX = " ]======================================";
public static final String TEST_OUT_PREFIX = "\n\n=====[ ";
public static final String TEST_OUT_SUFFIX = " ]======================================\n";
public static final String TEST_OUT_SECTION_PREFIX = "\n\n----- ";
public static final String TEST_OUT_SECTION_SUFFIX = " --------------------------------------\n";
public static final String TEST_LOG_SECTION_PREFIX = "----- ";
public static final String TEST_LOG_SECTION_SUFFIX = " --------------------------------------";
private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("1\\.(\\d+)\\.\\d+_\\d+");
public static boolean checkResults = true;
private static DatatypeFactory datatypeFactory = null;
private static final Trace LOGGER = TraceManager.getTrace(TestUtil.class);
private static final Random RND = new Random();
public static <T> void assertPropertyValueSetEquals(Collection<PrismPropertyValue<T>> actual, T... expected) {
Set<T> set = new HashSet<>();
for (PrismPropertyValue<T> value : actual) {
set.add(value.getValue());
}
assertSetEquals(set, expected);
}
public static <T> void assertSetEquals(Collection<T> actual, T... expected) {
assertSetEquals(null, actual, expected);
}
public static <T> void assertSetEquals(String message, Collection<T> actual, T... expected) {
Set<T> expectedSet = new HashSet<>();
expectedSet.addAll(Arrays.asList(expected));
Set<T> actualSet = new HashSet<>();
actualSet.addAll(actual);
if (message != null) {
assertEquals(message, expectedSet, actualSet);
} else {
assertEquals(expectedSet, actualSet);
}
}
public static <T> void assertSetEquals(String message, T[] actual, T[] expected) {
assertTrue(message + "expected " + Arrays.toString(expected) + ", was " + Arrays.toString(actual),
MiscUtil.unorderedArrayEquals(actual, expected));
}
public static String getNodeOid(Node node) {
Node oidNode = null;
if ((null == node.getAttributes())
|| (null == (oidNode = node.getAttributes().getNamedItem(
SchemaConstants.C_OID_ATTRIBUTE.getLocalPart())))
|| (StringUtils.isEmpty(oidNode.getNodeValue()))) {
return null;
}
String oid = oidNode.getNodeValue();
return oid;
}
public static void setAttribute(PrismObject<ShadowType> account, QName attrName, QName typeName,
PrismContext prismContext, String value) throws SchemaException {
PrismContainer<Containerable> attributesContainer = account.findContainer(ShadowType.F_ATTRIBUTES);
ResourceAttributeDefinition attrDef = ObjectFactory.createResourceAttributeDefinition(attrName, typeName, prismContext);
ResourceAttribute attribute = attrDef.instantiate();
attribute.setRealValue(value);
attributesContainer.add(attribute);
}
public static void assertElement(List<Object> elements, QName elementQName, String value) {
for (Object element : elements) {
QName thisElementQName = JAXBUtil.getElementQName(element);
if (elementQName.equals(thisElementQName)) {
if (element instanceof Element) {
String thisElementContent = ((Element) element).getTextContent();
if (value.equals(thisElementContent)) {
return;
} else {
AssertJUnit.fail("Wrong value for element with name " + elementQName + "; expected " + value + "; was " + thisElementContent);
}
} else {
throw new IllegalArgumentException("Unexpected type of element " + elementQName + ": " + element.getClass());
}
}
}
AssertJUnit.fail("No element with name " + elementQName);
}
public static void assertExceptionSanity(ObjectAlreadyExistsException e) {
LOGGER.debug("Exception (expected) {}", e, e);
System.out.println("Exception (expected)");
System.out.println(ExceptionUtils.getFullStackTrace(e));
assert !e.getMessage().isEmpty() : "Empty exception message";
assert e.getMessage().length() < MAX_EXCEPTION_MESSAGE_LENGTH : "Exception message too long ("
+ e.getMessage().length() + " characters): " + e.getMessage();
}
public static void displayTestTitle(String testName) {
System.out.println(TEST_OUT_PREFIX + testName + TEST_OUT_SUFFIX);
LOGGER.info(TEST_LOG_PREFIX + testName + TEST_LOG_SUFFIX);
TestNameHolder.setCurrentTestName(testName);
}
public static void displayTestTitle(Object testCase, String testName) {
String qualifiedTestName = testCase.getClass().getSimpleName() + "." + testName;
System.out.println(TEST_OUT_PREFIX + qualifiedTestName + TEST_OUT_SUFFIX);
LOGGER.info(TEST_LOG_PREFIX + qualifiedTestName + TEST_LOG_SUFFIX);
TestNameHolder.setCurrentTestName(qualifiedTestName);
}
public static void displayFooter(String footerText) {
System.out.println(TEST_OUT_PREFIX + footerText);
LOGGER.info(TEST_LOG_PREFIX + footerText);
}
public static void displayWhen(String testName) {
System.out.println(TEST_OUT_SECTION_PREFIX + " WHEN " + testName + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " WHEN " + testName + TEST_LOG_SECTION_SUFFIX);
}
public static void displayWhen(String testName, String part) {
System.out.println(TEST_OUT_SECTION_PREFIX + " WHEN " + testName + " (" + part + ")" + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " WHEN " + testName + " (" + part + ")" + TEST_LOG_SECTION_SUFFIX);
}
public static void displayThen(String testName) {
System.out.println(TEST_OUT_SECTION_PREFIX + " THEN " + testName + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " THEN " + testName + TEST_LOG_SECTION_SUFFIX);
}
public static void displayThen(String testName, String part) {
System.out.println(TEST_OUT_SECTION_PREFIX + " THEN " + testName + " (" + part + ")" + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " THEN " + testName + " (" + part + ")" + TEST_LOG_SECTION_SUFFIX);
}
public static void displayCleanup(String testName) {
System.out.println(TEST_OUT_SECTION_PREFIX + " CLEANUP " + testName + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " CLEANUP " + testName + TEST_LOG_SECTION_SUFFIX);
}
public static void displaySkip(String testName) {
System.out.println(TEST_OUT_SECTION_PREFIX + " SKIP " + testName + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " SKIP " + testName + TEST_LOG_SECTION_SUFFIX);
}
public static void info(String message) {
System.out.println(TEST_OUT_SECTION_PREFIX + message + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + message + TEST_LOG_SECTION_SUFFIX);
}
public static void assertSuccess(String message, OperationResult result, OperationResult originalResult, int stopLevel, int currentLevel, boolean warningOk) {
if (!checkResults) {
return;
}
if (result.getStatus() == null || result.getStatus().equals(OperationResultStatus.UNKNOWN)) {
String logmsg = message + ": undefined status (" + result.getStatus() + ") on operation " + result.getOperation();
LOGGER.error(logmsg);
LOGGER.trace(logmsg + "\n" + originalResult.debugDump());
System.out.println(logmsg + "\n" + originalResult.debugDump());
fail(logmsg);
}
if (result.isHandledError()) {
// There may be errors deeper in this result, even fatal errors. that's ok, we can ignore them.
return;
} else if (result.isSuccess() || result.isNotApplicable()) {
// OK ... expected error is as good as success
} else if (warningOk && result.getStatus() == OperationResultStatus.WARNING) {
// OK
} else {
String logmsg = message + ": " + result.getStatus() + ": " + result.getMessage();
LOGGER.error(logmsg);
LOGGER.trace(logmsg + "\n" + originalResult.debugDump());
System.out.println(logmsg + "\n" + originalResult.debugDump());
assert false : logmsg;
}
if (stopLevel == currentLevel) {
return;
}
List<OperationResult> partialResults = result.getSubresults();
for (OperationResult subResult : partialResults) {
assertSuccess(message, subResult, originalResult, stopLevel, currentLevel + 1, warningOk);
}
}
/**
* level=-1 - check all levels
* level=0 - check only the top-level
* level=1 - check one level below top-level
* ...
*
* @param message
* @param result
* @param level
*/
public static void assertSuccess(String message, OperationResult result, int level) {
assertSuccess(message, result, result, level, 0, false);
}
public static void assertSuccess(String message, OperationResult result) {
assertSuccess(message, result, -1);
}
public static void assertSuccess(OperationResultType result) {
assertSuccess(result.getOperation(), result);
}
public static void assertSuccess(String message, OperationResultType result) {
if (!checkResults) {
return;
}
assertNotNull(message + ": null result", result);
// Ignore top-level if the operation name is not set
if (result.getOperation() != null) {
if (result.getStatus() == null || result.getStatus() == OperationResultStatusType.UNKNOWN) {
fail(message + ": undefined status (" + result.getStatus() + ") on operation " + result.getOperation());
}
if (result.getStatus() != OperationResultStatusType.SUCCESS
&& result.getStatus() != OperationResultStatusType.NOT_APPLICABLE
&& result.getStatus() != OperationResultStatusType.HANDLED_ERROR) {
fail(message + ": " + result.getMessage() + " (" + result.getStatus() + ")");
}
}
List<OperationResultType> partialResults = result.getPartialResults();
for (OperationResultType subResult : partialResults) {
if (subResult == null) {
fail(message + ": null subresult under operation " + result.getOperation());
}
if (subResult.getOperation() == null) {
fail(message + ": null subresult operation under operation " + result.getOperation());
}
assertSuccess(message, subResult);
}
}
public static void assertInProgressOrSuccess(OperationResult result) {
if (!result.isInProgress()) {
assertSuccess("Operation " + result.getOperation() + " result", result);
}
}
public static void assertSuccess(OperationResult result) {
assertSuccess("Operation " + result.getOperation() + " result", result);
}
public static void assertSuccess(OperationResult result, int depth) {
assertSuccess("Operation " + result.getOperation() + " result", result, depth);
}
public static void assertStatus(OperationResult result, OperationResultStatus expectedStatus) {
assertEquals("Operation " + result.getOperation() + " result", expectedStatus, result.getStatus());
}
public static void assertStatus(OperationResultType result, OperationResultStatusType expectedStatus) {
assertEquals("Operation " + result.getOperation() + " result", expectedStatus, result.getStatus());
}
public static boolean hasWarningAssertSuccess(String message, OperationResultType result) {
boolean hasWarning = false;
// Ignore top-level if the operation name is not set
if (result.getOperation() != null) {
if (result.getStatus() == OperationResultStatusType.WARNING) {
// Do not descent into warnings. There may be lions inside. Or errors.
return true;
} else {
if (result.getStatus() == null || result.getStatus() == OperationResultStatusType.UNKNOWN) {
fail(message + ": undefined status (" + result.getStatus() + ") on operation " + result.getOperation());
}
if (result.getStatus() != OperationResultStatusType.SUCCESS
&& result.getStatus() != OperationResultStatusType.NOT_APPLICABLE
&& result.getStatus() != OperationResultStatusType.HANDLED_ERROR) {
fail(message + ": " + result.getMessage() + " (" + result.getStatus() + ")");
}
}
}
List<OperationResultType> partialResults = result.getPartialResults();
for (OperationResultType subResult : partialResults) {
if (subResult == null) {
fail(message + ": null subresult under operation " + result.getOperation());
}
if (subResult.getOperation() == null) {
fail(message + ": null subresult operation under operation " + result.getOperation());
}
if (hasWarningAssertSuccess(message, subResult)) {
hasWarning = true;
}
}
return hasWarning;
}
public static void assertWarning(String message, OperationResultType result) {
if (!checkResults) {
return;
}
assert hasWarningAssertSuccess(message, result) : message + ": does not have warning";
}
public static void assertFailure(String message, OperationResult result) {
assertTrue(message, result.isError());
assertNoUnknown(result);
}
public static void assertFailure(OperationResult result) {
if (!result.isError()) {
String message = "Expected that operation " + result.getOperation() + " fails, but the result was " + result.getStatus();
System.out.println(message);
System.out.println(result.debugDump());
LOGGER.error("{}", message);
LOGGER.error("{}", result.debugDump());
AssertJUnit.fail(message);
}
assertNoUnknown(result);
}
public static void assertPartialError(OperationResult result) {
assertTrue("Expected that operation " + result.getOperation() + " fails partially, but the result was " + result.getStatus(), result.getStatus() == OperationResultStatus.PARTIAL_ERROR);
assertNoUnknown(result);
}
public static void assertResultStatus(OperationResult result, OperationResultStatus expectedStatus) {
assertTrue("Expected that operation " + result.getOperation() + " will result with " + expectedStatus + ", but the result was " + result.getStatus(), result.getStatus() == expectedStatus);
assertNoUnknown(result);
}
public static void assertFailure(OperationResultType result) {
assertFailure(null, result);
}
public static void assertFailure(String message, OperationResultType result) {
assertTrue((message == null ? "" : message + ": ") +
"Expected that operation " + result.getOperation() + " fails, but the result was " + result.getStatus(),
OperationResultStatusType.FATAL_ERROR == result.getStatus() ||
OperationResultStatusType.PARTIAL_ERROR == result.getStatus());
assertNoUnknown(result);
}
public static void assertNoUnknown(OperationResult result) {
if (result.isUnknown()) {
AssertJUnit.fail("Unkwnown status for operation " + result.getOperation());
}
for (OperationResult subresult : result.getSubresults()) {
assertNoUnknown(subresult);
}
}
public static void assertNoUnknown(OperationResultType result) {
if (result.getStatus() == OperationResultStatusType.UNKNOWN) {
AssertJUnit.fail("Unkwnown status for operation " + result.getOperation());
}
for (OperationResultType subresult : result.getPartialResults()) {
assertNoUnknown(subresult);
}
}
public static void assertSuccessOrWarning(String message, OperationResult result, int level) {
assertSuccess(message, result, result, level, 0, true);
}
public static void assertSuccessOrWarning(String message, OperationResult result) {
assertSuccess(message, result, result, -1, 0, true);
}
public static void assertWarning(String message, OperationResult result) {
assertWarning(message, result, -1, 0);
}
public static boolean hasWarningAssertSuccess(String message, OperationResult result, OperationResult originalResult, int stopLevel, int currentLevel) {
if (result.getStatus() == null || result.getStatus().equals(OperationResultStatus.UNKNOWN)) {
String logmsg = message + ": undefined status (" + result.getStatus() + ") on operation " + result.getOperation();
LOGGER.error(logmsg);
LOGGER.trace(logmsg + "\n" + originalResult.debugDump());
System.out.println(logmsg + "\n" + originalResult.debugDump());
fail(logmsg);
}
if (result.isWarning()) {
// Do not descent into warnings. There may be lions inside. Or errors.
return true;
}
if (result.isSuccess() || result.isHandledError() || result.isNotApplicable()) {
// OK ... expected error is as good as success
} else {
String logmsg = message + ": " + result.getStatus() + ": " + result.getMessage();
LOGGER.error(logmsg);
LOGGER.trace(logmsg + "\n" + originalResult.debugDump());
System.out.println(logmsg + "\n" + originalResult.debugDump());
assert false : logmsg;
}
if (stopLevel == currentLevel) {
return false;
}
boolean hasWarning = false;
List<OperationResult> partialResults = result.getSubresults();
for (OperationResult subResult : partialResults) {
if (hasWarningAssertSuccess(message, subResult, originalResult, stopLevel, currentLevel + 1)) {
hasWarning = true;
}
}
return hasWarning;
}
public static void assertWarning(String message, OperationResult result, int stopLevel, int currentLevel) {
if (!checkResults) {
return;
}
hasWarningAssertSuccess(message, result, result, -1, 0);
}
public static void assertInProgress(String message, OperationResult result) {
assertTrue("Expected result IN_PROGRESS but it was " + result.getStatus() + " in " + message,
result.getStatus() == OperationResultStatus.IN_PROGRESS);
}
public static String getErrorMessage(OperationResult result) {
if (result.isError()) {
return result.getMessage();
}
for (OperationResult subresult : result.getSubresults()) {
String message = getErrorMessage(subresult);
if (message != null) {
return message;
}
}
return null;
}
public static List<OperationResult> selectSubresults(OperationResult result, String... operationNames) {
List<OperationResult> retval = new ArrayList<>();
selectSubresultsInternal(retval, result, operationNames);
return retval;
}
private static void selectSubresultsInternal(List<OperationResult> retval, OperationResult result, String... operationNames) {
if (result == null) {
return; // should not occur actually
}
for (int i = 0; i < operationNames.length; i++) {
if (operationNames[i].equals(result.getOperation())) {
retval.add(result);
break;
}
}
for (OperationResult subresult : result.getSubresults()) {
selectSubresultsInternal(retval, subresult, operationNames);
}
}
public static String execSystemCommand(String command) throws IOException, InterruptedException {
return execSystemCommand(command, false);
}
public static String execSystemCommand(String command, boolean ignoreExitCode) throws IOException, InterruptedException {
Runtime runtime = Runtime.getRuntime();
LOGGER.debug("Executing system command: {}", command);
Process process = runtime.exec(command);
int exitCode = process.waitFor();
LOGGER.debug("Command exit code: {}", exitCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder output = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
output.append(line);
}
reader.close();
String outstring = output.toString();
LOGGER.debug("Command output:\n{}", outstring);
if (!ignoreExitCode && exitCode != 0) {
String msg = "Execution of command '" + command + "' failed with exit code " + exitCode;
LOGGER.error("{}", msg);
throw new IOException(msg);
}
return outstring;
}
public static void assertBetween(String message, XMLGregorianCalendar start, XMLGregorianCalendar end,
XMLGregorianCalendar actual) {
assertNotNull(message + " is null", actual);
if (start != null) {
assertTrue(message + ": expected time to be after " + start + " but it was " + actual,
actual.compare(start) == DatatypeConstants.GREATER || actual.compare(start) == DatatypeConstants.EQUAL);
}
if (end != null) {
assertTrue(message + ": expected time to be before " + end + " but it was " + actual,
actual.compare(end) == DatatypeConstants.LESSER || actual.compare(end) == DatatypeConstants.EQUAL);
}
}
public static void assertBetween(String message, Long start, Long end,
Long actual) {
assertNotNull(message + " is null", actual);
if (start != null) {
assertTrue(message + ": expected time to be after " + start + " but it was " + actual, actual >= start);
}
if (end != null) {
assertTrue(message + ": expected time to be before " + end + " but it was " + actual, actual <= end);
}
}
public static void assertEqualsTimestamp(String message, XMLGregorianCalendar expected, XMLGregorianCalendar actual) {
assertNotNull(message + "; expected " + expected, actual);
assertTrue(message + "; expected " + expected + " but was " + actual, expected.compare(actual) == 0);
}
public static void assertCreateTimestamp(PrismObject<? extends ObjectType> object, XMLGregorianCalendar start,
XMLGregorianCalendar end) {
MetadataType metadata = object.asObjectable().getMetadata();
assertNotNull("No metadata in " + object, metadata);
assertBetween("createTimestamp in " + object, start, end, metadata.getCreateTimestamp());
}
public static void assertModifyTimestamp(PrismObject<? extends ObjectType> object, XMLGregorianCalendar start,
XMLGregorianCalendar end) {
assertModifyTimestamp(object, start, end, null);
}
public static void assertModifyTimestamp(PrismObject<? extends ObjectType> object, XMLGregorianCalendar start,
XMLGregorianCalendar end, String channel) {
MetadataType metadata = object.asObjectable().getMetadata();
assertNotNull("No metadata in " + object, metadata);
assertBetween("modifyTimestamp in " + object, start, end, metadata.getModifyTimestamp());
if (channel != null) {
assertEquals("Wrong channel", channel, metadata.getModifyChannel());
}
}
public static XMLGregorianCalendar currentTime() {
// This cannot use XmlTypeConverter as we want to use also in tests that do not depend on prism
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTimeInMillis(System.currentTimeMillis());
return getDatatypeFactory().newXMLGregorianCalendar(gregorianCalendar);
}
private static DatatypeFactory getDatatypeFactory() {
if (datatypeFactory == null) {
try {
datatypeFactory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException ex) {
throw new IllegalStateException("Cannot construct DatatypeFactory: " + ex.getMessage(), ex);
}
}
return datatypeFactory;
}
public static int getJavaMajorVersion() {
String javaVersionString = System.getProperty("java.version");
Matcher matcher = JAVA_VERSION_PATTERN.matcher(javaVersionString);
if (matcher.matches()) {
return Integer.parseInt(matcher.group(1));
} else {
throw new IllegalStateException("Cannot match java version string '" + javaVersionString + "'");
}
}
public static void assertMessageContains(String message, String expectedSubstring) {
assertTrue("Expected that message will contain substring '" + expectedSubstring + "', but it did not. Message: " + message,
message.contains(expectedSubstring));
}
// WARNING! Only works on Linux
public static int getPid() throws NumberFormatException, IOException {
return Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
}
public static void assertPrivateFilePermissions(File f) throws IOException {
try {
Set<PosixFilePermission> configPermissions = Files.getPosixFilePermissions(Paths.get(f.getPath()));
LOGGER.info("File {} permissions: {}", f, configPermissions);
assertPermission(f, configPermissions, PosixFilePermission.OWNER_READ);
assertPermission(f, configPermissions, PosixFilePermission.OWNER_WRITE);
assertNoPermission(f, configPermissions, PosixFilePermission.OWNER_EXECUTE);
assertPermission(f, configPermissions, PosixFilePermission.GROUP_READ);
assertPermission(f, configPermissions, PosixFilePermission.GROUP_WRITE);
assertNoPermission(f, configPermissions, PosixFilePermission.GROUP_EXECUTE);
assertNoPermission(f, configPermissions, PosixFilePermission.OTHERS_READ);
assertNoPermission(f, configPermissions, PosixFilePermission.OTHERS_WRITE);
assertNoPermission(f, configPermissions, PosixFilePermission.OTHERS_EXECUTE);
} catch (UnsupportedOperationException e) {
// Windows. Sorry.
}
}
private static void assertPermission(File f, Set<PosixFilePermission> permissions, PosixFilePermission permission) {
assertTrue(permissions.contains(permission), f.getPath() + ": missing permission " + permission);
}
private static void assertNoPermission(File f, Set<PosixFilePermission> permissions, PosixFilePermission permission) {
assertFalse(permissions.contains(permission), f.getPath() + ": unexpected permission " + permission);
}
public static ParallelTestThread[] multithread(final String TEST_NAME, MultithreadRunner lambda, int numberOfThreads, Integer randomStartDelayRange) {
ParallelTestThread[] threads = new ParallelTestThread[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
threads[i] = new ParallelTestThread(i,
(ii) -> {
randomDelay(randomStartDelayRange);
LOGGER.info("{} starting", Thread.currentThread().getName());
lambda.run(ii);
});
threads[i].setName("Thread " + (i + 1) + " of " + numberOfThreads);
threads[i].start();
}
return threads;
}
public static void randomDelay(Integer range) {
if (range == null || range == 0) {
return;
}
try {
Thread.sleep(RND.nextInt(range));
} catch (InterruptedException e) {
// Nothing to do, really
}
}
public static void waitForThreads(ParallelTestThread[] threads, long timeout) throws InterruptedException {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive()) {
System.out.println("Waiting for " + threads[i]);
threads[i].join(timeout);
}
Throwable threadException = threads[i].getException();
if (threadException != null) {
throw new AssertionError("Test thread " + i + " failed: " + threadException.getMessage(), threadException);
}
}
}
public static ItemDefinition createPrimitivePropertyDefinition(PrismContext prismContext, String name, PrimitiveType pType) {
return prismContext.definitionFactory().createPropertyDefinition(new ItemName(SchemaConstants.NS_C, name), pType.getQname());
}
public static void waitForCompletion(List<Thread> threads, long timeout) throws InterruptedException {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < timeout) {
boolean anyAlive = threads.stream().anyMatch(Thread::isAlive);
if (!anyAlive) {
break;
} else {
Thread.sleep(100);
}
}
}
}