-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ndt7test package for creating an ndt7 server for unit tests (#319)
* Add ndt7/ndt7test * Verify that TCPInfo is non-nil * Add unit test for ndt7test logic
- Loading branch information
1 parent
f8bed0a
commit 8da06dc
Showing
3 changed files
with
111 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package ndt7test | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"net" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/m-lab/go/testingx" | ||
"github.com/m-lab/ndt-server/ndt7/handler" | ||
"github.com/m-lab/ndt-server/ndt7/spec" | ||
"github.com/m-lab/ndt-server/netx" | ||
) | ||
|
||
// NewNDT7Server creates a local httptest server capable of running an ndt7 | ||
// measurement in unittests. | ||
func NewNDT7Server(t *testing.T) (*handler.Handler, *httptest.Server) { | ||
dir, err := ioutil.TempDir("", "ndt7test-*") | ||
testingx.Must(t, err, "failed to create temp dir") | ||
|
||
// TODO: add support for token verifiers. | ||
// TODO: add support for TLS server. | ||
ndt7Handler := &handler.Handler{DataDir: dir} | ||
ndt7Mux := http.NewServeMux() | ||
ndt7Mux.Handle(spec.DownloadURLPath, http.HandlerFunc(ndt7Handler.Download)) | ||
ndt7Mux.Handle(spec.UploadURLPath, http.HandlerFunc(ndt7Handler.Upload)) | ||
|
||
// Create unstarted so we can setup a custom netx.Listener. | ||
ts := httptest.NewUnstartedServer(ndt7Mux) | ||
listener, err := net.Listen("tcp", ":0") | ||
testingx.Must(t, err, "failed to allocate a listening tcp socket") | ||
addr := (listener.(*net.TCPListener)).Addr().(*net.TCPAddr) | ||
// Populate insecure port value with dynamic port. | ||
ndt7Handler.InsecurePort = fmt.Sprintf(":%d", addr.Port) | ||
ts.Listener = netx.NewListener(listener.(*net.TCPListener)) | ||
// Now that the test server has our custom listener, start it. | ||
ts.Start() | ||
return ndt7Handler, ts | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package ndt7test | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"github.com/gorilla/websocket" | ||
"github.com/m-lab/go/testingx" | ||
"github.com/m-lab/ndt-server/ndt7/spec" | ||
) | ||
|
||
func TestNewNDT7Server(t *testing.T) { | ||
// Create the ndt7test server. | ||
h, srv := NewNDT7Server(t) | ||
defer os.RemoveAll(h.DataDir) | ||
|
||
// Prepare to run a simplified download with ndt7test server. | ||
URL, _ := url.Parse(srv.URL) | ||
URL.Scheme = "ws" | ||
URL.Path = spec.DownloadURLPath | ||
headers := http.Header{} | ||
headers.Add("Sec-WebSocket-Protocol", spec.SecWebSocketProtocol) | ||
headers.Add("User-Agent", "fake-user-agent") | ||
ctx := context.Background() | ||
dialer := websocket.Dialer{HandshakeTimeout: 10 * time.Second} | ||
conn, _, err := dialer.DialContext(ctx, URL.String(), headers) | ||
testingx.Must(t, err, "failed to dial websocket ndt7 test") | ||
err = simpleDownload(ctx, t, conn) | ||
if err != nil && !websocket.IsCloseError(err, websocket.CloseNormalClosure) { | ||
testingx.Must(t, err, "failed to download") | ||
} | ||
|
||
// Allow the server time to save the file, the client may stop before the server does. | ||
time.Sleep(1 * time.Second) | ||
// Verify a file was saved. | ||
m, err := filepath.Glob(h.DataDir + "/ndt7/*/*/*/*") | ||
testingx.Must(t, err, "failed to glob datadir: %s", h.DataDir) | ||
if len(m) == 0 { | ||
t.Errorf("no files found") | ||
} | ||
} | ||
|
||
func simpleDownload(ctx context.Context, t *testing.T, conn *websocket.Conn) error { | ||
defer conn.Close() | ||
wholectx, cancel := context.WithTimeout(ctx, spec.MaxRuntime) | ||
defer cancel() | ||
conn.SetReadLimit(spec.MaxMessageSize) | ||
err := conn.SetReadDeadline(time.Now().Add(spec.MaxRuntime)) | ||
testingx.Must(t, err, "failed to set read deadline") | ||
|
||
var total int64 | ||
// WARNING: this is not a reference client. | ||
for wholectx.Err() == nil { | ||
_, mdata, err := conn.ReadMessage() | ||
if err != nil { | ||
return err | ||
} | ||
total += int64(len(mdata)) | ||
} | ||
return nil | ||
} |