github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ddl/table_test.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package ddl
    15  
    16  import (
    17  	"fmt"
    18  	"time"
    19  
    20  	. "github.com/insionng/yougam/libraries/pingcap/check"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/meta"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/meta/autoid"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/variable"
    28  	"github.com/insionng/yougam/libraries/pingcap/tidb/table"
    29  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/mock"
    30  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak"
    31  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    32  )
    33  
    34  var _ = Suite(&testTableSuite{})
    35  
    36  type testTableSuite struct {
    37  	store  kv.Storage
    38  	dbInfo *model.DBInfo
    39  
    40  	d *ddl
    41  }
    42  
    43  // create a test table with num int columns and with no index.
    44  func testTableInfo(c *C, d *ddl, name string, num int) *model.TableInfo {
    45  	var err error
    46  	tblInfo := &model.TableInfo{
    47  		Name: model.NewCIStr(name),
    48  	}
    49  	tblInfo.ID, err = d.genGlobalID()
    50  	c.Assert(err, IsNil)
    51  
    52  	cols := make([]*model.ColumnInfo, num)
    53  	for i := range cols {
    54  		col := &model.ColumnInfo{
    55  			Name:         model.NewCIStr(fmt.Sprintf("c%d", i+1)),
    56  			Offset:       i,
    57  			DefaultValue: i + 1,
    58  			State:        model.StatePublic,
    59  		}
    60  
    61  		col.FieldType = *types.NewFieldType(mysql.TypeLong)
    62  
    63  		col.ID, err = d.genGlobalID()
    64  		c.Assert(err, IsNil)
    65  		cols[i] = col
    66  	}
    67  
    68  	tblInfo.Columns = cols
    69  
    70  	return tblInfo
    71  }
    72  
    73  func testCreateTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) *model.Job {
    74  	job := &model.Job{
    75  		SchemaID: dbInfo.ID,
    76  		TableID:  tblInfo.ID,
    77  		Type:     model.ActionCreateTable,
    78  		Args:     []interface{}{tblInfo},
    79  	}
    80  
    81  	err := d.doDDLJob(ctx, job)
    82  	c.Assert(err, IsNil)
    83  	return job
    84  }
    85  
    86  func testDropTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) *model.Job {
    87  	job := &model.Job{
    88  		SchemaID: dbInfo.ID,
    89  		TableID:  tblInfo.ID,
    90  		Type:     model.ActionDropTable,
    91  	}
    92  
    93  	err := d.doDDLJob(ctx, job)
    94  	c.Assert(err, IsNil)
    95  	return job
    96  }
    97  
    98  func testCheckTableState(c *C, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo, state model.SchemaState) {
    99  	kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
   100  		t := meta.NewMeta(txn)
   101  		info, err := t.GetTable(dbInfo.ID, tblInfo.ID)
   102  		c.Assert(err, IsNil)
   103  
   104  		if state == model.StateNone {
   105  			c.Assert(info, IsNil)
   106  			return nil
   107  		}
   108  
   109  		c.Assert(info.Name, DeepEquals, tblInfo.Name)
   110  		c.Assert(info.State, Equals, state)
   111  		return nil
   112  	})
   113  }
   114  
   115  func testGetTable(c *C, d *ddl, schemaID int64, tableID int64) table.Table {
   116  	var tblInfo *model.TableInfo
   117  	kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
   118  		t := meta.NewMeta(txn)
   119  		var err error
   120  		tblInfo, err = t.GetTable(schemaID, tableID)
   121  		c.Assert(err, IsNil)
   122  		c.Assert(tblInfo, NotNil)
   123  		return nil
   124  	})
   125  	alloc := autoid.NewAllocator(d.store, schemaID)
   126  	tbl, err := table.TableFromMeta(alloc, tblInfo)
   127  	c.Assert(err, IsNil)
   128  	return tbl
   129  }
   130  
   131  func (s *testTableSuite) SetUpSuite(c *C) {
   132  	s.store = testCreateStore(c, "test_table")
   133  	lease := 50 * time.Millisecond
   134  	s.d = newDDL(s.store, nil, nil, lease)
   135  
   136  	s.dbInfo = testSchemaInfo(c, s.d, "test")
   137  	testCreateSchema(c, mock.NewContext(), s.d, s.dbInfo)
   138  }
   139  
   140  func (s *testTableSuite) TearDownSuite(c *C) {
   141  	testDropSchema(c, mock.NewContext(), s.d, s.dbInfo)
   142  	s.d.close()
   143  	s.store.Close()
   144  }
   145  
   146  func testNewContext(c *C, d *ddl) context.Context {
   147  	ctx := d.newReorgContext()
   148  	variable.BindSessionVars(ctx)
   149  	return ctx
   150  }
   151  
   152  func (s *testTableSuite) TestTable(c *C) {
   153  	defer testleak.AfterTest(c)()
   154  	d := s.d
   155  
   156  	ctx := testNewContext(c, d)
   157  	defer ctx.FinishTxn(true)
   158  
   159  	tblInfo := testTableInfo(c, d, "t", 3)
   160  
   161  	job := testCreateTable(c, ctx, d, s.dbInfo, tblInfo)
   162  	testCheckTableState(c, d, s.dbInfo, tblInfo, model.StatePublic)
   163  	testCheckJobDone(c, d, job, true)
   164  
   165  	newTblInfo := testTableInfo(c, d, "t", 3)
   166  	job = &model.Job{
   167  		SchemaID: s.dbInfo.ID,
   168  		TableID:  newTblInfo.ID,
   169  		Type:     model.ActionCreateTable,
   170  		Args:     []interface{}{newTblInfo},
   171  	}
   172  
   173  	err := d.doDDLJob(ctx, job)
   174  	c.Assert(err, NotNil)
   175  	testCheckJobCancelled(c, d, job)
   176  
   177  	tbl := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)
   178  
   179  	_, err = tbl.AddRecord(ctx, types.MakeDatums(1, 1, 1))
   180  	c.Assert(err, IsNil)
   181  
   182  	_, err = tbl.AddRecord(ctx, types.MakeDatums(2, 2, 2))
   183  	c.Assert(err, IsNil)
   184  
   185  	job = testDropTable(c, ctx, d, s.dbInfo, tblInfo)
   186  	testCheckJobDone(c, d, job, false)
   187  }
   188  
   189  func (s *testTableSuite) TestTableResume(c *C) {
   190  	defer testleak.AfterTest(c)()
   191  	d := s.d
   192  
   193  	testCheckOwner(c, d, true, ddlJobFlag)
   194  
   195  	tblInfo := testTableInfo(c, d, "t1", 3)
   196  
   197  	job := &model.Job{
   198  		SchemaID: s.dbInfo.ID,
   199  		TableID:  tblInfo.ID,
   200  		Type:     model.ActionCreateTable,
   201  		Args:     []interface{}{tblInfo},
   202  	}
   203  
   204  	testRunInterruptedJob(c, d, job)
   205  	testCheckTableState(c, d, s.dbInfo, tblInfo, model.StatePublic)
   206  
   207  	job = &model.Job{
   208  		SchemaID: s.dbInfo.ID,
   209  		TableID:  tblInfo.ID,
   210  		Type:     model.ActionDropTable,
   211  	}
   212  
   213  	testRunInterruptedJob(c, d, job)
   214  	testCheckTableState(c, d, s.dbInfo, tblInfo, model.StateNone)
   215  }