mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	fix route table migration wiping routes 0.22 -> 0.23 (#2076)
This commit is contained in:
		
							parent
							
								
									827e3e83ae
								
							
						
					
					
						commit
						cf6a606d74
					
				
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							@ -34,4 +34,4 @@ jobs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      - name: Run tests
 | 
					      - name: Run tests
 | 
				
			||||||
        if: steps.changed-files.outputs.files == 'true'
 | 
					        if: steps.changed-files.outputs.files == 'true'
 | 
				
			||||||
        run: nix develop --check
 | 
					        run: nix develop --command -- gotestsum
 | 
				
			||||||
 | 
				
			|||||||
@ -51,8 +51,8 @@ func NewHeadscaleDatabase(
 | 
				
			|||||||
		dbConn,
 | 
							dbConn,
 | 
				
			||||||
		gormigrate.DefaultOptions,
 | 
							gormigrate.DefaultOptions,
 | 
				
			||||||
		[]*gormigrate.Migration{
 | 
							[]*gormigrate.Migration{
 | 
				
			||||||
			// New migrations should be added as transactions at the end of this list.
 | 
								// New migrations must be added as transactions at the end of this list.
 | 
				
			||||||
			// The initial commit here is quite messy, completely out of order and
 | 
								// The initial migration here is quite messy, completely out of order and
 | 
				
			||||||
			// has no versioning and is the tech debt of not having versioned migrations
 | 
								// has no versioning and is the tech debt of not having versioned migrations
 | 
				
			||||||
			// prior to this point. This first migration is all DB changes to bring a DB
 | 
								// prior to this point. This first migration is all DB changes to bring a DB
 | 
				
			||||||
			// up to 0.23.0.
 | 
								// up to 0.23.0.
 | 
				
			||||||
@ -123,9 +123,21 @@ func NewHeadscaleDatabase(
 | 
				
			|||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					err = tx.AutoMigrate(&types.Route{})
 | 
										// Only run automigrate Route table if it does not exist. It has only been
 | 
				
			||||||
					if err != nil {
 | 
										// changed ones, when machines where renamed to nodes, which is covered
 | 
				
			||||||
						return err
 | 
										// further up. This whole initial integration is a mess and if AutoMigrate
 | 
				
			||||||
 | 
										// is ran on a 0.22 to 0.23 update, it will wipe all the routes.
 | 
				
			||||||
 | 
										if tx.Migrator().HasTable(&types.Route{}) && tx.Migrator().HasTable(&types.Node{}) {
 | 
				
			||||||
 | 
											err := tx.Exec("delete from routes where node_id not in (select id from nodes)").Error
 | 
				
			||||||
 | 
											if err != nil {
 | 
				
			||||||
 | 
												return err
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if !tx.Migrator().HasTable(&types.Route{}) {
 | 
				
			||||||
 | 
											err = tx.AutoMigrate(&types.Route{})
 | 
				
			||||||
 | 
											if err != nil {
 | 
				
			||||||
 | 
												return err
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					err = tx.AutoMigrate(&types.Node{})
 | 
										err = tx.AutoMigrate(&types.Node{})
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										168
									
								
								hscontrol/db/db_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								hscontrol/db/db_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					package db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"net/netip"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/google/go-cmp/cmp"
 | 
				
			||||||
 | 
						"github.com/google/go-cmp/cmp/cmpopts"
 | 
				
			||||||
 | 
						"github.com/juanfont/headscale/hscontrol/types"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMigrations(t *testing.T) {
 | 
				
			||||||
 | 
						ipp := func(p string) types.IPPrefix {
 | 
				
			||||||
 | 
							return types.IPPrefix(netip.MustParsePrefix(p))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r := func(id uint64, p string, a, e, i bool) types.Route {
 | 
				
			||||||
 | 
							return types.Route{
 | 
				
			||||||
 | 
								NodeID:     id,
 | 
				
			||||||
 | 
								Prefix:     ipp(p),
 | 
				
			||||||
 | 
								Advertised: a,
 | 
				
			||||||
 | 
								Enabled:    e,
 | 
				
			||||||
 | 
								IsPrimary:  i,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							dbPath   string
 | 
				
			||||||
 | 
							wantFunc func(*testing.T, *HSDatabase)
 | 
				
			||||||
 | 
							wantErr  string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								dbPath: "testdata/0-22-3-to-0-23-0-routes-are-dropped-2063.sqlite",
 | 
				
			||||||
 | 
								wantFunc: func(t *testing.T, h *HSDatabase) {
 | 
				
			||||||
 | 
									routes, err := Read(h.DB, func(rx *gorm.DB) (types.Routes, error) {
 | 
				
			||||||
 | 
										return GetRoutes(rx)
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									assert.NoError(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									assert.Len(t, routes, 10)
 | 
				
			||||||
 | 
									want := types.Routes{
 | 
				
			||||||
 | 
										r(1, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										r(1, "::/0", true, true, false),
 | 
				
			||||||
 | 
										r(1, "10.9.110.0/24", true, true, true),
 | 
				
			||||||
 | 
										r(26, "172.100.100.0/24", true, true, true),
 | 
				
			||||||
 | 
										r(26, "172.100.100.0/24", true, false, false),
 | 
				
			||||||
 | 
										r(31, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										r(31, "0.0.0.0/0", true, false, false),
 | 
				
			||||||
 | 
										r(31, "::/0", true, true, false),
 | 
				
			||||||
 | 
										r(31, "::/0", true, false, false),
 | 
				
			||||||
 | 
										r(32, "192.168.0.24/32", true, true, true),
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if diff := cmp.Diff(want, routes, cmpopts.IgnoreFields(types.Route{}, "Model", "Node"), cmp.Comparer(func(x, y types.IPPrefix) bool {
 | 
				
			||||||
 | 
										return x == y
 | 
				
			||||||
 | 
									})); diff != "" {
 | 
				
			||||||
 | 
										t.Errorf("TestMigrations() mismatch (-want +got):\n%s", diff)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								dbPath: "testdata/0-22-3-to-0-23-0-routes-fail-foreign-key-2076.sqlite",
 | 
				
			||||||
 | 
								wantFunc: func(t *testing.T, h *HSDatabase) {
 | 
				
			||||||
 | 
									routes, err := Read(h.DB, func(rx *gorm.DB) (types.Routes, error) {
 | 
				
			||||||
 | 
										return GetRoutes(rx)
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									assert.NoError(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									assert.Len(t, routes, 4)
 | 
				
			||||||
 | 
									want := types.Routes{
 | 
				
			||||||
 | 
										// These routes exists, but have no nodes associated with them
 | 
				
			||||||
 | 
										// when the migration starts.
 | 
				
			||||||
 | 
										// r(1, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(1, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(3, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(3, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(5, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(5, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(6, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(6, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(6, "10.0.0.0/8", true, false, false),
 | 
				
			||||||
 | 
										// r(7, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(7, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(7, "10.0.0.0/8", true, false, false),
 | 
				
			||||||
 | 
										// r(9, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(9, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(9, "10.0.0.0/8", true, true, false),
 | 
				
			||||||
 | 
										// r(11, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(11, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(11, "10.0.0.0/8", true, true, true),
 | 
				
			||||||
 | 
										// r(12, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										// r(12, "::/0", true, true, false),
 | 
				
			||||||
 | 
										// r(12, "10.0.0.0/8", true, false, false),
 | 
				
			||||||
 | 
										//
 | 
				
			||||||
 | 
										// These nodes exists, so routes should be kept.
 | 
				
			||||||
 | 
										r(13, "10.0.0.0/8", true, false, false),
 | 
				
			||||||
 | 
										r(13, "0.0.0.0/0", true, true, false),
 | 
				
			||||||
 | 
										r(13, "::/0", true, true, false),
 | 
				
			||||||
 | 
										r(13, "10.18.80.2/32", true, true, true),
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if diff := cmp.Diff(want, routes, cmpopts.IgnoreFields(types.Route{}, "Model", "Node"), cmp.Comparer(func(x, y types.IPPrefix) bool {
 | 
				
			||||||
 | 
										return x == y
 | 
				
			||||||
 | 
									})); diff != "" {
 | 
				
			||||||
 | 
										t.Errorf("TestMigrations() mismatch (-want +got):\n%s", diff)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.dbPath, func(t *testing.T) {
 | 
				
			||||||
 | 
								dbPath, err := testCopyOfDatabase(tt.dbPath)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									t.Fatalf("copying db for test: %s", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hsdb, err := NewHeadscaleDatabase(types.DatabaseConfig{
 | 
				
			||||||
 | 
									Type: "sqlite3",
 | 
				
			||||||
 | 
									Sqlite: types.SqliteConfig{
 | 
				
			||||||
 | 
										Path: dbPath,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								}, "")
 | 
				
			||||||
 | 
								if err != nil && tt.wantErr != err.Error() {
 | 
				
			||||||
 | 
									t.Errorf("TestMigrations() unexpected error = %v, wantErr %v", err, tt.wantErr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if tt.wantFunc != nil {
 | 
				
			||||||
 | 
									tt.wantFunc(t, hsdb)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func testCopyOfDatabase(src string) (string, error) {
 | 
				
			||||||
 | 
						sourceFileStat, err := os.Stat(src)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !sourceFileStat.Mode().IsRegular() {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("%s is not a regular file", src)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						source, err := os.Open(src)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer source.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmpDir, err := os.MkdirTemp("", "hsdb-test-*")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn := filepath.Base(src)
 | 
				
			||||||
 | 
						dst := filepath.Join(tmpDir, fn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						destination, err := os.Create(dst)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer destination.Close()
 | 
				
			||||||
 | 
						_, err = io.Copy(destination, source)
 | 
				
			||||||
 | 
						return dst, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/netip"
 | 
						"net/netip"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/juanfont/headscale/hscontrol/types"
 | 
						"github.com/juanfont/headscale/hscontrol/types"
 | 
				
			||||||
@ -12,7 +13,6 @@ import (
 | 
				
			|||||||
	"github.com/patrickmn/go-cache"
 | 
						"github.com/patrickmn/go-cache"
 | 
				
			||||||
	"github.com/puzpuzpuz/xsync/v3"
 | 
						"github.com/puzpuzpuz/xsync/v3"
 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
	"github.com/sasha-s/go-deadlock"
 | 
					 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
	"tailscale.com/tailcfg"
 | 
						"tailscale.com/tailcfg"
 | 
				
			||||||
	"tailscale.com/types/key"
 | 
						"tailscale.com/types/key"
 | 
				
			||||||
@ -724,7 +724,7 @@ func ExpireExpiredNodes(tx *gorm.DB,
 | 
				
			|||||||
// It is used to delete ephemeral nodes that have disconnected and should be
 | 
					// It is used to delete ephemeral nodes that have disconnected and should be
 | 
				
			||||||
// cleaned up.
 | 
					// cleaned up.
 | 
				
			||||||
type EphemeralGarbageCollector struct {
 | 
					type EphemeralGarbageCollector struct {
 | 
				
			||||||
	mu deadlock.Mutex
 | 
						mu sync.Mutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deleteFunc  func(types.NodeID)
 | 
						deleteFunc  func(types.NodeID)
 | 
				
			||||||
	toBeDeleted map[types.NodeID]*time.Timer
 | 
						toBeDeleted map[types.NodeID]*time.Timer
 | 
				
			||||||
@ -752,10 +752,9 @@ func (e *EphemeralGarbageCollector) Close() {
 | 
				
			|||||||
// Schedule schedules a node for deletion after the expiry duration.
 | 
					// Schedule schedules a node for deletion after the expiry duration.
 | 
				
			||||||
func (e *EphemeralGarbageCollector) Schedule(nodeID types.NodeID, expiry time.Duration) {
 | 
					func (e *EphemeralGarbageCollector) Schedule(nodeID types.NodeID, expiry time.Duration) {
 | 
				
			||||||
	e.mu.Lock()
 | 
						e.mu.Lock()
 | 
				
			||||||
	defer e.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	timer := time.NewTimer(expiry)
 | 
						timer := time.NewTimer(expiry)
 | 
				
			||||||
	e.toBeDeleted[nodeID] = timer
 | 
						e.toBeDeleted[nodeID] = timer
 | 
				
			||||||
 | 
						e.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
 | 
				
			|||||||
@ -609,12 +609,14 @@ func TestEphemeralGarbageCollectorOrder(t *testing.T) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
	go e.Start()
 | 
						go e.Start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	e.Schedule(1, 1*time.Second)
 | 
						go e.Schedule(1, 1*time.Second)
 | 
				
			||||||
	e.Schedule(2, 2*time.Second)
 | 
						go e.Schedule(2, 2*time.Second)
 | 
				
			||||||
	e.Schedule(3, 3*time.Second)
 | 
						go e.Schedule(3, 3*time.Second)
 | 
				
			||||||
	e.Schedule(4, 4*time.Second)
 | 
						go e.Schedule(4, 4*time.Second)
 | 
				
			||||||
	e.Cancel(2)
 | 
					
 | 
				
			||||||
	e.Cancel(4)
 | 
						time.Sleep(time.Second)
 | 
				
			||||||
 | 
						go e.Cancel(2)
 | 
				
			||||||
 | 
						go e.Cancel(4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	time.Sleep(6 * time.Second)
 | 
						time.Sleep(6 * time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								hscontrol/db/testdata/0-22-3-to-0-23-0-routes-are-dropped-2063.sqlite
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								hscontrol/db/testdata/0-22-3-to-0-23-0-routes-are-dropped-2063.sqlite
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								hscontrol/db/testdata/0-22-3-to-0-23-0-routes-fail-foreign-key-2076.sqlite
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								hscontrol/db/testdata/0-22-3-to-0-23-0-routes-fail-foreign-key-2076.sqlite
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -4,7 +4,9 @@ import (
 | 
				
			|||||||
	"net/netip"
 | 
						"net/netip"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/go-cmp/cmp"
 | 
						"github.com/google/go-cmp/cmp"
 | 
				
			||||||
 | 
						"tailscale.com/types/ipproto"
 | 
				
			||||||
	"tailscale.com/types/key"
 | 
						"tailscale.com/types/key"
 | 
				
			||||||
 | 
						"tailscale.com/types/views"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var PrefixComparer = cmp.Comparer(func(x, y netip.Prefix) bool {
 | 
					var PrefixComparer = cmp.Comparer(func(x, y netip.Prefix) bool {
 | 
				
			||||||
@ -31,6 +33,8 @@ var DkeyComparer = cmp.Comparer(func(x, y key.DiscoPublic) bool {
 | 
				
			|||||||
	return x.String() == y.String()
 | 
						return x.String() == y.String()
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var ViewSliceIPProtoComparer = cmp.Comparer(func(a, b views.Slice[ipproto.Proto]) bool { return views.SliceEqual(a, b) })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Comparers []cmp.Option = []cmp.Option{
 | 
					var Comparers []cmp.Option = []cmp.Option{
 | 
				
			||||||
	IPComparer, PrefixComparer, AddrPortComparer, MkeyComparer, NkeyComparer, DkeyComparer,
 | 
						IPComparer, PrefixComparer, AddrPortComparer, MkeyComparer, NkeyComparer, DkeyComparer, ViewSliceIPProtoComparer,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1170,7 +1170,7 @@ func TestSubnetRouteACL(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if diff := cmp.Diff(wantClientFilter, clientNm.PacketFilter, util.PrefixComparer); diff != "" {
 | 
						if diff := cmp.Diff(wantClientFilter, clientNm.PacketFilter, util.ViewSliceIPProtoComparer, util.PrefixComparer); diff != "" {
 | 
				
			||||||
		t.Errorf("Client (%s) filter, unexpected result (-want +got):\n%s", client.Hostname(), diff)
 | 
							t.Errorf("Client (%s) filter, unexpected result (-want +got):\n%s", client.Hostname(), diff)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1220,7 +1220,7 @@ func TestSubnetRouteACL(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if diff := cmp.Diff(wantSubnetFilter, subnetNm.PacketFilter, util.PrefixComparer); diff != "" {
 | 
						if diff := cmp.Diff(wantSubnetFilter, subnetNm.PacketFilter, util.ViewSliceIPProtoComparer, util.PrefixComparer); diff != "" {
 | 
				
			||||||
		t.Errorf("Subnet (%s) filter, unexpected result (-want +got):\n%s", subRouter1.Hostname(), diff)
 | 
							t.Errorf("Subnet (%s) filter, unexpected result (-want +got):\n%s", subRouter1.Hostname(), diff)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user