How to use Fatalf method of test Package

Best Go-testdeep code snippet using test.Fatalf

builtins_test.go

Source:builtins_test.go Github

copy

Full Screen

...23 out := archFn(ENV, []primitive.Primitive{})24 // Will lead to a number25 e, ok := out.(primitive.String)26 if !ok {27 t.Fatalf("expected string, got %v", out)28 }29 if e.ToString() != runtime.GOARCH {30 t.Fatalf("got wrong value for runtime architecture")31 }32}33// Test (car34func TestCar(t *testing.T) {35 // No arguments36 out := carFn(ENV, []primitive.Primitive{})37 // Will lead to an error38 e, ok := out.(primitive.Error)39 if !ok {40 t.Fatalf("expected error, got %v", out)41 }42 if e != primitive.ArityError() {43 t.Fatalf("got error, but wrong one %v", out)44 }45 // One argument46 out = carFn(ENV, []primitive.Primitive{47 primitive.Number(3),48 })49 // Will lead to an error50 e, ok = out.(primitive.Error)51 if !ok {52 t.Fatalf("expected error, got %v", out)53 }54 if !strings.Contains(string(e), "not a list") {55 t.Fatalf("got error, but wrong one %v", out)56 }57 // Now a list58 out = carFn(ENV, []primitive.Primitive{59 primitive.List{60 primitive.Number(3),61 primitive.Number(4),62 },63 })64 // No error65 r, ok2 := out.(primitive.Number)66 if !ok2 {67 t.Fatalf("expected number, got %v", out)68 }69 if r.ToString() != "3" {70 t.Fatalf("got wrong result : %v", r)71 }72 // Now a list which is empty73 out = carFn(ENV, []primitive.Primitive{74 primitive.List{},75 })76 // No error77 _, ok3 := out.(primitive.Nil)78 if !ok3 {79 t.Fatalf("expected nil, got %v", out)80 }81}82// Test (cdr83func TestCdr(t *testing.T) {84 // No arguments85 out := cdrFn(ENV, []primitive.Primitive{})86 // Will lead to an error87 e, ok := out.(primitive.Error)88 if !ok {89 t.Fatalf("expected error, got %v", out)90 }91 if e != primitive.ArityError() {92 t.Fatalf("got error, but wrong one %v", out)93 }94 // One argument95 out = cdrFn(ENV, []primitive.Primitive{96 primitive.Number(3),97 })98 // Will lead to an error99 e, ok = out.(primitive.Error)100 if !ok {101 t.Fatalf("expected error, got %v", out)102 }103 if !strings.Contains(string(e), "not a list") {104 t.Fatalf("got error, but wrong one %v", out)105 }106 // Now a list107 out = cdrFn(ENV, []primitive.Primitive{108 primitive.List{109 primitive.Number(3),110 primitive.Number(4),111 primitive.Number(5),112 },113 })114 // No error115 r, ok2 := out.(primitive.List)116 if !ok2 {117 t.Fatalf("expected list, got %v", out)118 }119 if r.ToString() != "(4 5)" {120 t.Fatalf("got wrong result : %v", r)121 }122 // Now a list which is empty123 out = cdrFn(ENV, []primitive.Primitive{124 primitive.List{},125 })126 // No error127 _, ok3 := out.(primitive.Nil)128 if !ok3 {129 t.Fatalf("expected nil, got %v", out)130 }131}132func TestChr(t *testing.T) {133 // no arguments134 out := chrFn(ENV, []primitive.Primitive{})135 // Will lead to an error136 e, ok := out.(primitive.Error)137 if !ok {138 t.Fatalf("expected error, got %v", out)139 }140 if e != primitive.ArityError() {141 t.Fatalf("got error, but wrong one:%s", out)142 }143 // First argument must be a number144 out = chrFn(ENV, []primitive.Primitive{145 primitive.String("4"),146 })147 // Will lead to an error148 e, ok = out.(primitive.Error)149 if !ok {150 t.Fatalf("expected error, got %v", out)151 }152 if !strings.Contains(string(e), "not a number") {153 t.Fatalf("got error, but wrong one %v", out)154 }155 // Now a valid call 42 => "*"156 val := chrFn(ENV, []primitive.Primitive{157 primitive.Number(42),158 })159 r, ok2 := val.(primitive.String)160 if !ok2 {161 t.Fatalf("expected string, got %v", val)162 }163 if r.ToString() != "*" {164 t.Fatalf("got wrong result %v", r)165 }166}167func TestCons(t *testing.T) {168 // No arguments169 out := consFn(ENV, []primitive.Primitive{})170 // Will lead to an error171 e, ok := out.(primitive.Error)172 if !ok {173 t.Fatalf("expected error, got %v", out)174 }175 if e != primitive.ArityError() {176 t.Fatalf("got error, but wrong one %v", out)177 }178 // one argument, string -> list179 out = consFn(ENV, []primitive.Primitive{180 primitive.String("steve"),181 })182 out, ok2 := out.(primitive.List)183 if !ok2 {184 t.Errorf("expected list")185 }186 if out.ToString() != "(steve)" {187 t.Fatalf("wrong result")188 }189 // A list with a nil second element is gonna be truncated190 out = consFn(ENV, []primitive.Primitive{191 primitive.String("steve"),192 primitive.Nil{},193 })194 out, ok2 = out.(primitive.List)195 if !ok2 {196 t.Errorf("expected list")197 }198 if out.ToString() != "(steve)" {199 t.Fatalf("wrong result")200 }201 // A list and a number202 a := []primitive.Primitive{203 primitive.List{204 primitive.Number(3),205 primitive.Number(4),206 },207 primitive.Number(5),208 }209 // A number and a list210 b := []primitive.Primitive{211 primitive.Number(5),212 primitive.List{213 primitive.Number(3),214 primitive.Number(4),215 },216 }217 // first one218 out = consFn(ENV, a)219 out, ok2 = out.(primitive.List)220 if !ok2 {221 t.Errorf("expected list")222 }223 if out.ToString() != "((3 4) 5)" {224 t.Fatalf("wrong result, got %v", out)225 }226 // second one227 out = consFn(ENV, b)228 out, ok2 = out.(primitive.List)229 if !ok2 {230 t.Errorf("expected list")231 }232 if out.ToString() != "(5 3 4)" {233 t.Fatalf("wrong result, got %v", out)234 }235}236func TestContains(t *testing.T) {237 // no arguments238 out := containsFn(ENV, []primitive.Primitive{})239 // Will lead to an error240 e, ok := out.(primitive.Error)241 if !ok {242 t.Fatalf("expected error, got %v", out)243 }244 if !strings.Contains(string(e), "argument") {245 t.Fatalf("got error, but wrong one")246 }247 // First argument must be a hash248 out = containsFn(ENV, []primitive.Primitive{249 primitive.String("foo"),250 primitive.String("bar"),251 })252 // Will lead to an error253 e, ok = out.(primitive.Error)254 if !ok {255 t.Fatalf("expected error, got %v", out)256 }257 if !strings.Contains(string(e), "not a hash") {258 t.Fatalf("got error, but wrong one %v", out)259 }260 // create a hash261 h := primitive.NewHash()262 h.Set("XXX", primitive.String("Last"))263 h.Set("Name", primitive.String("Steve"))264 h.Set("Age", primitive.Number(43))265 h.Set("Location", primitive.String("Helsinki"))266 // Should have Age267 res := containsFn(ENV, []primitive.Primitive{268 h,269 primitive.String("Age"),270 })271 // Will lead to a bool272 v, ok2 := res.(primitive.Bool)273 if !ok2 {274 t.Fatalf("expected bool, got %v", res)275 }276 if v != primitive.Bool(true) {277 t.Fatalf("failed to find expected key")278 }279 // Should have Age - as a symbol280 res = containsFn(ENV, []primitive.Primitive{281 h,282 primitive.Symbol("Age"),283 })284 // Will lead to a bool285 v, ok2 = res.(primitive.Bool)286 if !ok2 {287 t.Fatalf("expected bool, got %v", res)288 }289 if v != primitive.Bool(true) {290 t.Fatalf("failed to find expected key")291 }292 // Should NOT have Cake293 res = containsFn(ENV, []primitive.Primitive{294 h,295 primitive.String("Cake"),296 })297 // Will lead to a bool298 v, ok2 = res.(primitive.Bool)299 if !ok2 {300 t.Fatalf("expected bool, got %v", res)301 }302 if v != primitive.Bool(false) {303 t.Fatalf("unexpectedly found missing key")304 }305}306// We don't really test the contents here.307func TestDateTime(t *testing.T) {308 // No arguments309 dt := dateFn(ENV, []primitive.Primitive{})310 tm := timeFn(ENV, []primitive.Primitive{})311 // date should return a list312 out, ok := dt.(primitive.List)313 if !ok {314 t.Fatalf("expected list for (date), got %v", dt)315 }316 // "weekday", "day", "month", "year" == four entries317 if len(out) != 4 {318 t.Fatalf("date list had the wrong length, got %d: %v", len(out), out)319 }320 // time should return a list321 out, ok = tm.(primitive.List)322 if !ok {323 t.Fatalf("expected list for (time), got %v", tm)324 }325 // "hour", "minute", "seconds" == three entries326 if len(out) != 3 {327 t.Fatalf("time list had the wrong length, got %d: %v", len(out), out)328 }329}330// TestDirectory tests directory?331func TestDirectory(t *testing.T) {332 // No arguments333 out := directoryFn(ENV, []primitive.Primitive{})334 // Will lead to an error335 e, ok := out.(primitive.Error)336 if !ok {337 t.Fatalf("expected error, got %v", out)338 }339 if e != primitive.ArityError() {340 t.Fatalf("got error, but wrong one %v", out)341 }342 // One argument, wrong type343 out = directoryFn(ENV, []primitive.Primitive{primitive.Number(33)})344 // Will lead to an error345 e, ok = out.(primitive.Error)346 if !ok {347 t.Fatalf("expected error, got %v", out)348 }349 if !strings.Contains(string(e), "not a string") {350 t.Fatalf("got error, but wrong one %v", out)351 }352 // Create a temporary directory353 path, err := os.MkdirTemp("", "directory_")354 if err != nil {355 t.Fatalf("failed to create a temporary direcotry")356 }357 // directory? should return true358 res := directoryFn(ENV, []primitive.Primitive{primitive.String(path)})359 // So we need a boolean result360 r, ok2 := res.(primitive.Bool)361 if !ok2 {362 t.Fatalf("found wrong type in result")363 }364 if r.ToString() != "#t" {365 t.Fatalf("wrong result, got %v", r.ToString())366 }367 // Remove the file368 os.RemoveAll(path)369 // directory? should return false370 res = directoryFn(ENV, []primitive.Primitive{primitive.String(path)})371 // So we need a booelan result372 r, ok2 = res.(primitive.Bool)373 if !ok2 {374 t.Fatalf("found wrong type in result, got %v", res)375 }376 if r.ToString() != "#f" {377 t.Fatalf("wrong result, got %v", r.ToString())378 }379}380// TestDirectoryEntries tests directory:entries381func TestDirectoryEntries(t *testing.T) {382 // No arguments383 out := directoryEntriesFn(ENV, []primitive.Primitive{})384 // Will lead to an error385 e, ok := out.(primitive.Error)386 if !ok {387 t.Fatalf("expected error, got %v", out)388 }389 if !strings.Contains(string(e), "argument count") {390 t.Fatalf("got error, but wrong one %v", out)391 }392 // One argument, wrong type393 out = directoryEntriesFn(ENV, []primitive.Primitive{primitive.Number(33)})394 // Will lead to an error395 e, ok = out.(primitive.Error)396 if !ok {397 t.Fatalf("expected error, got %v", out)398 }399 if !strings.Contains(string(e), "not a string") {400 t.Fatalf("got error, but wrong one %v", out)401 }402 // Create a temporary directory403 path, err := os.MkdirTemp("", "directory_")404 if err != nil {405 t.Fatalf("failed to create a temporary directory")406 }407 // Populate two files.408 a := filepath.Join(path, "one.txt")409 b := filepath.Join(path, "two.foo")410 err = os.WriteFile(a, []byte("one.txt"), 0777)411 if err != nil {412 t.Fatalf("failed to write to file")413 }414 err = os.WriteFile(b, []byte("two.foo"), 0777)415 if err != nil {416 t.Fatalf("failed to write to file")417 }418 // Now we should find a list of two files if we walk the419 // temporary directory.420 res := directoryEntriesFn(ENV, []primitive.Primitive{421 primitive.String(path),422 })423 // Will lead to a list424 lst, ok2 := res.(primitive.List)425 if !ok2 {426 t.Fatalf("expected list, got %v", out)427 }428 if len(lst) != 3 {429 t.Fatalf("failed to find expected file-count, got %v", lst)430 }431 // Delete one of the two files, and ensure we still find results432 os.Remove(a)433 // walk again434 res = directoryEntriesFn(ENV, []primitive.Primitive{435 primitive.String(path),436 })437 // Will lead to a list438 lst, ok2 = res.(primitive.List)439 if !ok2 {440 t.Fatalf("expected list, got %v", out)441 }442 if len(lst) != 2 {443 t.Fatalf("failed to find expected file-count, got %v", lst)444 }445 // Finally cleanup446 os.RemoveAll(path)447 // walk a missing directory448 res = directoryEntriesFn(ENV, []primitive.Primitive{449 primitive.String("/ fdsf dsf /this doesnt exist"),450 })451 // Will lead to a list still452 lst, ok2 = res.(primitive.List)453 if !ok2 {454 t.Fatalf("expected list, got %v", out)455 }456 // but empty457 if len(lst) != 0 {458 t.Fatalf("failed to find expected file-count, got %v", lst)459 }460}461// TestDivide tests "*"462func TestDivide(t *testing.T) {463 // Test for "equality"464 //465 // Because floating points are hard466 almostEqual := func(a, b float64) bool {467 // Arbitrary equality threshold468 float64EqualityThreshold := float64(1.0 / 1000000)469 return math.Abs(a-b) <= float64EqualityThreshold470 }471 // No arguments472 out := divideFn(ENV, []primitive.Primitive{})473 // Will lead to an error474 e, ok := out.(primitive.Error)475 if !ok {476 t.Fatalf("expected error, got %v", out)477 }478 if e != primitive.ArityError() {479 t.Fatalf("got error, but wrong one %v", out)480 }481 // Argument which isn't a number482 out = divideFn(ENV, []primitive.Primitive{483 primitive.String("foo"),484 })485 // Will lead to an error486 e, ok = out.(primitive.Error)487 if !ok {488 t.Fatalf("expected error, got %v", out)489 }490 if !strings.Contains(string(e), "not a number") {491 t.Fatalf("got error, but wrong one %v", out)492 }493 // Argument which isn't a number494 out = divideFn(ENV, []primitive.Primitive{495 primitive.Number(32),496 primitive.String("foo"),497 })498 // Will lead to an error499 e, ok = out.(primitive.Error)500 if !ok {501 t.Fatalf("expected error, got %v", out)502 }503 if !strings.Contains(string(e), "not a number") {504 t.Fatalf("got error, but wrong one %v", out)505 }506 // Division by zero507 out = divideFn(ENV, []primitive.Primitive{508 primitive.Number(32),509 primitive.Number(0),510 })511 // Will lead to an error512 e, ok = out.(primitive.Error)513 if !ok {514 t.Fatalf("expected error, got %v", out)515 }516 if !strings.Contains(string(e), "division by zero") {517 t.Fatalf("got error, but wrong one %v", out)518 }519 //520 // Now a real one521 //522 out = divideFn(ENV, []primitive.Primitive{523 primitive.Number(12),524 primitive.Number(3),525 })526 // Will work527 n, ok2 := out.(primitive.Number)528 if !ok2 {529 t.Fatalf("expected number, got %v", out)530 }531 if n != 4 {532 t.Fatalf("got wrong result")533 }534 // Test only a single argument.535 out = divideFn(ENV, []primitive.Primitive{536 primitive.Number(12),537 })538 // Will work539 n, ok2 = out.(primitive.Number)540 if !ok2 {541 t.Fatalf("expected number, got %v", out)542 }543 if !almostEqual(float64(n), 0.083333) {544 t.Fatalf("got wrong result: %f", n)545 }546 // Another test547 out = divideFn(ENV, []primitive.Primitive{548 primitive.Number(-3),549 })550 // Will work551 n, ok2 = out.(primitive.Number)552 if !ok2 {553 t.Fatalf("expected number, got %v", out)554 }555 if !almostEqual(float64(n), -(1 / 3.0)) {556 t.Fatalf("got wrong result: %f", n)557 }558}559// TestEnsureHelpPresent ensures that all our built-in functions have560// help-text available561func TestEnsureHelpPresent(t *testing.T) {562 // create a new environment, and populate it563 e := env.New()564 PopulateEnvironment(e)565 // For each function566 items := e.Items()567 for name, val := range items {568 proc, ok := val.(*primitive.Procedure)569 if ok {570 t.Run("Testing "+name, func(t *testing.T) {571 if len(proc.Help) == 0 {572 t.Fatalf("help text is unset")573 }574 })575 }576 }577}578// TestEq tests "eq" (non-numerical equality)579func TestEq(t *testing.T) {580 // No arguments581 out := eqFn(ENV, []primitive.Primitive{})582 // Will lead to an error583 e, ok := out.(primitive.Error)584 if !ok {585 t.Fatalf("expected error, got %v", out)586 }587 if e != primitive.ArityError() {588 t.Fatalf("got error, but wrong one %v", out)589 }590 //591 // Now a real one: equal592 //593 out = eqFn(ENV, []primitive.Primitive{594 primitive.Number(9),595 primitive.Number(9),596 })597 // Will work598 n, ok2 := out.(primitive.Bool)599 if !ok2 {600 t.Fatalf("expected bool, got %v", out)601 }602 if n != true {603 t.Fatalf("got wrong result")604 }605 //606 // Now a real one: unequal values607 //608 out = eqFn(ENV, []primitive.Primitive{609 primitive.String("99"),610 primitive.String("9"),611 })612 // Will work613 n, ok2 = out.(primitive.Bool)614 if !ok2 {615 t.Fatalf("expected bool, got %v", out)616 }617 if n != false {618 t.Fatalf("got wrong result")619 }620 //621 // Now a real one: unequal types622 //623 out = eqFn(ENV, []primitive.Primitive{624 primitive.Number(9),625 primitive.String("9"),626 })627 // Will work628 n, ok2 = out.(primitive.Bool)629 if !ok2 {630 t.Fatalf("expected bool, got %v", out)631 }632 if n != false {633 t.Fatalf("got wrong result")634 }635}636// TestEquals tests "=" (numerical equality)637func TestEquals(t *testing.T) {638 // No arguments639 out := equalsFn(ENV, []primitive.Primitive{})640 // Will lead to an error641 e, ok := out.(primitive.Error)642 if !ok {643 t.Fatalf("expected error, got %v", out)644 }645 if e != primitive.ArityError() {646 t.Fatalf("got error, but wrong one %v", out)647 }648 //649 // Now a real one: equal650 //651 out = equalsFn(ENV, []primitive.Primitive{652 primitive.Number(9),653 primitive.Number(9),654 })655 // Will work656 n, ok2 := out.(primitive.Bool)657 if !ok2 {658 t.Fatalf("expected bool, got %v", out)659 }660 if n != true {661 t.Fatalf("got wrong result")662 }663 //664 // Now a real one: equal - but multiple values665 //666 out = equalsFn(ENV, []primitive.Primitive{667 primitive.Number(9),668 primitive.Number(9),669 primitive.Number(9),670 primitive.Number(9),671 primitive.Number(9),672 primitive.Number(9),673 })674 // Will work675 n, ok2 = out.(primitive.Bool)676 if !ok2 {677 t.Fatalf("expected bool, got %v", out)678 }679 if n != true {680 t.Fatalf("got wrong result")681 }682 //683 // Now a real one: unequal values684 //685 out = equalsFn(ENV, []primitive.Primitive{686 primitive.Number(99),687 primitive.Number(9),688 primitive.Number(99),689 primitive.Number(9),690 })691 // Will work692 n, ok2 = out.(primitive.Bool)693 if !ok2 {694 t.Fatalf("expected bool, got %v", out)695 }696 if n != false {697 t.Fatalf("got wrong result")698 }699 //700 // Now with wrong types - last one is wrong701 //702 out = equalsFn(ENV, []primitive.Primitive{703 primitive.Number(1),704 primitive.Number(2),705 primitive.Number(3),706 primitive.Number(4),707 primitive.String("5"),708 })709 e, ok = out.(primitive.Error)710 if !ok {711 t.Fatalf("expected error, got %v", out)712 }713 if !strings.Contains(string(e), "was not a number") {714 t.Fatalf("got error, but wrong one '%v'", e)715 }716 //717 // Now with wrong types718 //719 out = equalsFn(ENV, []primitive.Primitive{720 primitive.String("9"),721 primitive.Number(9),722 })723 // Will report an error724 e, ok = out.(primitive.Error)725 if !ok {726 t.Fatalf("expected error, got %v", out)727 }728 if !strings.Contains(string(e), "was not a number") {729 t.Fatalf("got error, but wrong one %v", out)730 }731}732// TestError tests error.733func TestError(t *testing.T) {734 // No arguments735 out := errorFn(ENV, []primitive.Primitive{})736 // Will lead to an error737 e, ok := out.(primitive.Error)738 if !ok {739 t.Fatalf("expected error, got %v", out)740 }741 if e != primitive.ArityError() {742 t.Fatalf("got error, but wrong one %v", out)743 }744 // calling with an arg745 out = errorFn(ENV, []primitive.Primitive{746 primitive.String("No Cheese Detected"),747 })748 // Will lead to an string749 e, ok = out.(primitive.Error)750 if !ok {751 t.Fatalf("expected error, got %v", out)752 }753 if e != "No Cheese Detected" {754 t.Fatalf("got wrong error %v", out)755 }756}757// TestExists tests exists?758func TestExists(t *testing.T) {759 // No arguments760 out := existsFn(ENV, []primitive.Primitive{})761 // Will lead to an error762 e, ok := out.(primitive.Error)763 if !ok {764 t.Fatalf("expected error, got %v", out)765 }766 if !strings.Contains(string(e), "argument count") {767 t.Fatalf("got error, but wrong one %v", out)768 }769 // One argument, wrong type770 out = existsFn(ENV, []primitive.Primitive{primitive.Number(33)})771 // Will lead to an error772 e, ok = out.(primitive.Error)773 if !ok {774 t.Fatalf("expected error, got %v", out)775 }776 if !strings.Contains(string(e), "not a string") {777 t.Fatalf("got error, but wrong one %v", out)778 }779 // Create a temporary file780 tmpfile, err := os.CreateTemp("", "exists")781 if err != nil {782 t.Fatalf("failed to create a temporary file")783 }784 // Exists should return true785 res := existsFn(ENV, []primitive.Primitive{primitive.String(tmpfile.Name())})786 // So we need a booelan result787 r, ok2 := res.(primitive.Bool)788 if !ok2 {789 t.Fatalf("found wrong type in result")790 }791 if r.ToString() != "#t" {792 t.Fatalf("wrong result, got %v", r.ToString())793 }794 // Remove the file795 os.Remove(tmpfile.Name())796 // Exists should return false797 res = existsFn(ENV, []primitive.Primitive{primitive.String(tmpfile.Name())})798 // So we need a booelan result799 r, ok2 = res.(primitive.Bool)800 if !ok2 {801 t.Fatalf("found wrong type in result")802 }803 if r.ToString() != "#f" {804 t.Fatalf("wrong result, got %v", r.ToString())805 }806}807// TestExpandString tests the escape-expansion of the various characters808func TestExpandString(t *testing.T) {809 type TC struct {810 in string811 out string812 }813 tests := []TC{814 {in: "steve", out: "steve"},815 {in: "steve\\tkemp", out: "steve\tkemp"},816 {in: "steve\\rkemp", out: "steve\rkemp"},817 {in: "steve\\nkemp", out: "steve\nkemp"},818 {in: "steve\"kemp", out: "steve\"kemp"},819 {in: "steve\\\\kemp", out: "steve\\kemp"},820 {in: "steve\\bkemp", out: "steve\\bkemp"},821 {in: "steve\\ekemp", out: "steve" + string(rune(033)) + "kemp"},822 }823 for i, test := range tests {824 if expandStr(test.in) != test.out {825 t.Fatalf("%d: expected %s, got %s", i, test.out, expandStr(test.in))826 }827 }828}829// TestExpn tests "#"830func TestExpn(t *testing.T) {831 // No arguments832 out := expnFn(ENV, []primitive.Primitive{})833 // Will lead to an error834 e, ok := out.(primitive.Error)835 if !ok {836 t.Fatalf("expected error, got %v", out)837 }838 if e != primitive.ArityError() {839 t.Fatalf("got error, but wrong one %v", out)840 }841 // Argument which isn't a number842 out = expnFn(ENV, []primitive.Primitive{843 primitive.String("foo"),844 primitive.String("foo"),845 })846 // Will lead to an error847 e, ok = out.(primitive.Error)848 if !ok {849 t.Fatalf("expected error, got %v", out)850 }851 if !strings.Contains(string(e), "not a number") {852 t.Fatalf("got error, but wrong one %v", out)853 }854 // Argument which isn't a number855 out = expnFn(ENV, []primitive.Primitive{856 primitive.Number(32),857 primitive.String("foo"),858 })859 // Will lead to an error860 e, ok = out.(primitive.Error)861 if !ok {862 t.Fatalf("expected error, got %v", out)863 }864 if !strings.Contains(string(e), "not a number") {865 t.Fatalf("got error, but wrong one %v", out)866 }867 //868 // Now a real one869 //870 out = expnFn(ENV, []primitive.Primitive{871 primitive.Number(9),872 primitive.Number(0.5),873 })874 // Will work875 n, ok2 := out.(primitive.Number)876 if !ok2 {877 t.Fatalf("expected number, got %v", out)878 }879 if n != 3 {880 t.Fatalf("got wrong result")881 }882}883// TestFile tests file?884func TestFile(t *testing.T) {885 // No arguments886 out := fileFn(ENV, []primitive.Primitive{})887 // Will lead to an error888 e, ok := out.(primitive.Error)889 if !ok {890 t.Fatalf("expected error, got %v", out)891 }892 if !strings.Contains(string(e), "argument count") {893 t.Fatalf("got error, but wrong one %v", out)894 }895 // One argument, wrong type896 out = fileFn(ENV, []primitive.Primitive{primitive.Number(33)})897 // Will lead to an error898 e, ok = out.(primitive.Error)899 if !ok {900 t.Fatalf("expected error, got %v", out)901 }902 if !strings.Contains(string(e), "not a string") {903 t.Fatalf("got error, but wrong one %v", out)904 }905 // Create a temporary directory906 path, err := os.MkdirTemp("", "directory_")907 if err != nil {908 t.Fatalf("failed to create a temporary directory")909 }910 // file? should return false911 res := fileFn(ENV, []primitive.Primitive{primitive.String(path)})912 // So we need a boolean result913 r, ok2 := res.(primitive.Bool)914 if !ok2 {915 t.Fatalf("found wrong type in result")916 }917 if r.ToString() != "#f" {918 t.Fatalf("wrong result, got %v", r.ToString())919 }920 // Remove the file921 os.RemoveAll(path)922 // Now create a file.923 tmp, _ := os.CreateTemp("", "yal")924 err = os.WriteFile(tmp.Name(), []byte("I like cake"), 0777)925 if err != nil {926 t.Fatalf("failed to write to file")927 }928 defer os.Remove(tmp.Name())929 // file? should return true930 res = fileFn(ENV, []primitive.Primitive{primitive.String(tmp.Name())})931 // So we need a boolean result932 r, ok2 = res.(primitive.Bool)933 if !ok2 {934 t.Fatalf("found wrong type in result, got %v", res)935 }936 if r.ToString() != "#t" {937 t.Fatalf("wrong result, got %v", r.ToString())938 }939}940// TestFileLines tests file:lines941func TestFileLines(t *testing.T) {942 // calling with no argument943 out := fileLinesFn(ENV, []primitive.Primitive{})944 // Will lead to an error945 _, ok := out.(primitive.Error)946 if !ok {947 t.Fatalf("expected error, got %v", out)948 }949 // calling with the wrong argument type.950 out = fileLinesFn(ENV, []primitive.Primitive{951 primitive.Number(3)})952 // Will lead to an error953 _, ok = out.(primitive.Error)954 if !ok {955 t.Fatalf("expected error, got %v", out)956 }957 // Call with a file that doesn't exist958 out = fileLinesFn(ENV, []primitive.Primitive{959 primitive.String("path/not/found")})960 _, ok = out.(primitive.Error)961 if !ok {962 t.Fatalf("expected error, got %v", out)963 }964 // Create a temporary file, and read the contents965 tmp, _ := os.CreateTemp("", "yal")966 err := os.WriteFile(tmp.Name(), []byte("I like cake\nAnd pie."), 0777)967 if err != nil {968 t.Fatalf("failed to write to file")969 }970 defer os.Remove(tmp.Name())971 str := fileLinesFn(ENV, []primitive.Primitive{972 primitive.String(tmp.Name())})973 // Will lead to a list974 lst, ok2 := str.(primitive.List)975 if !ok2 {976 t.Fatalf("expected list, got %v", out)977 }978 if len(lst) != 2 {979 t.Fatalf("re-reading the temporary file gave bogus contents")980 }981}982// TestFileRead tests file:read983func TestFileRead(t *testing.T) {984 // calling with no argument985 out := fileReadFn(ENV, []primitive.Primitive{})986 // Will lead to an error987 _, ok := out.(primitive.Error)988 if !ok {989 t.Fatalf("expected error, got %v", out)990 }991 // Call with the wrong type992 out = fileReadFn(ENV, []primitive.Primitive{993 primitive.Number(3)})994 _, ok = out.(primitive.Error)995 if !ok {996 t.Fatalf("expected error, got %v", out)997 }998 // Call with a file that doesn't exist999 out = fileReadFn(ENV, []primitive.Primitive{1000 primitive.String("path/not/found")})1001 _, ok = out.(primitive.Error)1002 if !ok {1003 t.Fatalf("expected error, got %v", out)1004 }1005 // Create a temporary file, and read the contents1006 tmp, _ := os.CreateTemp("", "yal")1007 err := os.WriteFile(tmp.Name(), []byte("I like cake"), 0777)1008 if err != nil {1009 t.Fatalf("failed to write to file")1010 }1011 defer os.Remove(tmp.Name())1012 str := fileReadFn(ENV, []primitive.Primitive{1013 primitive.String(tmp.Name())})1014 // Will lead to a string1015 txt, ok2 := str.(primitive.String)1016 if !ok2 {1017 t.Fatalf("expected string, got %v", out)1018 }1019 if txt.ToString() != "I like cake" {1020 t.Fatalf("re-reading the temporary file gave bogus contents")1021 }1022}1023// TestFileStat tests file:stat1024func TestFileStat(t *testing.T) {1025 // calling with no argument1026 out := fileStatFn(ENV, []primitive.Primitive{})1027 // Will lead to an error1028 _, ok := out.(primitive.Error)1029 if !ok {1030 t.Fatalf("expected error, got %v", out)1031 }1032 // Call with the wrong type1033 out = fileStatFn(ENV, []primitive.Primitive{1034 primitive.Number(3)})1035 _, ok = out.(primitive.Error)1036 if !ok {1037 t.Fatalf("expected error, got %v", out)1038 }1039 // Call with a file that doesn't exist1040 out = fileStatFn(ENV, []primitive.Primitive{1041 primitive.String("path/not/found")})1042 _, ok = out.(primitive.Nil)1043 if !ok {1044 t.Fatalf("expected nil, got %v", out)1045 }1046 // Create a temporary file1047 tmp, _ := os.CreateTemp("", "yal")1048 err := os.WriteFile(tmp.Name(), []byte("42 is the answer"), 0777)1049 if err != nil {1050 t.Fatalf("failed to write to file")1051 }1052 defer os.Remove(tmp.Name())1053 // stat that1054 str := fileStatFn(ENV, []primitive.Primitive{1055 primitive.String(tmp.Name())})1056 // Will lead to a list1057 lst, ok2 := str.(primitive.List)1058 if !ok2 {1059 t.Fatalf("expected list, got %v", out)1060 }1061 // List will be: NAME SIZE ..1062 if lst[1].ToString() != "16" {1063 t.Fatalf("The size was wrong: %s", lst)1064 }1065}1066// TestFileWrite tests file:write1067func TestFileWrite(t *testing.T) {1068 // calling with no argument1069 out := fileWriteFn(ENV, []primitive.Primitive{})1070 // Will lead to an error1071 _, ok := out.(primitive.Error)1072 if !ok {1073 t.Fatalf("expected error, got %v", out)1074 }1075 // Call with the wrong type1076 out = fileWriteFn(ENV, []primitive.Primitive{1077 primitive.Number(3),1078 primitive.String("cake")})1079 _, ok = out.(primitive.Error)1080 if !ok {1081 t.Fatalf("expected error, got %v", out)1082 }1083 // Call with the wrong type1084 out = fileWriteFn(ENV, []primitive.Primitive{1085 primitive.String("/tmp/blah.txt"),1086 primitive.Number(3)})1087 _, ok = out.(primitive.Error)1088 if !ok {1089 t.Fatalf("expected error, got %v", out)1090 }1091 // Now we can try to write to something real1092 // Create a temporary file to write to1093 tmpfile, err := os.CreateTemp("", "exists")1094 if err != nil {1095 t.Fatalf("failed to create a temporary file")1096 }1097 defer os.Remove(tmpfile.Name())1098 // Try to write there1099 result := fileWriteFn(ENV, []primitive.Primitive{1100 primitive.String(tmpfile.Name()),1101 primitive.String("cake")})1102 // Should be no errors1103 _, ok = result.(primitive.Nil)1104 if !ok {1105 t.Fatalf("expected nil, got %v", out)1106 }1107 // Now create a temmporary directory, and use that1108 // as the destination - which will fail once it is1109 // removed1110 path, err2 := os.MkdirTemp("", "directory_")1111 if err2 != nil {1112 t.Fatalf("failed to create temporary directory")1113 }1114 // path beneath the temporary directory1115 target := filepath.Join(path, "foo.txt")1116 // remove the direcotry1117 os.RemoveAll(path)1118 failure := fileWriteFn(ENV, []primitive.Primitive{1119 primitive.String(target),1120 primitive.String("cake")})1121 // Should be no errors1122 _, ok = failure.(primitive.Error)1123 if !ok {1124 t.Fatalf("expected failure writing beneath a directory which was removed, got %v", out)1125 }1126}1127// TestGenSym tests gensym1128func TestGenSym(t *testing.T) {1129 // no arguments are required1130 out := gensymFn(ENV, []primitive.Primitive{})1131 // Will lead to a symbol1132 _, ok := out.(primitive.Symbol)1133 if !ok {1134 t.Fatalf("expected symbol, got %v", out)1135 }1136}1137// TestGet tests get1138func TestGet(t *testing.T) {1139 // no arguments1140 out := getFn(ENV, []primitive.Primitive{})1141 // Will lead to an error1142 e, ok := out.(primitive.Error)1143 if !ok {1144 t.Fatalf("expected error, got %v", out)1145 }1146 if !strings.Contains(string(e), "argument") {1147 t.Fatalf("got error, but wrong one")1148 }1149 // First argument must be a hash1150 out = getFn(ENV, []primitive.Primitive{1151 primitive.String("foo"),1152 primitive.String("foo"),1153 })1154 // Will lead to an error1155 e, ok = out.(primitive.Error)1156 if !ok {1157 t.Fatalf("expected error, got %v", out)1158 }1159 if !strings.Contains(string(e), "not a hash") {1160 t.Fatalf("got error, but wrong one %v", out)1161 }1162 // create a hash1163 h := primitive.NewHash()1164 // Set a value1165 h.Set("Name", primitive.String("STEVE"))1166 // Now get it1167 out2 := getFn(ENV, []primitive.Primitive{1168 h,1169 primitive.String("Name"),1170 })1171 // Will lead to a string1172 s, ok2 := out2.(primitive.String)1173 if !ok2 {1174 t.Fatalf("expected string, got %v", out2)1175 }1176 if !strings.Contains(string(s), "STEVE") {1177 t.Fatalf("got string, but wrong one %v", s)1178 }1179}1180// TestGetenv tests getenv1181func TestGetenv(t *testing.T) {1182 // No arguments1183 out := getenvFn(ENV, []primitive.Primitive{})1184 // Will lead to an error1185 e, ok := out.(primitive.Error)1186 if !ok {1187 t.Fatalf("expected error, got %v", out)1188 }1189 if e != primitive.ArityError() {1190 t.Fatalf("got error, but wrong one %v", out)1191 }1192 // Argument that isn't a string1193 out = getenvFn(ENV, []primitive.Primitive{1194 primitive.Number(3),1195 })1196 // Will lead to an error1197 e, ok = out.(primitive.Error)1198 if !ok {1199 t.Fatalf("expected error, got %v", out)1200 }1201 if !strings.Contains(string(e), "not a string") {1202 t.Fatalf("got error, but wrong one %v", out)1203 }1204 // Valid result1205 x := os.Getenv("USER")1206 y := getenvFn(ENV, []primitive.Primitive{1207 primitive.String("USER"),1208 })1209 yStr := string(y.(primitive.String))1210 if yStr != x {1211 t.Fatalf("getenv USER mismatch")1212 }1213}1214// TestGlob tests glob1215func TestGlob(t *testing.T) {1216 // No arguments1217 out := globFn(ENV, []primitive.Primitive{})1218 // Will lead to an error1219 e, ok := out.(primitive.Error)1220 if !ok {1221 t.Fatalf("expected error, got %v", out)1222 }1223 if !strings.Contains(string(e), "argument count") {1224 t.Fatalf("got error, but wrong one %v", out)1225 }1226 // One argument, wrong type1227 out = globFn(ENV, []primitive.Primitive{primitive.Number(33)})1228 // Will lead to an error1229 e, ok = out.(primitive.Error)1230 if !ok {1231 t.Fatalf("expected error, got %v", out)1232 }1233 if !strings.Contains(string(e), "not a string") {1234 t.Fatalf("got error, but wrong one %v", out)1235 }1236 // Create a temporary directory1237 path, err := os.MkdirTemp("", "directory_")1238 if err != nil {1239 t.Fatalf("failed to create a temporary directory")1240 }1241 // Populate two files.1242 a := filepath.Join(path, "one.txt")1243 b := filepath.Join(path, "two.foo")1244 err = os.WriteFile(a, []byte("one.txt"), 0777)1245 if err != nil {1246 t.Fatalf("failed to write to file")1247 }1248 err = os.WriteFile(b, []byte("two.foo"), 0777)1249 if err != nil {1250 t.Fatalf("failed to write to file")1251 }1252 // Glob with two files1253 files := globFn(ENV, []primitive.Primitive{primitive.String(path + "/*.*")})1254 // Should get a list1255 lst, ok2 := files.(primitive.List)1256 if !ok2 {1257 t.Fatalf("expected a list, got %v", files)1258 }1259 if len(lst) != 2 {1260 t.Fatalf("expected two files, got %v", lst)1261 }1262 // Cleanup1263 os.RemoveAll(path)1264 // Finally an impossible glob1265 out = globFn(ENV, []primitive.Primitive{primitive.String("[]")})1266 // Will lead to an error1267 e, ok = out.(primitive.Error)1268 if !ok {1269 t.Fatalf("expected error, got %v", out)1270 }1271 if !strings.Contains(string(e), "error in pattern") {1272 t.Fatalf("got error, but wrong one %v", out)1273 }1274}1275// TestHelp tests help1276func TestHelp(t *testing.T) {1277 // no arguments1278 out := helpFn(ENV, []primitive.Primitive{})1279 // Will lead to an error1280 e, ok := out.(primitive.Error)1281 if !ok {1282 t.Fatalf("expected error, got %v", out)1283 }1284 if !strings.Contains(string(e), "argument") {1285 t.Fatalf("got error, but wrong one")1286 }1287 // First argument must be a procedure1288 out = helpFn(ENV, []primitive.Primitive{1289 primitive.String("foo"),1290 })1291 // Will lead to an error1292 e, ok = out.(primitive.Error)1293 if !ok {1294 t.Fatalf("expected error, got %v", out)1295 }1296 if !strings.Contains(string(e), "not a procedure") {1297 t.Fatalf("got error, but wrong one %v", out)1298 }1299 //1300 // create a new environment, and populate it1301 //1302 env := env.New()1303 PopulateEnvironment(env)1304 for _, name := range []string{"print", "sprintf", "length"} {1305 // Load our standard library1306 st := stdlib.Contents()1307 std := string(st)1308 // Create a new interpreter1309 l := eval.New(std + "\n")1310 l.Evaluate(env)1311 fn, ok := env.Get(name)1312 if !ok {1313 t.Fatalf("failed to lookup function %s in environment", name)1314 }1315 result := helpFn(ENV, []primitive.Primitive{fn.(*primitive.Procedure)})1316 txt, ok2 := result.(primitive.String)1317 if !ok2 {1318 t.Fatalf("expected a string, got %v", result)1319 }1320 if !strings.Contains(txt.ToString(), name) {1321 t.Fatalf("got help text, but didn't find expected content: %v", result)1322 }1323 }1324}1325// TestInequality tests /=1326func TestInequality(t *testing.T) {1327 // No arguments1328 out := inequalityFn(ENV, []primitive.Primitive{})1329 // Will lead to an error1330 e, ok := out.(primitive.Error)1331 if !ok {1332 t.Fatalf("expected error, got %v", out)1333 }1334 if e != primitive.ArityError() {1335 t.Fatalf("got error, but wrong one %v", out)1336 }1337 //1338 // Now a real one: unequal1339 //1340 out = inequalityFn(ENV, []primitive.Primitive{1341 primitive.Number(9),1342 primitive.Number(8),1343 })1344 // Will work1345 n, ok2 := out.(primitive.Bool)1346 if !ok2 {1347 t.Fatalf("expected bool, got %v", out)1348 }1349 if n != true {1350 t.Fatalf("got wrong result")1351 }1352 //1353 // Now a real one: unequal - but multiple values1354 //1355 out = inequalityFn(ENV, []primitive.Primitive{1356 primitive.Number(1),1357 primitive.Number(2),1358 primitive.Number(3),1359 primitive.Number(4),1360 primitive.Number(5),1361 primitive.Number(6),1362 })1363 // Will work1364 n, ok2 = out.(primitive.Bool)1365 if !ok2 {1366 t.Fatalf("expected bool, got %v", out)1367 }1368 if n != true {1369 t.Fatalf("got wrong result")1370 }1371 //1372 // Now a real one: unequal values1373 //1374 out = inequalityFn(ENV, []primitive.Primitive{1375 primitive.Number(1),1376 primitive.Number(2),1377 primitive.Number(2),1378 primitive.Number(1),1379 })1380 // Will work1381 n, ok2 = out.(primitive.Bool)1382 if !ok2 {1383 t.Fatalf("expected bool, got %v", out)1384 }1385 if n != false {1386 t.Fatalf("got wrong result")1387 }1388 //1389 // Now with wrong types - last one is wrong1390 //1391 out = inequalityFn(ENV, []primitive.Primitive{1392 primitive.Number(1),1393 primitive.Number(2),1394 primitive.Number(3),1395 primitive.Number(4),1396 primitive.String("5"),1397 })1398 e, ok = out.(primitive.Error)1399 if !ok {1400 t.Fatalf("expected error, got %v", out)1401 }1402 if !strings.Contains(string(e), "was not a number") {1403 t.Fatalf("got error, but wrong one '%v'", e)1404 }1405 //1406 // Now with wrong types1407 //1408 out = inequalityFn(ENV, []primitive.Primitive{1409 primitive.String("9"),1410 primitive.Number(9),1411 })1412 // Will report an error1413 e, ok = out.(primitive.Error)1414 if !ok {1415 t.Fatalf("expected error, got %v", out)1416 }1417 if !strings.Contains(string(e), "was not a number") {1418 t.Fatalf("got error, but wrong one %v", out)1419 }1420}1421// TestJoin tests join1422func TestJoin(t *testing.T) {1423 // No arguments1424 out := joinFn(ENV, []primitive.Primitive{})1425 // Will lead to an error1426 e, ok := out.(primitive.Error)1427 if !ok {1428 t.Fatalf("expected error, got %v", out)1429 }1430 if e != primitive.ArityError() {1431 t.Fatalf("got error, but wrong one %v", out)1432 }1433 // Not a list1434 out = joinFn(ENV, []primitive.Primitive{1435 primitive.String("s"),1436 })1437 // Will lead to an error1438 e, ok = out.(primitive.Error)1439 if !ok {1440 t.Fatalf("expected error, got %v", out)1441 }1442 if !strings.Contains(string(e), "not a list") {1443 t.Fatalf("got error, but wrong one %v", out)1444 }1445 // Now a list1446 out = joinFn(ENV, []primitive.Primitive{1447 primitive.List{1448 primitive.Number(3),1449 primitive.Number(4),1450 },1451 })1452 s, ok2 := out.(primitive.String)1453 if !ok2 {1454 t.Fatalf("expected string, got %v", s)1455 }1456 if s != "34" {1457 t.Fatalf("got wrong result %v", s)1458 }1459}1460// TestKeys tests keys1461func TestKeys(t *testing.T) {1462 // no arguments1463 out := keysFn(ENV, []primitive.Primitive{})1464 // Will lead to an error1465 e, ok := out.(primitive.Error)1466 if !ok {1467 t.Fatalf("expected error, got %v", out)1468 }1469 if !strings.Contains(string(e), "argument") {1470 t.Fatalf("got error, but wrong one")1471 }1472 // First argument must be a hash1473 out = keysFn(ENV, []primitive.Primitive{1474 primitive.String("foo"),1475 })1476 // Will lead to an error1477 e, ok = out.(primitive.Error)1478 if !ok {1479 t.Fatalf("expected error, got %v", out)1480 }1481 if !strings.Contains(string(e), "not a hash") {1482 t.Fatalf("got error, but wrong one %v", out)1483 }1484 // create a hash1485 h := primitive.NewHash()1486 h.Set("XXX", primitive.String("Last"))1487 h.Set("Name", primitive.String("Steve"))1488 h.Set("Age", primitive.Number(43))1489 h.Set("Location", primitive.String("Helsinki"))1490 // Get the keys1491 res := keysFn(ENV, []primitive.Primitive{1492 h,1493 })1494 // Will lead to a list1495 _, ok2 := res.(primitive.List)1496 if !ok2 {1497 t.Fatalf("expected list, got %v", res)1498 }1499 // Sorted1500 lst := res.(primitive.List)1501 if lst[0].ToString() != "Age" {1502 t.Fatalf("not a sorted list?")1503 }1504 if lst[1].ToString() != "Location" {1505 t.Fatalf("not a sorted list?")1506 }1507 if lst[2].ToString() != "Name" {1508 t.Fatalf("not a sorted list?")1509 }1510 if lst[3].ToString() != "XXX" {1511 t.Fatalf("not a sorted list?")1512 }1513}1514// TestList tests list1515func TestList(t *testing.T) {1516 // No arguments1517 out := listFn(ENV, []primitive.Primitive{})1518 // No error1519 e, ok := out.(primitive.List)1520 if !ok {1521 t.Fatalf("expected error, got %v", out)1522 }1523 if e.ToString() != "()" {1524 t.Fatalf("unexpected output %v", out)1525 }1526 // Two arguments1527 out = listFn(ENV, []primitive.Primitive{1528 primitive.Number(3),1529 primitive.Number(43),1530 })1531 // No error1532 e, ok = out.(primitive.List)1533 if !ok {1534 t.Fatalf("expected error, got %v", out)1535 }1536 if e.ToString() != "(3 43)" {1537 t.Fatalf("unexpected output %v", out)1538 }1539}1540// TestLt tests "<"1541func TestLt(t *testing.T) {1542 // No arguments1543 out := ltFn(ENV, []primitive.Primitive{})1544 // Will lead to an error1545 e, ok := out.(primitive.Error)1546 if !ok {1547 t.Fatalf("expected error, got %v", out)1548 }1549 if e != primitive.ArityError() {1550 t.Fatalf("got error, but wrong one %v", out)1551 }1552 // Argument which isn't a number1553 out = ltFn(ENV, []primitive.Primitive{1554 primitive.String("foo"),1555 primitive.String("foo"),1556 })1557 // Will lead to an error1558 e, ok = out.(primitive.Error)1559 if !ok {1560 t.Fatalf("expected error, got %v", out)1561 }1562 if !strings.Contains(string(e), "not a number") {1563 t.Fatalf("got error, but wrong one %v", out)1564 }1565 // Argument which isn't a number1566 out = ltFn(ENV, []primitive.Primitive{1567 primitive.Number(32),1568 primitive.String("foo"),1569 })1570 // Will lead to an error1571 e, ok = out.(primitive.Error)1572 if !ok {1573 t.Fatalf("expected error, got %v", out)1574 }1575 if !strings.Contains(string(e), "not a number") {1576 t.Fatalf("got error, but wrong one %v", out)1577 }1578 //1579 // Now a real one1580 //1581 out = ltFn(ENV, []primitive.Primitive{1582 primitive.Number(9),1583 primitive.Number(100),1584 })1585 // Will work1586 n, ok2 := out.(primitive.Bool)1587 if !ok2 {1588 t.Fatalf("expected bool, got %v", out)1589 }1590 if n != true {1591 t.Fatalf("got wrong result")1592 }1593}1594// TestMatches tests match1595func TestMatches(t *testing.T) {1596 // no arguments1597 out := matchFn(ENV, []primitive.Primitive{})1598 // Will lead to an error1599 e, ok := out.(primitive.Error)1600 if !ok {1601 t.Fatalf("expected error, got %v", out)1602 }1603 if e != primitive.ArityError() {1604 t.Fatalf("got error, but wrong one")1605 }1606 // First argument must be a string1607 out = matchFn(ENV, []primitive.Primitive{1608 primitive.Number(3),1609 primitive.Number(4),1610 })1611 // Will lead to an error1612 e, ok = out.(primitive.Error)1613 if !ok {1614 t.Fatalf("expected error, got %v", out)1615 }1616 if !strings.Contains(string(e), "not a string") {1617 t.Fatalf("got error, but wrong one %v", out)1618 }1619 // Regexp must be valid1620 out = matchFn(ENV, []primitive.Primitive{1621 primitive.String("+"),1622 primitive.Number(4),1623 })1624 // Will lead to an error1625 e, ok = out.(primitive.Error)1626 if !ok {1627 t.Fatalf("expected error, got %v", out)1628 }1629 if !strings.Contains(string(e), "error parsing regexp") {1630 t.Fatalf("got error, but wrong one %v", out)1631 }1632 // Now we have a valid call: no match1633 fail := matchFn(ENV, []primitive.Primitive{1634 primitive.String("foo"),1635 primitive.String("bar"),1636 })1637 _, ok = fail.(primitive.Nil)1638 if !ok {1639 t.Fatalf("expected nil, got %v", out)1640 }1641 // Now we have a valid call: a match1642 res := matchFn(ENV, []primitive.Primitive{1643 primitive.String("[Ff]ood"),1644 primitive.String("Food"),1645 })1646 // The list should have one entry1647 lst, ok2 := res.(primitive.List)1648 if !ok2 {1649 t.Fatalf("expected a list, got %v", out)1650 }1651 if len(lst) != 1 {1652 t.Fatalf("unexpected list size")1653 }1654 // Now we have a valid call: a match with capture group1655 res = matchFn(ENV, []primitive.Primitive{1656 primitive.String("([a-z]+)\\s*=\\s*([a-z]+)"),1657 primitive.String("key = value"),1658 })1659 // The list should have three entries1660 lst, ok2 = res.(primitive.List)1661 if !ok2 {1662 t.Fatalf("expected a list, got %v", out)1663 }1664 if len(lst) != 3 {1665 t.Fatalf("unexpected list size")1666 }1667 if lst[0].ToString() != "key = value" {1668 t.Fatalf("bogus match result")1669 }1670 if lst[1].ToString() != "key" {1671 t.Fatalf("bogus match result")1672 }1673 if lst[2].ToString() != "value" {1674 t.Fatalf("bogus match result")1675 }1676}1677// TestMinus tests "-"1678func TestMinus(t *testing.T) {1679 // No arguments1680 out := minusFn(ENV, []primitive.Primitive{})1681 // Will lead to an error1682 e, ok := out.(primitive.Error)1683 if !ok {1684 t.Fatalf("expected error, got %v", out)1685 }1686 if e != primitive.ArityError() {1687 t.Fatalf("got error, but wrong one %v", out)1688 }1689 // Argument which isn't a number1690 out = minusFn(ENV, []primitive.Primitive{1691 primitive.String("foo"),1692 })1693 // Will lead to an error1694 e, ok = out.(primitive.Error)1695 if !ok {1696 t.Fatalf("expected error, got %v", out)1697 }1698 if !strings.Contains(string(e), "not a number") {1699 t.Fatalf("got error, but wrong one %v", out)1700 }1701 // Argument which isn't a number1702 out = minusFn(ENV, []primitive.Primitive{1703 primitive.Number(32),1704 primitive.String("foo"),1705 })1706 // Will lead to an error1707 e, ok = out.(primitive.Error)1708 if !ok {1709 t.Fatalf("expected error, got %v", out)1710 }1711 if !strings.Contains(string(e), "not a number") {1712 t.Fatalf("got error, but wrong one %v", out)1713 }1714 //1715 // Now a real one1716 //1717 out = minusFn(ENV, []primitive.Primitive{1718 primitive.Number(10),1719 primitive.Number(3),1720 })1721 // Will work1722 n, ok2 := out.(primitive.Number)1723 if !ok2 {1724 t.Fatalf("expected number, got %v", out)1725 }1726 if n != 7 {1727 t.Fatalf("got wrong result")1728 }1729}1730// TestMod tests "%"1731func TestMod(t *testing.T) {1732 // No arguments1733 out := modFn(ENV, []primitive.Primitive{})1734 // Will lead to an error1735 e, ok := out.(primitive.Error)1736 if !ok {1737 t.Fatalf("expected error, got %v", out)1738 }1739 if e != primitive.ArityError() {1740 t.Fatalf("got error, but wrong one %v", out)1741 }1742 // Argument which isn't a number1743 out = modFn(ENV, []primitive.Primitive{1744 primitive.String("foo"),1745 primitive.String("foo"),1746 })1747 // Will lead to an error1748 e, ok = out.(primitive.Error)1749 if !ok {1750 t.Fatalf("expected error, got %v", out)1751 }1752 if !strings.Contains(string(e), "not a number") {1753 t.Fatalf("got error, but wrong one %v", out)1754 }1755 // Argument which isn't a number1756 out = modFn(ENV, []primitive.Primitive{1757 primitive.Number(32),1758 primitive.String("foo"),1759 })1760 // Will lead to an error1761 e, ok = out.(primitive.Error)1762 if !ok {1763 t.Fatalf("expected error, got %v", out)1764 }1765 if !strings.Contains(string(e), "not a number") {1766 t.Fatalf("got error, but wrong one %v", out)1767 }1768 //1769 // Mod 01770 //1771 out = modFn(ENV, []primitive.Primitive{1772 primitive.Number(32),1773 primitive.Number(0),1774 })1775 // Will lead to an error1776 e, ok = out.(primitive.Error)1777 if !ok {1778 t.Fatalf("expected error, got %v", out)1779 }1780 if !strings.Contains(string(e), "division by zero") {1781 t.Fatalf("got error, but wrong one %v", out)1782 }1783 //1784 // Now a real one1785 //1786 out = modFn(ENV, []primitive.Primitive{1787 primitive.Number(12),1788 primitive.Number(3),1789 })1790 // Will work1791 n, ok2 := out.(primitive.Number)1792 if !ok2 {1793 t.Fatalf("expected number, got %v", out)1794 }1795 if n != 0 {1796 t.Fatalf("got wrong result")1797 }1798}1799func TestMs(t *testing.T) {1800 // No arguments1801 out := msFn(ENV, []primitive.Primitive{})1802 // Will lead to a number1803 e, ok := out.(primitive.Number)1804 if !ok {1805 t.Fatalf("expected number, got %v", out)1806 }1807 // Get the current time1808 tm := int(time.Now().UnixNano() / int64(time.Millisecond))1809 if math.Abs(float64(tm-int(e))) > 10 {1810 t.Fatalf("weird result; (ms) != ms - outside our bound of ten seconds inaccuracy")1811 }1812}1813// TestMultiply tests "*"1814func TestMultiply(t *testing.T) {1815 // No arguments1816 out := multiplyFn(ENV, []primitive.Primitive{})1817 // Will lead to an error1818 e, ok := out.(primitive.Error)1819 if !ok {1820 t.Fatalf("expected error, got %v", out)1821 }1822 if e != primitive.ArityError() {1823 t.Fatalf("got error, but wrong one %v", out)1824 }1825 // Argument which isn't a number1826 out = multiplyFn(ENV, []primitive.Primitive{1827 primitive.String("foo"),1828 })1829 // Will lead to an error1830 e, ok = out.(primitive.Error)1831 if !ok {1832 t.Fatalf("expected error, got %v", out)1833 }1834 if !strings.Contains(string(e), "not a number") {1835 t.Fatalf("got error, but wrong one %v", out)1836 }1837 // Argument which isn't a number1838 out = multiplyFn(ENV, []primitive.Primitive{1839 primitive.Number(32),1840 primitive.String("foo"),1841 })1842 // Will lead to an error1843 e, ok = out.(primitive.Error)1844 if !ok {1845 t.Fatalf("expected error, got %v", out)1846 }1847 if !strings.Contains(string(e), "not a number") {1848 t.Fatalf("got error, but wrong one %v", out)1849 }1850 //1851 // Now a real one1852 //1853 out = multiplyFn(ENV, []primitive.Primitive{1854 primitive.Number(10),1855 primitive.Number(3),1856 })1857 // Will work1858 n, ok2 := out.(primitive.Number)1859 if !ok2 {1860 t.Fatalf("expected number, got %v", out)1861 }1862 if n != 30 {1863 t.Fatalf("got wrong result")1864 }1865}1866// test nil?1867func TestNil(t *testing.T) {1868 // No arguments1869 out := nilFn(ENV, []primitive.Primitive{})1870 // Will lead to an error1871 e, ok := out.(primitive.Error)1872 if !ok {1873 t.Fatalf("expected error, got %v", out)1874 }1875 if e != primitive.ArityError() {1876 t.Fatalf("got error, but wrong one %v", out)1877 }1878 // nil is nil1879 out = nilFn(ENV, []primitive.Primitive{1880 primitive.Nil{},1881 })1882 // Will lead to a bool1883 b, ok2 := out.(primitive.Bool)1884 if !ok2 {1885 t.Fatalf("unexpected type, expected bool, got %v", out)1886 }1887 if !b {1888 t.Fatalf("wrong result")1889 }1890 // empty list is nil1891 out = nilFn(ENV, []primitive.Primitive{1892 primitive.List{},1893 })1894 // Will lead to a bool1895 b, ok2 = out.(primitive.Bool)1896 if !ok2 {1897 t.Fatalf("unexpected type, expected bool, got %v", out)1898 }1899 if !b {1900 t.Fatalf("wrong result")1901 }1902 // Finally a number is not a nil1903 out = nilFn(ENV, []primitive.Primitive{1904 primitive.Number(32),1905 })1906 // Will lead to a bool1907 b, ok2 = out.(primitive.Bool)1908 if !ok2 {1909 t.Fatalf("unexpected type, expected bool, got %v", out)1910 }1911 if b {1912 t.Fatalf("wrong result")1913 }1914}1915func TestNow(t *testing.T) {1916 // No arguments1917 out := nowFn(ENV, []primitive.Primitive{})1918 // Will lead to a number1919 e, ok := out.(primitive.Number)1920 if !ok {1921 t.Fatalf("expected number, got %v", out)1922 }1923 // Get the current time1924 tm := time.Now().Unix()1925 if math.Abs(float64(tm-int64(e))) > 10 {1926 t.Fatalf("weird result; (now) != now - outside our bound of ten seconds inaccuracy")1927 }1928}1929func TestOrd(t *testing.T) {1930 // no arguments1931 out := ordFn(ENV, []primitive.Primitive{})1932 // Will lead to an error1933 e, ok := out.(primitive.Error)1934 if !ok {1935 t.Fatalf("expected error, got %v", out)1936 }1937 if e != primitive.ArityError() {1938 t.Fatalf("got error, but wrong one:%s", out)1939 }1940 // First argument must be a string1941 out = ordFn(ENV, []primitive.Primitive{1942 primitive.Number(4),1943 })1944 // Will lead to an error1945 e, ok = out.(primitive.Error)1946 if !ok {1947 t.Fatalf("expected error, got %v", out)1948 }1949 if !strings.Contains(string(e), "not a string") {1950 t.Fatalf("got error, but wrong one %v", out)1951 }1952 // Now a valid call: * => 421953 val := ordFn(ENV, []primitive.Primitive{1954 primitive.String("*"),1955 })1956 r, ok2 := val.(primitive.Number)1957 if !ok2 {1958 t.Fatalf("expected number, got %v", val)1959 }1960 if r.ToString() != "42" {1961 t.Fatalf("got wrong result %v", r)1962 }1963 // Now a valid call: empty string => 01964 val = ordFn(ENV, []primitive.Primitive{1965 primitive.String(""),1966 })1967 r, ok2 = val.(primitive.Number)1968 if !ok2 {1969 t.Fatalf("expected number, got %v", val)1970 }1971 if r.ToString() != "0" {1972 t.Fatalf("got wrong result %v", r)1973 }1974}1975func TestOs(t *testing.T) {1976 // No arguments1977 out := osFn(ENV, []primitive.Primitive{})1978 // Will lead to a number1979 e, ok := out.(primitive.String)1980 if !ok {1981 t.Fatalf("expected string, got %v", out)1982 }1983 if e.ToString() != runtime.GOOS {1984 t.Fatalf("got wrong value for runtime OS")1985 }1986}1987// TestPlus tests "+"1988func TestPlus(t *testing.T) {1989 // No arguments1990 out := plusFn(ENV, []primitive.Primitive{})1991 // Will lead to an error1992 e, ok := out.(primitive.Error)1993 if !ok {1994 t.Fatalf("expected error, got %v", out)1995 }1996 if e != primitive.ArityError() {1997 t.Fatalf("got error, but wrong one %v", out)1998 }1999 // Argument which isn't a number2000 out = plusFn(ENV, []primitive.Primitive{2001 primitive.String("foo"),2002 })2003 // Will lead to an error2004 e, ok = out.(primitive.Error)2005 if !ok {2006 t.Fatalf("expected error, got %v", out)2007 }2008 if !strings.Contains(string(e), "not a number") {2009 t.Fatalf("got error, but wrong one %v", out)2010 }2011 // Argument which isn't a number2012 out = plusFn(ENV, []primitive.Primitive{2013 primitive.Number(32),2014 primitive.String("foo"),2015 })2016 // Will lead to an error2017 e, ok = out.(primitive.Error)2018 if !ok {2019 t.Fatalf("expected error, got %v", out)2020 }2021 if !strings.Contains(string(e), "not a number") {2022 t.Fatalf("got error, but wrong one %v", out)2023 }2024 //2025 // Now a real one2026 //2027 out = plusFn(ENV, []primitive.Primitive{2028 primitive.Number(10),2029 primitive.Number(3),2030 })2031 // Will work2032 n, ok2 := out.(primitive.Number)2033 if !ok2 {2034 t.Fatalf("expected number, got %v", out)2035 }2036 if n != 13 {2037 t.Fatalf("got wrong result")2038 }2039}2040func TestPrint(t *testing.T) {2041 // No arguments2042 out := printFn(ENV, []primitive.Primitive{})2043 // Will lead to an error2044 e, ok := out.(primitive.Error)2045 if !ok {2046 t.Fatalf("expected error, got %v", out)2047 }2048 if e != primitive.ArityError() {2049 t.Fatalf("got error, but wrong one %v", out)2050 }2051 // One argument2052 out = printFn(ENV, []primitive.Primitive{2053 primitive.String("Hello!"),2054 })2055 e2, ok2 := out.(primitive.String)2056 if !ok2 {2057 t.Fatalf("expected string, got %v", out)2058 }2059 if e2 != "Hello!" {2060 t.Fatalf("got error, but wrong one %v", e2)2061 }2062 // Two argument2063 out = printFn(ENV, []primitive.Primitive{2064 primitive.String("Hello %s!"),2065 primitive.String("Steve"),2066 })2067 e2, ok2 = out.(primitive.String)2068 if !ok2 {2069 t.Fatalf("expected string, got %v", out)2070 }2071 if e2 != "Hello Steve!" {2072 t.Fatalf("got error, but wrong one %v", e2)2073 }2074}2075// TestRandom tests (random)2076func TestRandom(t *testing.T) {2077 // No arguments2078 out := randomFn(ENV, []primitive.Primitive{})2079 // Will lead to an error2080 e, ok := out.(primitive.Error)2081 if !ok {2082 t.Fatalf("expected error, got %v", out)2083 }2084 if e != primitive.ArityError() {2085 t.Fatalf("got error, but wrong one %v", out)2086 }2087 // One argument, of the wrong type2088 out = randomFn(ENV, []primitive.Primitive{2089 primitive.String("Hello!"),2090 })2091 e, ok = out.(primitive.Error)2092 if !ok {2093 t.Fatalf("expected error, got %v", out)2094 }2095 if !strings.Contains(string(e), "not a number") {2096 t.Fatalf("got error, but wrong one %v", out)2097 }2098 // Now call with a number2099 out = randomFn(ENV, []primitive.Primitive{2100 primitive.Number(1),2101 })2102 _, ok2 := out.(primitive.Number)2103 if !ok2 {2104 t.Fatalf("expected string, got %v", out)2105 }2106}2107// TestSet tests set2108func TestSet(t *testing.T) {2109 // no arguments2110 out := setFn(ENV, []primitive.Primitive{})2111 // Will lead to an error2112 e, ok := out.(primitive.Error)2113 if !ok {2114 t.Fatalf("expected error, got %v", out)2115 }2116 if !strings.Contains(string(e), "argument") {2117 t.Fatalf("got error, but wrong one")2118 }2119 // First argument must be a hash2120 out = setFn(ENV, []primitive.Primitive{2121 primitive.String("foo"),2122 primitive.String("foo"),2123 primitive.String("foo"),2124 })2125 // Will lead to an error2126 e, ok = out.(primitive.Error)2127 if !ok {2128 t.Fatalf("expected error, got %v", out)2129 }2130 if !strings.Contains(string(e), "not a hash") {2131 t.Fatalf("got error, but wrong one %v", out)2132 }2133 // create a hash2134 h := primitive.NewHash()2135 out2 := setFn(ENV, []primitive.Primitive{2136 h,2137 primitive.String("Name"),2138 primitive.String("Steve"),2139 })2140 // Will lead to a string2141 s, ok2 := out2.(primitive.String)2142 if !ok2 {2143 t.Fatalf("expected string, got %v", out2)2144 }2145 if !strings.Contains(string(s), "Steve") {2146 t.Fatalf("got string, but wrong one %v", s)2147 }2148 // Now ensure the hash value was set2149 v := h.Get("Name")2150 if v.ToString() != "Steve" {2151 t.Fatalf("The value wasn't set?")2152 }2153}2154// TestSetup just instantiates the primitives in the environment2155func TestSetup(t *testing.T) {2156 // Create an empty environment2157 e := env.New()2158 // Before we start we have no functions2159 _, ok := e.Get("print")2160 if ok {2161 t.Fatalf("didn't expect to get 'print' but did")2162 }2163 // Setup the builtins2164 PopulateEnvironment(e)2165 // Now we have functions2166 _, ok = e.Get("print")2167 if !ok {2168 t.Fatalf("failed to find 'print' ")2169 }2170}2171func TestSort(t *testing.T) {2172 // No arguments2173 out := sortFn(ENV, []primitive.Primitive{})2174 // Will lead to an error2175 e, ok := out.(primitive.Error)2176 if !ok {2177 t.Fatalf("expected error, got %v", out)2178 }2179 if e != primitive.ArityError() {2180 t.Fatalf("got error, but wrong one %v", out)2181 }2182 // Not a list2183 out = sortFn(ENV, []primitive.Primitive{2184 primitive.Number(3),2185 })2186 e, ok = out.(primitive.Error)2187 if !ok {2188 t.Fatalf("expected error, got %v", out)2189 }2190 if !strings.Contains(string(e), "not a list") {2191 t.Fatalf("got error, but wrong one %v", out)2192 }2193 //2194 // Now we sort2195 //2196 out = sortFn(ENV, []primitive.Primitive{2197 primitive.List{2198 primitive.Number(30),2199 primitive.Number(3),2200 primitive.Number(-3),2201 },2202 })2203 // Will lead to an error2204 s, ok2 := out.(primitive.List)2205 if !ok2 {2206 t.Fatalf("expected list, got %v", out)2207 }2208 if s.ToString() != "(-3 3 30)" {2209 t.Fatalf("got wrong result %v", s)2210 }2211 //2212 // Now we sort a different range of things2213 //2214 out = sortFn(ENV, []primitive.Primitive{2215 primitive.List{2216 primitive.Bool(true),2217 primitive.String("steve"),2218 primitive.Number(3),2219 },2220 })2221 s, ok2 = out.(primitive.List)2222 if !ok2 {2223 t.Fatalf("expected list, got %v", out)2224 }2225 if s.ToString() != "(#t 3 steve)" {2226 t.Fatalf("got wrong result %v", s)2227 }2228}2229func TestSplit(t *testing.T) {2230 // No arguments2231 out := splitFn(ENV, []primitive.Primitive{})2232 // Will lead to an error2233 e, ok := out.(primitive.Error)2234 if !ok {2235 t.Fatalf("expected error, got %v", out)2236 }2237 if e != primitive.ArityError() {2238 t.Fatalf("got error, but wrong one %v", out)2239 }2240 // Arguments that aren't strings: 12241 out = splitFn(ENV, []primitive.Primitive{2242 primitive.String("foo"),2243 primitive.Number(3),2244 })2245 // Will lead to an error2246 e, ok = out.(primitive.Error)2247 if !ok {2248 t.Fatalf("expected error, got %v", out)2249 }2250 if !strings.Contains(string(e), "not a string") {2251 t.Fatalf("got error, but wrong one %v", out)2252 }2253 // Arguments that aren't strings: 22254 out = splitFn(ENV, []primitive.Primitive{2255 primitive.Number(3),2256 primitive.String("foo"),2257 })2258 // Will lead to an error2259 e, ok = out.(primitive.Error)2260 if !ok {2261 t.Fatalf("expected error, got %v", out)2262 }2263 if !strings.Contains(string(e), "not a string") {2264 t.Fatalf("got error, but wrong one %v", out)2265 }2266 //2267 // Now a proper split2268 //2269 out = splitFn(ENV, []primitive.Primitive{2270 primitive.String("foo"),2271 primitive.String(""),2272 })2273 // Will lead to a list2274 l, ok2 := out.(primitive.List)2275 if !ok2 {2276 t.Fatalf("expected list, got %v", out)2277 }2278 if l.ToString() != "(f o o)" {2279 t.Fatalf("got wrong result %v", out)2280 }2281}2282func TestSprintf(t *testing.T) {2283 // No arguments2284 out := sprintfFn(ENV, []primitive.Primitive{})2285 // Will lead to an error2286 e, ok := out.(primitive.Error)2287 if !ok {2288 t.Fatalf("expected error, got %v", out)2289 }2290 if e != primitive.ArityError() {2291 t.Fatalf("got error, but wrong one %v", out)2292 }2293 // Two arguments2294 out = sprintfFn(ENV, []primitive.Primitive{2295 primitive.String("Hello\t\"%s\"\n\r!"),2296 primitive.String("world"),2297 })2298 e2, ok2 := out.(primitive.String)2299 if !ok2 {2300 t.Fatalf("expected string, got %v", out)2301 }2302 if e2 != "Hello\t\"world\"\n\r!" {2303 t.Fatalf("got wrong result %v", e2)2304 }2305}2306func TestStr(t *testing.T) {2307 // calling with no arguments will lead to an error2308 fail := strFn(ENV, []primitive.Primitive{})2309 // Will lead to an error2310 _, ok := fail.(primitive.Error)2311 if !ok {2312 t.Fatalf("expected error, got %v", fail)2313 }2314 // calling with an arg2315 out := strFn(ENV, []primitive.Primitive{2316 primitive.Number(32),2317 })2318 // Will lead to an string2319 e, ok := out.(primitive.String)2320 if !ok {2321 t.Fatalf("expected string, got %v", out)2322 }2323 if e != "32" {2324 t.Fatalf("got wrong result %v", out)2325 }2326}2327func TestType(t *testing.T) {2328 // No arguments2329 out := typeFn(ENV, []primitive.Primitive{})2330 // Will lead to an error2331 e, ok := out.(primitive.Error)2332 if !ok {2333 t.Fatalf("expected error, got %v", out)2334 }2335 if e != primitive.ArityError() {2336 t.Fatalf("got error, but wrong one %v", out)2337 }2338 // calling with an arg2339 out = typeFn(ENV, []primitive.Primitive{2340 primitive.Number(32),2341 })2342 // Will lead to an string2343 e2, ok2 := out.(primitive.String)2344 if !ok2 {2345 t.Fatalf("expected string, got %v", out)2346 }2347 if e2 != "number" {2348 t.Fatalf("got wrong result %v", out)2349 }2350}2351func TestVals(t *testing.T) {2352 // no arguments2353 out := valsFn(ENV, []primitive.Primitive{})2354 // Will lead to an error2355 e, ok := out.(primitive.Error)2356 if !ok {2357 t.Fatalf("expected error, got %v", out)2358 }2359 if !strings.Contains(string(e), "argument") {2360 t.Fatalf("got error, but wrong one")2361 }2362 // First argument must be a hash2363 out = valsFn(ENV, []primitive.Primitive{2364 primitive.String("foo"),2365 })2366 // Will lead to an error2367 e, ok = out.(primitive.Error)2368 if !ok {2369 t.Fatalf("expected error, got %v", out)2370 }2371 if !strings.Contains(string(e), "not a hash") {2372 t.Fatalf("got error, but wrong one %v", out)2373 }2374 // create a hash2375 h := primitive.NewHash()2376 h.Set("XXX", primitive.String("Last"))2377 h.Set("Name", primitive.String("Steve"))2378 h.Set("Age", primitive.Number(43))2379 h.Set("Location", primitive.String("Helsinki"))2380 // Get the values2381 res := valsFn(ENV, []primitive.Primitive{2382 h,2383 })2384 // Will lead to a list2385 _, ok2 := res.(primitive.List)2386 if !ok2 {2387 t.Fatalf("expected list, got %v", res)2388 }2389 lst := res.(primitive.List)2390 if lst[0].ToString() != "43" {2391 t.Fatalf("not a sorted list?")2392 }2393 if lst[1].ToString() != "Helsinki" {2394 t.Fatalf("not a sorted list?")2395 }2396 if lst[2].ToString() != "Steve" {2397 t.Fatalf("not a sorted list?")2398 }2399 if lst[3].ToString() != "Last" {2400 t.Fatalf("not a sorted list?")2401 }2402}...

Full Screen

Full Screen

consensus_test.go

Source:consensus_test.go Github

copy

Full Screen

...111 t.Fatal(err)112 }113 graph := factory.New()114 if err := graph.Initialize(ctx, params); err == nil {115 t.Fatalf("should have errored due to a duplicated metric")116 }117 }118 {119 ctx := snow.DefaultConsensusContextTest()120 params := sbcon.Parameters{121 K: 2,122 Alpha: 2,123 BetaVirtuous: 1,124 BetaRogue: 2,125 ConcurrentRepolls: 1,126 }127 err := ctx.Registerer.Register(prometheus.NewCounter(prometheus.CounterOpts{128 Name: "tx_accepted",129 }))130 if err != nil {131 t.Fatal(err)132 }133 graph := factory.New()134 if err := graph.Initialize(ctx, params); err == nil {135 t.Fatalf("should have errored due to a duplicated metric")136 }137 }138 {139 ctx := snow.DefaultConsensusContextTest()140 params := sbcon.Parameters{141 K: 2,142 Alpha: 2,143 BetaVirtuous: 1,144 BetaRogue: 2,145 ConcurrentRepolls: 1,146 }147 err := ctx.Registerer.Register(prometheus.NewCounter(prometheus.CounterOpts{148 Name: "tx_rejected",149 }))150 if err != nil {151 t.Fatal(err)152 }153 graph := factory.New()154 if err := graph.Initialize(ctx, params); err == nil {155 t.Fatalf("should have errored due to a duplicated metric")156 }157 }158}159func ParamsTest(t *testing.T, factory Factory) {160 graph := factory.New()161 params := sbcon.Parameters{162 K: 2,163 Alpha: 2,164 BetaVirtuous: 1,165 BetaRogue: 2,166 ConcurrentRepolls: 1,167 OptimalProcessing: 1,168 MaxOutstandingItems: 1,169 MaxItemProcessingTime: 1,170 }171 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)172 if err != nil {173 t.Fatal(err)174 }175 if p := graph.Parameters(); p.K != params.K {176 t.Fatalf("Wrong K parameter")177 } else if p := graph.Parameters(); p.Alpha != params.Alpha {178 t.Fatalf("Wrong Alpha parameter")179 } else if p := graph.Parameters(); p.BetaVirtuous != params.BetaVirtuous {180 t.Fatalf("Wrong Beta1 parameter")181 } else if p := graph.Parameters(); p.BetaRogue != params.BetaRogue {182 t.Fatalf("Wrong Beta2 parameter")183 }184}185func IssuedTest(t *testing.T, factory Factory) {186 graph := factory.New()187 params := sbcon.Parameters{188 K: 2,189 Alpha: 2,190 BetaVirtuous: 1,191 BetaRogue: 1,192 ConcurrentRepolls: 1,193 OptimalProcessing: 1,194 MaxOutstandingItems: 1,195 MaxItemProcessingTime: 1,196 }197 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)198 if err != nil {199 t.Fatal(err)200 }201 if issued := graph.Issued(Red); issued {202 t.Fatalf("Haven't issued anything yet.")203 } else if err := graph.Add(Red); err != nil {204 t.Fatal(err)205 } else if issued := graph.Issued(Red); !issued {206 t.Fatalf("Have already issued.")207 }208 _ = Blue.Accept()209 if issued := graph.Issued(Blue); !issued {210 t.Fatalf("Have already accepted.")211 }212}213func LeftoverInputTest(t *testing.T, factory Factory) {214 graph := factory.New()215 params := sbcon.Parameters{216 K: 2,217 Alpha: 2,218 BetaVirtuous: 1,219 BetaRogue: 1,220 ConcurrentRepolls: 1,221 OptimalProcessing: 1,222 MaxOutstandingItems: 1,223 MaxItemProcessingTime: 1,224 }225 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)226 if err != nil {227 t.Fatal(err)228 }229 if err := graph.Add(Red); err != nil {230 t.Fatal(err)231 } else if err := graph.Add(Green); err != nil {232 t.Fatal(err)233 }234 prefs := graph.Preferences()235 switch {236 case prefs.Len() != 1:237 t.Fatalf("Wrong number of preferences.")238 case !prefs.Contains(Red.ID()):239 t.Fatalf("Wrong preference. Expected %s got %s", Red.ID(), prefs.List()[0])240 case graph.Finalized():241 t.Fatalf("Finalized too early")242 }243 r := ids.Bag{}244 r.SetThreshold(2)245 r.AddCount(Red.ID(), 2)246 if updated, err := graph.RecordPoll(r); err != nil {247 t.Fatal(err)248 } else if !updated {249 t.Fatalf("Should have updated the frontiers")250 }251 prefs = graph.Preferences()252 switch {253 case prefs.Len() != 0:254 t.Fatalf("Wrong number of preferences.")255 case !graph.Finalized():256 t.Fatalf("Finalized too late")257 case Red.Status() != choices.Accepted:258 t.Fatalf("%s should have been accepted", Red.ID())259 case Green.Status() != choices.Rejected:260 t.Fatalf("%s should have been rejected", Green.ID())261 }262}263func LowerConfidenceTest(t *testing.T, factory Factory) {264 graph := factory.New()265 params := sbcon.Parameters{266 K: 2,267 Alpha: 2,268 BetaVirtuous: 1,269 BetaRogue: 1,270 ConcurrentRepolls: 1,271 OptimalProcessing: 1,272 MaxOutstandingItems: 1,273 MaxItemProcessingTime: 1,274 }275 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)276 if err != nil {277 t.Fatal(err)278 }279 if err := graph.Add(Red); err != nil {280 t.Fatal(err)281 }282 if err := graph.Add(Green); err != nil {283 t.Fatal(err)284 }285 if err := graph.Add(Blue); err != nil {286 t.Fatal(err)287 }288 prefs := graph.Preferences()289 switch {290 case prefs.Len() != 1:291 t.Fatalf("Wrong number of preferences.")292 case !prefs.Contains(Red.ID()):293 t.Fatalf("Wrong preference. Expected %s got %s", Red.ID(), prefs.List()[0])294 case graph.Finalized():295 t.Fatalf("Finalized too early")296 }297 r := ids.Bag{}298 r.SetThreshold(2)299 r.AddCount(Red.ID(), 2)300 if updated, err := graph.RecordPoll(r); err != nil {301 t.Fatal(err)302 } else if !updated {303 t.Fatalf("Should have updated the frontiers")304 }305 prefs = graph.Preferences()306 switch {307 case prefs.Len() != 1:308 t.Fatalf("Wrong number of preferences.")309 case !prefs.Contains(Blue.ID()):310 t.Fatalf("Wrong preference. Expected %s", Blue.ID())311 case graph.Finalized():312 t.Fatalf("Finalized too early")313 }314}315func MiddleConfidenceTest(t *testing.T, factory Factory) {316 graph := factory.New()317 params := sbcon.Parameters{318 K: 2,319 Alpha: 2,320 BetaVirtuous: 1,321 BetaRogue: 1,322 ConcurrentRepolls: 1,323 OptimalProcessing: 1,324 MaxOutstandingItems: 1,325 MaxItemProcessingTime: 1,326 }327 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)328 if err != nil {329 t.Fatal(err)330 }331 if err := graph.Add(Red); err != nil {332 t.Fatal(err)333 }334 if err := graph.Add(Green); err != nil {335 t.Fatal(err)336 }337 if err := graph.Add(Alpha); err != nil {338 t.Fatal(err)339 }340 if err := graph.Add(Blue); err != nil {341 t.Fatal(err)342 }343 prefs := graph.Preferences()344 switch {345 case prefs.Len() != 2:346 t.Fatalf("Wrong number of preferences.")347 case !prefs.Contains(Red.ID()):348 t.Fatalf("Wrong preference. Expected %s", Red.ID())349 case !prefs.Contains(Alpha.ID()):350 t.Fatalf("Wrong preference. Expected %s", Alpha.ID())351 case graph.Finalized():352 t.Fatalf("Finalized too early")353 }354 r := ids.Bag{}355 r.SetThreshold(2)356 r.AddCount(Red.ID(), 2)357 if updated, err := graph.RecordPoll(r); err != nil {358 t.Fatal(err)359 } else if !updated {360 t.Fatalf("Should have updated the frontiers")361 }362 prefs = graph.Preferences()363 switch {364 case prefs.Len() != 1:365 t.Fatalf("Wrong number of preferences.")366 case !prefs.Contains(Alpha.ID()):367 t.Fatalf("Wrong preference. Expected %s", Alpha.ID())368 case graph.Finalized():369 t.Fatalf("Finalized too early")370 }371}372func IndependentTest(t *testing.T, factory Factory) {373 graph := factory.New()374 params := sbcon.Parameters{375 K: 2,376 Alpha: 2,377 BetaVirtuous: 2,378 BetaRogue: 2,379 ConcurrentRepolls: 1,380 OptimalProcessing: 1,381 MaxOutstandingItems: 1,382 MaxItemProcessingTime: 1,383 }384 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)385 if err != nil {386 t.Fatal(err)387 }388 if err := graph.Add(Red); err != nil {389 t.Fatal(err)390 }391 if err := graph.Add(Alpha); err != nil {392 t.Fatal(err)393 }394 prefs := graph.Preferences()395 switch {396 case prefs.Len() != 2:397 t.Fatalf("Wrong number of preferences.")398 case !prefs.Contains(Red.ID()):399 t.Fatalf("Wrong preference. Expected %s", Red.ID())400 case !prefs.Contains(Alpha.ID()):401 t.Fatalf("Wrong preference. Expected %s", Alpha.ID())402 case graph.Finalized():403 t.Fatalf("Finalized too early")404 }405 ra := ids.Bag{}406 ra.SetThreshold(2)407 ra.AddCount(Red.ID(), 2)408 ra.AddCount(Alpha.ID(), 2)409 if updated, err := graph.RecordPoll(ra); err != nil {410 t.Fatal(err)411 } else if updated {412 t.Fatalf("Shouldn't have updated the frontiers")413 } else if prefs := graph.Preferences(); prefs.Len() != 2 {414 t.Fatalf("Wrong number of preferences.")415 } else if !prefs.Contains(Red.ID()) {416 t.Fatalf("Wrong preference. Expected %s", Red.ID())417 } else if !prefs.Contains(Alpha.ID()) {418 t.Fatalf("Wrong preference. Expected %s", Alpha.ID())419 } else if graph.Finalized() {420 t.Fatalf("Finalized too early")421 } else if updated, err := graph.RecordPoll(ra); err != nil {422 t.Fatal(err)423 } else if !updated {424 t.Fatalf("Should have updated the frontiers")425 } else if prefs := graph.Preferences(); prefs.Len() != 0 {426 t.Fatalf("Wrong number of preferences.")427 } else if !graph.Finalized() {428 t.Fatalf("Finalized too late")429 }430}431func VirtuousTest(t *testing.T, factory Factory) {432 graph := factory.New()433 params := sbcon.Parameters{434 K: 2,435 Alpha: 2,436 BetaVirtuous: 1,437 BetaRogue: 1,438 ConcurrentRepolls: 1,439 OptimalProcessing: 1,440 MaxOutstandingItems: 1,441 MaxItemProcessingTime: 1,442 }443 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)444 if err != nil {445 t.Fatal(err)446 }447 if err := graph.Add(Red); err != nil {448 t.Fatal(err)449 } else if virtuous := graph.Virtuous(); virtuous.Len() != 1 {450 t.Fatalf("Wrong number of virtuous.")451 } else if !virtuous.Contains(Red.ID()) {452 t.Fatalf("Wrong virtuous. Expected %s", Red.ID())453 } else if err := graph.Add(Alpha); err != nil {454 t.Fatal(err)455 } else if virtuous := graph.Virtuous(); virtuous.Len() != 2 {456 t.Fatalf("Wrong number of virtuous.")457 } else if !virtuous.Contains(Red.ID()) {458 t.Fatalf("Wrong virtuous. Expected %s", Red.ID())459 } else if !virtuous.Contains(Alpha.ID()) {460 t.Fatalf("Wrong virtuous. Expected %s", Alpha.ID())461 } else if err := graph.Add(Green); err != nil {462 t.Fatal(err)463 } else if virtuous := graph.Virtuous(); virtuous.Len() != 1 {464 t.Fatalf("Wrong number of virtuous.")465 } else if !virtuous.Contains(Alpha.ID()) {466 t.Fatalf("Wrong virtuous. Expected %s", Alpha.ID())467 } else if err := graph.Add(Blue); err != nil {468 t.Fatal(err)469 } else if virtuous := graph.Virtuous(); virtuous.Len() != 0 {470 t.Fatalf("Wrong number of virtuous.")471 }472}473func IsVirtuousTest(t *testing.T, factory Factory) {474 graph := factory.New()475 params := sbcon.Parameters{476 K: 2,477 Alpha: 2,478 BetaVirtuous: 1,479 BetaRogue: 1,480 ConcurrentRepolls: 1,481 OptimalProcessing: 1,482 MaxOutstandingItems: 1,483 MaxItemProcessingTime: 1,484 }485 if err := graph.Initialize(snow.DefaultConsensusContextTest(), params); err != nil {486 t.Fatal(err)487 }488 switch {489 case !graph.IsVirtuous(Red):490 t.Fatalf("Should be virtuous")491 case !graph.IsVirtuous(Green):492 t.Fatalf("Should be virtuous")493 case !graph.IsVirtuous(Blue):494 t.Fatalf("Should be virtuous")495 case !graph.IsVirtuous(Alpha):496 t.Fatalf("Should be virtuous")497 }498 err := graph.Add(Red)499 switch {500 case err != nil:501 t.Fatal(err)502 case !graph.IsVirtuous(Red):503 t.Fatalf("Should be virtuous")504 case graph.IsVirtuous(Green):505 t.Fatalf("Should not be virtuous")506 case !graph.IsVirtuous(Blue):507 t.Fatalf("Should be virtuous")508 case !graph.IsVirtuous(Alpha):509 t.Fatalf("Should be virtuous")510 }511 err = graph.Add(Green)512 switch {513 case err != nil:514 t.Fatal(err)515 case graph.IsVirtuous(Red):516 t.Fatalf("Should not be virtuous")517 case graph.IsVirtuous(Green):518 t.Fatalf("Should not be virtuous")519 case graph.IsVirtuous(Blue):520 t.Fatalf("Should not be virtuous")521 }522}523func QuiesceTest(t *testing.T, factory Factory) {524 graph := factory.New()525 params := sbcon.Parameters{526 K: 2,527 Alpha: 2,528 BetaVirtuous: 1,529 BetaRogue: 1,530 ConcurrentRepolls: 1,531 OptimalProcessing: 1,532 MaxOutstandingItems: 1,533 MaxItemProcessingTime: 1,534 }535 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)536 if err != nil {537 t.Fatal(err)538 }539 if !graph.Quiesce() {540 t.Fatalf("Should quiesce")541 } else if err := graph.Add(Red); err != nil {542 t.Fatal(err)543 } else if graph.Quiesce() {544 t.Fatalf("Shouldn't quiesce")545 } else if err := graph.Add(Green); err != nil {546 t.Fatal(err)547 } else if !graph.Quiesce() {548 t.Fatalf("Should quiesce")549 }550}551func AcceptingDependencyTest(t *testing.T, factory Factory) {552 graph := factory.New()553 purple := &TestTx{554 TestDecidable: choices.TestDecidable{555 IDV: ids.Empty.Prefix(7),556 StatusV: choices.Processing,557 },558 DependenciesV: []Tx{Red},559 }560 purple.InputIDsV = append(purple.InputIDsV, ids.Empty.Prefix(8))561 params := sbcon.Parameters{562 K: 1,563 Alpha: 1,564 BetaVirtuous: 1,565 BetaRogue: 2,566 ConcurrentRepolls: 1,567 OptimalProcessing: 1,568 MaxOutstandingItems: 1,569 MaxItemProcessingTime: 1,570 }571 if err := graph.Initialize(snow.DefaultConsensusContextTest(), params); err != nil {572 t.Fatal(err)573 }574 if err := graph.Add(Red); err != nil {575 t.Fatal(err)576 }577 if err := graph.Add(Green); err != nil {578 t.Fatal(err)579 }580 if err := graph.Add(purple); err != nil {581 t.Fatal(err)582 }583 prefs := graph.Preferences()584 switch {585 case prefs.Len() != 2:586 t.Fatalf("Wrong number of preferences.")587 case !prefs.Contains(Red.ID()):588 t.Fatalf("Wrong preference. Expected %s", Red.ID())589 case !prefs.Contains(purple.ID()):590 t.Fatalf("Wrong preference. Expected %s", purple.ID())591 case Red.Status() != choices.Processing:592 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)593 case Green.Status() != choices.Processing:594 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)595 case purple.Status() != choices.Processing:596 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)597 }598 g := ids.Bag{}599 g.Add(Green.ID())600 if updated, err := graph.RecordPoll(g); err != nil {601 t.Fatal(err)602 } else if !updated {603 t.Fatalf("Should have updated the frontiers")604 }605 prefs = graph.Preferences()606 switch {607 case prefs.Len() != 2:608 t.Fatalf("Wrong number of preferences.")609 case !prefs.Contains(Green.ID()):610 t.Fatalf("Wrong preference. Expected %s", Green.ID())611 case !prefs.Contains(purple.ID()):612 t.Fatalf("Wrong preference. Expected %s", purple.ID())613 case Red.Status() != choices.Processing:614 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)615 case Green.Status() != choices.Processing:616 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)617 case purple.Status() != choices.Processing:618 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)619 }620 rp := ids.Bag{}621 rp.Add(Red.ID(), purple.ID())622 if updated, err := graph.RecordPoll(rp); err != nil {623 t.Fatal(err)624 } else if updated {625 t.Fatalf("Shouldn't have updated the frontiers")626 }627 prefs = graph.Preferences()628 switch {629 case prefs.Len() != 2:630 t.Fatalf("Wrong number of preferences.")631 case !prefs.Contains(Green.ID()):632 t.Fatalf("Wrong preference. Expected %s", Green.ID())633 case !prefs.Contains(purple.ID()):634 t.Fatalf("Wrong preference. Expected %s", purple.ID())635 case Red.Status() != choices.Processing:636 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)637 case Green.Status() != choices.Processing:638 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)639 case purple.Status() != choices.Processing:640 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)641 }642 r := ids.Bag{}643 r.Add(Red.ID())644 if updated, err := graph.RecordPoll(r); err != nil {645 t.Fatal(err)646 } else if !updated {647 t.Fatalf("Should have updated the frontiers")648 }649 prefs = graph.Preferences()650 switch {651 case prefs.Len() != 0:652 t.Fatalf("Wrong number of preferences.")653 case Red.Status() != choices.Accepted:654 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Accepted)655 case Green.Status() != choices.Rejected:656 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Rejected)657 case purple.Status() != choices.Accepted:658 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Accepted)659 }660}661type singleAcceptTx struct {662 Tx663 t *testing.T664 accepted bool665}666func (tx *singleAcceptTx) Accept() error {667 if tx.accepted {668 tx.t.Fatalf("accept called multiple times")669 }670 tx.accepted = true671 return tx.Tx.Accept()672}673func AcceptingSlowDependencyTest(t *testing.T, factory Factory) {674 graph := factory.New()675 rawPurple := &TestTx{676 TestDecidable: choices.TestDecidable{677 IDV: ids.Empty.Prefix(7),678 StatusV: choices.Processing,679 },680 DependenciesV: []Tx{Red},681 }682 rawPurple.InputIDsV = append(rawPurple.InputIDsV, ids.Empty.Prefix(8))683 purple := &singleAcceptTx{684 Tx: rawPurple,685 t: t,686 }687 params := sbcon.Parameters{688 K: 1,689 Alpha: 1,690 BetaVirtuous: 1,691 BetaRogue: 2,692 ConcurrentRepolls: 1,693 OptimalProcessing: 1,694 MaxOutstandingItems: 1,695 MaxItemProcessingTime: 1,696 }697 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)698 if err != nil {699 t.Fatal(err)700 }701 if err := graph.Add(Red); err != nil {702 t.Fatal(err)703 }704 if err := graph.Add(Green); err != nil {705 t.Fatal(err)706 }707 if err := graph.Add(purple); err != nil {708 t.Fatal(err)709 }710 prefs := graph.Preferences()711 switch {712 case prefs.Len() != 2:713 t.Fatalf("Wrong number of preferences.")714 case !prefs.Contains(Red.ID()):715 t.Fatalf("Wrong preference. Expected %s", Red.ID())716 case !prefs.Contains(purple.ID()):717 t.Fatalf("Wrong preference. Expected %s", purple.ID())718 case Red.Status() != choices.Processing:719 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)720 case Green.Status() != choices.Processing:721 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)722 case purple.Status() != choices.Processing:723 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)724 }725 g := ids.Bag{}726 g.Add(Green.ID())727 if updated, err := graph.RecordPoll(g); err != nil {728 t.Fatal(err)729 } else if !updated {730 t.Fatalf("Should have updated the frontiers")731 }732 prefs = graph.Preferences()733 switch {734 case prefs.Len() != 2:735 t.Fatalf("Wrong number of preferences.")736 case !prefs.Contains(Green.ID()):737 t.Fatalf("Wrong preference. Expected %s", Green.ID())738 case !prefs.Contains(purple.ID()):739 t.Fatalf("Wrong preference. Expected %s", purple.ID())740 case Red.Status() != choices.Processing:741 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)742 case Green.Status() != choices.Processing:743 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)744 case purple.Status() != choices.Processing:745 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)746 }747 p := ids.Bag{}748 p.Add(purple.ID())749 if updated, err := graph.RecordPoll(p); err != nil {750 t.Fatal(err)751 } else if updated {752 t.Fatalf("Shouldn't have updated the frontiers")753 }754 prefs = graph.Preferences()755 switch {756 case prefs.Len() != 2:757 t.Fatalf("Wrong number of preferences.")758 case !prefs.Contains(Green.ID()):759 t.Fatalf("Wrong preference. Expected %s", Green.ID())760 case !prefs.Contains(purple.ID()):761 t.Fatalf("Wrong preference. Expected %s", purple.ID())762 case Red.Status() != choices.Processing:763 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)764 case Green.Status() != choices.Processing:765 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)766 case purple.Status() != choices.Processing:767 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)768 }769 rp := ids.Bag{}770 rp.Add(Red.ID(), purple.ID())771 if updated, err := graph.RecordPoll(rp); err != nil {772 t.Fatal(err)773 } else if updated {774 t.Fatalf("Shouldn't have updated the frontiers")775 }776 prefs = graph.Preferences()777 switch {778 case prefs.Len() != 2:779 t.Fatalf("Wrong number of preferences.")780 case !prefs.Contains(Green.ID()):781 t.Fatalf("Wrong preference. Expected %s", Green.ID())782 case !prefs.Contains(purple.ID()):783 t.Fatalf("Wrong preference. Expected %s", purple.ID())784 case Red.Status() != choices.Processing:785 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)786 case Green.Status() != choices.Processing:787 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)788 case purple.Status() != choices.Processing:789 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)790 }791 r := ids.Bag{}792 r.Add(Red.ID())793 if updated, err := graph.RecordPoll(r); err != nil {794 t.Fatal(err)795 } else if !updated {796 t.Fatalf("Should have updated the frontiers")797 }798 prefs = graph.Preferences()799 switch {800 case prefs.Len() != 0:801 t.Fatalf("Wrong number of preferences.")802 case Red.Status() != choices.Accepted:803 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Accepted)804 case Green.Status() != choices.Rejected:805 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Rejected)806 case purple.Status() != choices.Accepted:807 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Accepted)808 }809}810func RejectingDependencyTest(t *testing.T, factory Factory) {811 graph := factory.New()812 purple := &TestTx{813 TestDecidable: choices.TestDecidable{814 IDV: ids.Empty.Prefix(7),815 StatusV: choices.Processing,816 },817 DependenciesV: []Tx{Red, Blue},818 }819 purple.InputIDsV = append(purple.InputIDsV, ids.Empty.Prefix(8))820 params := sbcon.Parameters{821 K: 1,822 Alpha: 1,823 BetaVirtuous: 1,824 BetaRogue: 2,825 ConcurrentRepolls: 1,826 OptimalProcessing: 1,827 MaxOutstandingItems: 1,828 MaxItemProcessingTime: 1,829 }830 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)831 if err != nil {832 t.Fatal(err)833 }834 if err := graph.Add(Red); err != nil {835 t.Fatal(err)836 }837 if err := graph.Add(Green); err != nil {838 t.Fatal(err)839 }840 if err := graph.Add(Blue); err != nil {841 t.Fatal(err)842 }843 if err := graph.Add(purple); err != nil {844 t.Fatal(err)845 }846 prefs := graph.Preferences()847 switch {848 case prefs.Len() != 2:849 t.Fatalf("Wrong number of preferences.")850 case !prefs.Contains(Red.ID()):851 t.Fatalf("Wrong preference. Expected %s", Red.ID())852 case !prefs.Contains(purple.ID()):853 t.Fatalf("Wrong preference. Expected %s", purple.ID())854 case Red.Status() != choices.Processing:855 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)856 case Green.Status() != choices.Processing:857 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)858 case Blue.Status() != choices.Processing:859 t.Fatalf("Wrong status. %s should be %s", Blue.ID(), choices.Processing)860 case purple.Status() != choices.Processing:861 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)862 }863 gp := ids.Bag{}864 gp.Add(Green.ID(), purple.ID())865 if updated, err := graph.RecordPoll(gp); err != nil {866 t.Fatal(err)867 } else if !updated {868 t.Fatalf("Should have updated the frontiers")869 }870 prefs = graph.Preferences()871 switch {872 case prefs.Len() != 2:873 t.Fatalf("Wrong number of preferences.")874 case !prefs.Contains(Green.ID()):875 t.Fatalf("Wrong preference. Expected %s", Green.ID())876 case !prefs.Contains(purple.ID()):877 t.Fatalf("Wrong preference. Expected %s", purple.ID())878 case Red.Status() != choices.Processing:879 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Processing)880 case Green.Status() != choices.Processing:881 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Processing)882 case Blue.Status() != choices.Processing:883 t.Fatalf("Wrong status. %s should be %s", Blue.ID(), choices.Processing)884 case purple.Status() != choices.Processing:885 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Processing)886 }887 if updated, err := graph.RecordPoll(gp); err != nil {888 t.Fatal(err)889 } else if !updated {890 t.Fatalf("Should have updated the frontiers")891 }892 prefs = graph.Preferences()893 switch {894 case prefs.Len() != 0:895 t.Fatalf("Wrong number of preferences.")896 case Red.Status() != choices.Rejected:897 t.Fatalf("Wrong status. %s should be %s", Red.ID(), choices.Rejected)898 case Green.Status() != choices.Accepted:899 t.Fatalf("Wrong status. %s should be %s", Green.ID(), choices.Accepted)900 case Blue.Status() != choices.Rejected:901 t.Fatalf("Wrong status. %s should be %s", Blue.ID(), choices.Rejected)902 case purple.Status() != choices.Rejected:903 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Rejected)904 }905}906func VacuouslyAcceptedTest(t *testing.T, factory Factory) {907 graph := factory.New()908 purple := &TestTx{TestDecidable: choices.TestDecidable{909 IDV: ids.Empty.Prefix(7),910 StatusV: choices.Processing,911 }}912 params := sbcon.Parameters{913 K: 1,914 Alpha: 1,915 BetaVirtuous: 1,916 BetaRogue: 2,917 ConcurrentRepolls: 1,918 OptimalProcessing: 1,919 MaxOutstandingItems: 1,920 MaxItemProcessingTime: 1,921 }922 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)923 if err != nil {924 t.Fatal(err)925 }926 if err := graph.Add(purple); err != nil {927 t.Fatal(err)928 } else if prefs := graph.Preferences(); prefs.Len() != 0 {929 t.Fatalf("Wrong number of preferences.")930 } else if status := purple.Status(); status != choices.Accepted {931 t.Fatalf("Wrong status. %s should be %s", purple.ID(), choices.Accepted)932 }933}934func ConflictsTest(t *testing.T, factory Factory) {935 graph := factory.New()936 params := sbcon.Parameters{937 K: 1,938 Alpha: 1,939 BetaVirtuous: 1,940 BetaRogue: 2,941 ConcurrentRepolls: 1,942 OptimalProcessing: 1,943 MaxOutstandingItems: 1,944 MaxItemProcessingTime: 1,945 }946 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)947 if err != nil {948 t.Fatal(err)949 }950 conflictInputID := ids.Empty.Prefix(0)951 purple := &TestTx{952 TestDecidable: choices.TestDecidable{953 IDV: ids.Empty.Prefix(6),954 StatusV: choices.Processing,955 },956 InputIDsV: []ids.ID{conflictInputID},957 }958 orange := &TestTx{959 TestDecidable: choices.TestDecidable{960 IDV: ids.Empty.Prefix(7),961 StatusV: choices.Processing,962 },963 InputIDsV: []ids.ID{conflictInputID},964 }965 if err := graph.Add(purple); err != nil {966 t.Fatal(err)967 } else if orangeConflicts := graph.Conflicts(orange); orangeConflicts.Len() != 1 {968 t.Fatalf("Wrong number of conflicts")969 } else if !orangeConflicts.Contains(purple.IDV) {970 t.Fatalf("Conflicts does not contain the right transaction")971 } else if err := graph.Add(orange); err != nil {972 t.Fatal(err)973 } else if orangeConflicts := graph.Conflicts(orange); orangeConflicts.Len() != 1 {974 t.Fatalf("Wrong number of conflicts")975 } else if !orangeConflicts.Contains(purple.IDV) {976 t.Fatalf("Conflicts does not contain the right transaction")977 }978}979func VirtuousDependsOnRogueTest(t *testing.T, factory Factory) {980 graph := factory.New()981 params := sbcon.Parameters{982 K: 1,983 Alpha: 1,984 BetaVirtuous: 1,985 BetaRogue: 2,986 ConcurrentRepolls: 1,987 OptimalProcessing: 1,988 MaxOutstandingItems: 1,989 MaxItemProcessingTime: 1,990 }991 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)992 if err != nil {993 t.Fatal(err)994 }995 rogue1 := &TestTx{TestDecidable: choices.TestDecidable{996 IDV: ids.Empty.Prefix(0),997 StatusV: choices.Processing,998 }}999 rogue2 := &TestTx{TestDecidable: choices.TestDecidable{1000 IDV: ids.Empty.Prefix(1),1001 StatusV: choices.Processing,1002 }}1003 virtuous := &TestTx{1004 TestDecidable: choices.TestDecidable{1005 IDV: ids.Empty.Prefix(2),1006 StatusV: choices.Processing,1007 },1008 DependenciesV: []Tx{rogue1},1009 }1010 input1 := ids.Empty.Prefix(3)1011 input2 := ids.Empty.Prefix(4)1012 rogue1.InputIDsV = append(rogue1.InputIDsV, input1)1013 rogue2.InputIDsV = append(rogue2.InputIDsV, input1)1014 virtuous.InputIDsV = append(virtuous.InputIDsV, input2)1015 if err := graph.Add(rogue1); err != nil {1016 t.Fatal(err)1017 } else if err := graph.Add(rogue2); err != nil {1018 t.Fatal(err)1019 } else if err := graph.Add(virtuous); err != nil {1020 t.Fatal(err)1021 }1022 votes := ids.Bag{}1023 votes.Add(rogue1.ID())1024 votes.Add(virtuous.ID())1025 if updated, err := graph.RecordPoll(votes); err != nil {1026 t.Fatal(err)1027 } else if updated {1028 t.Fatalf("Shouldn't have updated the frontiers")1029 } else if status := rogue1.Status(); status != choices.Processing {1030 t.Fatalf("Rogue Tx is %s expected %s", status, choices.Processing)1031 } else if status := rogue2.Status(); status != choices.Processing {1032 t.Fatalf("Rogue Tx is %s expected %s", status, choices.Processing)1033 } else if status := virtuous.Status(); status != choices.Processing {1034 t.Fatalf("Virtuous Tx is %s expected %s", status, choices.Processing)1035 } else if !graph.Quiesce() {1036 t.Fatalf("Should quiesce as there are no pending virtuous transactions")1037 }1038}1039func ErrorOnVacuouslyAcceptedTest(t *testing.T, factory Factory) {1040 graph := factory.New()1041 purple := &TestTx{TestDecidable: choices.TestDecidable{1042 IDV: ids.Empty.Prefix(7),1043 AcceptV: errors.New(""),1044 StatusV: choices.Processing,1045 }}1046 params := sbcon.Parameters{1047 K: 1,1048 Alpha: 1,1049 BetaVirtuous: 1,1050 BetaRogue: 2,1051 ConcurrentRepolls: 1,1052 OptimalProcessing: 1,1053 MaxOutstandingItems: 1,1054 MaxItemProcessingTime: 1,1055 }1056 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1057 if err != nil {1058 t.Fatal(err)1059 }1060 if err := graph.Add(purple); err == nil {1061 t.Fatalf("Should have errored on acceptance")1062 }1063}1064func ErrorOnAcceptedTest(t *testing.T, factory Factory) {1065 graph := factory.New()1066 purple := &TestTx{TestDecidable: choices.TestDecidable{1067 IDV: ids.Empty.Prefix(7),1068 AcceptV: errors.New(""),1069 StatusV: choices.Processing,1070 }}1071 purple.InputIDsV = append(purple.InputIDsV, ids.Empty.Prefix(4))1072 params := sbcon.Parameters{1073 K: 1,1074 Alpha: 1,1075 BetaVirtuous: 1,1076 BetaRogue: 2,1077 ConcurrentRepolls: 1,1078 OptimalProcessing: 1,1079 MaxOutstandingItems: 1,1080 MaxItemProcessingTime: 1,1081 }1082 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1083 if err != nil {1084 t.Fatal(err)1085 }1086 if err := graph.Add(purple); err != nil {1087 t.Fatal(err)1088 }1089 votes := ids.Bag{}1090 votes.Add(purple.ID())1091 if _, err := graph.RecordPoll(votes); err == nil {1092 t.Fatalf("Should have errored on accepting an invalid tx")1093 }1094}1095func ErrorOnRejectingLowerConfidenceConflictTest(t *testing.T, factory Factory) {1096 graph := factory.New()1097 X := ids.Empty.Prefix(4)1098 purple := &TestTx{TestDecidable: choices.TestDecidable{1099 IDV: ids.Empty.Prefix(7),1100 StatusV: choices.Processing,1101 }}1102 purple.InputIDsV = append(purple.InputIDsV, X)1103 pink := &TestTx{TestDecidable: choices.TestDecidable{1104 IDV: ids.Empty.Prefix(8),1105 RejectV: errors.New(""),1106 StatusV: choices.Processing,1107 }}1108 pink.InputIDsV = append(pink.InputIDsV, X)1109 params := sbcon.Parameters{1110 K: 1,1111 Alpha: 1,1112 BetaVirtuous: 1,1113 BetaRogue: 1,1114 ConcurrentRepolls: 1,1115 OptimalProcessing: 1,1116 MaxOutstandingItems: 1,1117 MaxItemProcessingTime: 1,1118 }1119 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1120 if err != nil {1121 t.Fatal(err)1122 }1123 if err := graph.Add(purple); err != nil {1124 t.Fatal(err)1125 } else if err := graph.Add(pink); err != nil {1126 t.Fatal(err)1127 }1128 votes := ids.Bag{}1129 votes.Add(purple.ID())1130 if _, err := graph.RecordPoll(votes); err == nil {1131 t.Fatalf("Should have errored on rejecting an invalid tx")1132 }1133}1134func ErrorOnRejectingHigherConfidenceConflictTest(t *testing.T, factory Factory) {1135 graph := factory.New()1136 X := ids.Empty.Prefix(4)1137 purple := &TestTx{TestDecidable: choices.TestDecidable{1138 IDV: ids.Empty.Prefix(7),1139 StatusV: choices.Processing,1140 }}1141 purple.InputIDsV = append(purple.InputIDsV, X)1142 pink := &TestTx{TestDecidable: choices.TestDecidable{1143 IDV: ids.Empty.Prefix(8),1144 RejectV: errors.New(""),1145 StatusV: choices.Processing,1146 }}1147 pink.InputIDsV = append(pink.InputIDsV, X)1148 params := sbcon.Parameters{1149 K: 1,1150 Alpha: 1,1151 BetaVirtuous: 1,1152 BetaRogue: 1,1153 ConcurrentRepolls: 1,1154 OptimalProcessing: 1,1155 MaxOutstandingItems: 1,1156 MaxItemProcessingTime: 1,1157 }1158 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1159 if err != nil {1160 t.Fatal(err)1161 }1162 if err := graph.Add(pink); err != nil {1163 t.Fatal(err)1164 } else if err := graph.Add(purple); err != nil {1165 t.Fatal(err)1166 }1167 votes := ids.Bag{}1168 votes.Add(purple.ID())1169 if _, err := graph.RecordPoll(votes); err == nil {1170 t.Fatalf("Should have errored on rejecting an invalid tx")1171 }1172}1173func UTXOCleanupTest(t *testing.T, factory Factory) {1174 graph := factory.New()1175 params := sbcon.Parameters{1176 K: 1,1177 Alpha: 1,1178 BetaVirtuous: 1,1179 BetaRogue: 2,1180 ConcurrentRepolls: 1,1181 OptimalProcessing: 1,1182 MaxOutstandingItems: 1,1183 MaxItemProcessingTime: 1,1184 }1185 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1186 assert.NoError(t, err)1187 err = graph.Add(Red)1188 assert.NoError(t, err)1189 err = graph.Add(Green)1190 assert.NoError(t, err)1191 redVotes := ids.Bag{}1192 redVotes.Add(Red.ID())1193 changed, err := graph.RecordPoll(redVotes)1194 assert.NoError(t, err)1195 assert.False(t, changed, "shouldn't have accepted the red tx")1196 changed, err = graph.RecordPoll(redVotes)1197 assert.NoError(t, err)1198 assert.True(t, changed, "should have accepted the red tx")1199 assert.Equal(t, choices.Accepted, Red.Status())1200 assert.Equal(t, choices.Rejected, Green.Status())1201 err = graph.Add(Blue)1202 assert.NoError(t, err)1203 blueVotes := ids.Bag{}1204 blueVotes.Add(Blue.ID())1205 changed, err = graph.RecordPoll(blueVotes)1206 assert.NoError(t, err)1207 assert.True(t, changed, "should have accepted the blue tx")1208 assert.Equal(t, choices.Accepted, Blue.Status())1209}1210func RemoveVirtuousTest(t *testing.T, factory Factory) {1211 graph := factory.New()1212 params := sbcon.Parameters{1213 K: 1,1214 Alpha: 1,1215 BetaVirtuous: 1,1216 BetaRogue: 2,1217 ConcurrentRepolls: 1,1218 OptimalProcessing: 1,1219 MaxOutstandingItems: 1,1220 MaxItemProcessingTime: 1,1221 }1222 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1223 assert.NoError(t, err)1224 err = graph.Add(Red)1225 assert.NoError(t, err)1226 virtuous := graph.Virtuous()1227 assert.NotEmpty(t, virtuous, "a virtuous transaction was added but not tracked")1228 err = graph.Remove(Red.ID())1229 assert.NoError(t, err)1230 virtuous = graph.Virtuous()1231 assert.Empty(t, virtuous, "removal of a virtuous transaction should have emptied the virtuous set")1232}1233func StringTest(t *testing.T, factory Factory, prefix string) {1234 graph := factory.New()1235 params := sbcon.Parameters{1236 K: 2,1237 Alpha: 2,1238 BetaVirtuous: 1,1239 BetaRogue: 2,1240 ConcurrentRepolls: 1,1241 OptimalProcessing: 1,1242 MaxOutstandingItems: 1,1243 MaxItemProcessingTime: 1,1244 }1245 err := graph.Initialize(snow.DefaultConsensusContextTest(), params)1246 if err != nil {1247 t.Fatal(err)1248 }1249 if err := graph.Add(Red); err != nil {1250 t.Fatal(err)1251 }1252 if err := graph.Add(Green); err != nil {1253 t.Fatal(err)1254 }1255 if err := graph.Add(Blue); err != nil {1256 t.Fatal(err)1257 }1258 if err := graph.Add(Alpha); err != nil {1259 t.Fatal(err)1260 }1261 prefs := graph.Preferences()1262 switch {1263 case prefs.Len() != 1:1264 t.Fatalf("Wrong number of preferences.")1265 case !prefs.Contains(Red.ID()):1266 t.Fatalf("Wrong preference. Expected %s got %s", Red.ID(), prefs.List()[0])1267 case graph.Finalized():1268 t.Fatalf("Finalized too early")1269 }1270 rb := ids.Bag{}1271 rb.SetThreshold(2)1272 rb.AddCount(Red.ID(), 2)1273 rb.AddCount(Blue.ID(), 2)1274 if changed, err := graph.RecordPoll(rb); err != nil {1275 t.Fatal(err)1276 } else if !changed {1277 t.Fatalf("Should have caused the frontiers to recalculate")1278 } else if err := graph.Add(Blue); err != nil {1279 t.Fatal(err)1280 }1281 {1282 expected := prefix + "(\n" +1283 " Choice[0] = ID: LUC1cmcxnfNR9LdkACS2ccGKLEK7SYqB4gLLTycQfg1koyfSq SB(NumSuccessfulPolls = 1, Confidence = 1)\n" +1284 " Choice[1] = ID: TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES SB(NumSuccessfulPolls = 0, Confidence = 0)\n" +1285 " Choice[2] = ID: Zda4gsqTjRaX6XVZekVNi3ovMFPHDRQiGbzYuAb7Nwqy1rGBc SB(NumSuccessfulPolls = 0, Confidence = 0)\n" +1286 " Choice[3] = ID: 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w SB(NumSuccessfulPolls = 1, Confidence = 1)\n" +1287 ")"1288 if str := graph.String(); str != expected {1289 t.Fatalf("Expected %s, got %s", expected, str)1290 }1291 }1292 prefs = graph.Preferences()1293 switch {1294 case prefs.Len() != 2:1295 t.Fatalf("Wrong number of preferences.")1296 case !prefs.Contains(Red.ID()):1297 t.Fatalf("Wrong preference. Expected %s", Red.ID())1298 case !prefs.Contains(Blue.ID()):1299 t.Fatalf("Wrong preference. Expected %s", Blue.ID())1300 case graph.Finalized():1301 t.Fatalf("Finalized too early")1302 }1303 ga := ids.Bag{}1304 ga.SetThreshold(2)1305 ga.AddCount(Green.ID(), 2)1306 ga.AddCount(Alpha.ID(), 2)1307 if changed, err := graph.RecordPoll(ga); err != nil {1308 t.Fatal(err)1309 } else if changed {1310 t.Fatalf("Shouldn't have caused the frontiers to recalculate")1311 }1312 {1313 expected := prefix + "(\n" +1314 " Choice[0] = ID: LUC1cmcxnfNR9LdkACS2ccGKLEK7SYqB4gLLTycQfg1koyfSq SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1315 " Choice[1] = ID: TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES SB(NumSuccessfulPolls = 1, Confidence = 1)\n" +1316 " Choice[2] = ID: Zda4gsqTjRaX6XVZekVNi3ovMFPHDRQiGbzYuAb7Nwqy1rGBc SB(NumSuccessfulPolls = 1, Confidence = 1)\n" +1317 " Choice[3] = ID: 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1318 ")"1319 if str := graph.String(); str != expected {1320 t.Fatalf("Expected %s, got %s", expected, str)1321 }1322 }1323 prefs = graph.Preferences()1324 switch {1325 case prefs.Len() != 2:1326 t.Fatalf("Wrong number of preferences.")1327 case !prefs.Contains(Red.ID()):1328 t.Fatalf("Wrong preference. Expected %s", Red.ID())1329 case !prefs.Contains(Blue.ID()):1330 t.Fatalf("Wrong preference. Expected %s", Blue.ID())1331 case graph.Finalized():1332 t.Fatalf("Finalized too early")1333 }1334 empty := ids.Bag{}1335 if changed, err := graph.RecordPoll(empty); err != nil {1336 t.Fatal(err)1337 } else if changed {1338 t.Fatalf("Shouldn't have caused the frontiers to recalculate")1339 }1340 {1341 expected := prefix + "(\n" +1342 " Choice[0] = ID: LUC1cmcxnfNR9LdkACS2ccGKLEK7SYqB4gLLTycQfg1koyfSq SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1343 " Choice[1] = ID: TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1344 " Choice[2] = ID: Zda4gsqTjRaX6XVZekVNi3ovMFPHDRQiGbzYuAb7Nwqy1rGBc SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1345 " Choice[3] = ID: 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1346 ")"1347 if str := graph.String(); str != expected {1348 t.Fatalf("Expected %s, got %s", expected, str)1349 }1350 }1351 prefs = graph.Preferences()1352 switch {1353 case prefs.Len() != 2:1354 t.Fatalf("Wrong number of preferences.")1355 case !prefs.Contains(Red.ID()):1356 t.Fatalf("Wrong preference. Expected %s", Red.ID())1357 case !prefs.Contains(Blue.ID()):1358 t.Fatalf("Wrong preference. Expected %s", Blue.ID())1359 case graph.Finalized():1360 t.Fatalf("Finalized too early")1361 }1362 if changed, err := graph.RecordPoll(ga); err != nil {1363 t.Fatal(err)1364 } else if !changed {1365 t.Fatalf("Should have caused the frontiers to recalculate")1366 }1367 {1368 expected := prefix + "(\n" +1369 " Choice[0] = ID: LUC1cmcxnfNR9LdkACS2ccGKLEK7SYqB4gLLTycQfg1koyfSq SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1370 " Choice[1] = ID: TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES SB(NumSuccessfulPolls = 2, Confidence = 1)\n" +1371 " Choice[2] = ID: Zda4gsqTjRaX6XVZekVNi3ovMFPHDRQiGbzYuAb7Nwqy1rGBc SB(NumSuccessfulPolls = 2, Confidence = 1)\n" +1372 " Choice[3] = ID: 2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w SB(NumSuccessfulPolls = 1, Confidence = 0)\n" +1373 ")"1374 if str := graph.String(); str != expected {1375 t.Fatalf("Expected %s, got %s", expected, str)1376 }1377 }1378 prefs = graph.Preferences()1379 switch {1380 case prefs.Len() != 2:1381 t.Fatalf("Wrong number of preferences.")1382 case !prefs.Contains(Green.ID()):1383 t.Fatalf("Wrong preference. Expected %s", Green.ID())1384 case !prefs.Contains(Alpha.ID()):1385 t.Fatalf("Wrong preference. Expected %s", Alpha.ID())1386 case graph.Finalized():1387 t.Fatalf("Finalized too early")1388 }1389 if changed, err := graph.RecordPoll(ga); err != nil {1390 t.Fatal(err)1391 } else if !changed {1392 t.Fatalf("Should have caused the frontiers to recalculate")1393 }1394 {1395 expected := prefix + "()"1396 if str := graph.String(); str != expected {1397 t.Fatalf("Expected %s, got %s", expected, str)1398 }1399 }1400 prefs = graph.Preferences()1401 switch {1402 case prefs.Len() != 0:1403 t.Fatalf("Wrong number of preferences.")1404 case !graph.Finalized():1405 t.Fatalf("Finalized too late")1406 case Green.Status() != choices.Accepted:1407 t.Fatalf("%s should have been accepted", Green.ID())1408 case Alpha.Status() != choices.Accepted:1409 t.Fatalf("%s should have been accepted", Alpha.ID())1410 case Red.Status() != choices.Rejected:1411 t.Fatalf("%s should have been rejected", Red.ID())1412 case Blue.Status() != choices.Rejected:1413 t.Fatalf("%s should have been rejected", Blue.ID())1414 }1415 if changed, err := graph.RecordPoll(rb); err != nil {1416 t.Fatal(err)1417 } else if changed {1418 t.Fatalf("Shouldn't have caused the frontiers to recalculate")1419 }1420 {1421 expected := prefix + "()"1422 if str := graph.String(); str != expected {1423 t.Fatalf("Expected %s, got %s", expected, str)1424 }1425 }1426 prefs = graph.Preferences()1427 switch {1428 case prefs.Len() != 0:1429 t.Fatalf("Wrong number of preferences.")1430 case !graph.Finalized():1431 t.Fatalf("Finalized too late")1432 case Green.Status() != choices.Accepted:1433 t.Fatalf("%s should have been accepted", Green.ID())1434 case Alpha.Status() != choices.Accepted:1435 t.Fatalf("%s should have been accepted", Alpha.ID())1436 case Red.Status() != choices.Rejected:1437 t.Fatalf("%s should have been rejected", Red.ID())1438 case Blue.Status() != choices.Rejected:1439 t.Fatalf("%s should have been rejected", Blue.ID())1440 }1441}...

Full Screen

Full Screen

redis_test.go

Source:redis_test.go Github

copy

Full Screen

...31 var err error32 var client *Client33 client = New()34 if err = client.Connect(testHost, testPort); err != nil {35 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)36 }37 if err = client.Close(); err != nil {38 t.Fatalf("Client should be able to close the connection.")39 }40 if err = client.Connect(testHost, 0); err == nil {41 t.Fatalf("Client should not be able to connect to a unused port.")42 }43 if err = client.Close(); err != nil {44 t.Fatalf("Client should be able to close the connection.")45 }46}47func TestPing(t *testing.T) {48 var s string49 var err error50 var client *Client51 client = New()52 if err = client.ConnectWithTimeout(testHost, testPort, 0); err != nil {53 t.Fatalf("Client failed to connect and set a timeout: %q", err)54 }55 defer client.Close()56 if s, err = client.Ping(); err != nil {57 t.Fatalf("Command PING failed: %q", err)58 }59 if s != "PONG" {60 t.Fatal("Expecting PONG reply.")61 }62 client.Quit()63}64func TestSimpleSet(t *testing.T) {65 var s string66 var b bool67 var err error68 var client *Client69 client = New()70 if err = client.Connect(testHost, testPort); err != nil {71 t.Fatal(err)72 }73 defer client.Close()74 if s, err = client.Set("foo", "hello world."); err != nil {75 t.Fatalf("Command SET failed: %q", err)76 }77 if s != "OK" {78 t.Fatal("Expecting OK response.")79 }80 if b, err = client.SetNX("foo", "exists!"); err != nil {81 t.Fatalf("Command SETNX failed: %q", err)82 }83 if b == true {84 t.Fatal()85 }86}87func TestGet(t *testing.T) {88 var s string89 var err error90 var client *Client91 client = New()92 if err = client.Connect(testHost, testPort); err != nil {93 t.Fatal("Client failed to connect: ", err)94 }95 defer client.Close()96 // Setting the FOO key.97 client.Set("foo", "hello")98 // Getting the FOO key.99 if s, err = client.Get("foo"); err != nil {100 t.Fatalf("Command GET failed: %q", err)101 }102 if s != "hello" {103 t.Fatalf("Could not SET/GET value.")104 }105 // Deleting key.106 client.Del("foo")107 // Attempting to retrieve deleted key.108 s, err = client.Get("foo")109 if s != "" {110 t.Fatalf("Expecting an empty string.")111 }112 if err != ErrNilReply {113 t.Fatalf("Expecting a redis.ErrNilReply error, got %q.", err)114 }115 // Making sure https://github.com/gosexy/redis/issues/23 does not interfere116 // with https://github.com/gosexy/redis/issues/12.117 client.Del("test")118 client.HMSet("test", "123", "*", "456", "*", "789", "*")119 var vals []string120 vals, err = client.HMGet("test", "1232", "456")121 if err != nil {122 t.Fatal(err)123 }124 if vals[0] != "" || vals[1] != "*" {125 t.Fatalf("Unexpected values.")126 }127}128func TestSetGetUnicode(t *testing.T) {129 var r string130 var err error131 var client *Client132 client = New()133 if err = client.Connect(testHost, testPort); err != nil {134 t.Fatal(err)135 }136 defer client.Close()137 if r, err = client.Set("heart", "♥"); err != nil {138 t.Fatalf("Command failed: %q", err)139 }140 if r != "OK" {141 t.Fatalf("Could not SET binary value.")142 }143 if r, err = client.Get("heart"); err != nil {144 t.Fatalf("Command failed: %q", err)145 }146 if r != "♥" {147 t.Fatalf("Could not GET binary value.")148 }149}150func TestDel(t *testing.T) {151 var i int64152 var err error153 var client *Client154 client = New()155 if err = client.Connect(testHost, testPort); err != nil {156 t.Fatal(err)157 }158 defer client.Close()159 client.Set("counter", 0)160 i, err = client.Del("counter")161 if err != nil {162 t.Fatal(err)163 }164 if i != 1 {165 t.Fatalf("Failed")166 }167 i, err = client.Del("counter")168 if err != nil {169 t.Fatal(err)170 }171 if i != 0 {172 t.Fatalf("Failed")173 }174}175func TestList(t *testing.T) {176 var items []string177 var err error178 var client *Client179 client = New()180 if err = client.Connect(testHost, testPort); err != nil {181 t.Fatal(err)182 }183 _, err = client.Del("list")184 if err != nil {185 t.Fatalf("Command failed: %q", err)186 }187 for i := 0; i < 10; i++ {188 _, err = client.LPush("list", fmt.Sprintf("element-%d", i))189 if err != nil {190 t.Fatalf("Command failed: %s", err.Error())191 }192 }193 items, err = client.LRange("list", 0, -1)194 if err != nil {195 t.Fatalf("Command failed: %s", err.Error())196 }197 if len(items) != 10 {198 t.Fatalf("Failed.")199 }200}201func TestAppendGetRange(t *testing.T) {202 var err error203 var s string204 var b bool205 var i int64206 var client *Client207 client = New()208 if err = client.Connect(testHost, testPort); err != nil {209 t.Fatal(err)210 }211 _, err = client.Del("mykey")212 if err != nil {213 t.Fatalf("Error: %s", err.Error())214 }215 b, err = client.Exists("mykey")216 if err != nil {217 t.Fatalf("Error: %s", err.Error())218 }219 if b == true {220 t.Fatalf("Failed.")221 }222 i, err = client.Append("mykey", "Hello")223 if err != nil {224 t.Fatalf("Error: %s", err.Error())225 }226 if i != 5 {227 t.Fatalf("Failed.")228 }229 i, err = client.Append("mykey", " World")230 if err != nil {231 t.Fatalf("Error: %s", err.Error())232 }233 if i != 11 {234 t.Fatalf("Failed.")235 }236 s, err = client.Get("mykey")237 if err != nil {238 t.Fatalf("Error: %s", err.Error())239 }240 if s != "Hello World" {241 t.Fatalf("Failed.")242 }243 _, err = client.Del("ts")244 if err != nil {245 t.Fatalf("Error: %s", err.Error())246 }247 _, err = client.Append("ts", "0043")248 if err != nil {249 t.Fatalf("Error: %s", err.Error())250 }251 _, err = client.Append("ts", "0035")252 if err != nil {253 t.Fatalf("Error: %s", err.Error())254 }255 s, err = client.GetRange("ts", 0, 3)256 if err != nil {257 t.Fatalf("Error: %s", err.Error())258 }259 if s != "0043" {260 t.Fatalf("Failed.")261 }262 s, err = client.GetRange("ts", 4, 7)263 if err != nil {264 t.Fatalf("Error: %s", err.Error())265 }266 if s != "0035" {267 t.Fatalf("Failed.")268 }269}270func TestBitCount(t *testing.T) {271 var err error272 var i int64273 var client *Client274 client = New()275 if err = client.Connect(testHost, testPort); err != nil {276 t.Fatal(err)277 }278 _, err = client.Set("mykey", "foobar")279 if err != nil {280 t.Fatalf("Error: %s", err.Error())281 }282 i, err = client.BitCount("mykey")283 if i != 26 {284 t.Fatalf("Failed.")285 }286 i, err = client.BitCount("mykey", 0, 0)287 if i != 4 {288 t.Fatalf("Failed.")289 }290 i, err = client.BitCount("mykey", 1, 1)291 if i != 6 {292 t.Fatalf("Failed.")293 }294}295func TestIncrDecr(t *testing.T) {296 var i int64297 var err error298 var s string299 var client *Client300 client = New()301 if err = client.Connect(testHost, testPort); err != nil {302 t.Fatal(err)303 }304 defer client.Close()305 // -> 0306 client.Set("counter", 0)307 // -> 1308 client.Incr("counter")309 err = client.Command(&i, "GET", "counter")310 if err != nil {311 t.Fatalf("Error: %s", err.Error())312 }313 if i != 1 {314 t.Fatalf("Failed")315 }316 // -> 1 + 10317 client.IncrBy("counter", 10)318 s, err = client.Get("counter")319 if err != nil {320 t.Fatalf("Error: %s", err.Error())321 }322 if s != "11" {323 t.Fatalf("Failed")324 }325 // -> 11 - 1326 i, err = client.Decr("counter")327 if err != nil {328 t.Fatalf("Error: %s", err.Error())329 }330 // 10 - 6331 i, err = client.DecrBy("counter", 6)332 if err != nil {333 t.Fatalf("Error: %s", err.Error())334 }335 if i != 4 {336 t.Fatalf("Failed")337 }338 s, err = client.IncrByFloat("counter", 0.01)339 if err != nil {340 t.Fatalf("Error: %s", err.Error())341 }342 if s != "4.01" {343 t.Fatalf("Failed")344 }345 s, err = client.IncrByFloat("counter", -0.02)346 if err != nil {347 t.Fatalf("Error: %s", err.Error())348 }349 if s != "3.99" {350 t.Fatalf("Failed")351 }352}353func TestDump(t *testing.T) {354 var s string355 var d string356 var ls []string357 var i int64358 var err error359 var client *Client360 client = New()361 if err = client.Connect(testHost, testPort); err != nil {362 t.Fatal(err)363 }364 defer client.Close()365 // Deleting key366 client.Del("mykey")367 // Trying to RPUSHX, but key does not exists.368 i, err = client.RPushX("mykey", 3)369 if err != nil {370 t.Fatalf("Error: %s", err.Error())371 }372 if i != 0 {373 t.Fatalf("Failed")374 }375 // Pushing 1, 2376 i, err = client.RPush("mykey", 1, 2)377 if err != nil {378 t.Fatalf("Error: %s", err.Error())379 }380 if i != 2 {381 t.Fatalf("Failed")382 }383 // Pushing 3384 i, err = client.RPushX("mykey", 3)385 if err != nil {386 t.Fatalf("Error: %s", err.Error())387 }388 if i != 3 {389 t.Fatalf("Failed")390 }391 // Generating a dump392 d, err = client.Dump("mykey")393 if err != nil {394 t.Fatalf("Error: %s", err.Error())395 }396 // Deleting key397 client.Del("mykey")398 // Restoring key from dump.399 s, err = client.Restore("mykey", 0, d)400 if err != nil {401 t.Fatalf("Error: %s", err.Error())402 }403 if s != "OK" {404 t.Fatalf("Failed")405 }406 // Key type407 s, err = client.Type("mykey")408 if err != nil {409 t.Fatalf("Error: %s", err.Error())410 }411 if s != "list" {412 t.Fatalf("Failed")413 }414 // Getting values.415 ls, err = client.LRange("mykey", 0, -1)416 if err != nil {417 t.Fatalf("Command failed: %s", err.Error())418 }419 if len(ls) != 3 {420 t.Fatalf("Failed")421 }422}423func TestExpire(t *testing.T) {424 var b bool425 var i int64426 var s string427 var err error428 var client *Client429 client = New()430 if err = client.Connect(testHost, testPort); err != nil {431 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)432 }433 defer client.Close()434 // Setting key435 client.Set("mykey", "Hello")436 // Setting expiration437 b, err = client.Expire("mykey", 10)438 if err != nil {439 t.Fatalf("Command failed: %s", err.Error())440 }441 if b != true {442 t.Fatalf("Failed")443 }444 // Checking time to live445 i, err = client.TTL("mykey")446 if err != nil {447 t.Fatalf("Command failed: %s", err.Error())448 }449 if i != 10 {450 t.Fatalf("Failed")451 }452 // Making key persistent453 b, err = client.Persist("mykey")454 if err != nil {455 t.Fatalf("Command failed: %s", err.Error())456 }457 if b != true {458 t.Fatalf("Failed")459 }460 // Checking time to live461 i, err = client.TTL("mykey")462 if err != nil {463 t.Fatalf("Command failed: %s", err.Error())464 }465 if i != -1 {466 t.Fatalf("Failed")467 }468 // Checking if the key exists469 b, err = client.Exists("mykey")470 if err != nil {471 t.Fatalf("Command failed: %s", err.Error())472 }473 if b != true {474 t.Fatalf("Failed")475 }476 // Setting past expiration477 b, err = client.ExpireAt("mykey", 1)478 if err != nil {479 t.Fatalf("Command failed: %s", err.Error())480 }481 if b != true {482 t.Fatalf("Failed")483 }484 // Checking if the key exists485 b, err = client.Exists("mykey")486 if err != nil {487 t.Fatalf("Command failed: %s", err.Error())488 }489 if b != false {490 t.Fatalf("Failed")491 }492 // Creating key493 client.Set("mykey", "Hello")494 // Setting expiration (ms)495 b, err = client.PExpire("mykey", 1500)496 if err != nil {497 t.Fatalf("Command failed: %s", err.Error())498 }499 if b == false {500 t.Fatalf("Failed")501 }502 // Checking time to live503 i, err = client.TTL("mykey")504 if err != nil {505 t.Fatalf("Command failed: %s", err.Error())506 }507 if i < 1 {508 t.Fatalf("Failed")509 }510 // Checking time to live (ms)511 i, err = client.PTTL("mykey")512 if err != nil {513 t.Fatalf("Command failed: %s", err.Error())514 }515 if i < 1000 {516 t.Fatalf("Failed")517 }518 // Setting past expiration519 b, err = client.PExpireAt("mykey", 1)520 if err != nil {521 t.Fatalf("Command failed: %s", err.Error())522 }523 if b != true {524 t.Fatalf("Failed")525 }526 // Checking if the key exists527 b, err = client.Exists("mykey")528 if err != nil {529 t.Fatalf("Command failed: %s", err.Error())530 }531 if b == true {532 t.Fatalf("Failed")533 }534 // Deleting key535 client.Del("mykey")536 // Setting value with expiration537 s, err = client.PSetEx("mykey", 1000, "Hello")538 if err != nil {539 t.Fatalf("Command failed: %s", err.Error())540 }541 if s != "OK" {542 t.Fatalf("Failed")543 }544 // Confirming TTL545 i, err = client.PTTL("mykey")546 if err != nil {547 t.Fatalf("Command failed: %s", err.Error())548 }549 if i < 100 {550 t.Fatalf("Failed")551 }552}553func TestSet(t *testing.T) {554 var i int64555 var b bool556 var s string557 var ls []string558 var err error559 var client *Client560 client = New()561 if err = client.Connect(testHost, testPort); err != nil {562 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)563 }564 defer client.Close()565 // Deleting566 client.Del("myset")567 // Adding568 i, err = client.SAdd("myset", "Hello", "World", "World")569 if err != nil {570 t.Fatalf("Command failed: %s", err.Error())571 }572 if i != 2 {573 t.Fatalf("Failed")574 }575 // Counting elements576 i, err = client.SCard("myset")577 if err != nil {578 t.Fatalf("Command failed: %s", err.Error())579 }580 if i != 2 {581 t.Fatalf("Failed")582 }583 // Deleting584 client.Del("key1", "key2")585 // Adding586 client.SAdd("key1", "a", "b", "c")587 client.SAdd("key2", "c", "d", "e")588 // Difference589 ls, err = client.SDiff("key1", "key2")590 if err != nil {591 t.Fatalf("Command failed: %s", err.Error())592 }593 if len(ls) != 2 {594 t.Fatalf("Failed")595 }596 // Difference597 i, err = client.SDiffStore("key3", "key1", "key2")598 if err != nil {599 t.Fatalf("Command failed: %s", err.Error())600 }601 if i != 2 {602 t.Fatalf("Failed")603 }604 // Intersection605 ls, err = client.SInter("key1", "key2")606 if err != nil {607 t.Fatalf("Command failed: %s", err.Error())608 }609 if len(ls) != 1 {610 t.Fatalf("Failed")611 }612 // Intersection613 i, err = client.SInterStore("key3", "key1", "key2")614 if err != nil {615 t.Fatalf("Command failed: %s", err.Error())616 }617 if i != 1 {618 t.Fatalf("Failed")619 }620 // Is member?621 b, err = client.SIsMember("key3", "c")622 if err != nil {623 t.Fatalf("Command failed: %s", err.Error())624 }625 if b != true {626 t.Fatalf("Failed")627 }628 // Members629 ls, err = client.SMembers("key1")630 if err != nil {631 t.Fatalf("Command failed: %s", err.Error())632 }633 if len(ls) != 3 {634 t.Fatalf("Failed")635 }636 // Move637 b, err = client.SMove("key1", "key2", "a")638 if err != nil {639 t.Fatalf("Command failed: %s", err.Error())640 }641 if b != true {642 t.Fatalf("Failed")643 }644 // Pop645 s, err = client.SPop("key1")646 if err != nil {647 t.Fatalf("Command failed: %s", err.Error())648 }649 if s == "" {650 t.Fatalf("Failed")651 }652 // Random members653 ls, err = client.SRandMember("key2", 2)654 if err != nil {655 t.Fatalf("Command failed: %s", err.Error())656 }657 if len(ls) != 2 {658 t.Fatalf("Failed")659 }660 // Random members661 i, err = client.SRem("key2", "c")662 if err != nil {663 t.Fatalf("Command failed: %s", err.Error())664 }665 if i != 1 {666 t.Fatalf("Failed")667 }668 // Union669 ls, err = client.SUnion("key1", "key2")670 if err != nil {671 t.Fatalf("Command failed: %s", err.Error())672 }673 if len(ls) != 4 {674 t.Fatalf("Failed")675 }676 // Union677 i, err = client.SUnionStore("key3", "key1", "key2")678 if err != nil {679 t.Fatalf("Command failed: %s", err.Error())680 }681 if i != 4 {682 t.Fatalf("Failed")683 }684}685func TestZSet(t *testing.T) {686 var i int64687 var s string688 var ls []string689 var err error690 var client *Client691 client = New()692 if err = client.Connect(testHost, testPort); err != nil {693 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)694 }695 defer client.Close()696 // Deleting697 client.Del("myset")698 // Adding699 i, err = client.ZAdd("myset", 1, "one", 2, "teo")700 if err != nil {701 t.Fatalf("Command failed: %s", err.Error())702 }703 if i != 2 {704 t.Fatalf("Failed")705 }706 // Counting elements707 i, err = client.ZCard("myset")708 if err != nil {709 t.Fatalf("Command failed: %s", err.Error())710 }711 if i != 2 {712 t.Fatalf("Failed")713 }714 // Counting elements715 i, err = client.ZCount("myset", "-inf", "+inf")716 if err != nil {717 t.Fatalf("Command failed: %s", err.Error())718 }719 if i != 2 {720 t.Fatalf("Failed")721 }722 // Increment723 s, err = client.ZIncrBy("myset", 1, "one")724 if err != nil {725 t.Fatalf("Command failed: %s", err.Error())726 }727 if s != "2" {728 t.Fatalf("Failed")729 }730 // Deleting731 client.Del("zset1", "zset2")732 // Adding733 client.ZAdd("zset1", 1, "one", 2, "two")734 client.ZAdd("zset2", 1, "one", 2, "two", 3, "three")735 // Intersection736 i, err = client.ZInterStore("out", 2, "zset1", "zset2", "WEIGHTS", 2, 3)737 if err != nil {738 t.Fatalf("Command failed: %s", err.Error())739 }740 if i != 2 {741 t.Fatalf("Failed")742 }743 // Range744 ls, err = client.ZRange("out", 0, -1, "WITHSCORES")745 if err != nil {746 t.Fatalf("Command failed: %s", err.Error())747 }748 if len(ls) != 4 {749 t.Fatalf("Failed")750 }751 // Adding752 client.Del("myzset")753 client.ZAdd("myzset", 1, "one", 2, "two", 3, "three")754 // Range755 ls, err = client.ZRangeByScore("myzset", 1, 2)756 if err != nil {757 t.Fatalf("Command failed: %s", err.Error())758 }759 if len(ls) != 2 {760 t.Fatalf("Failed")761 }762 // Rank763 i, err = client.ZRank("myzset", "two")764 if err != nil {765 t.Fatalf("Command failed: %s", err.Error())766 }767 if i != 1 {768 t.Fatalf("Failed")769 }770 // Reverse Rank771 i, err = client.ZRevRank("myzset", "one")772 if err != nil {773 t.Fatalf("Command failed: %s", err.Error())774 }775 if i != 2 {776 t.Fatalf("Failed")777 }778 // Reverse Rank779 i, err = client.ZRevRank("myzset", "none")780 if i != 0 {781 t.Fatalf("Expecting error.")782 }783 // Remove784 i, err = client.ZRem("myzset", "two", "three")785 if err != nil {786 t.Fatalf("Command failed: %s", err.Error())787 }788 if i != 2 {789 t.Fatalf("Failed")790 }791 // Remove792 i, err = client.ZRemRangeByRank("myzset", 0, 1)793 if err != nil {794 t.Fatalf("Command failed: %s", err.Error())795 }796 if i != 1 {797 t.Fatalf("Failed")798 }799 // Adding800 client.Del("myzset")801 client.ZAdd("myzset", 1, "one", 2, "two", 3, "three")802 // Remove803 i, err = client.ZRemRangeByScore("myzset", "-inf", "(2")804 if err != nil {805 t.Fatalf("Command failed: %s", err.Error())806 }807 if i != 1 {808 t.Fatalf("Failed")809 }810 // Range811 ls, err = client.ZRevRange("myzset", 0, -1)812 if err != nil {813 t.Fatalf("Command failed: %s", err.Error())814 }815 if len(ls) != 2 {816 t.Fatalf("Failed")817 }818 // Range819 ls, err = client.ZRevRangeByScore("myzset", "+inf", "-inf")820 if err != nil {821 t.Fatalf("Command failed: %s", err.Error())822 }823 if len(ls) != 2 {824 t.Fatalf("Failed")825 }826 // Score827 i, err = client.ZScore("myzset", "two")828 if err != nil {829 t.Fatalf("Command failed: %s", err.Error())830 }831 if i != 2 {832 t.Fatalf("Failed")833 }834 // Deleting835 client.Del("zset1", "zset2")836 // Adding837 client.ZAdd("zset1", 1, "one", 2, "two")838 client.ZAdd("zset2", 1, "one", 2, "two", 3, "three")839 // Intersection840 i, err = client.ZUnionStore("out", 2, "zset1", "zset2", "WEIGHTS", 2, 3)841 if err != nil {842 t.Fatalf("Command failed: %s", err.Error())843 }844 if i != 3 {845 t.Fatalf("Failed")846 }847}848func TestSubscribe(t *testing.T) {849 var ls []string850 var err error851 ok := make(chan bool)852 consumer := New()853 if err = consumer.Connect(testHost, testPort); err != nil {854 t.Fatal("Failed to connect: ", err)855 }856 rec := make(chan []string)857 go func() {858 select {859 case ls = <-rec:860 t.Logf("Got: %v\n", ls)861 ok <- true862 return863 }864 }()865 if err = consumer.Subscribe(rec, "channel"); err != nil {866 t.Fatal("Failed to subscribe: ", err)867 }868 <-ok869 consumer.Unsubscribe("channel")870 consumer.Quit()871}872func TestPublishAndSubscribe(t *testing.T) {873 var err error874 var received map[int]bool875 var tests int876 wg := new(sync.WaitGroup)877 mu := new(sync.Mutex)878 tests = 10879 // Subscriber880 consumer := New()881 if err = consumer.Connect(testHost, testPort); err != nil {882 t.Fatal("Failed to connect: ", err)883 }884 rec := make(chan []string, tests)885 subscribed := make(chan bool)886 go func() {887 received = make(map[int]bool)888 for {889 // Receiving messages.890 select {891 case ls := <-rec:892 if ls[0] == `message` {893 i, _ := strconv.Atoi(ls[2])894 received[i] = true895 // Marking job as done.896 wg.Done()897 } else if ls[0] == `subscribe` {898 subscribed <- true899 } else if ls[0] == `unsubscribe` {900 return901 }902 }903 }904 }()905 if err = consumer.Subscribe(rec, "channel"); err != nil {906 t.Fatal("Subscribe() ", err)907 }908 // Waiting for subscription to happen.909 <-subscribed910 // Publisher911 publisher := New()912 if err = publisher.Connect(testHost, testPort); err != nil {913 t.Fatal("Failed to connect: ", err)914 }915 // Publishing916 var clients int64917 for i := 0; i < tests; i++ {918 mu.Lock()919 wg.Add(1)920 clients, err = publisher.Publish("channel", i)921 if err != nil {922 t.Fatal("Publish(): ", err)923 }924 if clients < 1 {925 t.Fatal("We should have at least one subscribed client.")926 }927 mu.Unlock()928 }929 // Waiting jobs to finish.930 wg.Wait()931 if _, err = publisher.Quit(); err != nil {932 t.Fatal("Quit(): ", err)933 }934 if err = consumer.Unsubscribe("channel"); err != nil {935 t.Fatal("Unsubscribe(): ", err)936 }937 if _, err = consumer.Quit(); err != nil {938 t.Fatal("Quit(): ", err)939 }940 // Verifying data map.941 for i := 0; i < tests; i++ {942 if received[i] == false {943 t.Fatal(`The "test" map should be populated with true values.`)944 }945 }946}947func TestPSubscribe(t *testing.T) {948 var ls []string949 var err error950 ok := make(chan bool)951 consumer := New()952 if err = consumer.Connect(testHost, testPort); err != nil {953 t.Fatal("Failed to connect: ", err)954 }955 rec := make(chan []string)956 go func() {957 select {958 case ls = <-rec:959 t.Logf("Got: %v\n", ls)960 ok <- true961 return962 }963 }()964 if err = consumer.PSubscribe(rec, "channel"); err != nil {965 t.Fatal("Failed to subscribe: ", err)966 }967 <-ok968 consumer.PUnsubscribe("channel")969 consumer.Quit()970}971func TestPublishAndPSubscribe(t *testing.T) {972 var err error973 var received map[int]bool974 var tests int975 wg := new(sync.WaitGroup)976 mu := new(sync.Mutex)977 tests = 10978 // Subscriber979 consumer := New()980 if err = consumer.Connect(testHost, testPort); err != nil {981 t.Fatal("Failed to connect: ", err)982 }983 rec := make(chan []string, tests)984 psubscribed := make(chan bool)985 go func() {986 received = make(map[int]bool)987 for {988 // Receiving messages.989 select {990 case ls := <-rec:991 if ls[0] == `pmessage` {992 i, _ := strconv.Atoi(ls[3])993 received[i] = true994 // Marking job as done.995 wg.Done()996 } else if ls[0] == `psubscribe` {997 psubscribed <- true998 } else if ls[0] == `punsubscribe` {999 return1000 }1001 }1002 }1003 }()1004 if err = consumer.PSubscribe(rec, "channe?"); err != nil {1005 t.Fatal("Subscribe() ", err)1006 }1007 // Waiting for subscription to happen.1008 <-psubscribed1009 // Publisher1010 publisher := New()1011 if err = publisher.Connect(testHost, testPort); err != nil {1012 t.Fatal("Failed to connect: ", err)1013 }1014 // Publishing1015 var clients int641016 for i := 0; i < tests; i++ {1017 mu.Lock()1018 wg.Add(1)1019 clients, err = publisher.Publish("channel", i)1020 if err != nil {1021 t.Fatal("Publish(): ", err)1022 }1023 if clients < 1 {1024 t.Fatal("We should have at least one subscribed client.")1025 }1026 mu.Unlock()1027 }1028 // Waiting jobs to finish.1029 wg.Wait()1030 if _, err = publisher.Quit(); err != nil {1031 t.Fatal("Quit(): ", err)1032 }1033 if err = consumer.PUnsubscribe("channel"); err != nil {1034 t.Fatal("PUnsubscribe(): ", err)1035 }1036 if _, err = consumer.Quit(); err != nil {1037 t.Fatal("Quit(): ", err)1038 }1039 // Verifying data map.1040 for i := 0; i < tests; i++ {1041 if received[i] == false {1042 t.Fatal(`The "test" map should be populated with true values.`)1043 }1044 }1045}1046/*1047func TestTransactions(t *testing.T) {1048 var ls []interface{}1049 var err error1050 var s string1051 var client *Client1052 client = New()1053 if err = client.Connect(testHost, testPort); err != nil {1054 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1055 }1056 defer client.Close()1057 client.Del("mykey")1058 client.Multi()1059 client.Del("mykey")1060 client.Set("mykey", 1)1061 client.Incr("mykey")1062 client.Discard()1063 client.Multi()1064 client.Set("mykey", 10)1065 client.Incr("mykey")1066 ls, err = client.Exec()1067 if err != nil {1068 t.Fatalf("Command failed: %s", err.Error())1069 }1070 if len(ls) != 2 {1071 t.Fatalf("Failed.")1072 }1073 s, _ = client.Get("mykey")1074 if s != "11" {1075 t.Fatalf("Failed.")1076 }1077}1078*/1079func TestEval(t *testing.T) {1080 var ls []string1081 var h string1082 var err error1083 var client *Client1084 client = New()1085 if err = client.Connect(testHost, testPort); err != nil {1086 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1087 }1088 defer client.Close()1089 ls, err = client.Eval("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", 2, "key1", "key2", "first", "second")1090 if err != nil {1091 t.Fatalf("Command failed: %s", err.Error())1092 }1093 if len(ls) == 0 {1094 t.Fatalf("Failed")1095 }1096 h, err = client.ScriptLoad("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}")1097 if err != nil {1098 t.Fatalf("Command failed: %s", err.Error())1099 }1100 ls, err = client.ScriptExists("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}")1101 if err != nil {1102 t.Fatalf("Command failed: %s", err.Error())1103 }1104 if len(ls) == 0 {1105 t.Fatalf("Failed")1106 }1107 ls, err = client.EvalSHA(h, 2, "key1", "key2", "first", "second")1108 if err != nil {1109 t.Fatalf("Command failed: %s", err.Error())1110 }1111 if len(ls) == 0 {1112 t.Fatalf("Failed")1113 }1114}1115func TestRandom(t *testing.T) {1116 var s string1117 var err error1118 var client *Client1119 client = New()1120 if err = client.Connect(testHost, testPort); err != nil {1121 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1122 }1123 defer client.Close()1124 // Getting a random key1125 s, err = client.RandomKey()1126 if err != nil {1127 t.Fatalf("Command failed: %s", err.Error())1128 }1129 if len(s) == 0 {1130 t.Fatalf("Failed")1131 }1132}1133func TestRename(t *testing.T) {1134 var s string1135 var b bool1136 var err error1137 var client *Client1138 client = New()1139 if err = client.Connect(testHost, testPort); err != nil {1140 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1141 }1142 defer client.Close()1143 // Setting key1144 client.Set("mykey", "Hello")1145 // Renaming1146 s, err = client.Rename("mykey", "myotherkey")1147 if err != nil {1148 t.Fatalf("Command failed: %s", err.Error())1149 }1150 if s != "OK" {1151 t.Fatalf("Failed")1152 }1153 // Getting value1154 s, err = client.Get("myotherkey")1155 if err != nil {1156 t.Fatalf("Command failed: %s", err.Error())1157 }1158 if s != "Hello" {1159 t.Fatalf("Failed")1160 }1161 // Setting key1162 client.Set("mykey", "taken")1163 // Renaming if not exists, but it does.1164 b, err = client.RenameNX("myotherkey", "mykey")1165 if err != nil {1166 t.Fatalf("Command failed: %s", err.Error())1167 }1168 if b == true {1169 t.Fatalf("Failed")1170 }1171}1172func TestSort(t *testing.T) {1173 var el []string1174 var err error1175 var client *Client1176 client = New()1177 if err = client.Connect(testHost, testPort); err != nil {1178 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1179 }1180 defer client.Close()1181 // Deleting key1182 client.Del("mylist")1183 // Pushing stuff into key1184 client.LPush("mylist", 5)1185 client.LPush("mylist", 1)1186 client.LPush("mylist", 4)1187 client.LPush("mylist", -1)1188 client.LPush("mylist", 9)1189 // Sorting1190 el, err = client.Sort("mylist")1191 if err != nil {1192 t.Fatalf("Command failed: %s", err.Error())1193 }1194 if len(el) != 5 {1195 t.Fatalf("Failed")1196 }1197 if el[0] != "-1" {1198 t.Fatalf("Failed")1199 }1200}1201func TestObject(t *testing.T) {1202 var s string1203 var i int641204 var err error1205 var client *Client1206 client = New()1207 if err = client.Connect(testHost, testPort); err != nil {1208 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1209 }1210 defer client.Close()1211 client.Del("mylist")1212 i, err = client.LPush("mylist", "Hello world")1213 if err != nil {1214 t.Fatalf("Command failed: %s", err.Error())1215 }1216 if i != 1 {1217 t.Fatalf("Failed")1218 }1219 s, err = client.Object("refcount", "mylist")1220 if err != nil {1221 t.Fatalf("Command failed: %s", err.Error())1222 }1223 if s != "1" {1224 t.Fatalf("Failed")1225 }1226 s, err = client.Object("encoding", "mylist")1227 if err != nil {1228 t.Fatalf("Command failed: %s", err.Error())1229 }1230 if s != "ziplist" {1231 t.Fatalf("Failed")1232 }1233}1234func TestKeys(t *testing.T) {1235 var b bool1236 var k []string1237 var s string1238 var err error1239 var client *Client1240 client = New()1241 if err = client.Connect(testHost, testPort); err != nil {1242 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1243 }1244 defer client.Close()1245 // Multiple set1246 s, err = client.MSet(1247 "one", 1,1248 "two", 2,1249 "three", 3,1250 "four", 4,1251 )1252 if err != nil {1253 t.Fatalf("Command failed: %s", err.Error())1254 }1255 if s != "OK" {1256 t.Fatalf("Failed")1257 }1258 // Getting "o" keys1259 k, err = client.Keys("*o*")1260 if err != nil {1261 t.Fatalf("Command failed: %s", err.Error())1262 }1263 if len(k) < 3 {1264 t.Fatalf("Failed")1265 }1266 // Getting "t" keys1267 k, err = client.Keys("t??")1268 if err != nil {1269 t.Fatalf("Command failed: %s", err.Error())1270 }1271 if len(k) < 1 {1272 t.Fatalf("Failed")1273 }1274 // Getting all keys1275 k, err = client.MGet("one", "two", "three", "four")1276 if err != nil {1277 t.Fatalf("Command failed: %s", err.Error())1278 }1279 if len(k) != 4 {1280 t.Fatalf("Failed")1281 }1282 // Deleting keys1283 client.Del("one", "two", "three", "four")1284 // Multiple set (NX)1285 b, err = client.MSetNX(1286 "one", 1,1287 "two", 2,1288 "three", 3,1289 "four", 4,1290 )1291 if err != nil {1292 t.Fatalf("Command failed: %s", err.Error())1293 }1294 if b == false {1295 t.Fatalf("Failed")1296 }1297 // Multiple set (NX)1298 b, err = client.MSetNX(1299 "one", 1,1300 "two", 2,1301 "three", 3,1302 "four", 4,1303 )1304 if err != nil {1305 t.Fatalf("Command failed: %s", err.Error())1306 }1307 if b == true {1308 t.Fatalf("Failed")1309 }1310}1311func TestRange(t *testing.T) {1312 var i int641313 var s string1314 var err error1315 var client *Client1316 client = New()1317 if err = client.Connect(testHost, testPort); err != nil {1318 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1319 }1320 defer client.Close()1321 // Setting key1322 client.Set("key1", "Hello World")1323 // Overwriting range1324 i, err = client.SetRange("key1", 6, "Redis")1325 if err != nil {1326 t.Fatalf("Command failed: %s", err.Error())1327 }1328 if i != 11 {1329 t.Fatalf("Failed")1330 }1331 // Verifying1332 s, _ = client.Get("key1")1333 if s != "Hello Redis" {1334 t.Fatalf("Failed")1335 }1336 i, err = client.Strlen("key1")1337 if err != nil {1338 t.Fatalf("Command failed: %s", err.Error())1339 }1340 if i != 11 {1341 t.Fatalf("Failed")1342 }1343}1344func TextHashes(t *testing.T) {1345 var i int641346 var b bool1347 var s string1348 var ls []string1349 var err error1350 var client *Client1351 client = New()1352 if err = client.Connect(testHost, testPort); err != nil {1353 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1354 }1355 defer client.Close()1356 // Deleting hash1357 client.Del("myhash")1358 // Setting hash value1359 b, err = client.HSet("myhash", "field1", "foo")1360 if err != nil {1361 t.Fatalf("Command failed: %s", err.Error())1362 }1363 if b == false {1364 t.Fatalf("Failed")1365 }1366 // Getting hash value1367 s, err = client.HGet("myhash", "field1")1368 if err != nil {1369 t.Fatalf("Command failed: %s", err.Error())1370 }1371 if s != "foo" {1372 t.Fatalf("Failed")1373 }1374 // Getting all hash values1375 ls, err = client.HGetAll("myhash")1376 if err != nil {1377 t.Fatalf("Command failed: %s", err.Error())1378 }1379 if len(ls) != 1 {1380 t.Fatalf("Failed")1381 }1382 // Deleting hash value1383 i, err = client.HDel("myhash", "field1")1384 if err != nil {1385 t.Fatalf("Command failed: %s", err.Error())1386 }1387 if i != 1 {1388 t.Fatalf("Failed")1389 }1390 // Deleting non-existent hash value1391 i, err = client.HDel("myhash", "field2")1392 if err != nil {1393 t.Fatalf("Command failed: %s", err.Error())1394 }1395 if i != 0 {1396 t.Fatalf("Failed")1397 }1398 // Incrementing key value1399 i, err = client.HIncrBy("myhash", "field", 10)1400 if err != nil {1401 t.Fatalf("Command failed: %s", err.Error())1402 }1403 if i != 10 {1404 t.Fatalf("Failed")1405 }1406 // Incrementing key value (float)1407 s, err = client.HIncrByFloat("myhash", "field", 1.01)1408 if err != nil {1409 t.Fatalf("Command failed: %s", err.Error())1410 }1411 if s != "11.01" {1412 t.Fatalf("Failed")1413 }1414 // Getting all hash keys1415 ls, err = client.HKeys("myhash")1416 if err != nil {1417 t.Fatalf("Command failed: %s", err.Error())1418 }1419 i, err = client.HLen("myhash")1420 if err != nil {1421 t.Fatalf("Command failed: %s", err.Error())1422 }1423 if len(ls) != int(i) {1424 t.Fatalf("Failed")1425 }1426 // Using multi get1427 ls, err = client.HMGet("myhash", "field1", "field2", "nofield")1428 if err != nil {1429 t.Fatalf("Command failed: %s", err.Error())1430 }1431 if len(ls) != 3 {1432 t.Fatalf("Failed")1433 }1434 // Using multi set1435 s, err = client.HMSet("myhash", "field1", 1, "field2", 2)1436 if err != nil {1437 t.Fatalf("Command failed: %s", err.Error())1438 }1439 if s != "OK" {1440 t.Fatalf("Failed")1441 }1442 // Non-existent set1443 b, err = client.HSetNX("myhash", "field1", 1)1444 if err != nil {1445 t.Fatalf("Command failed: %s", err.Error())1446 }1447 if b == true {1448 t.Fatalf("Failed")1449 }1450 // Getting values1451 ls, err = client.HVals("myhash")1452 if err != nil {1453 t.Fatalf("Command failed: %s", err.Error())1454 }1455 if len(ls) != 2 {1456 t.Fatalf("Failed")1457 }1458}1459func TestLists(t *testing.T) {1460 var ls []string1461 var s string1462 var i int641463 var err error1464 var client *Client1465 client = New()1466 if err = client.Connect(testHost, testPort); err != nil {1467 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1468 }1469 defer client.Close()1470 // Deleting lists1471 client.Del("list1", "list2")1472 client.RPush("list1", "a", "b", "c")1473 client.RPush("list2", "a", "b", "c")1474 // Blocking LPOP1475 ls, err = client.BLPop(0, "list1", "list2")1476 if err != nil {1477 t.Fatalf("Command failed: %s", err.Error())1478 }1479 if len(ls) == 0 {1480 t.Fatalf("Failed")1481 }1482 // Blocking RPOP1483 ls, err = client.BRPop(0, "list1", "list2")1484 if err != nil {1485 t.Fatalf("Command failed: %s", err.Error())1486 }1487 if len(ls) == 0 {1488 t.Fatalf("Failed")1489 }1490 // Deleting lists1491 client.Del("list1", "list2")1492 // Pushing1493 client.RPush("list1", "a", "b", "c")1494 // RPop and LPush1495 s, err = client.RPopLPush("list1", "list2")1496 if err != nil {1497 t.Fatalf("Command failed: %s", err.Error())1498 }1499 if s != "c" {1500 t.Fatalf("Failed")1501 }1502 // Checking second key1503 ls, err = client.LRange("list2", 0, -1)1504 if err != nil {1505 t.Fatalf("Command failed: %s", err.Error())1506 }1507 if len(ls) != 1 {1508 t.Fatalf("Failed")1509 }1510 // Deleting lists1511 client.Del("list1", "list2")1512 // Pushing1513 client.RPush("list1", "a", "b", "c")1514 // RPop and LPush1515 s, err = client.BRPopLPush("list1", "list2", 10)1516 if err != nil {1517 t.Fatalf("Command failed: %s", err.Error())1518 }1519 if s != "c" {1520 t.Fatalf("Failed")1521 }1522 // Checking second key1523 ls, err = client.LRange("list2", 0, -1)1524 if err != nil {1525 t.Fatalf("Command failed: %s", err.Error())1526 }1527 if len(ls) != 1 {1528 t.Fatalf("Failed")1529 }1530 // Deleting lists1531 client.Del("list1", "list2")1532 // Pushing1533 client.LPush("list1", "a", "b", "c")1534 // Getting list element by index1535 s, err = client.LIndex("list1", 1)1536 if err != nil {1537 t.Fatalf("Command failed: %s", err.Error())1538 }1539 if s != "b" {1540 t.Fatalf("Failed")1541 }1542 // Deleting lists1543 client.Del("list1", "list2")1544 // Pushing1545 client.RPush("list1", "Hello", "World")1546 // Inserting1547 i, err = client.LInsert("list1", "BEFORE", "World", "There")1548 if err != nil {1549 t.Fatalf("Command failed: %s", err.Error())1550 }1551 if i != 3 {1552 t.Fatalf("Failed")1553 }1554 // List pop1555 s, err = client.LPop("list1")1556 if err != nil {1557 t.Fatalf("Command failed: %s", err.Error())1558 }1559 if s != "Hello" {1560 t.Fatalf("Failed")1561 }1562 // List Length1563 i, err = client.LLen("list1")1564 if err != nil {1565 t.Fatalf("Command failed: %s", err.Error())1566 }1567 if i != 2 {1568 t.Fatalf("Failed")1569 }1570 // List pop1571 i, err = client.LPushX("list1", "Hello")1572 if err != nil {1573 t.Fatalf("Command failed: %s", err.Error())1574 }1575 if i != 3 {1576 t.Fatalf("Failed")1577 }1578 // Removing equal1579 i, err = client.LRem("list1", 0, "World")1580 if err != nil {1581 t.Fatalf("Command failed: %s", err.Error())1582 }1583 if i != 1 {1584 t.Fatalf("Failed")1585 }1586 // Setting by index1587 s, err = client.LSet("list1", 1, "World")1588 if err != nil {1589 t.Fatalf("Command failed: %s", err.Error())1590 }1591 if s != "OK" {1592 t.Fatalf("Failed")1593 }1594 // Deleting lists1595 client.Del("mylist")1596 // Pushing1597 client.RPush("mylist", "one", "two", "three")1598 // Trimming1599 s, err = client.LTrim("mylist", 1, -1)1600 if err != nil {1601 t.Fatalf("Command failed: %s", err.Error())1602 }1603 if s != "OK" {1604 t.Fatalf("Failed")1605 }1606 // Popping1607 s, err = client.RPop("mylist")1608 if err != nil {1609 t.Fatalf("Command failed: %s", err.Error())1610 }1611 if s != "three" {1612 t.Fatalf("Failed")1613 }1614 // RPop and LPush1615 s, err = client.RPopLPush("mylist", "list2")1616 if err != nil {1617 t.Fatalf("Command failed: %s", err.Error())1618 }1619 if s != "two" {1620 t.Fatalf("Failed")1621 }1622}1623func TestSetBit(t *testing.T) {1624 var err error1625 var i int641626 var client *Client1627 client = New()1628 if err = client.Connect(testHost, testPort); err != nil {1629 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1630 }1631 defer client.Close()1632 client.Del("mykey")1633 _, err = client.SetBit("mykey", 7, 1)1634 if err != nil {1635 t.Fatalf("Error: %s", err.Error())1636 }1637 i, err = client.GetBit("mykey", 0)1638 if err != nil {1639 t.Fatalf("Error: %s", err.Error())1640 }1641 if i != 0 {1642 t.Fatalf("Failed")1643 }1644 i, err = client.GetBit("mykey", 7)1645 if err != nil {1646 t.Fatalf("Error: %s", err.Error())1647 }1648 if i != 1 {1649 t.Fatalf("Failed")1650 }1651}1652func TestBitOp(t *testing.T) {1653 var err error1654 var s string1655 var i int641656 var client *Client1657 client = New()1658 if err = client.Connect(testHost, testPort); err != nil {1659 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1660 }1661 defer client.Close()1662 client.Set("key1", "foobar")1663 client.Set("key2", "foobax")1664 i, err = client.BitOp("AND", "dest", "key1", "key2")1665 if err != nil {1666 t.Fatalf("Error: %s", err.Error())1667 }1668 if i != 6 {1669 t.Fatalf("Failed.")1670 }1671 s, err = client.Get("dest")1672 if s != "foobap" {1673 t.Fatalf("Failed.")1674 }1675}1676func TestRawList(t *testing.T) {1677 var r int1678 var items []int1679 var sitems []string1680 var err error1681 var client *Client1682 client = New()1683 if err = client.Connect(testHost, testPort); err != nil {1684 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1685 }1686 defer client.Close()1687 err = client.Command(nil, "DEL", "list")1688 if err != nil {1689 if err != ErrNilReply {1690 t.Fatalf("Command failed: %s", err.Error())1691 }1692 }1693 for i := 0; i < 10; i++ {1694 err = client.Command(&r, "LPUSH", "list", i)1695 if err != nil {1696 t.Fatalf("Command failed: %s", err.Error())1697 }1698 if r != i+1 {1699 t.Fatalf("Failed, expecting %d, got %d", i+1, r)1700 }1701 }1702 err = client.Command(&items, "LRANGE", "list", 0, -1)1703 if err != nil {1704 t.Fatalf("Command failed: %s", err.Error())1705 }1706 if len(items) != 10 {1707 t.Fatalf("Failed")1708 }1709 err = client.Command(&sitems, "LRANGE", "list", 0, -1)1710 if err != nil {1711 t.Fatalf("Command failed: %s", err.Error())1712 }1713 if len(sitems) != 10 {1714 t.Fatalf("Failed")1715 }1716}1717// https://github.com/gosexy/redis/issues/271718func Test_Issue27(t *testing.T) {1719 var client *Client1720 var err error1721 client = New()1722 if err = client.Connect(testHost, testPort); err != nil {1723 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1724 }1725 defer client.Close()1726 info, err := client.Info("all")1727 if err != nil {1728 t.Fatalf("Command failed: %q", err)1729 }1730 if len(info) == 0 {1731 t.Fatalf("Failed to actually get data from INFO.")1732 }1733}1734// See https://github.com/gosexy/redis/issues/381735func Test_Issue38(t *testing.T) {1736 var client *Client1737 var err error1738 client = New()1739 if err = client.Connect(testHost, testPort); err != nil {1740 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1741 }1742 client.Del("mylist")1743 client.Set("mylist", 1)1744 defer client.Close()1745 if _, err = client.RPush("mylist", 1); err == nil {1746 t.Fatalf("Expecting an error.")1747 }1748 if !strings.Contains(err.Error(), "WRONGTYPE") {1749 t.Fatalf("Expecting WRONGTYPE error.")1750 }1751}1752func TestQuit(t *testing.T) {1753 var err error1754 var s string1755 var client *Client1756 client = New()1757 if err = client.Connect(testHost, testPort); err != nil {1758 t.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1759 }1760 defer client.Close()1761 s, err = client.Quit()1762 if err != nil {1763 t.Fatalf("Failed")1764 }1765 if s != "OK" {1766 t.Fatal()1767 }1768 s, err = client.Quit()1769 if err == nil {1770 t.Fatalf("Did not fail.")1771 }1772 if s == "OK" {1773 t.Fatal()1774 }1775 _, err = client.Set("foo", 1)1776 if err == nil {1777 t.Fatalf("Did not fail.")1778 }1779}1780func BenchmarkConnect(b *testing.B) {1781 var client *Client1782 var err error1783 client = New()1784 if err = client.Connect(testHost, testPort); err != nil {1785 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1786 }1787 defer client.Close()1788 err = client.ConnectWithTimeout(testHost, testPort, time.Second*1)1789 //err := client.Connect(testHost, testPort)1790 if err != nil {1791 b.Fatalf(err.Error())1792 }1793}1794func BenchmarkPing(b *testing.B) {1795 var client *Client1796 var err error1797 client = New()1798 if err = client.Connect(testHost, testPort); err != nil {1799 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1800 }1801 defer client.Close()1802 for i := 0; i < b.N; i++ {1803 _, err = client.Ping()1804 if err != nil {1805 b.Fatal(err)1806 break1807 }1808 }1809}1810func BenchmarkSet(b *testing.B) {1811 var client *Client1812 var err error1813 client = New()1814 if err = client.Connect(testHost, testPort); err != nil {1815 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1816 }1817 defer client.Close()1818 client.Del("hello")1819 for i := 0; i < b.N; i++ {1820 _, err = client.Set("hello", 1)1821 if err != nil {1822 b.Fatalf(err.Error())1823 break1824 }1825 }1826}1827func BenchmarkGet(b *testing.B) {1828 var client *Client1829 var err error1830 client = New()1831 if err = client.Connect(testHost, testPort); err != nil {1832 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1833 }1834 defer client.Close()1835 for i := 0; i < b.N; i++ {1836 _, err = client.Get("hello")1837 if err != nil {1838 b.Fatalf(err.Error())1839 break1840 }1841 }1842}1843func BenchmarkIncr(b *testing.B) {1844 var client *Client1845 var err error1846 client = New()1847 if err = client.Connect(testHost, testPort); err != nil {1848 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1849 }1850 defer client.Close()1851 for i := 0; i < b.N; i++ {1852 _, err = client.Incr("hello")1853 if err != nil {1854 b.Fatalf(err.Error())1855 break1856 }1857 }1858}1859func BenchmarkLPush(b *testing.B) {1860 var client *Client1861 var err error1862 client = New()1863 if err = client.Connect(testHost, testPort); err != nil {1864 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1865 }1866 defer client.Close()1867 client.Del("hello")1868 for i := 0; i < b.N; i++ {1869 _, err = client.LPush("hello", i)1870 if err != nil {1871 b.Fatalf(err.Error())1872 break1873 }1874 }1875}1876func BenchmarkLRange10(b *testing.B) {1877 var client *Client1878 var err error1879 client = New()1880 if err = client.Connect(testHost, testPort); err != nil {1881 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1882 }1883 defer client.Close()1884 for i := 0; i < b.N; i++ {1885 _, err = client.LRange("hello", 0, 10)1886 if err != nil {1887 b.Fatalf(err.Error())1888 break1889 }1890 }1891}1892func BenchmarkLRange100(b *testing.B) {1893 var client *Client1894 var err error1895 client = New()1896 if err = client.Connect(testHost, testPort); err != nil {1897 b.Fatalf("Client failed to connect to an up-and-running redis server: %q", err)1898 }1899 defer client.Close()1900 for i := 0; i < b.N; i++ {1901 _, err = client.LRange("hello", 0, 100)1902 if err != nil {1903 b.Fatalf(err.Error())1904 break1905 }1906 }1907}...

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestFatalf(t *testing.T) {3 fmt.Println("Hello World")4 t.Fatalf("Failed")5 fmt.Println("Hello World Again")6}7--- FAIL: TestFatalf (0.00s)8import (9func TestFatal(t *testing.T) {10 fmt.Println("Hello World")11 t.Fatal("Failed")12 fmt.Println("Hello World Again")13}14--- FAIL: TestFatal (0.00s)15import (16func TestErrorf(t *testing.T) {17 fmt.Println("Hello World")18 t.Errorf("Failed")19 fmt.Println("Hello World Again")20}21--- FAIL: TestErrorf (0.00s)22import (23func TestError(t *testing.T) {24 fmt.Println("Hello World")25 t.Error("Failed")26 fmt.Println("Hello World Again")27}28--- FAIL: TestError (0.00s)

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestFirst(t *testing.T) {3 t.Log("Hello World")4 t.Fatal("Hello World")5 t.Log("Hello World")6}7--- FAIL: TestFirst (0.00s)8--- FAIL: TestFirst (0.00s)9--- FAIL: TestFirst (0.00s)10--- FAIL: TestFirst (0.00s)11--- FAIL: TestFirst (0.00s)12--- FAIL: TestFirst (0.00s)

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful