public void checkPropertyValueOrTransition(String property, String[] values, boolean mustBeAtBegin, boolean mustBeAtEnd,
          long maxTime_ms, String expectedValueOrTransition)
          throws QTasteDataException, QTasteTestFailException {
        long beginTime_ms = System.currentTimeMillis(); // begin time
        long elapsedTime_ms; // total elapsed time
        long checkTimeInterval_ms = 100; // check every 100 milliseconds
        LinkedList<TimestampedValue> list = null;

        long lastCheckedTimestamp = 0;
        boolean foundMatching = false;
        boolean foundNotMatching = false;
        String currentPropertyHistory = null;

        loop:
        do {
            synchronized (this) {
                // get list of values if none yet
                if (list == null) {
                    list = hash.get(property);
                }
                if (list != null && list.size() > 0) {
                    if (mustBeAtBegin) {
                        if (!list.get(0).value.equals(values[0])) {
                            foundNotMatching = true;
                        } else if (list.size() >= values.length) {
                            if ((values.length == 1 || list.get(1).value.equals(values[1])) && (!mustBeAtEnd
                                  || list.size() == values.length)) {
                                foundMatching = true;
                                lastCheckedTimestamp = list.get(values.length - 1).timestamp;
                                break loop;
                            } else {
                                foundNotMatching = true;
                            }
                        }
                    } else {
                        ListIterator<TimestampedValue> iTSValue = list.listIterator();
                        int index = -1;
                        while (iTSValue.hasNext()) {
                            index++;
                            TimestampedValue tsValue = iTSValue.next();
                            TimestampedValue nextTsValue = null;
                            if (iTSValue.hasNext()) {
                                nextTsValue = iTSValue.next();
                                iTSValue.previous();
                            }
                            if (tsValue.value.equals(values[0]) && (values.length == 1 || (iTSValue.hasNext() && nextTsValue.value
                                  .equals(values[1])))) {
                                if (!mustBeAtEnd || list.size() == (index + values.length)) {
                                    foundMatching = true;
                                    lastCheckedTimestamp = (values.length == 1 ? tsValue.timestamp : nextTsValue.timestamp);
                                    break loop;
                                } else {
                                    foundNotMatching = true;
                                }
                            }
                        }
                    }
                }

                // value is not in list yet
                elapsedTime_ms = System.currentTimeMillis() - beginTime_ms;
                if (foundNotMatching || (elapsedTime_ms >= maxTime_ms)) {
                    currentPropertyHistory = getHistoryString(property, false);
                    break;
                }
            }

            try {
                Thread.sleep(checkTimeInterval_ms);
            } catch (InterruptedException e) {
                throw new QTasteDataException("Sleep has been interrupted while checking " + component + " property");
            }
        }
        while (true);

        if (possibleNotificationLoss) {
            throw new QTasteTestFailException(
                  component + " property value cannot be checked because of a possible notification loss!");
        }

        if (foundMatching) {
            removePrecedingValues(property, lastCheckedTimestamp);
        } else {
            throw new QTasteTestFailException(
                  component + " " + property + " property didn't behave as expected ('" + currentPropertyHistory
                        + "' doesn't match expected '" + expectedValueOrTransition + "')");
        }
    }
public void checkPropertyValueOrTransition ( String property , String [ ] values , boolean mustBeAtBegin , boolean mustBeAtEnd , long maxTime_ms , String expectedValueOrTransition ) throws QTasteDataException , QTasteTestFailException { long beginTime_ms = System . currentTimeMillis ( ) ; long elapsedTime_ms ; long checkTimeInterval_ms = 100 ; LinkedList < TimestampedValue > list = null ; long lastCheckedTimestamp = 0 ; boolean foundMatching = false ; boolean foundNotMatching = false ; String currentPropertyHistory = null ; loop : do { synchronized ( this ) { if ( list == null ) { list = hash . get ( property ) ; } if ( list != null && list . size ( ) > 0 ) { if ( mustBeAtBegin ) { if ( ! list . get ( 0 ) . value . equals ( values [ 0 ] ) ) { foundNotMatching = true ; } else if ( list . size ( ) >= values . length ) { if ( ( values . length == 1 || list . get ( 1 ) . value . equals ( values [ 1 ] ) ) && ( ! mustBeAtEnd || list . size ( ) == values . length ) ) { foundMatching = true ; lastCheckedTimestamp = list . get ( values . length - 1 ) . timestamp ; break loop ; } else { foundNotMatching = true ; } } } else { ListIterator < TimestampedValue > iTSValue = list . listIterator ( ) ; int index = - 1 ; while ( iTSValue . hasNext ( ) ) { index ++ ; TimestampedValue tsValue = iTSValue . next ( ) ; TimestampedValue nextTsValue = null ; if ( iTSValue . hasNext ( ) ) { nextTsValue = iTSValue . next ( ) ; iTSValue . previous ( ) ; } if ( tsValue . value . equals ( values [ 0 ] ) && ( values . length == 1 || ( iTSValue . hasNext ( ) && nextTsValue . value . equals ( values [ 1 ] ) ) ) ) { if ( ! mustBeAtEnd || list . size ( ) == ( index + values . length ) ) { foundMatching = true ; lastCheckedTimestamp = ( values . length == 1 ? tsValue . timestamp : nextTsValue . timestamp ) ; break loop ; } else { foundNotMatching = true ; } } } } } elapsedTime_ms = System . currentTimeMillis ( ) - beginTime_ms ; if ( foundNotMatching || ( elapsedTime_ms >= maxTime_ms ) ) { currentPropertyHistory = getHistoryString ( property , false ) ; break ; } } try { Thread . sleep ( checkTimeInterval_ms ) ; } catch ( InterruptedException e ) { throw new QTasteDataException ( "Sleep has been interrupted while checking " + component + " property" ) ; } } while ( true ) ; if ( possibleNotificationLoss ) { throw new QTasteTestFailException ( component + " property value cannot be checked because of a possible notification loss!" ) ; } if ( foundMatching ) { removePrecedingValues ( property , lastCheckedTimestamp ) ; } else { throw new QTasteTestFailException ( component + " " + property + " property didn't behave as expected ('" + currentPropertyHistory + "' doesn't match expected '" + expectedValueOrTransition + "')" ) ; } }
Checks that property reaches given value or makes given transition within given time.
If found, remove old values from history.

@param property the property name
@param values the expected property value or values (transition)
@param mustBeAtBegin true if value or transition must occur at begin of history
@param mustBeAtEnd true if value or transition must occur at end of history
@param maxTime_ms the maximum time to wait for the property value, in milliseconds
@param expectedValueOrTransition expected value or transition (only used for error messages)
@throws QTasteTestFailException if the property doesn't reach specified value or make specified transition or
if a possible notification loss occurred