Skip to content

Commit 338b5f3

Browse files
committed
100% coverage
Signed-off-by: hfuss <[email protected]>
1 parent 4bce3f4 commit 338b5f3

File tree

3 files changed

+144
-19
lines changed

3 files changed

+144
-19
lines changed

internal/dataexchange/ffdx/ffdx.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,15 @@ func (h *FFDX) TransferBlob(ctx context.Context, nsOpID string, peer, sender fft
466466
}
467467

468468
func (h *FFDX) CheckNodeIdentityStatus(ctx context.Context, dxPeer fftypes.JSONObject, node *core.Identity) error {
469-
if err := h.checkInitialized(h.ctx); err != nil {
469+
if err := h.checkInitialized(ctx); err != nil {
470470
return err
471471
}
472+
var mismatchState = metrics.NodeIdentityDXCertMismatchStatusUnknown
473+
defer func() {
474+
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
475+
h.metrics.NodeIdentityDXCertMismatch(node.Namespace, mismatchState)
476+
}
477+
}()
472478

473479
if dxPeer.GetString("cert") == "" {
474480
log.L(ctx).Warnf("DX peer does not have a 'cert', DX plugin may be unsupported")
@@ -479,20 +485,15 @@ func (h *FFDX) CheckNodeIdentityStatus(ctx context.Context, dxPeer fftypes.JSONO
479485
return i18n.NewError(ctx, coremsgs.MsgDXInfoMissingID) // TODO
480486
}
481487

482-
var mismatchState = metrics.NodeIdentityDXCertMismatchStatusUnknown
483-
defer func() {
484-
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
485-
h.metrics.NodeIdentityDXCertMismatch(node.Namespace, mismatchState)
486-
}
487-
}()
488-
489488
mismatchState = metrics.NodeIdentityDXCertMismatchStatusHealthy
490489
if dxPeer.GetString("cert") != node.Profile.GetString("cert") {
491490
mismatchState = metrics.NodeIdentityDXCertMismatchStatusMismatched
492491
}
493492

494493
if h.metrics != nil && h.metrics.IsMetricsEnabled() {
495-
expiry, err := extractSoonestExpiryFromCertBundle(dxPeer.GetString("cert"))
494+
h.metrics.NodeIdentityDXCertMismatch(node.Namespace, mismatchState)
495+
496+
expiry, err := extractSoonestExpiryFromCertBundle(strings.ReplaceAll(dxPeer.GetString("cert"), `\n`, "\n"))
496497
if err == nil {
497498
if expiry.Before(time.Now()) {
498499
log.L(ctx).Warnf("Certificate for node '%s' has expired", node.Name)

internal/dataexchange/ffdx/ffdx_test.go

Lines changed: 132 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ import (
2222
"encoding/json"
2323
"errors"
2424
"fmt"
25+
"github.com/hyperledger/firefly/internal/metrics"
2526
"io/ioutil"
2627
"net/http"
2728
"net/url"
29+
"strings"
2830
"testing"
31+
"time"
2932

3033
"github.com/hyperledger/firefly/mocks/metricsmocks"
3134

@@ -49,6 +52,8 @@ import (
4952
var utConfig = config.RootSection("ffdx_unit_tests")
5053

5154
const (
55+
// NOTE: the CA cert expires on Monday, February 28, 2035 7:30:57 PM,
56+
// and the leaf cert expires on Monday, February 28, 2028 7:30:57 PM
5257
testCertBundle = `
5358
-----BEGIN CERTIFICATE-----
5459
MIIDqTCCApGgAwIBAgIUbZT+Ds4f2oDmGpgVi+SaQq9gxvcwDQYJKoZIhvcNAQEL
@@ -94,6 +99,30 @@ rNTfiFZbc7eHmFRTkKXWW4j6b6ElygrBvV999BhCRNf6NS0/syjqsbALHkFGeIcl
9499
R0gnXX/IZFnLhLh6UpLOBB0KIGENh75EEU7755jMKDKFj16D0uA1Lzrh5YxicTMy
95100
ydFYQLpLycsWl2oV3JB4pO5TIzjY9awkRE0MeMMc
96101
-----END CERTIFICATE-----
102+
`
103+
testExpiredCert = `
104+
-----BEGIN CERTIFICATE-----
105+
MIIDqjCCApKgAwIBAgIUWnobAQ4vq8gWBAXZBf7XZG3oSicwDQYJKoZIhvcNAQEL
106+
BQAwZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
107+
DVNhbiBGcmFuY2lzY28xEzARBgNVBAoMCkV4YW1wbGUgQ0ExEzARBgNVBAMMCmV4
108+
YW1wbGUtY2EwHhcNMjUwMzAyMTQxNDA1WhcNMjUwMzAyMTQxNDA1WjB2MQswCQYD
109+
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j
110+
aXNjbzEcMBoGA1UECgwTSHlwZXJsZWRnZXIgRmlyZWZseTEcMBoGA1UEAwwTaHlw
111+
ZXJsZWRnZXItZmlyZWZseTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
112+
AKlbQ+7cWWS0+QPp03PrdxsnAAtG2tWOk2CEG7HS3AlBU82YImhCidKOw+jQPS68
113+
2f2d0tYBhugqB2Ki6HsfYMGTjHDLbUQ5y+cLk6PFbvhjm39Ayd+WGmhWht5qFtRN
114+
gllTa/SbG8+iGaSPIVFCyvg1IzxsFnBGn+05Gu+KjpL4i0l1RqDmy5ItxKGP77in
115+
RPEUkejiUozg/X3v2TWAGagIVF5+EQ2Cswot9W1faAvyu/QmSGLLfSH22GdEDHXa
116+
U4DV5ArJ2U2eNkOuasSWGKBopa/Wh1SZjKrNsy5Gw84ihAI4k7ARoP+vu1dIPdaX
117+
ElipmGMtUWu0Azn2l9QJZpMCAwEAAaNCMEAwHQYDVR0OBBYEFL798jEmX2+hw70t
118+
SmfJA78PZnnHMB8GA1UdIwQYMBaAFJfNoXmIn5S6W7Lcj5G/huW5q1YQMA0GCSqG
119+
SIb3DQEBCwUAA4IBAQA1dY8UCf1YSLG3Vu/u20ucw5q9tnYYoTi4fHm/g+imTvEQ
120+
KgTQBd5s9EHmj0BSjVFy9eSSTx5XiH6JqzGhCJRSbOIQ8RwrXpUlTuLr7gp0cO9c
121+
Ykxz6wt0k1F+9Iq+K8Eb6jzXoZe/ebMz611zUqY7+9lIl1AIIgx96MoZcDS/LA0e
122+
p/TUQ6q+Mg3W9pSXqLm8jmWNBfDViQF1v9Z3ASFYHUF/yak8jMdBEUpAqDadd/ay
123+
BHm9m8IvFevQjpUw6kyyg77ehEBBn7H/ISTL3HTCpUbkR3qUnFjOyBJ0G02XoozB
124+
I/hI0mpd6y+/JwyvG0smbD2lioiO/JQaUEZGU8pU
125+
-----END CERTIFICATE-----
97126
`
98127
)
99128

@@ -1047,16 +1076,109 @@ BAYTAkFVMRMwEQYDVQQIDApxdWVlbnNsYW5kMREwDwYDVQQHDAhCcm9va2ZpZWxk
10471076

10481077
_, err := extractSoonestExpiryFromCertBundle(nonCertPEMBundle)
10491078
assert.ErrorContains(t, err, "failed to parse non-certificate within bundle")
1079+
}
10501080

1081+
func TestCheckNodeIdentityStatusReturnsErrorWhenNotInitialized(t *testing.T) {
1082+
h := &FFDX{initialized: false}
1083+
err := h.CheckNodeIdentityStatus(context.Background(), fftypes.JSONObject{}, &core.Identity{})
1084+
assert.Regexp(t, "FF10342", err)
10511085
}
10521086

1053-
//
1054-
//matchingProfile := fftypes.JSONAnyPtr(fmt.Sprintf(`{"cert": "%s" }`, strings.ReplaceAll(testCertBundle, "\n", `\n`))).JSONObject()
1055-
//
1056-
//nm.identity.(*identitymanagermocks.Manager).On("GetLocalNode", ctx).Return(&core.Identity{
1057-
//IdentityProfile: core.IdentityProfile{
1058-
//Profile: matchingProfile,
1059-
//},
1060-
//}, nil)
1061-
//
1062-
//expiry := time.Unix(1835379057, 0).UTC()
1087+
func TestCheckNodeIdentityStatusReturnsNilWhenCertIsEmpty(t *testing.T) {
1088+
mmm := metricsmocks.NewManager(t)
1089+
1090+
h := &FFDX{initialized: true, metrics: mmm}
1091+
dxPeer := fftypes.JSONObject{"cert": ""}
1092+
node := &core.Identity{
1093+
IdentityBase: core.IdentityBase{
1094+
Namespace: "ns1",
1095+
},
1096+
}
1097+
1098+
mmm.On("IsMetricsEnabled").Return(true)
1099+
mmm.On("NodeIdentityDXCertMismatch", "ns1", metrics.NodeIdentityDXCertMismatchStatusUnknown).Return(true)
1100+
1101+
err := h.CheckNodeIdentityStatus(context.Background(), dxPeer, node)
1102+
assert.NoError(t, err)
1103+
}
1104+
1105+
func TestCheckNodeIdentityStatusReturnsErrorWhenNodeProfileIsNil(t *testing.T) {
1106+
mmm := metricsmocks.NewManager(t)
1107+
1108+
h := &FFDX{initialized: true, metrics: mmm}
1109+
dxPeer := fftypes.JSONObject{"cert": "cert"}
1110+
node := &core.Identity{
1111+
IdentityBase: core.IdentityBase{
1112+
Namespace: "ns1",
1113+
},
1114+
}
1115+
mmm.On("IsMetricsEnabled").Return(false)
1116+
1117+
err := h.CheckNodeIdentityStatus(context.Background(), dxPeer, node)
1118+
assert.Error(t, err)
1119+
//assert.Equal(t, coremsgs.MsgDXInfoMissingID, err.(*i18n.Error).ID)
1120+
}
1121+
1122+
func TestCheckNodeIdentityStatusSetsMismatchStateWhenCertsDiffer(t *testing.T) {
1123+
1124+
mmm := &metricsmocks.Manager{}
1125+
h := &FFDX{initialized: true, metrics: mmm}
1126+
dxPeer := fftypes.JSONObject{"cert": "a-cert"}
1127+
node := &core.Identity{
1128+
IdentityBase: core.IdentityBase{
1129+
Namespace: "ns1",
1130+
},
1131+
IdentityProfile: core.IdentityProfile{
1132+
Profile: fftypes.JSONObject{"cert": "b-cert"},
1133+
},
1134+
}
1135+
1136+
mmm.On("IsMetricsEnabled").Return(true)
1137+
mmm.On("NodeIdentityDXCertMismatch", "ns1", metrics.NodeIdentityDXCertMismatchStatusMismatched).Return(true)
1138+
err := h.CheckNodeIdentityStatus(context.Background(), dxPeer, node)
1139+
assert.NoError(t, err)
1140+
}
1141+
1142+
func TestCheckNodeIdentityStatusSetsHealthyStateWhenCertsMatch(t *testing.T) {
1143+
mmm := metricsmocks.NewManager(t)
1144+
h := &FFDX{initialized: true, metrics: mmm}
1145+
dxPeer := fftypes.JSONObject{"cert": strings.ReplaceAll(testCertBundle, "\n", `\n`)}
1146+
node := &core.Identity{
1147+
IdentityBase: core.IdentityBase{
1148+
Namespace: "ns1",
1149+
},
1150+
IdentityProfile: core.IdentityProfile{
1151+
Profile: fftypes.JSONObject{"cert": strings.ReplaceAll(testCertBundle, "\n", `\n`)},
1152+
},
1153+
}
1154+
1155+
mmm.On("IsMetricsEnabled").Return(true)
1156+
mmm.On("NodeIdentityDXCertMismatch", "ns1", metrics.NodeIdentityDXCertMismatchStatusHealthy).Return(true)
1157+
expiry := time.Unix(1835379057, 0).UTC()
1158+
mmm.On("NodeIdentityDXCertExpiry", "ns1", expiry).Return(true)
1159+
1160+
err := h.CheckNodeIdentityStatus(context.Background(), dxPeer, node)
1161+
assert.NoError(t, err)
1162+
}
1163+
1164+
func TestCheckNodeIdentityStatusSetsHealthyStateWhenCertsExpire(t *testing.T) {
1165+
mmm := metricsmocks.NewManager(t)
1166+
h := &FFDX{initialized: true, metrics: mmm}
1167+
dxPeer := fftypes.JSONObject{"cert": strings.ReplaceAll(testExpiredCert, "\n", `\n`)}
1168+
node := &core.Identity{
1169+
IdentityBase: core.IdentityBase{
1170+
Namespace: "ns1",
1171+
},
1172+
IdentityProfile: core.IdentityProfile{
1173+
Profile: fftypes.JSONObject{"cert": strings.ReplaceAll(testExpiredCert, "\n", `\n`)},
1174+
},
1175+
}
1176+
1177+
mmm.On("IsMetricsEnabled").Return(true)
1178+
mmm.On("NodeIdentityDXCertMismatch", "ns1", metrics.NodeIdentityDXCertMismatchStatusHealthy).Return(true)
1179+
expiry := time.Unix(1740924845, 0).UTC()
1180+
mmm.On("NodeIdentityDXCertExpiry", "ns1", expiry).Return(true)
1181+
1182+
err := h.CheckNodeIdentityStatus(context.Background(), dxPeer, node)
1183+
assert.NoError(t, err)
1184+
}

internal/networkmap/update_identity.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ func (nm *networkMap) UpdateIdentity(ctx context.Context, uuidStr string, dto *c
3131
return nil, err
3232
}
3333
return nm.updateIdentityID(ctx, id, dto, waitConfirm)
34+
35+
// TODO check node status if its the same as our local node ??
3436
}
3537

3638
func (nm *networkMap) updateIdentityID(ctx context.Context, id *fftypes.UUID, dto *core.IdentityUpdateDTO, waitConfirm bool) (identity *core.Identity, err error) {

0 commit comments

Comments
 (0)