212 lines
5.1 KiB
Go
212 lines
5.1 KiB
Go
|
/*
|
||
|
Copyright 2014 The Kubernetes 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 resource
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func TestDetectOverflowAdd(t *testing.T) {
|
||
|
for _, test := range []struct {
|
||
|
a, b int64
|
||
|
c int64
|
||
|
ok bool
|
||
|
}{
|
||
|
{0, 0, 0, true},
|
||
|
{-1, 1, 0, true},
|
||
|
{0, 1, 1, true},
|
||
|
{2, 2, 4, true},
|
||
|
{2, -2, 0, true},
|
||
|
{-2, -2, -4, true},
|
||
|
|
||
|
{mostNegative, -1, 0, false},
|
||
|
{mostNegative, 1, mostNegative + 1, true},
|
||
|
{mostPositive, -1, mostPositive - 1, true},
|
||
|
{mostPositive, 1, 0, false},
|
||
|
|
||
|
{mostNegative, mostPositive, -1, true},
|
||
|
{mostPositive, mostNegative, -1, true},
|
||
|
{mostPositive, mostPositive, 0, false},
|
||
|
{mostNegative, mostNegative, 0, false},
|
||
|
|
||
|
{-mostPositive, mostNegative, 0, false},
|
||
|
{mostNegative, -mostPositive, 0, false},
|
||
|
{-mostPositive, -mostPositive, 0, false},
|
||
|
} {
|
||
|
c, ok := int64Add(test.a, test.b)
|
||
|
if c != test.c {
|
||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||
|
}
|
||
|
if ok != test.ok {
|
||
|
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||
|
}
|
||
|
// addition is commutative
|
||
|
d, ok2 := int64Add(test.b, test.a)
|
||
|
if c != d || ok != ok2 {
|
||
|
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDetectOverflowMultiply(t *testing.T) {
|
||
|
for _, test := range []struct {
|
||
|
a, b int64
|
||
|
c int64
|
||
|
ok bool
|
||
|
}{
|
||
|
{0, 0, 0, true},
|
||
|
{-1, 1, -1, true},
|
||
|
{-1, -1, 1, true},
|
||
|
{1, 1, 1, true},
|
||
|
{0, 1, 0, true},
|
||
|
{1, 0, 0, true},
|
||
|
{2, 2, 4, true},
|
||
|
{2, -2, -4, true},
|
||
|
{-2, -2, 4, true},
|
||
|
|
||
|
{mostNegative, -1, 0, false},
|
||
|
{mostNegative, 1, mostNegative, true},
|
||
|
{mostPositive, -1, -mostPositive, true},
|
||
|
{mostPositive, 1, mostPositive, true},
|
||
|
|
||
|
{mostNegative, mostPositive, 0, false},
|
||
|
{mostPositive, mostNegative, 0, false},
|
||
|
{mostPositive, mostPositive, 1, false},
|
||
|
{mostNegative, mostNegative, 0, false},
|
||
|
|
||
|
{-mostPositive, mostNegative, 0, false},
|
||
|
{mostNegative, -mostPositive, 0, false},
|
||
|
{-mostPositive, -mostPositive, 1, false},
|
||
|
} {
|
||
|
c, ok := int64Multiply(test.a, test.b)
|
||
|
if c != test.c {
|
||
|
t.Errorf("%v: unexpected result: %d", test, c)
|
||
|
}
|
||
|
if ok != test.ok {
|
||
|
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||
|
}
|
||
|
// multiplication is commutative
|
||
|
d, ok2 := int64Multiply(test.b, test.a)
|
||
|
if c != d || ok != ok2 {
|
||
|
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDetectOverflowScale(t *testing.T) {
|
||
|
for _, a := range []int64{0, -1, 1, 10, -10, mostPositive, mostNegative, -mostPositive} {
|
||
|
for _, b := range []int64{1, 2, 10, 100, 1000, mostPositive} {
|
||
|
expect, expectOk := int64Multiply(a, b)
|
||
|
|
||
|
c, ok := int64MultiplyScale(a, b)
|
||
|
if c != expect {
|
||
|
t.Errorf("%d*%d: unexpected result: %d", a, b, c)
|
||
|
}
|
||
|
if ok != expectOk {
|
||
|
t.Errorf("%d*%d: unexpected overflow: %t", a, b, ok)
|
||
|
}
|
||
|
}
|
||
|
for _, test := range []struct {
|
||
|
base int64
|
||
|
fn func(a int64) (int64, bool)
|
||
|
}{
|
||
|
{10, int64MultiplyScale10},
|
||
|
{100, int64MultiplyScale100},
|
||
|
{1000, int64MultiplyScale1000},
|
||
|
} {
|
||
|
expect, expectOk := int64Multiply(a, test.base)
|
||
|
c, ok := test.fn(a)
|
||
|
if c != expect {
|
||
|
t.Errorf("%d*%d: unexpected result: %d", a, test.base, c)
|
||
|
}
|
||
|
if ok != expectOk {
|
||
|
t.Errorf("%d*%d: unexpected overflow: %t", a, test.base, ok)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemoveInt64Factors(t *testing.T) {
|
||
|
for _, test := range []struct {
|
||
|
value int64
|
||
|
max int64
|
||
|
result int64
|
||
|
scale int32
|
||
|
}{
|
||
|
{100, 10, 1, 2},
|
||
|
{100, 10, 1, 2},
|
||
|
{100, 100, 1, 1},
|
||
|
{1, 10, 1, 0},
|
||
|
} {
|
||
|
r, s := removeInt64Factors(test.value, test.max)
|
||
|
if r != test.result {
|
||
|
t.Errorf("%v: unexpected result: %d", test, r)
|
||
|
}
|
||
|
if s != test.scale {
|
||
|
t.Errorf("%v: unexpected scale: %d", test, s)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestNegativeScaleInt64(t *testing.T) {
|
||
|
for _, test := range []struct {
|
||
|
base int64
|
||
|
scale Scale
|
||
|
result int64
|
||
|
exact bool
|
||
|
}{
|
||
|
{1234567, 0, 1234567, true},
|
||
|
{1234567, 1, 123457, false},
|
||
|
{1234567, 2, 12346, false},
|
||
|
{1234567, 3, 1235, false},
|
||
|
{1234567, 4, 124, false},
|
||
|
|
||
|
{-1234567, 0, -1234567, true},
|
||
|
{-1234567, 1, -123457, false},
|
||
|
{-1234567, 2, -12346, false},
|
||
|
{-1234567, 3, -1235, false},
|
||
|
{-1234567, 4, -124, false},
|
||
|
|
||
|
{1000, 0, 1000, true},
|
||
|
{1000, 1, 100, true},
|
||
|
{1000, 2, 10, true},
|
||
|
{1000, 3, 1, true},
|
||
|
{1000, 4, 1, false},
|
||
|
|
||
|
{-1000, 0, -1000, true},
|
||
|
{-1000, 1, -100, true},
|
||
|
{-1000, 2, -10, true},
|
||
|
{-1000, 3, -1, true},
|
||
|
{-1000, 4, -1, false},
|
||
|
|
||
|
{0, 0, 0, true},
|
||
|
{0, 1, 0, true},
|
||
|
{0, 2, 0, true},
|
||
|
|
||
|
// negative scale is undefined behavior
|
||
|
{1000, -1, 1000, true},
|
||
|
} {
|
||
|
result, exact := negativeScaleInt64(test.base, test.scale)
|
||
|
if result != test.result {
|
||
|
t.Errorf("%v: unexpected result: %d", test, result)
|
||
|
}
|
||
|
if exact != test.exact {
|
||
|
t.Errorf("%v: unexpected exact: %t", test, exact)
|
||
|
}
|
||
|
}
|
||
|
}
|