github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/version_beacon_test.go (about)

     1  package flow_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  )
    10  
    11  func TestEqualTo(t *testing.T) {
    12  	testCases := []struct {
    13  		name   string
    14  		vb1    flow.VersionBeacon
    15  		vb2    flow.VersionBeacon
    16  		result bool
    17  	}{
    18  		{
    19  			name: "Equal version beacons",
    20  			vb1: flow.VersionBeacon{
    21  				VersionBoundaries: []flow.VersionBoundary{
    22  					{BlockHeight: 1, Version: "1.0.0"},
    23  					{BlockHeight: 2, Version: "1.1.0"},
    24  				},
    25  				Sequence: 1,
    26  			},
    27  			vb2: flow.VersionBeacon{
    28  				VersionBoundaries: []flow.VersionBoundary{
    29  					{BlockHeight: 1, Version: "1.0.0"},
    30  					{BlockHeight: 2, Version: "1.1.0"},
    31  				},
    32  				Sequence: 1,
    33  			},
    34  			result: true,
    35  		},
    36  		{
    37  			name: "Different sequence",
    38  			vb1: flow.VersionBeacon{
    39  				VersionBoundaries: []flow.VersionBoundary{
    40  					{BlockHeight: 1, Version: "1.0.0"},
    41  					{BlockHeight: 2, Version: "1.1.0"},
    42  				},
    43  				Sequence: 1,
    44  			},
    45  			vb2: flow.VersionBeacon{
    46  				VersionBoundaries: []flow.VersionBoundary{
    47  					{BlockHeight: 1, Version: "1.0.0"},
    48  					{BlockHeight: 2, Version: "1.1.0"},
    49  				},
    50  				Sequence: 2,
    51  			},
    52  			result: false,
    53  		},
    54  		{
    55  			name: "Equal sequence, but invalid version",
    56  			vb1: flow.VersionBeacon{
    57  				VersionBoundaries: []flow.VersionBoundary{
    58  					{BlockHeight: 1, Version: "v1.0.0"},
    59  				},
    60  				Sequence: 1,
    61  			},
    62  			vb2: flow.VersionBeacon{
    63  				VersionBoundaries: []flow.VersionBoundary{
    64  					{BlockHeight: 1, Version: "v1.0.0"},
    65  				},
    66  				Sequence: 1,
    67  			},
    68  			result: false,
    69  		},
    70  		{
    71  			name: "Different version boundaries",
    72  			vb1: flow.VersionBeacon{
    73  				VersionBoundaries: []flow.VersionBoundary{
    74  					{BlockHeight: 1, Version: "1.0.0"},
    75  					{BlockHeight: 2, Version: "1.1.0"},
    76  				},
    77  				Sequence: 1,
    78  			},
    79  			vb2: flow.VersionBeacon{
    80  				VersionBoundaries: []flow.VersionBoundary{
    81  					{BlockHeight: 1, Version: "1.0.0"},
    82  					{BlockHeight: 2, Version: "1.2.0"},
    83  				},
    84  				Sequence: 1,
    85  			},
    86  			result: false,
    87  		},
    88  		{
    89  			name: "Different length of version boundaries",
    90  			vb1: flow.VersionBeacon{
    91  				VersionBoundaries: []flow.VersionBoundary{
    92  					{BlockHeight: 1, Version: "1.0.0"},
    93  					{BlockHeight: 2, Version: "1.1.0"},
    94  				},
    95  				Sequence: 1,
    96  			},
    97  			vb2: flow.VersionBeacon{
    98  				VersionBoundaries: []flow.VersionBoundary{
    99  					{BlockHeight: 1, Version: "1.0.0"},
   100  				},
   101  				Sequence: 1,
   102  			},
   103  			result: false,
   104  		},
   105  	}
   106  
   107  	for _, tc := range testCases {
   108  		t.Run(tc.name, func(t *testing.T) {
   109  			require.Equal(t, tc.result, tc.vb1.EqualTo(&tc.vb2))
   110  		})
   111  	}
   112  }
   113  
   114  func TestValidate(t *testing.T) {
   115  	testCases := []struct {
   116  		name     string
   117  		vb       *flow.VersionBeacon
   118  		expected bool
   119  	}{
   120  		{
   121  			name: "empty requirements table is invalid",
   122  			vb: &flow.VersionBeacon{
   123  				VersionBoundaries: []flow.VersionBoundary{},
   124  				Sequence:          1,
   125  			},
   126  			expected: false,
   127  		},
   128  		{
   129  			name: "single version required requirement must be valid semver",
   130  			vb: &flow.VersionBeacon{
   131  				VersionBoundaries: []flow.VersionBoundary{
   132  					{BlockHeight: 1, Version: "v0.21.37"},
   133  				},
   134  				Sequence: 1,
   135  			},
   136  			expected: false,
   137  		},
   138  		{
   139  			name: "ordered by height ascending is valid",
   140  			vb: &flow.VersionBeacon{
   141  				VersionBoundaries: []flow.VersionBoundary{
   142  					{BlockHeight: 1, Version: "0.21.37"},
   143  					{BlockHeight: 100, Version: "0.21.37"},
   144  					{BlockHeight: 200, Version: "0.21.37"},
   145  					{BlockHeight: 300, Version: "0.21.37"},
   146  				},
   147  				Sequence: 1,
   148  			},
   149  			expected: true,
   150  		},
   151  		{
   152  			name: "decreasing height is invalid",
   153  			vb: &flow.VersionBeacon{
   154  				VersionBoundaries: []flow.VersionBoundary{
   155  					{BlockHeight: 1, Version: "0.21.37"},
   156  					{BlockHeight: 200, Version: "0.21.37"},
   157  					{BlockHeight: 180, Version: "0.21.37"},
   158  					{BlockHeight: 300, Version: "0.21.37"},
   159  				},
   160  				Sequence: 1,
   161  			},
   162  			expected: false,
   163  		},
   164  		{
   165  			name: "version higher or equal to the previous one is valid",
   166  			vb: &flow.VersionBeacon{
   167  				VersionBoundaries: []flow.VersionBoundary{
   168  					{BlockHeight: 1, Version: "0.21.37"},
   169  					{BlockHeight: 200, Version: "0.21.37"},
   170  					{BlockHeight: 300, Version: "0.21.38"},
   171  					{BlockHeight: 400, Version: "1.0.0"},
   172  				},
   173  				Sequence: 1,
   174  			},
   175  			expected: true,
   176  		},
   177  		{
   178  			name: "any version lower than previous one is invalid",
   179  			vb: &flow.VersionBeacon{
   180  				VersionBoundaries: []flow.VersionBoundary{
   181  					{BlockHeight: 1, Version: "0.21.37"},
   182  					{BlockHeight: 200, Version: "1.2.3"},
   183  					{BlockHeight: 300, Version: "1.2.4"},
   184  					{BlockHeight: 400, Version: "1.2.3"},
   185  				},
   186  				Sequence: 1,
   187  			},
   188  			expected: false,
   189  		},
   190  		{
   191  			name: "all version must be valid semver string to be valid",
   192  			vb: &flow.VersionBeacon{
   193  				VersionBoundaries: []flow.VersionBoundary{
   194  					{BlockHeight: 1, Version: "0.21.37"},
   195  					{BlockHeight: 200, Version: "0.21.37"},
   196  					{BlockHeight: 300, Version: "0.21.38"},
   197  					{BlockHeight: 400, Version: "v0.21.39"},
   198  				},
   199  				Sequence: 1,
   200  			},
   201  			expected: false,
   202  		},
   203  	}
   204  
   205  	for _, tc := range testCases {
   206  		t.Run(tc.name, func(t *testing.T) {
   207  			err := tc.vb.Validate()
   208  			if tc.expected {
   209  				require.NoError(t, err)
   210  			} else {
   211  				require.Error(t, err)
   212  			}
   213  		})
   214  	}
   215  }
   216  
   217  func TestVersionBeaconString(t *testing.T) {
   218  	vb := &flow.VersionBeacon{
   219  		VersionBoundaries: []flow.VersionBoundary{
   220  			{BlockHeight: 1, Version: "0.21.37"},
   221  			{BlockHeight: 200, Version: "0.21.37-patch.1"},
   222  		},
   223  		Sequence: 1,
   224  	}
   225  	require.Equal(t, "1:0.21.37 200:0.21.37-patch.1 ", vb.String())
   226  }