github.com/sacloud/iaas-api-go@v1.12.0/test/database_op_test.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go Authors
     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 test
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/sacloud/iaas-api-go"
    22  	"github.com/sacloud/iaas-api-go/helper/power"
    23  	"github.com/sacloud/iaas-api-go/helper/query"
    24  	"github.com/sacloud/iaas-api-go/helper/wait"
    25  	"github.com/sacloud/iaas-api-go/testutil"
    26  	"github.com/sacloud/iaas-api-go/types"
    27  )
    28  
    29  func TestDatabaseOpCRUD(t *testing.T) {
    30  	// Note: バージョン省略後のサーバサイドでの算出処理をfakeが実装していないためAccTestだけとする
    31  	if !testutil.IsAccTest() {
    32  		t.Skip()
    33  	}
    34  	testutil.RunCRUD(t, &testutil.CRUDTestCase{
    35  		Parallel: true,
    36  
    37  		SetupAPICallerFunc: singletonAPICaller,
    38  		Setup: setupSwitchFunc("db",
    39  			createDatabaseParam,
    40  			createDatabaseExpected,
    41  			updateDatabaseSettingsExpected,
    42  			updateDatabaseExpected,
    43  			updateDatabaseToFullExpected,
    44  			updateDatabaseToMinExpected,
    45  		),
    46  		Create: &testutil.CRUDTestFunc{
    47  			Func: testDatabaseCreate,
    48  			CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    49  				ExpectValue:  createDatabaseExpected,
    50  				IgnoreFields: ignoreDatabaseFields,
    51  			}),
    52  		},
    53  		Read: &testutil.CRUDTestFunc{
    54  			Func: testDatabaseRead,
    55  			CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    56  				ExpectValue:  createDatabaseExpected,
    57  				IgnoreFields: ignoreDatabaseFields,
    58  			}),
    59  		},
    60  		Updates: []*testutil.CRUDTestFunc{
    61  			{
    62  				Func: testDatabaseUpdateSettings,
    63  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    64  					ExpectValue:  updateDatabaseSettingsExpected,
    65  					IgnoreFields: ignoreDatabaseFields,
    66  				}),
    67  			},
    68  			{
    69  				Func: testDatabaseUpdate,
    70  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    71  					ExpectValue:  updateDatabaseExpected,
    72  					IgnoreFields: ignoreDatabaseFields,
    73  				}),
    74  			},
    75  			{
    76  				Func: testDatabaseUpdate,
    77  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    78  					ExpectValue:  updateDatabaseExpected,
    79  					IgnoreFields: ignoreDatabaseFields,
    80  				}),
    81  			},
    82  			{
    83  				Func: testDatabaseUpdateToFull,
    84  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    85  					ExpectValue:  updateDatabaseToFullExpected,
    86  					IgnoreFields: ignoreDatabaseFields,
    87  				}),
    88  			},
    89  			{
    90  				Func: testDatabaseUpdateToMin,
    91  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    92  					ExpectValue:  updateDatabaseToMinExpected,
    93  					IgnoreFields: ignoreDatabaseFields,
    94  				}),
    95  			},
    96  			// parameter settings
    97  			{
    98  				Func: func(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
    99  					dbOp := iaas.NewDatabaseOp(caller)
   100  					err := dbOp.SetParameter(ctx, testZone, ctx.ID, map[string]interface{}{
   101  						"MariaDB/server.cnf/mysqld/max_connections": 50,
   102  					})
   103  					if err != nil {
   104  						return nil, err
   105  					}
   106  					return dbOp.GetParameter(ctx, testZone, ctx.ID)
   107  				},
   108  				CheckFunc: func(t testutil.TestT, ctx *testutil.CRUDTestContext, v interface{}) error {
   109  					param := v.(*iaas.DatabaseParameter)
   110  					return testutil.DoAsserts(
   111  						testutil.AssertLenFunc(t, param.Settings, 1, "Settings"),
   112  						testutil.AssertEqualFunc(t, float64(50), param.Settings["MariaDB/server.cnf/mysqld/max_connections"], "Settings.Value"),
   113  					)
   114  				},
   115  				SkipExtractID: true,
   116  			},
   117  			// reset parameter
   118  			{
   119  				Func: func(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   120  					dbOp := iaas.NewDatabaseOp(caller)
   121  					err := dbOp.SetParameter(ctx, testZone, ctx.ID, map[string]interface{}{
   122  						"MariaDB/server.cnf/mysqld/max_connections": nil,
   123  					})
   124  					if err != nil {
   125  						return nil, err
   126  					}
   127  					return dbOp.GetParameter(ctx, testZone, ctx.ID)
   128  				},
   129  				CheckFunc: func(t testutil.TestT, ctx *testutil.CRUDTestContext, v interface{}) error {
   130  					param := v.(*iaas.DatabaseParameter)
   131  					return testutil.DoAsserts(
   132  						testutil.AssertLenFunc(t, param.Settings, 0, "Settings"),
   133  					)
   134  				},
   135  				SkipExtractID: true,
   136  			},
   137  		},
   138  		Shutdown: func(ctx *testutil.CRUDTestContext, caller iaas.APICaller) error {
   139  			client := iaas.NewDatabaseOp(caller)
   140  			return power.ShutdownDatabase(ctx, client, testZone, ctx.ID, true)
   141  		},
   142  
   143  		Delete: &testutil.CRUDTestDeleteFunc{
   144  			Func: testDatabaseDelete,
   145  		},
   146  
   147  		Cleanup: cleanupSwitchFunc("db"),
   148  	})
   149  }
   150  
   151  var (
   152  	ignoreDatabaseFields = []string{
   153  		"ID",
   154  		"Class",
   155  		"Tags", // Create(POST)時は指定したタグが返ってくる。その後利用可能になったらデータベースの種類に応じて@MariaDBxxxのようなタグが付与される
   156  		"Availability",
   157  		"InstanceStatus",
   158  		"InstanceHostName",
   159  		"InstanceHostInfoURL",
   160  		"InstanceStatusChangedAt",
   161  		"Interfaces",
   162  		"ZoneID",
   163  		"CreatedAt",
   164  		"ModifiedAt",
   165  		"SettingsHash",
   166  	}
   167  
   168  	createDatabaseParam = &iaas.DatabaseCreateRequest{
   169  		PlanID:         types.DatabasePlans.DB10GB,
   170  		IPAddresses:    []string{"192.168.0.11"},
   171  		NetworkMaskLen: 24,
   172  		DefaultRoute:   "192.168.0.1",
   173  		Name:           testutil.ResourceName("db"),
   174  		Description:    "desc",
   175  		Tags:           []string{"tag1", "tag2"},
   176  
   177  		Conf: &iaas.DatabaseRemarkDBConfCommon{
   178  			DatabaseName: types.RDBMSTypesMariaDB.String(),
   179  			DefaultUser:  "exa.mple",
   180  			UserPassword: "LibsacloudExamplePassword01",
   181  		},
   182  		CommonSetting: &iaas.DatabaseSettingCommon{
   183  			ServicePort:     5432,
   184  			DefaultUser:     "exa.mple",
   185  			UserPassword:    "LibsacloudExamplePassword01",
   186  			ReplicaUser:     "replica",
   187  			ReplicaPassword: "replica-user-password",
   188  		},
   189  		ReplicationSetting: &iaas.DatabaseReplicationSetting{
   190  			Model: types.DatabaseReplicationModels.MasterSlave,
   191  		},
   192  	}
   193  	createDatabaseExpected = &iaas.Database{
   194  		Name:           createDatabaseParam.Name,
   195  		Description:    createDatabaseParam.Description,
   196  		Availability:   types.Availabilities.Available,
   197  		PlanID:         createDatabaseParam.PlanID,
   198  		DefaultRoute:   createDatabaseParam.DefaultRoute,
   199  		NetworkMaskLen: createDatabaseParam.NetworkMaskLen,
   200  		IPAddresses:    createDatabaseParam.IPAddresses,
   201  		Conf: &iaas.DatabaseRemarkDBConfCommon{
   202  			DatabaseName:     types.RDBMSTypesMariaDB.String(),
   203  			DatabaseVersion:  "10.4",
   204  			DatabaseRevision: "10.4.12",
   205  			DefaultUser:      "exa.mple",
   206  			UserPassword:     "LibsacloudExamplePassword01",
   207  		},
   208  		CommonSetting:      createDatabaseParam.CommonSetting,
   209  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   210  	}
   211  	updateDatabaseSettingsParam = &iaas.DatabaseUpdateSettingsRequest{
   212  		CommonSetting: &iaas.DatabaseSettingCommon{
   213  			ServicePort:     54322,
   214  			DefaultUser:     "exa.mple.upd",
   215  			UserPassword:    "LibsacloudExamplePassword01up1",
   216  			ReplicaUser:     "replica-upd",
   217  			ReplicaPassword: "replica-user-password-upd",
   218  		},
   219  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   220  	}
   221  	updateDatabaseSettingsExpected = &iaas.Database{
   222  		Name:           createDatabaseParam.Name,
   223  		Description:    createDatabaseParam.Description,
   224  		Availability:   types.Availabilities.Available,
   225  		PlanID:         createDatabaseParam.PlanID,
   226  		InstanceStatus: types.ServerInstanceStatuses.Up,
   227  		DefaultRoute:   createDatabaseParam.DefaultRoute,
   228  		NetworkMaskLen: createDatabaseParam.NetworkMaskLen,
   229  		IPAddresses:    createDatabaseParam.IPAddresses,
   230  		Conf:           createDatabaseExpected.Conf,
   231  		CommonSetting: &iaas.DatabaseSettingCommon{
   232  			ServicePort:     54322,
   233  			DefaultUser:     "exa.mple.upd",
   234  			UserPassword:    "LibsacloudExamplePassword01up1",
   235  			ReplicaUser:     "replica-upd",
   236  			ReplicaPassword: "replica-user-password-upd",
   237  		},
   238  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   239  	}
   240  	updateDatabaseParam = &iaas.DatabaseUpdateRequest{
   241  		Name:        testutil.ResourceName("db-upd"),
   242  		Tags:        []string{"tag1-upd", "tag2-upd"},
   243  		Description: "desc-upd",
   244  		CommonSetting: &iaas.DatabaseSettingCommon{
   245  			ServicePort:     5432,
   246  			DefaultUser:     "exa.mple",
   247  			UserPassword:    "LibsacloudExamplePassword02",
   248  			ReplicaUser:     "replica",
   249  			ReplicaPassword: "replica-user-password",
   250  		},
   251  		ReplicationSetting: &iaas.DatabaseReplicationSetting{
   252  			Model: types.DatabaseReplicationModels.MasterSlave,
   253  		},
   254  	}
   255  	updateDatabaseExpected = &iaas.Database{
   256  		Name:           updateDatabaseParam.Name,
   257  		Description:    updateDatabaseParam.Description,
   258  		Availability:   types.Availabilities.Available,
   259  		PlanID:         createDatabaseParam.PlanID,
   260  		InstanceStatus: types.ServerInstanceStatuses.Up,
   261  		DefaultRoute:   createDatabaseParam.DefaultRoute,
   262  		NetworkMaskLen: createDatabaseParam.NetworkMaskLen,
   263  		IPAddresses:    createDatabaseParam.IPAddresses,
   264  		Conf:           createDatabaseExpected.Conf,
   265  		CommonSetting: &iaas.DatabaseSettingCommon{
   266  			ServicePort:     5432,
   267  			DefaultUser:     "exa.mple",
   268  			UserPassword:    "LibsacloudExamplePassword02",
   269  			ReplicaUser:     "replica",
   270  			ReplicaPassword: "replica-user-password",
   271  		},
   272  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   273  	}
   274  	updateDatabaseToFullParam = &iaas.DatabaseUpdateRequest{
   275  		Name:        testutil.ResourceName("db-to-full"),
   276  		Tags:        []string{"tag1-upd", "tag2-upd"},
   277  		Description: "desc-upd",
   278  		BackupSetting: &iaas.DatabaseSettingBackup{
   279  			Rotate: 3,
   280  			Time:   "00:00",
   281  			DayOfWeek: []types.EDayOfTheWeek{
   282  				types.DaysOfTheWeek.Sunday,
   283  				types.DaysOfTheWeek.Monday,
   284  			},
   285  		},
   286  		CommonSetting: &iaas.DatabaseSettingCommon{
   287  			ServicePort:     54321,
   288  			DefaultUser:     "exa.mple",
   289  			UserPassword:    "LibsacloudExamplePassword03",
   290  			SourceNetwork:   []string{"192.168.11.0/24", "192.168.12.0/24"},
   291  			ReplicaUser:     "replica",
   292  			ReplicaPassword: "replica-user-password",
   293  		},
   294  		ReplicationSetting: &iaas.DatabaseReplicationSetting{
   295  			Model: types.DatabaseReplicationModels.MasterSlave,
   296  		},
   297  		IconID: testIconID,
   298  	}
   299  	updateDatabaseToFullExpected = &iaas.Database{
   300  		Name:           updateDatabaseToFullParam.Name,
   301  		Description:    updateDatabaseToFullParam.Description,
   302  		Availability:   types.Availabilities.Available,
   303  		PlanID:         createDatabaseParam.PlanID,
   304  		InstanceStatus: types.ServerInstanceStatuses.Up,
   305  		DefaultRoute:   createDatabaseParam.DefaultRoute,
   306  		NetworkMaskLen: createDatabaseParam.NetworkMaskLen,
   307  		IPAddresses:    createDatabaseParam.IPAddresses,
   308  		Conf:           createDatabaseExpected.Conf,
   309  		CommonSetting: &iaas.DatabaseSettingCommon{
   310  			ServicePort:     54321,
   311  			DefaultUser:     "exa.mple",
   312  			UserPassword:    "LibsacloudExamplePassword03",
   313  			SourceNetwork:   []string{"192.168.11.0/24", "192.168.12.0/24"},
   314  			ReplicaUser:     "replica",
   315  			ReplicaPassword: "replica-user-password",
   316  		},
   317  		BackupSetting:      updateDatabaseToFullParam.BackupSetting,
   318  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   319  		IconID:             updateDatabaseToFullParam.IconID,
   320  	}
   321  	updateDatabaseToMinParam = &iaas.DatabaseUpdateRequest{
   322  		Name: testutil.ResourceName("db-to-min"),
   323  		CommonSetting: &iaas.DatabaseSettingCommon{
   324  			DefaultUser:     "exa.mple",
   325  			UserPassword:    "LibsacloudExamplePassword04",
   326  			ReplicaUser:     "replica",
   327  			ReplicaPassword: "replica-user-password",
   328  		},
   329  		ReplicationSetting: &iaas.DatabaseReplicationSetting{
   330  			Model: types.DatabaseReplicationModels.MasterSlave,
   331  		},
   332  	}
   333  	updateDatabaseToMinExpected = &iaas.Database{
   334  		Name:           updateDatabaseToMinParam.Name,
   335  		Availability:   types.Availabilities.Available,
   336  		PlanID:         createDatabaseParam.PlanID,
   337  		InstanceStatus: types.ServerInstanceStatuses.Up,
   338  		DefaultRoute:   createDatabaseParam.DefaultRoute,
   339  		NetworkMaskLen: createDatabaseParam.NetworkMaskLen,
   340  		IPAddresses:    createDatabaseParam.IPAddresses,
   341  		Conf:           createDatabaseExpected.Conf,
   342  		CommonSetting: &iaas.DatabaseSettingCommon{
   343  			DefaultUser:     "exa.mple",
   344  			UserPassword:    "LibsacloudExamplePassword04",
   345  			ReplicaUser:     "replica",
   346  			ReplicaPassword: "replica-user-password",
   347  		},
   348  		ReplicationSetting: createDatabaseParam.ReplicationSetting,
   349  	}
   350  )
   351  
   352  func testDatabaseCreate(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   353  	client := iaas.NewDatabaseOp(caller)
   354  	db, err := client.Create(ctx, testZone, createDatabaseParam)
   355  	if err != nil {
   356  		return nil, err
   357  	}
   358  	return wait.UntilDatabaseIsUp(ctx, client, testZone, db.ID)
   359  }
   360  
   361  func testDatabaseRead(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   362  	client := iaas.NewDatabaseOp(caller)
   363  	return client.Read(ctx, testZone, ctx.ID)
   364  }
   365  
   366  func testDatabaseUpdateSettings(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   367  	client := iaas.NewDatabaseOp(caller)
   368  	return client.UpdateSettings(ctx, testZone, ctx.ID, updateDatabaseSettingsParam)
   369  }
   370  
   371  func testDatabaseUpdate(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   372  	client := iaas.NewDatabaseOp(caller)
   373  	return client.Update(ctx, testZone, ctx.ID, updateDatabaseParam)
   374  }
   375  
   376  func testDatabaseUpdateToFull(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   377  	client := iaas.NewDatabaseOp(caller)
   378  	return client.Update(ctx, testZone, ctx.ID, updateDatabaseToFullParam)
   379  }
   380  
   381  func testDatabaseUpdateToMin(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   382  	client := iaas.NewDatabaseOp(caller)
   383  	return client.Update(ctx, testZone, ctx.ID, updateDatabaseToMinParam)
   384  }
   385  
   386  func testDatabaseDelete(ctx *testutil.CRUDTestContext, caller iaas.APICaller) error {
   387  	client := iaas.NewDatabaseOp(caller)
   388  	return client.Delete(ctx, testZone, ctx.ID)
   389  }
   390  
   391  // TestCreateProxyDatabase 冗長化オプションが有効なデータベースアプライアンスの作成テスト
   392  func TestCreateProxyDatabase(t *testing.T) {
   393  	if !testutil.IsAccTest() {
   394  		t.Skip()
   395  	}
   396  
   397  	ctx := context.Background()
   398  	caller := testutil.SingletonAPICaller()
   399  	name := testutil.ResourceName("proxy-database")
   400  
   401  	sw, err := iaas.NewSwitchOp(caller).Create(ctx, testutil.TestZone(), &iaas.SwitchCreateRequest{
   402  		Name: name,
   403  	})
   404  	if err != nil {
   405  		t.Fatal(err)
   406  	}
   407  
   408  	planID, _, err := query.GetProxyDatabasePlan(ctx, iaas.NewNoteOp(caller), 4, 4, 90)
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  
   413  	dbOp := iaas.NewDatabaseOp(caller)
   414  	db, err := dbOp.Create(ctx, testutil.TestZone(), &iaas.DatabaseCreateRequest{
   415  		PlanID:   planID,
   416  		SwitchID: sw.ID,
   417  		IPAddresses: []string{
   418  			"192.168.22.111",
   419  			"192.168.22.112",
   420  		},
   421  		NetworkMaskLen: 24,
   422  		DefaultRoute:   "192.168.22.1",
   423  		Conf: &iaas.DatabaseRemarkDBConfCommon{
   424  			DatabaseName: types.RDBMSTypesPostgreSQL.String(),
   425  			DefaultUser:  "sacloud",
   426  			UserPassword: "TestUserPassword01",
   427  		},
   428  		CommonSetting: &iaas.DatabaseSettingCommon{
   429  			DefaultUser:  "sacloud",
   430  			UserPassword: testutil.WithRandomPrefix("password"),
   431  		},
   432  		InterfaceSettings: []*iaas.DatabaseSettingsInterface{
   433  			{
   434  				VirtualIPAddress: "192.168.22.11",
   435  				Index:            1,
   436  			},
   437  		},
   438  		Name: name,
   439  	})
   440  	if err != nil {
   441  		t.Fatal(err)
   442  	}
   443  
   444  	if _, err := wait.UntilDatabaseIsUp(ctx, dbOp, testutil.TestZone(), db.ID); err != nil {
   445  		t.Fatal(err)
   446  	}
   447  }