git » chasquid » commit 0611b7a

test: Add small miscellaneous tests

author Alberto Bertogli
2018-03-02 16:14:10 UTC
committer Alberto Bertogli
2018-03-02 19:37:37 UTC
parent d80c76f7464148a22fb56ce894e46530b697213a

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.

internal/config/config_test.go +19 -0
internal/normalize/normalize_test.go +36 -2
internal/protoio/protoio_test.go +10 -0
internal/queue/queue.go +0 -7
internal/queue/queue_test.go +43 -0
internal/tlsconst/tlsconst_test.go +37 -0
test/t-01-simple_local/run.sh +4 -0

diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index c871457..7b6dfc1 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -1,11 +1,13 @@
 package config
 
 import (
+	"io"
 	"io/ioutil"
 	"os"
 	"testing"
 
 	"blitiri.com.ar/go/chasquid/internal/testlib"
+	"blitiri.com.ar/go/log"
 )
 
 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)
 	}
 
+	testLogConfig(c)
 }
 
 func TestFullConfig(t *testing.T) {
@@ -85,6 +88,8 @@ func TestFullConfig(t *testing.T) {
 	if c.MonitoringAddress != ":1111" {
 		t.Errorf("monitoring address %q != ':1111;", c.MonitoringAddress)
 	}
+
+	testLogConfig(c)
 }
 
 func TestErrorLoading(t *testing.T) {
@@ -104,3 +109,17 @@ func TestBrokenConfig(t *testing.T) {
 		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 }
diff --git a/internal/normalize/normalize_test.go b/internal/normalize/normalize_test.go
index dd59a29..bc3a2ec 100644
--- a/internal/normalize/normalize_test.go
+++ b/internal/normalize/normalize_test.go
@@ -78,11 +78,10 @@ func TestAddr(t *testing.T) {
 		if err != nil {
 			t.Errorf("%q error: %v", c.user, err)
 		}
-
 	}
 
 	invalid := []string{
-		"á é@i", "henry\u2163@throne",
+		"á é@i", "henry\u2163@throne", "a@xn---",
 	}
 	for _, u := range invalid {
 		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)
+		}
+	}
+}
diff --git a/internal/protoio/protoio_test.go b/internal/protoio/protoio_test.go
index 32e79e6..c827a84 100644
--- a/internal/protoio/protoio_test.go
+++ b/internal/protoio/protoio_test.go
@@ -1,6 +1,7 @@
 package protoio
 
 import (
+	"os"
 	"testing"
 
 	"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)
 	}
 
+	// 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 {
 		t.Errorf("expected [f], got %v - %v", ids, err)
 	}
diff --git a/internal/queue/queue.go b/internal/queue/queue.go
index b228e85..7b3d4e3 100644
--- a/internal/queue/queue.go
+++ b/internal/queue/queue.go
@@ -30,7 +30,6 @@ import (
 	"blitiri.com.ar/go/log"
 
 	"github.com/golang/protobuf/ptypes"
-	"github.com/golang/protobuf/ptypes/timestamp"
 	"golang.org/x/net/idna"
 )
 
@@ -481,12 +480,6 @@ func nextDelay(createdAt time.Time) time.Duration {
 	return delay
 }
 
-func timestampNow() *timestamp.Timestamp {
-	now := time.Now()
-	ts, _ := ptypes.TimestampProto(now)
-	return ts
-}
-
 func mustIDNAToASCII(s string) string {
 	a, err := idna.ToASCII(s)
 	if err != nil {
diff --git a/internal/queue/queue_test.go b/internal/queue/queue_test.go
index bd9839a..82e68f0 100644
--- a/internal/queue/queue_test.go
+++ b/internal/queue/queue_test.go
@@ -141,6 +141,9 @@ func TestDSNOnTimeout(t *testing.T) {
 		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).
 	localC.wg.Add(1)
 	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)
+	}
+}
diff --git a/internal/tlsconst/tlsconst_test.go b/internal/tlsconst/tlsconst_test.go
new file mode 100644
index 0000000..1270439
--- /dev/null
+++ b/internal/tlsconst/tlsconst_test.go
@@ -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)
+		}
+	}
+}
diff --git a/test/t-01-simple_local/run.sh b/test/t-01-simple_local/run.sh
index 16f3251..88b4d19 100755
--- a/test/t-01-simple_local/run.sh
+++ b/test/t-01-simple_local/run.sh
@@ -5,6 +5,10 @@ set -e
 
 init
 
+if ! chasquid --version > /dev/null; then
+	fail "chasquid --version failed"
+fi
+
 # This should fail, as it has no certificates.
 rm -f config/certs/testserver/*.pem
 if chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config; then