github.com/matrixorigin/matrixone@v0.7.0/pkg/taskservice/task_storage_test.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package taskservice
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/runtime"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/task"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  var (
    29  	storages = map[string]func(*testing.T) TaskStorage{
    30  		"mem":     createMem,
    31  		"refresh": createRefresh,
    32  	}
    33  )
    34  
    35  func createMem(t *testing.T) TaskStorage {
    36  	return NewMemTaskStorage()
    37  }
    38  
    39  func createRefresh(t *testing.T) TaskStorage {
    40  	return newRefreshableTaskStorage(
    41  		runtime.DefaultRuntime(),
    42  		func(context.Context) (string, error) { return "", nil },
    43  		NewFixedTaskStorageFactory(NewMemTaskStorage()))
    44  }
    45  
    46  // TODO: move to cluster testing.
    47  // func createMysql(t *testing.T) TaskStorage {
    48  // 	storage, err := NewMysqlTaskStorage("root:root@tcp(127.0.0.1:12345)/", "mo_task")
    49  // 	require.NoError(t, err)
    50  // 	return storage
    51  // }
    52  
    53  func TestAddTask(t *testing.T) {
    54  	for name, factory := range storages {
    55  		t.Run(name, func(t *testing.T) {
    56  			s := factory(t)
    57  			defer func() {
    58  				assert.NoError(t, s.Close())
    59  			}()
    60  
    61  			v := newTestTask("t1")
    62  			mustAddTestTask(t, s, 1, v)
    63  			mustAddTestTask(t, s, 0, v)
    64  			assert.Equal(t, 1, len(mustGetTestTask(t, s, 1)))
    65  		})
    66  	}
    67  }
    68  
    69  func TestUpdateTask(t *testing.T) {
    70  	for name, factory := range storages {
    71  		t.Run(name, func(t *testing.T) {
    72  			s := factory(t)
    73  			defer func() {
    74  				assert.NoError(t, s.Close())
    75  			}()
    76  
    77  			v := newTestTask("t1")
    78  			mustAddTestTask(t, s, 1, v)
    79  
    80  			tasks := mustGetTestTask(t, s, 1)
    81  			tasks[0].Metadata.Executor = 1
    82  			mustUpdateTestTask(t, s, 1, tasks)
    83  		})
    84  	}
    85  }
    86  
    87  func TestUpdateTaskWithConditions(t *testing.T) {
    88  	for name, factory := range storages {
    89  		t.Run(name, func(t *testing.T) {
    90  			s := factory(t)
    91  			defer func() {
    92  				assert.NoError(t, s.Close())
    93  			}()
    94  
    95  			mustAddTestTask(t, s, 1, newTestTask("t1"))
    96  			tasks := mustGetTestTask(t, s, 1)
    97  
    98  			mustUpdateTestTask(t, s, 0, tasks, WithTaskRunnerCond(EQ, "t2"))
    99  			mustUpdateTestTask(t, s, 1, tasks, WithTaskRunnerCond(EQ, "t1"))
   100  
   101  			tasks[0].Metadata.Context = []byte{1}
   102  			mustUpdateTestTask(t, s, 0, tasks, WithTaskIDCond(EQ, tasks[0].ID+1))
   103  			mustUpdateTestTask(t, s, 1, tasks, WithTaskIDCond(EQ, tasks[0].ID))
   104  			tasks[0].Metadata.Context = []byte{1, 2}
   105  			mustUpdateTestTask(t, s, 1, tasks, WithTaskIDCond(GT, 0))
   106  		})
   107  	}
   108  }
   109  
   110  func TestDeleteTaskWithConditions(t *testing.T) {
   111  	for name, factory := range storages {
   112  		t.Run(name, func(t *testing.T) {
   113  			s := factory(t)
   114  			defer func() {
   115  				assert.NoError(t, s.Close())
   116  			}()
   117  
   118  			mustAddTestTask(t, s, 1, newTestTask("t1"))
   119  			mustAddTestTask(t, s, 1, newTestTask("t2"))
   120  			mustAddTestTask(t, s, 1, newTestTask("t3"))
   121  			tasks := mustGetTestTask(t, s, 3)
   122  
   123  			mustDeleteTestTask(t, s, 0, WithTaskRunnerCond(EQ, "t4"))
   124  			mustDeleteTestTask(t, s, 1, WithTaskRunnerCond(EQ, "t1"))
   125  
   126  			mustDeleteTestTask(t, s, 0, WithTaskIDCond(EQ, tasks[len(tasks)-1].ID+1))
   127  			mustDeleteTestTask(t, s, 2, WithTaskIDCond(GT, tasks[0].ID))
   128  
   129  			mustGetTestTask(t, s, 0)
   130  		})
   131  	}
   132  }
   133  
   134  func TestQueryTaskWithConditions(t *testing.T) {
   135  	for name, factory := range storages {
   136  		t.Run(name, func(t *testing.T) {
   137  			s := factory(t)
   138  			defer func() {
   139  				assert.NoError(t, s.Close())
   140  			}()
   141  
   142  			mustAddTestTask(t, s, 1, newTestTask("t1"))
   143  			mustAddTestTask(t, s, 1, newTestTask("t2"))
   144  			mustAddTestTask(t, s, 1, newTestTask("t3"))
   145  			tasks := mustGetTestTask(t, s, 3)
   146  
   147  			mustGetTestTask(t, s, 1, WithLimitCond(1))
   148  			mustGetTestTask(t, s, 1, WithTaskRunnerCond(EQ, "t1"))
   149  			mustGetTestTask(t, s, 2, WithTaskIDCond(GT, tasks[0].ID))
   150  			mustGetTestTask(t, s, 3, WithTaskIDCond(GE, tasks[0].ID))
   151  			mustGetTestTask(t, s, 3, WithTaskIDCond(LE, tasks[2].ID))
   152  			mustGetTestTask(t, s, 2, WithTaskIDCond(LT, tasks[2].ID))
   153  			mustGetTestTask(t, s, 1, WithLimitCond(1), WithTaskIDCond(GT, tasks[0].ID))
   154  			mustGetTestTask(t, s, 1, WithTaskIDCond(EQ, tasks[0].ID))
   155  		})
   156  	}
   157  }
   158  
   159  func TestAddAndQueryCronTask(t *testing.T) {
   160  	for name, factory := range storages {
   161  		t.Run(name, func(t *testing.T) {
   162  			s := factory(t)
   163  			defer func() {
   164  				assert.NoError(t, s.Close())
   165  			}()
   166  
   167  			mustQueryTestCronTask(t, s, 0)
   168  
   169  			v1 := newTestCronTask("t1", "cron1")
   170  			v2 := newTestCronTask("t2", "cron2")
   171  			mustAddTestCronTask(t, s, 2, v1, v2)
   172  			mustQueryTestCronTask(t, s, 2)
   173  
   174  			mustAddTestCronTask(t, s, 0, v1, v2)
   175  			mustQueryTestCronTask(t, s, 2)
   176  		})
   177  	}
   178  }
   179  
   180  func TestUpdateCronTask(t *testing.T) {
   181  	for name, factory := range storages {
   182  		t.Run(name, func(t *testing.T) {
   183  			s := factory(t)
   184  			defer func() {
   185  				assert.NoError(t, s.Close())
   186  			}()
   187  
   188  			v1 := newTestCronTask("t1", "cron1")
   189  			v2 := newTestTask("t1-cron-1")
   190  			v3 := newTestTask("t1-cron-2")
   191  
   192  			ctx, cancel := context.WithTimeout(context.TODO(), time.Second*10)
   193  			defer cancel()
   194  
   195  			n, err := s.UpdateCronTask(ctx, v1, v2)
   196  			assert.NoError(t, err)
   197  			assert.Equal(t, 0, n)
   198  
   199  			mustAddTestCronTask(t, s, 1, v1)
   200  			mustAddTestTask(t, s, 1, v2)
   201  
   202  			v1 = mustQueryTestCronTask(t, s, 1)[0]
   203  
   204  			n, err = s.UpdateCronTask(ctx, v1, v2)
   205  			assert.NoError(t, err)
   206  			assert.Equal(t, 0, n)
   207  
   208  			n, err = s.UpdateCronTask(ctx, v1, v3)
   209  			assert.NoError(t, err)
   210  			assert.Equal(t, 0, n)
   211  
   212  			v1.TriggerTimes++
   213  			n, err = s.UpdateCronTask(ctx, v1, v3)
   214  			assert.NoError(t, err)
   215  			assert.Equal(t, 2, n)
   216  		})
   217  	}
   218  }
   219  
   220  func mustGetTestTask(t *testing.T, s TaskStorage, expectCount int, conds ...Condition) []task.Task {
   221  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
   222  	defer cancel()
   223  	tasks, err := s.Query(ctx, conds...)
   224  	require.NoError(t, err)
   225  	require.Equal(t, expectCount, len(tasks))
   226  	return tasks
   227  }
   228  
   229  func mustAddTestTask(t *testing.T, s TaskStorage, expectAdded int, tasks ...task.Task) {
   230  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
   231  	defer cancel()
   232  
   233  	n, err := s.Add(ctx, tasks...)
   234  	require.NoError(t, err)
   235  	require.Equal(t, expectAdded, n)
   236  }
   237  
   238  func mustUpdateTestTask(t *testing.T, s TaskStorage, expectUpdated int, tasks []task.Task, conds ...Condition) {
   239  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
   240  	defer cancel()
   241  
   242  	n, err := s.Update(ctx, tasks, conds...)
   243  	require.NoError(t, err)
   244  	require.Equal(t, expectUpdated, n)
   245  }
   246  
   247  func mustDeleteTestTask(t *testing.T, s TaskStorage, expectUpdated int, conds ...Condition) {
   248  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
   249  	defer cancel()
   250  
   251  	n, err := s.Delete(ctx, conds...)
   252  	require.NoError(t, err)
   253  	require.Equal(t, expectUpdated, n)
   254  }
   255  
   256  func mustAddTestCronTask(t *testing.T, s TaskStorage, expectAdded int, tasks ...task.CronTask) {
   257  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*1000)
   258  	defer cancel()
   259  
   260  	n, err := s.AddCronTask(ctx, tasks...)
   261  	require.NoError(t, err)
   262  	require.Equal(t, expectAdded, n)
   263  }
   264  
   265  func mustQueryTestCronTask(t *testing.T, s TaskStorage, expectQueryCount int) []task.CronTask {
   266  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
   267  	defer cancel()
   268  
   269  	tasks, err := s.QueryCronTask(ctx)
   270  	require.NoError(t, err)
   271  	require.Equal(t, expectQueryCount, len(tasks))
   272  	return tasks
   273  }
   274  
   275  func newTestTask(id string) task.Task {
   276  	v := task.Task{}
   277  	v.Metadata.ID = id
   278  	v.TaskRunner = id
   279  	return v
   280  }
   281  
   282  func newTestCronTask(id, cron string) task.CronTask {
   283  	v := task.CronTask{}
   284  	v.Metadata.ID = id
   285  	v.CronExpr = cron
   286  	return v
   287  }