Skip to content

Commit

Permalink
fix flaky server input test
Browse files Browse the repository at this point in the history
  • Loading branch information
jakecoffman committed Nov 16, 2023
1 parent 2e92e05 commit 6277fa8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 25 deletions.
7 changes: 6 additions & 1 deletion cmd/dependabot/internal/cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"log"
"net"
"os"

"github.com/MakeNowJust/heredoc"
Expand Down Expand Up @@ -140,7 +141,11 @@ func extractInput(cmd *cobra.Command, flags *UpdateFlags) (*model.Input, error)
}

if hasServer {
return server.Input(flags.inputServerPort)
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", flags.inputServerPort))
if err != nil {
return nil, fmt.Errorf("failed to create listener: %w", err)
}
return server.Input(l)
}

if hasStdin {
Expand Down
29 changes: 12 additions & 17 deletions internal/server/input.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package server

import (
"context"
"encoding/json"
"fmt"
"errors"
"github.com/dependabot/cli/internal/model"
"log"
"net"
"net/http"
"time"

"github.com/dependabot/cli/internal/model"
)

type credServer struct {
server *http.Server
data *model.Input
listener net.Listener
data *model.Input
}

// the server receives one payload and shuts itself down
Expand All @@ -24,22 +22,19 @@ func (s *credServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
_ = r.Body.Close()
go func() {
_ = s.server.Shutdown(context.Background())
_ = s.listener.Close()
}()
}

// Input receives configuration via HTTP on the port and returns it decoded
func Input(port int) (*model.Input, error) {
server := &http.Server{
Addr: fmt.Sprintf("127.0.0.1:%d", port),
ReadHeaderTimeout: time.Second,
func Input(listener net.Listener) (*model.Input, error) {
handler := &credServer{
listener: listener,
}
s := &credServer{server: server}
server.Handler = s
// printing so the user doesn't think the cli is hanging
log.Println("waiting for input on port", port)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Println("waiting for input on", listener.Addr())
if err := http.Serve(listener, handler); err != nil && !errors.Is(err, net.ErrClosed) {
return nil, err
}
return s.data, nil
return handler.data, nil
}
24 changes: 17 additions & 7 deletions internal/server/input_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,43 @@ package server

import (
"bytes"
"fmt"
"github.com/dependabot/cli/internal/model"
"net"
"net/http"
"sync"
"testing"
"time"

"github.com/dependabot/cli/internal/model"
)

func TestInput(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
var input *model.Input

l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal("Failed to create listener: ", err.Error())
}

go func() {
input, _ = Input(8080)
input, err = Input(l)
if err != nil {
t.Errorf(err.Error())
}
wg.Done()
}()
// give the server time to start
time.Sleep(10 * time.Millisecond)

url := fmt.Sprintf("http://%s", l.Addr().String())
data := `{"job":{"package-manager":"test"},"credentials":[{"credential":"value"}]}`
resp, err := http.Post("http://localhost:8080", "application/json", bytes.NewReader([]byte(data)))
resp, err := http.Post(url, "application/json", bytes.NewReader([]byte(data)))
if err != nil {
t.Fatal(err.Error())
}
if resp.StatusCode != 200 {
t.Errorf("expected status code 200, got %d", resp.StatusCode)
}

// Test will hang here if the server does not shut down
wg.Wait()

if input.Job.PackageManager != "test" {
Expand Down

0 comments on commit 6277fa8

Please sign in to comment.