summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/time/parameters_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/time/parameters_test.go')
-rw-r--r--pkg/sentry/time/parameters_test.go501
1 files changed, 0 insertions, 501 deletions
diff --git a/pkg/sentry/time/parameters_test.go b/pkg/sentry/time/parameters_test.go
deleted file mode 100644
index 0ce1257f6..000000000
--- a/pkg/sentry/time/parameters_test.go
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package time
-
-import (
- "math"
- "testing"
- "time"
-)
-
-func TestParametersComputeTime(t *testing.T) {
- testCases := []struct {
- name string
- params Parameters
- now TSCValue
- want int64
- }{
- {
- // Now is the same as the base cycles.
- name: "base-cycles",
- params: Parameters{
- BaseCycles: 10000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 10000,
- want: 5000 * time.Millisecond.Nanoseconds(),
- },
- {
- // Now is the behind the base cycles. Time is frozen.
- name: "backwards",
- params: Parameters{
- BaseCycles: 10000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 9000,
- want: 5000 * time.Millisecond.Nanoseconds(),
- },
- {
- // Now is ahead of the base cycles.
- name: "ahead",
- params: Parameters{
- BaseCycles: 10000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 15000,
- want: 5500 * time.Millisecond.Nanoseconds(),
- },
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- got, ok := tc.params.ComputeTime(tc.now)
- if !ok {
- t.Errorf("ComputeTime ok got %v want true", got)
- }
- if got != tc.want {
- t.Errorf("ComputeTime got %+v want %+v", got, tc.want)
- }
- })
- }
-}
-
-func TestParametersErrorAdjust(t *testing.T) {
- testCases := []struct {
- name string
- oldParams Parameters
- now TSCValue
- newParams Parameters
- want Parameters
- errorNS ReferenceNS
- wantErr bool
- }{
- {
- // newParams are perfectly continuous with oldParams
- // and don't need adjustment.
- name: "continuous",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 50000,
- newParams: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- want: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- },
- {
- // Same as "continuous", but with now ahead of
- // newParams.BaseCycles. The result is the same as
- // there is no error to correct.
- name: "continuous-nowdiff",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 60000,
- newParams: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- want: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- },
- {
- // errorAdjust bails out if the TSC goes backwards.
- name: "tsc-backwards",
- oldParams: Parameters{
- BaseCycles: 10000,
- BaseRef: ReferenceNS(1000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 9000,
- newParams: Parameters{
- BaseCycles: 9000,
- BaseRef: ReferenceNS(1100 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- wantErr: true,
- },
- {
- // errorAdjust bails out if new params are from after now.
- name: "params-after-now",
- oldParams: Parameters{
- BaseCycles: 10000,
- BaseRef: ReferenceNS(1000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 11000,
- newParams: Parameters{
- BaseCycles: 12000,
- BaseRef: ReferenceNS(1200 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- wantErr: true,
- },
- {
- // Host clock sped up.
- name: "speed-up",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 45000,
- // Host frequency changed to 9000 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 45000,
- // From oldParams, we think ref = 4.5s at cycles = 45000.
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 9000,
- },
- want: Parameters{
- BaseCycles: 45000,
- BaseRef: ReferenceNS(4500 * time.Millisecond.Nanoseconds()),
- // We must decrease the new frequency by 50% to
- // correct 0.5s of error in 1s
- // (ApproxUpdateInterval).
- Frequency: 4500,
- },
- errorNS: ReferenceNS(-500 * time.Millisecond.Nanoseconds()),
- },
- {
- // Host clock sped up, with now ahead of newParams.
- name: "speed-up-nowdiff",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 50000,
- // Host frequency changed to 9000 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 45000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 9000,
- },
- // nextRef = 6000ms
- // nextCycles = 9000 * (6000ms - 5000ms) + 45000
- // nextCycles = 9000 * (1s) + 45000
- // nextCycles = 54000
- // f = (54000 - 50000) / 1s = 4000
- //
- // ref = 5000ms - (50000 - 45000) / 4000
- // ref = 3.75s
- want: Parameters{
- BaseCycles: 45000,
- BaseRef: ReferenceNS(3750 * time.Millisecond.Nanoseconds()),
- Frequency: 4000,
- },
- // oldNow = 50000 * 10000 = 5s
- // newNow = (50000 - 45000) / 9000 + 5s = 5.555s
- errorNS: ReferenceNS((5000*time.Millisecond - 5555555555).Nanoseconds()),
- },
- {
- // Host clock sped up. The new parameters are so far
- // ahead that the next update time already passed.
- name: "speed-up-uncorrectable-baseref",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 50000,
- // Host frequency changed to 5000 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 45000,
- BaseRef: ReferenceNS(9000 * time.Millisecond.Nanoseconds()),
- Frequency: 5000,
- },
- // The next update should be at 10s, but newParams
- // already passed 6s. Thus it is impossible to correct
- // the clock by then.
- wantErr: true,
- },
- {
- // Host clock sped up. The new parameters are moving so
- // fast that the next update should be before now.
- name: "speed-up-uncorrectable-frequency",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 55000,
- // Host frequency changed to 7500 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 45000,
- BaseRef: ReferenceNS(6000 * time.Millisecond.Nanoseconds()),
- Frequency: 7500,
- },
- // The next update should be at 6.5s, but newParams are
- // so far ahead and fast that they reach 6.5s at cycle
- // 48750, which before now! Thus it is impossible to
- // correct the clock by then.
- wantErr: true,
- },
- {
- // Host clock slowed down.
- name: "slow-down",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 55000,
- // Host frequency changed to 11000 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 55000,
- // From oldParams, we think ref = 5.5s at cycles = 55000.
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 11000,
- },
- want: Parameters{
- BaseCycles: 55000,
- BaseRef: ReferenceNS(5500 * time.Millisecond.Nanoseconds()),
- // We must increase the new frequency by 50% to
- // correct 0.5s of error in 1s
- // (ApproxUpdateInterval).
- Frequency: 16500,
- },
- errorNS: ReferenceNS(500 * time.Millisecond.Nanoseconds()),
- },
- {
- // Host clock slowed down, with now ahead of newParams.
- name: "slow-down-nowdiff",
- oldParams: Parameters{
- BaseCycles: 0,
- BaseRef: 0,
- Frequency: 10000,
- },
- now: 60000,
- // Host frequency changed to 11000 immediately after
- // oldParams was returned.
- newParams: Parameters{
- BaseCycles: 55000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 11000,
- },
- // nextRef = 7000ms
- // nextCycles = 11000 * (7000ms - 5000ms) + 55000
- // nextCycles = 11000 * (2000ms) + 55000
- // nextCycles = 77000
- // f = (77000 - 60000) / 1s = 17000
- //
- // ref = 6000ms - (60000 - 55000) / 17000
- // ref = 5705882353ns
- want: Parameters{
- BaseCycles: 55000,
- BaseRef: ReferenceNS(5705882353),
- Frequency: 17000,
- },
- // oldNow = 60000 * 10000 = 6s
- // newNow = (60000 - 55000) / 11000 + 5s = 5.4545s
- errorNS: ReferenceNS((6*time.Second - 5454545454).Nanoseconds()),
- },
- {
- // Host time went backwards.
- name: "time-backwards",
- oldParams: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 60000,
- newParams: Parameters{
- BaseCycles: 60000,
- // From oldParams, we think ref = 6s at cycles = 60000.
- BaseRef: ReferenceNS(4000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- want: Parameters{
- BaseCycles: 60000,
- BaseRef: ReferenceNS(6000 * time.Millisecond.Nanoseconds()),
- // We must increase the frequency by 200% to
- // correct 2s of error in 1s
- // (ApproxUpdateInterval).
- Frequency: 30000,
- },
- errorNS: ReferenceNS(2000 * time.Millisecond.Nanoseconds()),
- },
- {
- // Host time went backwards, with now ahead of newParams.
- name: "time-backwards-nowdiff",
- oldParams: Parameters{
- BaseCycles: 50000,
- BaseRef: ReferenceNS(5000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- now: 65000,
- // nextRef = 7500ms
- // nextCycles = 10000 * (7500ms - 4000ms) + 60000
- // nextCycles = 10000 * (3500ms) + 60000
- // nextCycles = 95000
- // f = (95000 - 65000) / 1s = 30000
- //
- // ref = 6500ms - (65000 - 60000) / 30000
- // ref = 6333333333ns
- newParams: Parameters{
- BaseCycles: 60000,
- BaseRef: ReferenceNS(4000 * time.Millisecond.Nanoseconds()),
- Frequency: 10000,
- },
- want: Parameters{
- BaseCycles: 60000,
- BaseRef: ReferenceNS(6333333334),
- Frequency: 30000,
- },
- // oldNow = 65000 * 10000 = 6.5s
- // newNow = (65000 - 60000) / 10000 + 4s = 4.5s
- errorNS: ReferenceNS(2000 * time.Millisecond.Nanoseconds()),
- },
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- got, errorNS, err := errorAdjust(tc.oldParams, tc.newParams, tc.now)
- if err != nil && !tc.wantErr {
- t.Errorf("err got %v want nil", err)
- } else if err == nil && tc.wantErr {
- t.Errorf("err got nil want non-nil")
- }
-
- if got != tc.want {
- t.Errorf("Parameters got %+v want %+v", got, tc.want)
- }
- if errorNS != tc.errorNS {
- t.Errorf("errorNS got %v want %v", errorNS, tc.errorNS)
- }
- })
- }
-}
-
-func testMuldiv(t *testing.T, v uint64) {
- for i := uint64(1); i <= 1000000; i++ {
- mult := uint64(1000000000)
- div := i * mult
- res, ok := muldiv64(v, mult, div)
- if !ok {
- t.Errorf("Result of %v * %v / %v ok got false want true", v, mult, div)
- }
- if want := v / i; res != want {
- t.Errorf("Bad result of %v * %v / %v: got %v, want %v", v, mult, div, res, want)
- }
- }
-}
-
-func TestMulDiv(t *testing.T) {
- testMuldiv(t, math.MaxUint64)
- for i := int64(-10); i <= 10; i++ {
- testMuldiv(t, uint64(i))
- }
-}
-
-func TestMulDivZero(t *testing.T) {
- if r, ok := muldiv64(2, 4, 0); ok {
- t.Errorf("muldiv64(2, 4, 0) got %d, ok want !ok", r)
- }
-
- if r, ok := muldiv64(0, 0, 0); ok {
- t.Errorf("muldiv64(0, 0, 0) got %d, ok want !ok", r)
- }
-}
-
-func TestMulDivOverflow(t *testing.T) {
- testCases := []struct {
- name string
- val uint64
- mult uint64
- div uint64
- ok bool
- ret uint64
- }{
- {
- name: "2^62",
- val: 1 << 63,
- mult: 4,
- div: 8,
- ok: true,
- ret: 1 << 62,
- },
- {
- name: "2^64-1",
- val: 0xffffffffffffffff,
- mult: 1,
- div: 1,
- ok: true,
- ret: 0xffffffffffffffff,
- },
- {
- name: "2^64",
- val: 1 << 63,
- mult: 4,
- div: 2,
- ok: false,
- },
- {
- name: "2^125",
- val: 1 << 63,
- mult: 1 << 63,
- div: 2,
- ok: false,
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- r, ok := muldiv64(tc.val, tc.mult, tc.div)
- if ok != tc.ok {
- t.Errorf("ok got %v want %v", ok, tc.ok)
- }
- if tc.ok && r != tc.ret {
- t.Errorf("ret got %v want %v", r, tc.ret)
- }
- })
- }
-}
-
-func BenchmarkMuldiv64(b *testing.B) {
- var v uint64 = math.MaxUint64
- for i := uint64(1); i <= 1000000; i++ {
- mult := uint64(1000000000)
- div := i * mult
- res, ok := muldiv64(v, mult, div)
- if !ok {
- b.Errorf("Result of %v * %v / %v ok got false want true", v, mult, div)
- }
- if want := v / i; res != want {
- b.Errorf("Bad result of %v * %v / %v: got %v, want %v", v, mult, div, res, want)
- }
- }
-}