Skip to content

Commit

Permalink
Add test for request cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Nov 20, 2020
1 parent b49ae2a commit 0aa7c0f
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 7 deletions.
77 changes: 77 additions & 0 deletions langserver/handlers/cancel_request_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package handlers

import (
"context"
"fmt"
"log"
"sync"
"testing"
"time"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/hashicorp/terraform-ls/langserver"
)

func TestLangServer_cancelRequest(t *testing.T) {
tmpDir := TempDir(t)

ls := langserver.NewLangServerMock(t, NewMockSession(&MockSessionInput{
AdditionalHandlers: map[string]handler.Func{
"$/sleepTicker": func(ctx context.Context, req *jrpc2.Request) (interface{}, error) {
ticker := time.NewTicker(10 * time.Millisecond)

ctx, cancelFunc := context.WithTimeout(ctx, 1*time.Second)
t.Cleanup(cancelFunc)

var wg sync.WaitGroup
wg.Add(1)
go func(ctx context.Context) {
defer wg.Done()
for {
select {
case <-ctx.Done():
ticker.Stop()
return
case <-ticker.C:
log.Printf("tick at %s", time.Now())
}
}
}(ctx)
wg.Wait()

return nil, ctx.Err()
},
},
}))
stop := ls.Start(t)
defer stop()

ls.Call(t, &langserver.CallRequest{
Method: "initialize",
ReqParams: fmt.Sprintf(`{
"capabilities": {},
"rootUri": %q,
"processId": 12345
}`, tmpDir.URI())})
ls.Notify(t, &langserver.CallRequest{
Method: "initialized",
ReqParams: "{}",
})

var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
ls.CallAndExpectError(t, &langserver.CallRequest{
Method: "$/sleepTicker",
ReqParams: `{}`,
}, context.Canceled)
}()
time.Sleep(100 * time.Millisecond)
ls.Call(t, &langserver.CallRequest{
Method: "$/cancelRequest",
ReqParams: fmt.Sprintf(`{"id": %d}`, 2),
})
wg.Wait()
}
8 changes: 8 additions & 0 deletions langserver/handlers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type service struct {
newRootModuleManager rootmodule.RootModuleManagerFactory
newWatcher watcher.WatcherFactory
newWalker rootmodule.WalkerFactory
additionalHandlers map[string]rpch.Func
}

var discardLogs = log.New(ioutil.Discard, "", 0)
Expand Down Expand Up @@ -294,6 +295,13 @@ func (svc *service) Assigner() (jrpc2.Assigner, error) {
},
}

// For use in tests, e.g. to test request cancellation
if len(svc.additionalHandlers) > 0 {
for methodName, handlerFunc := range svc.additionalHandlers {
m[methodName] = handlerFunc
}
}

return convertMap(m), nil
}

Expand Down
20 changes: 13 additions & 7 deletions langserver/handlers/service_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"testing"

"github.com/creachadair/jrpc2/handler"
"github.com/hashicorp/terraform-ls/internal/filesystem"
"github.com/hashicorp/terraform-ls/internal/terraform/exec"
"github.com/hashicorp/terraform-ls/internal/terraform/rootmodule"
Expand All @@ -15,9 +16,10 @@ import (
)

type MockSessionInput struct {
RootModules map[string]*rootmodule.RootModuleMock
Filesystem filesystem.Filesystem
TfExecutorFactory exec.ExecutorFactory
RootModules map[string]*rootmodule.RootModuleMock
Filesystem filesystem.Filesystem
TfExecutorFactory exec.ExecutorFactory
AdditionalHandlers map[string]handler.Func
}

type mockSession struct {
Expand All @@ -40,10 +42,13 @@ func (ms *mockSession) new(srvCtx context.Context) session.Session {
}

var fs filesystem.Filesystem
if ms.mockInput != nil && ms.mockInput.Filesystem != nil {
fs = ms.mockInput.Filesystem
} else {
fs = filesystem.NewFilesystem()
fs = filesystem.NewFilesystem()
var handlers map[string]handler.Func
if ms.mockInput != nil {
if ms.mockInput.Filesystem != nil {
fs = ms.mockInput.Filesystem
}
handlers = ms.mockInput.AdditionalHandlers
}

svc := &service{
Expand All @@ -55,6 +60,7 @@ func (ms *mockSession) new(srvCtx context.Context) session.Session {
newRootModuleManager: rootmodule.NewRootModuleManagerMock(input),
newWatcher: watcher.MockWatcher(),
newWalker: rootmodule.MockWalker,
additionalHandlers: handlers,
}

return svc
Expand Down

0 comments on commit 0aa7c0f

Please sign in to comment.