github.com/square/finch@v0.0.0-20240412205204-6530c03e2b96/data/scope_test.go (about)

     1  // Copyright 2024 Block, Inc.
     2  
     3  package data_test
     4  
     5  import (
     6  	"testing"
     7  
     8  	"github.com/go-test/deep"
     9  	"github.com/square/finch"
    10  	"github.com/square/finch/data"
    11  )
    12  
    13  func TestScope_Trx(t *testing.T) {
    14  	keyName := "@d"
    15  	g, _ := data.NewAutoInc(nil)
    16  
    17  	r := finch.RunLevel{
    18  		Stage:         1,
    19  		StageName:     "benchmark",
    20  		ExecGroup:     1,
    21  		ExecGroupName: "test-execgrp",
    22  		ClientGroup:   1,
    23  		Client:        1,
    24  		Trx:           1,
    25  		TrxName:       "test-trx",
    26  		Query:         1,
    27  	}
    28  
    29  	scope := data.NewScope()
    30  	scope.Keys[keyName] = data.Key{
    31  		Name:      keyName,
    32  		Scope:     finch.SCOPE_TRX,
    33  		Trx:       "test-trx",
    34  		Statement: 1,
    35  		Column:    -1,
    36  		Generator: g,
    37  	}
    38  
    39  	// ----------------------------------------------------------------------
    40  	// Client 1
    41  
    42  	g1 := scope.Copy(keyName, r) // COPY 1
    43  	id := g1.Id()
    44  	if id.CopyNo != 1 {
    45  		t.Errorf("got copy %d, expected 1: %+v", id.CopyNo, id)
    46  	}
    47  
    48  	// Trx hasn't changed, so data gen shouldn't change; should be first copy ^
    49  	r.Query += 1
    50  	g2 := scope.Copy(keyName, r)
    51  	id = g2.Id()
    52  	if id.CopyNo != 1 {
    53  		t.Errorf("got copy %d, expected 1: %+v", id.CopyNo, id)
    54  	}
    55  	if g1 != g2 {
    56  		t.Errorf("got differnet generators, expected same")
    57  	}
    58  
    59  	// Now trx changes, which should generate a new copy
    60  	r.Trx += 1
    61  	r.Query = 1                  // query count resets for new trx
    62  	g3 := scope.Copy(keyName, r) // COPY 2
    63  	id = g3.Id()
    64  	if id.CopyNo != 2 {
    65  		t.Errorf("got copy %d, expected 2 after trx change: %+v", id.CopyNo, id)
    66  	}
    67  	if g3 == g2 {
    68  		t.Errorf("got same generator, expected different after trx change")
    69  	}
    70  
    71  	// Copy 2 should be recorded at the correct run level (i.e. trx 2, query 1)
    72  	gotRL := scope.CopiedAt[keyName]
    73  	expectRL := r
    74  	expectRL.Trx = 2
    75  	expectRL.Query = 1
    76  	if diff := deep.Equal(gotRL, expectRL); diff != nil {
    77  		t.Error(diff)
    78  	}
    79  
    80  	// Next stmt in new trx should should use its generator (copy 2)
    81  	r.Query += 1
    82  	g4 := scope.Copy(keyName, r)
    83  	id = g4.Id()
    84  	if id.CopyNo != 2 {
    85  		t.Errorf("got copy %d, expected 2: %+v", id.CopyNo, id)
    86  	}
    87  	if g4 != g3 {
    88  		t.Errorf("got differnet generators, expected same")
    89  	}
    90  
    91  	// Recorded run level shouldn't change unless/until generator changes
    92  	// i.e. trx gen copy 2 still only copied at trx 2, query 1 (same as above)
    93  	gotRL = scope.CopiedAt[keyName]
    94  	if diff := deep.Equal(gotRL, expectRL); diff != nil {
    95  		t.Error(diff)
    96  	}
    97  
    98  	// ----------------------------------------------------------------------
    99  	// Client 2
   100  	r.Client = 2
   101  	r.Trx = 1
   102  	r.Query = 1
   103  
   104  	g5 := scope.Copy(keyName, r)
   105  	id = g5.Id()
   106  	if id.CopyNo != 3 {
   107  		t.Errorf("got copy %d, expected 3 after client change: %+v", id.CopyNo, id)
   108  	}
   109  	if g5 == g4 {
   110  		t.Errorf("got same generator, expected different after client change")
   111  	}
   112  }
   113  
   114  func TestScope_PREV(t *testing.T) {
   115  	// Test that a @PREV key is handled by using the previous key, as in
   116  	//   SELECT c FROM t WHERE id BETWEEN @d AND @PREV
   117  	// That's 2 statement inputs (values) but only 1 data gen. So copying
   118  	// @PREV should return nil to signal "skip it; previous data gen will
   119  	// return multiple values."
   120  	keyName := "@d"
   121  	g, _ := data.NewAutoInc(nil)
   122  	r := finch.RunLevel{
   123  		Client: 1,
   124  		Trx:    1,
   125  		Query:  1,
   126  	}
   127  	scope := data.NewScope()
   128  	scope.Keys[keyName] = data.Key{
   129  		Name:      keyName,
   130  		Trx:       "test-trx",
   131  		Statement: 1,
   132  		Column:    -1,
   133  		Generator: g,
   134  	}
   135  	g1 := scope.Copy(keyName, r)
   136  	if g1 == nil {
   137  		t.Fatal("got nil Generator, expected a value")
   138  	}
   139  	id := g1.Id()
   140  	if id.CopyNo != 1 {
   141  		t.Errorf("got copy %d, expected 1: %+v", id.CopyNo, id)
   142  	}
   143  	g2 := scope.Copy("@PREV", r) // should return nil
   144  	if g2 != nil {
   145  		t.Errorf("got Generator for @PREV, expected nil: %+v", g2)
   146  	}
   147  }