github.com/matrixorigin/matrixone@v1.2.0/pkg/tests/upgrade/upgrade_test.go (about)

     1  // Copyright 2024 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 upgrade
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/bootstrap"
    23  	"github.com/matrixorigin/matrixone/pkg/bootstrap/versions"
    24  	"github.com/matrixorigin/matrixone/pkg/bootstrap/versions/v1_2_0"
    25  	"github.com/matrixorigin/matrixone/pkg/cnservice"
    26  	"github.com/matrixorigin/matrixone/pkg/tests/service"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  func TestUpgrade(t *testing.T) {
    31  	if testing.Short() {
    32  		t.Skip("skipping in short mode.")
    33  		return
    34  	}
    35  
    36  	h := newTestVersionHandler("1.3.0", "1.2.0", versions.Yes, versions.Yes)
    37  	runUpgradeTest(
    38  		t,
    39  		func(opts service.Options) service.Options {
    40  			return opts.WithCNOptionFunc(func(i int) []cnservice.Option {
    41  				if i == 0 {
    42  					return []cnservice.Option{
    43  						cnservice.WithBootstrapOptions(
    44  							bootstrap.WithCheckUpgradeDuration(time.Millisecond*100),
    45  							bootstrap.WithCheckUpgradeTenantDuration(time.Millisecond*100),
    46  							bootstrap.WithCheckUpgradeTenantWorkers(1),
    47  							bootstrap.WithUpgradeTenantBatch(1),
    48  							bootstrap.WithUpgradeHandles([]bootstrap.VersionHandle{
    49  								v1_2_0.Handler,
    50  							})),
    51  					}
    52  				}
    53  				return []cnservice.Option{
    54  					cnservice.WithBootstrapOptions(
    55  						bootstrap.WithCheckUpgradeDuration(time.Millisecond*100),
    56  						bootstrap.WithCheckUpgradeTenantDuration(time.Millisecond*100),
    57  						bootstrap.WithCheckUpgradeTenantWorkers(1),
    58  						bootstrap.WithUpgradeTenantBatch(1),
    59  						bootstrap.WithUpgradeHandles([]bootstrap.VersionHandle{
    60  							v1_2_0.Handler,
    61  							h,
    62  						})),
    63  				}
    64  			})
    65  		},
    66  		func(c service.Cluster) {
    67  			waitVersionReady(t, "1.2.0", c)
    68  			checkVersionUpgrades(t, "1.2.0", c, func(upgrades []versions.VersionUpgrade) {
    69  				require.Equal(t, 0, len(upgrades))
    70  			})
    71  			createTenants(t, c, 10, "1.2.0")
    72  
    73  			require.NoError(t, c.StartCNServices(2))
    74  			waitVersionReady(t, "1.3.0", c)
    75  			checkVersionUpgrades(t, "1.3.0", c, func(upgrades []versions.VersionUpgrade) {
    76  				require.Equal(t, 1, len(upgrades))
    77  				checkVersionUpgrade(t, upgrades[0], "1.2.0", "1.3.0", "1.3.0", 11)
    78  			})
    79  			checkTenantVersion(t, c, "1.3.0")
    80  		})
    81  }
    82  
    83  func TestUpgradeCrossVersions(t *testing.T) {
    84  	if testing.Short() {
    85  		t.Skip("skipping in short mode.")
    86  		return
    87  	}
    88  
    89  	h1 := newTestVersionHandler("1.3.0", "1.2.0", versions.Yes, versions.No)
    90  	h2 := newTestVersionHandler("1.4.0", "1.3.0", versions.No, versions.No)
    91  	h3 := newTestVersionHandler("1.5.0", "1.4.0", versions.No, versions.Yes)
    92  	runUpgradeTest(
    93  		t,
    94  		func(opts service.Options) service.Options {
    95  			return opts.WithCNOptionFunc(func(i int) []cnservice.Option {
    96  				if i == 0 {
    97  					return []cnservice.Option{
    98  						cnservice.WithBootstrapOptions(
    99  							bootstrap.WithCheckUpgradeDuration(time.Millisecond*100),
   100  							bootstrap.WithCheckUpgradeTenantDuration(time.Millisecond*100),
   101  							bootstrap.WithCheckUpgradeTenantWorkers(1),
   102  							bootstrap.WithUpgradeTenantBatch(1),
   103  							bootstrap.WithUpgradeHandles([]bootstrap.VersionHandle{
   104  								v1_2_0.Handler,
   105  							})),
   106  					}
   107  				}
   108  				return []cnservice.Option{
   109  					cnservice.WithBootstrapOptions(
   110  						bootstrap.WithCheckUpgradeDuration(time.Millisecond*100),
   111  						bootstrap.WithCheckUpgradeTenantDuration(time.Millisecond*100),
   112  						bootstrap.WithCheckUpgradeTenantWorkers(1),
   113  						bootstrap.WithUpgradeTenantBatch(30),
   114  						bootstrap.WithUpgradeHandles([]bootstrap.VersionHandle{
   115  							v1_2_0.Handler,
   116  							h1,
   117  							h2,
   118  							h3,
   119  						})),
   120  				}
   121  			})
   122  		},
   123  		func(c service.Cluster) {
   124  			waitVersionReady(t, "1.2.0", c)
   125  			checkVersionUpgrades(t, "1.2.0", c, func(upgrades []versions.VersionUpgrade) {
   126  				require.Equal(t, 0, len(upgrades))
   127  			})
   128  			createTenants(t, c, 100, "1.2.0")
   129  
   130  			// start new cn to upgrade to 1.5.0
   131  			require.NoError(t, c.StartCNServices(2))
   132  			waitVersionReady(t, "1.5.0", c)
   133  			checkVersionUpgrades(t, "1.5.0", c, func(upgrades []versions.VersionUpgrade) {
   134  				require.Equal(t, 3, len(upgrades))
   135  				checkVersionUpgrade(t, upgrades[0], "1.2.0", "1.3.0", "1.5.0", 0)
   136  				checkVersionUpgrade(t, upgrades[1], "1.3.0", "1.4.0", "1.5.0", 0)
   137  				checkVersionUpgrade(t, upgrades[2], "1.4.0", "1.5.0", "1.5.0", 101)
   138  			})
   139  			checkTenantVersion(t, c, "1.5.0")
   140  
   141  			// create old tenant
   142  			oldID := createTenants(t, c, 1, "1.2.0")[0]
   143  			checkTenantVersion(t, c, "1.2.0", oldID)
   144  
   145  			svc, err := c.GetCNServiceIndexed(1)
   146  			require.NoError(t, err)
   147  			bs := svc.GetBootstrapService()
   148  
   149  			ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
   150  			defer cancel()
   151  
   152  			for i := 0; i < 2; i++ {
   153  				upgrade, err := bs.MaybeUpgradeTenant(
   154  					ctx,
   155  					func() (int32, string, error) {
   156  						return oldID, "1.2.0", nil
   157  					},
   158  					nil)
   159  				require.NoError(t, err)
   160  				if i == 0 {
   161  					require.True(t, upgrade)
   162  					checkTenantVersion(t, c, "1.5.0")
   163  				} else {
   164  					require.False(t, upgrade)
   165  				}
   166  			}
   167  		})
   168  }
   169  
   170  func checkVersionUpgrade(
   171  	t *testing.T,
   172  	upgrade versions.VersionUpgrade,
   173  	from, to, final string,
   174  	tenant int32) {
   175  	require.Equal(t, from, upgrade.FromVersion)
   176  	require.Equal(t, to, upgrade.ToVersion)
   177  	require.Equal(t, final, upgrade.FinalVersion)
   178  	require.Equal(t, versions.StateReady, upgrade.State)
   179  	require.Equal(t, tenant, upgrade.TotalTenant)
   180  	require.Equal(t, tenant, upgrade.ReadyTenant)
   181  }