func TestDecScan(t *testing.T) { tmp := new(inf.Dec) for i, test := range decStringTests { if test.scale < 0 { // SetString only supports scale >= 0 continue } // initialize to a non-zero value so that issues with parsing // 0 are detected tmp.Set(inf.NewDec(1234567890, 123)) n1, n2 := new(inf.Dec), tmp nn1, err1 := fmt.Sscan(test.in, n1) nn2, err2 := fmt.Sscan(test.in, n2) if !test.scanOk { if err1 == nil || err2 == nil { t.Errorf("#%d (input '%s') ok incorrect, should be %t", i, test.in, test.scanOk) } continue } expected := inf.NewDec(test.val, test.scale) if nn1 != 1 || err1 != nil || nn2 != 1 || err2 != nil { t.Errorf("#%d (input '%s') error %d %v, %d %v", i, test.in, nn1, err1, nn2, err2) continue } if n1.Cmp(expected) != 0 { t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val) } if n2.Cmp(expected) != 0 { t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val) } } }
func TestDecGobEncoding(t *testing.T) { var medium bytes.Buffer enc := gob.NewEncoder(&medium) dec := gob.NewDecoder(&medium) for i, test := range decGobEncodingTests { for j := 0; j < 2; j++ { for k := inf.Scale(-5); k <= 5; k++ { medium.Reset() // empty buffer for each test case (in case of failures) stest := test if j != 0 { // negative numbers stest = "-" + test } var tx inf.Dec tx.SetString(stest) tx.SetScale(k) // test with positive, negative, and zero scale if err := enc.Encode(&tx); err != nil { t.Errorf("#%d%c: encoding failed: %s", i, 'a'+j, err) } var rx inf.Dec if err := dec.Decode(&rx); err != nil { t.Errorf("#%d%c: decoding failed: %s", i, 'a'+j, err) } if rx.Cmp(&tx) != 0 { t.Errorf("#%d%c: transmission failed: got %s want %s", i, 'a'+j, &rx, &tx) } } } } }
// checkResource determines whether a specific resource needs to be over-written. func checkResource(threshold int64, actual, expected api.ResourceList, res api.ResourceName) bool { val, ok := actual[res] expVal, expOk := expected[res] if ok != expOk { return true } if !ok && !expOk { return false } q := new(inf.Dec).QuoRound(val.Amount, expVal.Amount, 2, inf.RoundDown) lower := inf.NewDec(100-threshold, 2) upper := inf.NewDec(100+threshold, 2) if q.Cmp(lower) == -1 || q.Cmp(upper) == 1 { return true } return false }
func TestDecSetString(t *testing.T) { tmp := new(inf.Dec) for i, test := range decStringTests { if test.scale < 0 { // SetString only supports scale >= 0 continue } // initialize to a non-zero value so that issues with parsing // 0 are detected tmp.Set(inf.NewDec(1234567890, 123)) n1, ok1 := new(inf.Dec).SetString(test.in) n2, ok2 := tmp.SetString(test.in) expected := inf.NewDec(test.val, test.scale) if ok1 != test.ok || ok2 != test.ok { t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok) continue } if !ok1 { if n1 != nil { t.Errorf("#%d (input '%s') n1 != nil", i, test.in) } continue } if !ok2 { if n2 != nil { t.Errorf("#%d (input '%s') n2 != nil", i, test.in) } continue } if n1.Cmp(expected) != 0 { t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val) } if n2.Cmp(expected) != 0 { t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val) } } }
func TestDecGetString(t *testing.T) { z := new(inf.Dec) for i, test := range decStringTests { if !test.ok { continue } z.SetUnscaled(test.val) z.SetScale(test.scale) s := z.String() if s != test.out { t.Errorf("#%da got %s; want %s", i, s, test.out) } s = fmt.Sprintf("%d", z) if s != test.out { t.Errorf("#%db got %s; want %s", i, s, test.out) } } }
// ParseQuantity turns str into a Quantity, or returns an error. func ParseQuantity(str string) (*Quantity, error) { parts := splitRE.FindStringSubmatch(strings.TrimSpace(str)) // regexp returns are entire match, followed by an entry for each () section. if len(parts) != 3 { return nil, ErrFormatWrong } amount := new(inf.Dec) if _, ok := amount.SetString(parts[1]); !ok { return nil, ErrNumeric } base, exponent, format, ok := quantitySuffixer.interpret(suffix(parts[2])) if !ok { return nil, ErrSuffix } // So that no one but us has to think about suffixes, remove it. if base == 10 { amount.SetScale(amount.Scale() + inf.Scale(-exponent)) } else if base == 2 { // numericSuffix = 2 ** exponent numericSuffix := big.NewInt(1).Lsh(bigOne, uint(exponent)) ub := amount.UnscaledBig() amount.SetUnscaledBig(ub.Mul(ub, numericSuffix)) } // Cap at min/max bounds. sign := amount.Sign() if sign == -1 { amount.Neg(amount) } // This rounds non-zero values up to the minimum representable // value, under the theory that if you want some resources, you // should get some resources, even if you asked for way too small // of an amount. // Arguably, this should be inf.RoundHalfUp (normal rounding), but // that would have the side effect of rounding values < .5m to zero. if v, ok := amount.Unscaled(); v != int64(0) || !ok { amount.Round(amount, 3, inf.RoundUp) } // The max is just a simple cap. if amount.Cmp(maxAllowed) > 0 { amount.Set(maxAllowed) } if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 { // This avoids rounding and hopefully confusion, too. format = DecimalSI } if sign == -1 { amount.Neg(amount) } return &Quantity{amount, format}, nil }
func TestReadNodeConfigLocalVolumeDirQuota(t *testing.T) { tests := map[string]struct { config string expected string }{ "null quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: null `, expected: "", }, "missing quota": { config: ` apiVersion: v1 volumeConfig: localQuota: `, expected: "", }, "missing localQuota": { config: ` apiVersion: v1 volumeConfig: `, expected: "", }, "missing volumeConfig": { config: ` apiVersion: v1 `, expected: "", }, "no unit (bytes) quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 200000 `, expected: "200000", }, "Kb quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 200Ki `, expected: "204800", }, "Mb quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 512Mi `, expected: "536870912", }, "Gb quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 2Gi `, expected: "2147483648", }, "Tb quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 2Ti `, expected: "2199023255552", }, // This is invalid config, would be caught by validation but just // testing it parses ok: "negative quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: -512Mi `, expected: "-536870912", }, "zero quota": { config: ` apiVersion: v1 volumeConfig: localQuota: perFSGroup: 0 `, expected: "0", }, } for name, test := range tests { t.Logf("Running test: %s", name) nodeConfig := &internal.NodeConfig{} if err := latest.ReadYAMLInto([]byte(test.config), nodeConfig); err != nil { t.Errorf("Error reading yaml: %s", err.Error()) } if test.expected == "" && nodeConfig.VolumeConfig.LocalQuota.PerFSGroup != nil { t.Errorf("Expected empty quota but got: %s", *nodeConfig.VolumeConfig.LocalQuota.PerFSGroup) } if test.expected != "" { if nodeConfig.VolumeConfig.LocalQuota.PerFSGroup == nil { t.Errorf("Expected quota: %s, got: nil", test.expected) } else { amount := nodeConfig.VolumeConfig.LocalQuota.PerFSGroup.Amount t.Logf("%s", amount.String()) rounded := new(inf.Dec) rounded.Round(amount, 0, inf.RoundUp) t.Logf("%s", rounded.String()) if test.expected != rounded.String() { t.Errorf("Expected quota: %s, got: %s", test.expected, rounded.String()) } } } } }
func TestLowLevelAPIOnly(t *testing.T) { type CDR struct { Imsi string Timestamp time.Time Duration int64 Carrier string Cost *inf.Dec } strat := func(c gocql.ColumnInfo) (reflect.StructField, bool) { st := reflect.TypeOf((*CDR)(nil)).Elem() switch c.Name { case "imsi": return st.FieldByName("Imsi") case "timestamp": return st.FieldByName("Timestamp") case "duration": return st.FieldByName("Duration") case "carrier": return st.FieldByName("Carrier") case "charge": return st.FieldByName("Cost") default: return reflect.StructField{}, false } } s := setup(t, "calls") measurements := 43 start := time.Now() for i := 0; i < measurements; i++ { cost := new(inf.Dec) cost.SetString(fmt.Sprintf("1.0%d", i)) cdr := CDR{ Imsi: "240080852000132", Timestamp: start.Add(time.Duration(i) * time.Millisecond), Duration: int64(i) + 60, Carrier: "TMOB", Cost: cost, } if err := Bind(`INSERT INTO calls (imsi, timestamp, duration, carrier, charge) VALUES (?, ?, ?, ?, ?)`, cdr).Use(strat).Exec(s); err != nil { t.Fatal(err) } } q := s.Query(`SELECT imsi, timestamp, duration, carrier, charge FROM calls`) b := BindQuery(q).Use(strat) count := 0 var r CDR for b.Scan(&r) { count++ assert.Equal(t, "TMOB", r.Carrier) } err := b.Close() assert.Nil(t, err, "Could not close binding") assert.Equal(t, measurements, count) }
func ExampleDec_SetString() { d := new(inf.Dec) d.SetString("012345.67890") // decimal; leading 0 ignored; trailing 0 kept fmt.Println(d) // Output: 12345.67890 }
func TestDecAbsZ(t *testing.T) { var zero inf.Dec for _, a := range decSumZZ { var z inf.Dec z.Abs(a.z) var e inf.Dec e.Set(a.z) if e.Cmp(&zero) < 0 { e.Sub(&zero, &e) } if z.Cmp(&e) != 0 { t.Errorf("got z = %v; want %v", z, e) } } }