mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-18 14:47:03 +00:00
test: Add small miscellaneous tests
This patch extends various packages and integration tests, increasing test coverage. They're small enough that it's not worth splitting them up, as it would add a lot of noise to the history.
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"blitiri.com.ar/go/chasquid/internal/testlib"
|
"blitiri.com.ar/go/chasquid/internal/testlib"
|
||||||
|
"blitiri.com.ar/go/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustCreateConfig(t *testing.T, contents string) (string, string) {
|
func mustCreateConfig(t *testing.T, contents string) (string, string) {
|
||||||
@@ -50,6 +52,7 @@ func TestEmptyConfig(t *testing.T) {
|
|||||||
t.Errorf("monitoring address is set: %v", c.MonitoringAddress)
|
t.Errorf("monitoring address is set: %v", c.MonitoringAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testLogConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFullConfig(t *testing.T) {
|
func TestFullConfig(t *testing.T) {
|
||||||
@@ -85,6 +88,8 @@ func TestFullConfig(t *testing.T) {
|
|||||||
if c.MonitoringAddress != ":1111" {
|
if c.MonitoringAddress != ":1111" {
|
||||||
t.Errorf("monitoring address %q != ':1111;", c.MonitoringAddress)
|
t.Errorf("monitoring address %q != ':1111;", c.MonitoringAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testLogConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorLoading(t *testing.T) {
|
func TestErrorLoading(t *testing.T) {
|
||||||
@@ -104,3 +109,17 @@ func TestBrokenConfig(t *testing.T) {
|
|||||||
t.Fatalf("loaded an invalid config: %v", c)
|
t.Fatalf("loaded an invalid config: %v", c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run LogConfig, overriding the default logger first. This exercises the
|
||||||
|
// code, we don't yet validate the output, but it is an useful sanity check.
|
||||||
|
func testLogConfig(c *Config) {
|
||||||
|
l := log.New(nopWCloser{ioutil.Discard})
|
||||||
|
log.Default = l
|
||||||
|
LogConfig(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
type nopWCloser struct {
|
||||||
|
io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nopWCloser) Close() error { return nil }
|
||||||
|
|||||||
@@ -78,11 +78,10 @@ func TestAddr(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%q error: %v", c.user, err)
|
t.Errorf("%q error: %v", c.user, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid := []string{
|
invalid := []string{
|
||||||
"á é@i", "henry\u2163@throne",
|
"á é@i", "henry\u2163@throne", "a@xn---",
|
||||||
}
|
}
|
||||||
for _, u := range invalid {
|
for _, u := range invalid {
|
||||||
nu, err := Addr(u)
|
nu, err := Addr(u)
|
||||||
@@ -94,3 +93,38 @@ func TestAddr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDomainToUnicode(t *testing.T) {
|
||||||
|
valid := []struct{ domain, expected string }{
|
||||||
|
{"<>", "<>"},
|
||||||
|
{"a@b", "a@b"},
|
||||||
|
{"a@Ñ", "a@ñ"},
|
||||||
|
{"xn--lca@xn--lca", "xn--lca@ñ"}, // Punycode is for 'Ñ'.
|
||||||
|
{"a@e\u0301", "a@é"}, // Transform to NFC form.
|
||||||
|
|
||||||
|
// Degenerate case, we don't expect to ever produce this; at least
|
||||||
|
// check it does not crash.
|
||||||
|
{"", "@"},
|
||||||
|
}
|
||||||
|
for _, c := range valid {
|
||||||
|
got, err := DomainToUnicode(c.domain)
|
||||||
|
if got != c.expected {
|
||||||
|
t.Errorf("DomainToUnicode(%q) = %q, expected %q",
|
||||||
|
c.domain, got, c.expected)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("DomainToUnicode(%q) error: %v", c.domain, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invalid := []string{"a@xn---", "a@xn--xyz-ñ"}
|
||||||
|
for _, u := range invalid {
|
||||||
|
got, err := DomainToUnicode(u)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected DomainToUnicode(%+q) to fail, but did not", u)
|
||||||
|
}
|
||||||
|
if got != u {
|
||||||
|
t.Errorf("%+q failed norm, but returned %+q", u, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package protoio
|
package protoio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"blitiri.com.ar/go/chasquid/internal/protoio/testpb"
|
"blitiri.com.ar/go/chasquid/internal/protoio/testpb"
|
||||||
@@ -73,6 +74,15 @@ func TestStore(t *testing.T) {
|
|||||||
t.Errorf("Get(notexists): %v - %v", ok, err)
|
t.Errorf("Get(notexists): %v - %v", ok, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add an extraneous file, which ListIDs should ignore.
|
||||||
|
fd, err := os.Create(dir + "/store/" + "somefile")
|
||||||
|
if fd != nil {
|
||||||
|
fd.Close()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create extraneous file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if ids, err := st.ListIDs(); len(ids) != 1 || ids[0] != "f" || err != nil {
|
if ids, err := st.ListIDs(); len(ids) != 1 || ids[0] != "f" || err != nil {
|
||||||
t.Errorf("expected [f], got %v - %v", ids, err)
|
t.Errorf("expected [f], got %v - %v", ids, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import (
|
|||||||
"blitiri.com.ar/go/log"
|
"blitiri.com.ar/go/log"
|
||||||
|
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
"github.com/golang/protobuf/ptypes/timestamp"
|
|
||||||
"golang.org/x/net/idna"
|
"golang.org/x/net/idna"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -481,12 +480,6 @@ func nextDelay(createdAt time.Time) time.Duration {
|
|||||||
return delay
|
return delay
|
||||||
}
|
}
|
||||||
|
|
||||||
func timestampNow() *timestamp.Timestamp {
|
|
||||||
now := time.Now()
|
|
||||||
ts, _ := ptypes.TimestampProto(now)
|
|
||||||
return ts
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustIDNAToASCII(s string) string {
|
func mustIDNAToASCII(s string) string {
|
||||||
a, err := idna.ToASCII(s)
|
a, err := idna.ToASCII(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ func TestDSNOnTimeout(t *testing.T) {
|
|||||||
t.Errorf("failed to write item: %v", err)
|
t.Errorf("failed to write item: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exercise DumpString while at it.
|
||||||
|
q.DumpString()
|
||||||
|
|
||||||
// Launch the sending loop, expect 1 local delivery (the DSN).
|
// Launch the sending loop, expect 1 local delivery (the DSN).
|
||||||
localC.wg.Add(1)
|
localC.wg.Add(1)
|
||||||
go item.SendLoop(q)
|
go item.SendLoop(q)
|
||||||
@@ -296,3 +299,43 @@ func TestNextDelay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSerialization(t *testing.T) {
|
||||||
|
dir := testlib.MustTempDir(t)
|
||||||
|
defer testlib.RemoveIfOk(t, dir)
|
||||||
|
|
||||||
|
// Save an item in the queue directory.
|
||||||
|
item := &Item{
|
||||||
|
Message: Message{
|
||||||
|
ID: <-newID,
|
||||||
|
From: fmt.Sprintf("from@loco"),
|
||||||
|
Rcpt: []*Recipient{
|
||||||
|
{"to@to", Recipient_EMAIL, Recipient_PENDING, "err", "to@to"}},
|
||||||
|
Data: []byte("data"),
|
||||||
|
},
|
||||||
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
||||||
|
}
|
||||||
|
err := item.WriteTo(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to write item: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the queue; should load the
|
||||||
|
remoteC := newTestCourier()
|
||||||
|
remoteC.wg.Add(1)
|
||||||
|
q := New(dir, set.NewString("loco"), aliases.NewResolver(),
|
||||||
|
dumbCourier, remoteC)
|
||||||
|
q.Load()
|
||||||
|
|
||||||
|
// Launch the sending loop, expect 1 remote delivery for the item we saved.
|
||||||
|
remoteC.wg.Wait()
|
||||||
|
|
||||||
|
req := remoteC.reqFor["to@to"]
|
||||||
|
if req == nil {
|
||||||
|
t.Fatal("email not delivered")
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.from != "from@loco" || req.to != "to@to" {
|
||||||
|
t.Errorf("wrong email: %v", req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
37
internal/tlsconst/tlsconst_test.go
Normal file
37
internal/tlsconst/tlsconst_test.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package tlsconst
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestVersionName(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
ver uint16
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{0x0302, "TLS-1.1"},
|
||||||
|
{0x1234, "TLS-0x1234"},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
got := VersionName(c.ver)
|
||||||
|
if got != c.expected {
|
||||||
|
t.Errorf("VersionName(%x) = %q, expected %q",
|
||||||
|
c.ver, got, c.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCipherSuiteName(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
suite uint16
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{0xc073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"},
|
||||||
|
{0x1234, "TLS_UNKNOWN_CIPHER_SUITE-0x1234"},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
got := CipherSuiteName(c.suite)
|
||||||
|
if got != c.expected {
|
||||||
|
t.Errorf("CipherSuiteName(%x) = %q, expected %q",
|
||||||
|
c.suite, got, c.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,10 @@ set -e
|
|||||||
|
|
||||||
init
|
init
|
||||||
|
|
||||||
|
if ! chasquid --version > /dev/null; then
|
||||||
|
fail "chasquid --version failed"
|
||||||
|
fi
|
||||||
|
|
||||||
# This should fail, as it has no certificates.
|
# This should fail, as it has no certificates.
|
||||||
rm -f config/certs/testserver/*.pem
|
rm -f config/certs/testserver/*.pem
|
||||||
if chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config; then
|
if chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config; then
|
||||||
|
|||||||
Reference in New Issue
Block a user