Files
android/libwvdrmengine/cdm/util/test/test_sleep.h
Fred Gylys-Colwell b7b423aca3 Reduce clock skew in flaky duration tests
There are three changes here that should help reduce the
amount of duration test failures caused by clock skew.

First, we reported some skew when the test expected playback
to start immediately after loading the license. However,
with round-off, this could easily be more than 1 second. So
this does not warrent even a warning.

Second, the fake and real clocks were only synced after
computing how long to sleep. This is fixed by moving
SleepUntil to the TestSleep class and having it sync before
computing the delta and after doing the sleep.

Third, I am guessing that some failures due to unexpected
lenience were caused by the rental or playback clock being
started at the end of signing the license or the end of the
first decrypt instead of the beginning. We work around this
by recording how long these operations take, and then adding
this extra time at the end of the check for FailDecrypt.

Bug: 275003529
Bug: 279249646
Bug: 207500749
Merged from https://widevine-internal-review.googlesource.com/176070

Change-Id: I6a973565edfbebca53ee7f239b4b93f8f73d1e0a
2024-01-26 17:46:49 -08:00

85 lines
3.2 KiB
C++

// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
//
// TestSleep - Controls sleep and clock adjustment during tests.
//
#ifndef WVCDM_UTIL_TEST_SLEEP_H_
#define WVCDM_UTIL_TEST_SLEEP_H_
#include <stdint.h>
namespace wvutil {
class TestSleep {
public:
// The callback is called when the test clock should be advanced. If the
// system uses a real clock, it is used to sync the real and test
// clock. Otherwise it is used to simulate sleep in the test clock.
class CallBack {
public:
virtual void ElapseTime(int64_t milliseconds) = 0;
protected:
virtual ~CallBack(){};
};
// If real_sleep_ is true, then this sleeps for |seconds| of time. If
// real_sleep_ is false, then the fake clock is advanced by |seconds|. If the
// callback exists, this calls the callback.
static void Sleep(unsigned int seconds);
// Like sleep, above, except it sleeps until the specified time.
static void SleepUntil(int64_t desired_time);
// If we are using a real clock and a fake clock, then the real clock advances
// a little while we are doing work, but the fake one only advances when we
// sleep. This function advances the fake clock to be in sync with the real
// clock. This function should be called to prevent a slow flaky test from
// failing due to this drift.
static void SyncFakeClock();
// Roll the system clock back by |seconds|. Returns true on success. A well
// mannered test will call CanChangeSystemTime before attempting to call this
// function and then assert that this is true. This function should *NOT* roll
// back the clock used by OEMCrypto -- in fact, there are several tests that
// verify this function does not roll back the clock used by OEMCrypto.
static bool RollbackSystemTime(int seconds);
// Set the system clock to the specified time. This is only expected to work
// when real_sleep is false.
static void SetFakeClock(int64_t time_seconds);
// Roll the system clock forward to undo all previous calls to
// RollBackSystemTime. Returns true on success.
static bool ResetRollback() {
return total_clock_rollback_seconds_ == 0 ||
RollbackSystemTime(-total_clock_rollback_seconds_);
}
// Returns true if the system time can be rolled back. This is true on some
// devices if the tests are run as root. It is also true when using a fake
// clock with the reference version of OEMCrypto. This function is about the
// system clock, *NOT* the clock used by OEMCrypto.
static bool CanChangeSystemTime();
static void set_real_sleep(bool real_sleep) { real_sleep_ = real_sleep; }
static bool real_sleep() { return real_sleep_; }
// The callback is notified whenever sleep is called.
static void set_callback(CallBack* callback) { callback_ = callback; }
private:
// Controls if the test sleep should use real sleep.
static bool real_sleep_;
// Called when the clock should advance.
static CallBack* callback_;
// The sum of all calls to RollBackSystemTime. Kept so we can undo all changes
// at the end of a test.
static int total_clock_rollback_seconds_;
};
} // namespace wvutil
#endif // WVCDM_UTIL_TEST_SLEEP_H_