Skip to content

Commit 267780c

Browse files
bassosimoneMurphy-OrangeMud
authored andcommitted
chore(model): add tests for ArchivalTLSOrQUICHandshakeResult (ooni#1322)
I am about to modify this structure to unconditionally use ArchivalBinaryData rather than ArchivalMaybeBinaryData, following the plan that I explained in ooni#1319. Before doing that, I want MORE test coverage for ArchivalTLSOrQUICHandshakeResult. Part of ooni/probe#2531
1 parent ecd945a commit 267780c

File tree

1 file changed

+208
-1
lines changed

1 file changed

+208
-1
lines changed

internal/model/archival_test.go

Lines changed: 208 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/google/go-cmp/cmp"
99
"github.com/google/go-cmp/cmp/cmpopts"
1010
"github.com/ooni/probe-cli/v3/internal/model"
11+
"github.com/ooni/probe-cli/v3/internal/netxlite"
1112
"github.com/ooni/probe-cli/v3/internal/testingx"
1213
)
1314

@@ -206,7 +207,7 @@ func TestArchivalBinaryData(t *testing.T) {
206207
err := json.Unmarshal(tc.input, &abd)
207208

208209
t.Log("got this error", err)
209-
t.Log("got this .Value filed", abd.Value)
210+
t.Log("got this .Value field", abd.Value)
210211
t.Logf("converted to string: %s", string(abd.Value))
211212

212213
// handle errors
@@ -565,3 +566,209 @@ func TestHTTPBody(t *testing.T) {
565566
t.Fatal(diff)
566567
}
567568
}
569+
570+
// This test ensures that ArchivalTLSOrQUICHandshakeResult is WAI
571+
func TestArchivalTLSOrQUICHandshakeResult(t *testing.T) {
572+
573+
// This test ensures that we correctly serialize to JSON.
574+
t.Run("MarshalJSON", func(t *testing.T) {
575+
// testcase is a test case defined by this function
576+
type testcase struct {
577+
// name is the name of the test case
578+
name string
579+
580+
// input is the input struct
581+
input model.ArchivalTLSOrQUICHandshakeResult
582+
583+
// expectErr is the error we expect to see or nil
584+
expectErr error
585+
586+
// expectData is the data we expect to see
587+
expectData []byte
588+
}
589+
590+
cases := []testcase{{
591+
name: "serialization of a successful TLS handshake",
592+
input: model.ArchivalTLSOrQUICHandshakeResult{
593+
Network: "tcp",
594+
Address: "8.8.8.8:443",
595+
CipherSuite: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
596+
Failure: nil,
597+
SoError: nil,
598+
NegotiatedProtocol: "http/1.1",
599+
NoTLSVerify: false,
600+
PeerCertificates: []model.ArchivalMaybeBinaryData{{
601+
Value: string(archivalBinaryInput),
602+
}},
603+
ServerName: "dns.google",
604+
T0: 1.0,
605+
T: 2.0,
606+
Tags: []string{"tls"},
607+
TLSVersion: "TLSv1.3",
608+
TransactionID: 14,
609+
},
610+
expectErr: nil,
611+
expectData: []byte(`{"network":"tcp","address":"8.8.8.8:443","cipher_suite":"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","failure":null,"negotiated_protocol":"http/1.1","no_tls_verify":false,"peer_certificates":[{"data":"V+V5+6a7DbzOvaeguqR4eBJZ7mg5pAeYxT68Vcv+NDx+G1qzIp3BLW7KW/EQJUceROItYAjqsArMBUig9Xg48Ns/nZ8lb4kAlpOvQ6xNyawT2yK+en3ZJKJSadiJwdFXqgQrotixGfbVETm7gM+G+V+djKv1xXQkOqLUQE7XEB8=","format":"base64"}],"server_name":"dns.google","t0":1,"t":2,"tags":["tls"],"tls_version":"TLSv1.3","transaction_id":14}`),
612+
}, {
613+
name: "serialization of a failed TLS handshake",
614+
input: model.ArchivalTLSOrQUICHandshakeResult{
615+
Network: "tcp",
616+
Address: "8.8.8.8:443",
617+
CipherSuite: "",
618+
Failure: (func() *string {
619+
s := netxlite.FailureConnectionReset
620+
return &s
621+
})(),
622+
SoError: (func() *string {
623+
s := "connection reset by peer"
624+
return &s
625+
})(),
626+
NegotiatedProtocol: "",
627+
NoTLSVerify: false,
628+
PeerCertificates: []model.ArchivalMaybeBinaryData{},
629+
ServerName: "dns.google",
630+
T0: 1.0,
631+
T: 2.0,
632+
Tags: []string{"tls"},
633+
TLSVersion: "",
634+
TransactionID: 4,
635+
},
636+
expectErr: nil,
637+
expectData: []byte(`{"network":"tcp","address":"8.8.8.8:443","cipher_suite":"","failure":"connection_reset","so_error":"connection reset by peer","negotiated_protocol":"","no_tls_verify":false,"peer_certificates":[],"server_name":"dns.google","t0":1,"t":2,"tags":["tls"],"tls_version":"","transaction_id":4}`),
638+
}}
639+
640+
for _, tc := range cases {
641+
t.Run(tc.name, func(t *testing.T) {
642+
// serialize to JSON
643+
data, err := json.Marshal(tc.input)
644+
645+
t.Log("got this error", err)
646+
t.Log("got this raw data", data)
647+
t.Logf("converted to string: %s", string(data))
648+
649+
// handle errors
650+
switch {
651+
case err == nil && tc.expectErr != nil:
652+
t.Fatal("expected", tc.expectErr, "got", err)
653+
654+
case err != nil && tc.expectErr == nil:
655+
t.Fatal("expected", tc.expectErr, "got", err)
656+
657+
case err != nil && tc.expectErr != nil:
658+
if err.Error() != tc.expectErr.Error() {
659+
t.Fatal("expected", tc.expectErr, "got", err)
660+
}
661+
662+
case err == nil && tc.expectErr == nil:
663+
// all good--fallthrough
664+
}
665+
666+
// make sure the serialization is OK
667+
if diff := cmp.Diff(tc.expectData, data); diff != "" {
668+
t.Fatal(diff)
669+
}
670+
})
671+
}
672+
})
673+
674+
// This test ensures that we can unmarshal from the JSON representation
675+
t.Run("UnmarshalJSON", func(t *testing.T) {
676+
// testcase is a test case defined by this function
677+
type testcase struct {
678+
// name is the name of the test case
679+
name string
680+
681+
// input is the binary input
682+
input []byte
683+
684+
// expectErr is the error we expect to see or nil
685+
expectErr error
686+
687+
// expectStruct is the struct we expect to see
688+
expectStruct model.ArchivalTLSOrQUICHandshakeResult
689+
}
690+
691+
cases := []testcase{{
692+
name: "deserialization of a successful TLS handshake",
693+
expectErr: nil,
694+
input: []byte(`{"network":"tcp","address":"8.8.8.8:443","cipher_suite":"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","failure":null,"negotiated_protocol":"http/1.1","no_tls_verify":false,"peer_certificates":[{"data":"V+V5+6a7DbzOvaeguqR4eBJZ7mg5pAeYxT68Vcv+NDx+G1qzIp3BLW7KW/EQJUceROItYAjqsArMBUig9Xg48Ns/nZ8lb4kAlpOvQ6xNyawT2yK+en3ZJKJSadiJwdFXqgQrotixGfbVETm7gM+G+V+djKv1xXQkOqLUQE7XEB8=","format":"base64"}],"server_name":"dns.google","t0":1,"t":2,"tags":["tls"],"tls_version":"TLSv1.3","transaction_id":14}`),
695+
expectStruct: model.ArchivalTLSOrQUICHandshakeResult{
696+
Network: "tcp",
697+
Address: "8.8.8.8:443",
698+
CipherSuite: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
699+
Failure: nil,
700+
SoError: nil,
701+
NegotiatedProtocol: "http/1.1",
702+
NoTLSVerify: false,
703+
PeerCertificates: []model.ArchivalMaybeBinaryData{{
704+
Value: string(archivalBinaryInput),
705+
}},
706+
ServerName: "dns.google",
707+
T0: 1.0,
708+
T: 2.0,
709+
Tags: []string{"tls"},
710+
TLSVersion: "TLSv1.3",
711+
TransactionID: 14,
712+
},
713+
}, {
714+
name: "deserialization of a failed TLS handshake",
715+
input: []byte(`{"network":"tcp","address":"8.8.8.8:443","cipher_suite":"","failure":"connection_reset","so_error":"connection reset by peer","negotiated_protocol":"","no_tls_verify":false,"peer_certificates":[],"server_name":"dns.google","t0":1,"t":2,"tags":["tls"],"tls_version":"","transaction_id":4}`),
716+
expectErr: nil,
717+
expectStruct: model.ArchivalTLSOrQUICHandshakeResult{
718+
Network: "tcp",
719+
Address: "8.8.8.8:443",
720+
CipherSuite: "",
721+
Failure: (func() *string {
722+
s := netxlite.FailureConnectionReset
723+
return &s
724+
})(),
725+
SoError: (func() *string {
726+
s := "connection reset by peer"
727+
return &s
728+
})(),
729+
NegotiatedProtocol: "",
730+
NoTLSVerify: false,
731+
PeerCertificates: []model.ArchivalMaybeBinaryData{},
732+
ServerName: "dns.google",
733+
T0: 1.0,
734+
T: 2.0,
735+
Tags: []string{"tls"},
736+
TLSVersion: "",
737+
TransactionID: 4,
738+
},
739+
}}
740+
741+
for _, tc := range cases {
742+
t.Run(tc.name, func(t *testing.T) {
743+
// parse the JSON
744+
var data model.ArchivalTLSOrQUICHandshakeResult
745+
err := json.Unmarshal(tc.input, &data)
746+
747+
t.Log("got this error", err)
748+
t.Logf("got this struct %+v", data)
749+
750+
// handle errors
751+
switch {
752+
case err == nil && tc.expectErr != nil:
753+
t.Fatal("expected", tc.expectErr, "got", err)
754+
755+
case err != nil && tc.expectErr == nil:
756+
t.Fatal("expected", tc.expectErr, "got", err)
757+
758+
case err != nil && tc.expectErr != nil:
759+
if err.Error() != tc.expectErr.Error() {
760+
t.Fatal("expected", tc.expectErr, "got", err)
761+
}
762+
763+
case err == nil && tc.expectErr == nil:
764+
// all good--fallthrough
765+
}
766+
767+
// make sure the deserialization is OK
768+
if diff := cmp.Diff(tc.expectStruct, data); diff != "" {
769+
t.Fatal(diff)
770+
}
771+
})
772+
}
773+
})
774+
}

0 commit comments

Comments
 (0)