github.com/decred/dcrlnd@v0.7.6/feature/manager_internal_test.go (about)

     1  package feature
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/decred/dcrlnd/lnwire"
     8  )
     9  
    10  type managerTest struct {
    11  	name string
    12  	cfg  Config
    13  }
    14  
    15  const unknownFeature lnwire.FeatureBit = 30
    16  
    17  var testSetDesc = setDesc{
    18  	lnwire.DataLossProtectRequired: {
    19  		SetNodeAnn: {}, // I
    20  	},
    21  	lnwire.TLVOnionPayloadOptional: {
    22  		SetInit:    {}, // I
    23  		SetNodeAnn: {}, // N
    24  	},
    25  	lnwire.StaticRemoteKeyOptional: {
    26  		SetInit:    {}, // I
    27  		SetNodeAnn: {}, // N
    28  	},
    29  }
    30  
    31  var managerTests = []managerTest{
    32  	{
    33  		name: "default",
    34  		cfg:  Config{},
    35  	},
    36  	{
    37  		name: "no tlv",
    38  		cfg: Config{
    39  			NoTLVOnion: true,
    40  		},
    41  	},
    42  	{
    43  		name: "no static remote key",
    44  		cfg: Config{
    45  			NoStaticRemoteKey: true,
    46  		},
    47  	},
    48  	{
    49  		name: "no tlv or static remote key",
    50  		cfg: Config{
    51  			NoTLVOnion:        true,
    52  			NoStaticRemoteKey: true,
    53  		},
    54  	},
    55  	{
    56  		name: "anchors should disable anything dependent on it",
    57  		cfg: Config{
    58  			NoAnchors: true,
    59  		},
    60  	},
    61  }
    62  
    63  // TestManager asserts basic initialazation and operation of a feature manager,
    64  // including that the proper features are removed in response to config changes.
    65  func TestManager(t *testing.T) {
    66  	for _, test := range managerTests {
    67  		test := test
    68  		t.Run(test.name, func(t *testing.T) {
    69  			testManager(t, test)
    70  		})
    71  	}
    72  }
    73  
    74  func testManager(t *testing.T, test managerTest) {
    75  	m, err := newManager(test.cfg, testSetDesc)
    76  	if err != nil {
    77  		t.Fatalf("unable to create feature manager: %v", err)
    78  	}
    79  
    80  	sets := []Set{
    81  		SetInit,
    82  		SetLegacyGlobal,
    83  		SetNodeAnn,
    84  		SetInvoice,
    85  	}
    86  
    87  	for _, set := range sets {
    88  		raw := m.GetRaw(set)
    89  		fv := m.Get(set)
    90  
    91  		fv2 := lnwire.NewFeatureVector(raw, lnwire.Features)
    92  
    93  		if !reflect.DeepEqual(fv, fv2) {
    94  			t.Fatalf("mismatch Get vs GetRaw, raw: %v vs fv: %v",
    95  				fv2, fv)
    96  		}
    97  
    98  		assertUnset := func(bit lnwire.FeatureBit) {
    99  			hasBit := fv.HasFeature(bit) || fv.HasFeature(bit^1)
   100  			if hasBit {
   101  				t.Fatalf("bit %v or %v is set", bit, bit^1)
   102  			}
   103  		}
   104  
   105  		// Assert that the manager properly unset the configured feature
   106  		// bits from all sets.
   107  		if test.cfg.NoTLVOnion {
   108  			assertUnset(lnwire.TLVOnionPayloadOptional)
   109  		}
   110  		if test.cfg.NoStaticRemoteKey {
   111  			assertUnset(lnwire.StaticRemoteKeyOptional)
   112  		}
   113  		if test.cfg.NoAnchors {
   114  			assertUnset(lnwire.ScriptEnforcedLeaseRequired)
   115  			assertUnset(lnwire.ScriptEnforcedLeaseOptional)
   116  		}
   117  
   118  		assertUnset(unknownFeature)
   119  	}
   120  
   121  	// Do same basic sanity checks on features that are always present.
   122  	nodeFeatures := m.Get(SetNodeAnn)
   123  
   124  	assertSet := func(bit lnwire.FeatureBit) {
   125  		has := nodeFeatures.HasFeature(bit)
   126  		if !has {
   127  			t.Fatalf("node features don't advertised %v", bit)
   128  		}
   129  	}
   130  
   131  	assertSet(lnwire.DataLossProtectOptional)
   132  	if !test.cfg.NoTLVOnion {
   133  		assertSet(lnwire.TLVOnionPayloadRequired)
   134  	}
   135  	if !test.cfg.NoStaticRemoteKey {
   136  		assertSet(lnwire.StaticRemoteKeyOptional)
   137  	}
   138  }