1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-14 20:56:42 +00:00

nfd-worker: extend unit test to cover 'main'

Also, adds new method WaitForReady() into NfdMaster.

In practice, this quite widely tests nfd-master, too, as the tests
create an instance of NfdMaster and verify that the communication
between master and worker works.
This commit is contained in:
Markus Lehtonen 2019-02-11 15:10:29 +02:00
parent 90d9819062
commit 5fd72a0b60
8 changed files with 218 additions and 1 deletions

View file

@ -27,6 +27,7 @@ import (
"regexp"
"sort"
"strings"
"time"
"golang.org/x/net/context"
"google.golang.org/grpc"
@ -72,16 +73,18 @@ type Args struct {
type NfdMaster interface {
Run() error
Stop()
WaitForReady(time.Duration) bool
}
type nfdMaster struct {
args Args
server *grpc.Server
ready chan bool
}
// Create new NfdMaster server instance.
func NewNfdMaster(args Args) (*nfdMaster, error) {
nfd := &nfdMaster{args: args}
nfd := &nfdMaster{args: args, ready: make(chan bool, 1)}
// Check TLS related args
if args.CertFile != "" || args.KeyFile != "" || args.CaFile != "" {
@ -121,6 +124,9 @@ func (m *nfdMaster) Run() error {
if err != nil {
return fmt.Errorf("failed to listen: %v", err)
}
// Notify that we're ready to accept connections
m.ready <- true
close(m.ready)
serverOpts := []grpc.ServerOption{}
// Enable mutual TLS authentication if --cert-file, --key-file or --ca-file
@ -159,6 +165,21 @@ func (m *nfdMaster) Stop() {
m.server.Stop()
}
// Wait until NfdMaster is able able to accept connections.
func (m *nfdMaster) WaitForReady(timeout time.Duration) bool {
select {
case ready, ok := <-m.ready:
// Ready if the flag is true or the channel has been closed
if ready == true || ok == false {
return true
}
case <-time.After(timeout):
return false
}
// We should never end-up here
return false
}
// Advertise NFD master information
func updateMasterNode(helper apihelper.APIHelpers) error {
cli, err := helper.GetClient()

View file

@ -17,12 +17,57 @@ limitations under the License.
package nfdworker_test
import (
"fmt"
"os"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
nfdmaster "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
w "sigs.k8s.io/node-feature-discovery/pkg/nfd-worker"
"sigs.k8s.io/node-feature-discovery/test/data"
)
type testContext struct {
master nfdmaster.NfdMaster
errs chan error
}
func setupTest(args nfdmaster.Args) testContext {
// Fixed port and no-publish, for convenience
args.NoPublish = true
args.Port = 8192
m, err := nfdmaster.NewNfdMaster(args)
if err != nil {
fmt.Printf("Test setup failed: %v\n", err)
os.Exit(1)
}
ctx := testContext{master: m, errs: make(chan error)}
// Run nfd-master instance, intended to be used as the server counterpart
go func() {
ctx.errs <- ctx.master.Run()
close(ctx.errs)
}()
ready := ctx.master.WaitForReady(time.Second)
if !ready {
fmt.Println("Test setup failed: timeout while waiting for nfd-master")
os.Exit(1)
}
return ctx
}
func teardownTest(ctx testContext) {
ctx.master.Stop()
for e := range ctx.errs {
if e != nil {
fmt.Printf("Error in test context: %v\n", e)
os.Exit(1)
}
}
}
func TestNewNfdWorker(t *testing.T) {
Convey("When initializing new NfdWorker instance", t, func() {
Convey("When one of --cert-file, --key-file or --ca-file is missing", func() {
@ -37,3 +82,45 @@ func TestNewNfdWorker(t *testing.T) {
})
})
}
func TestRun(t *testing.T) {
ctx := setupTest(nfdmaster.Args{})
defer teardownTest(ctx)
Convey("When running nfd-worker against nfd-master", t, func() {
Convey("When publishing features from fake source", func() {
worker, _ := w.NewNfdWorker(w.Args{Oneshot: true, Sources: []string{"fake"}, Server: "localhost:8192"})
err := worker.Run()
Convey("No error should be returned", func() {
So(err, ShouldBeNil)
})
})
})
}
func TestRunTls(t *testing.T) {
masterArgs := nfdmaster.Args{
CaFile: data.FilePath("ca.crt"),
CertFile: data.FilePath("nfd-test-master.crt"),
KeyFile: data.FilePath("nfd-test-master.key"),
VerifyNodeName: false,
}
ctx := setupTest(masterArgs)
defer teardownTest(ctx)
Convey("When running nfd-worker against nfd-master with mutual TLS auth enabled", t, func() {
Convey("When publishing features from fake source", func() {
workerArgs := w.Args{
CaFile: data.FilePath("ca.crt"),
CertFile: data.FilePath("nfd-test-worker.crt"),
KeyFile: data.FilePath("nfd-test-worker.key"),
Oneshot: true,
Sources: []string{"fake"},
Server: "localhost:8192",
ServerNameOverride: "nfd-test-master"}
worker, _ := w.NewNfdWorker(workerArgs)
err := worker.Run()
Convey("No error should be returned", func() {
So(err, ShouldBeNil)
})
})
})
}

16
test/data/ca.crt Normal file
View file

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIIChzCCAfCgAwIBAgIJAN7lBwV9QUv7MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC25mZC10ZXN0LWNhMB4XDTE5MDQwNTEz
MzAxNVoXDTI5MDQwMjEzMzAxNVowWzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNv
bWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIG
A1UEAwwLbmZkLXRlc3QtY2EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPAc
vlYeDH60PziqlNGwRJ6MQLGfAMgGNZnaBu7vFa0Bs4PK35AnzaFPi9F6mGtl19AF
G4CQuZ8SZdopztd3xpB5bKzDkVpwuNiCYTmAhnCNZu3MCVD8oMUgoU1ZRm+gDGF/
OnIUKG8a681t99FLob6q8oHWAWXxUcAyfdYhypopAgMBAAGjUzBRMB0GA1UdDgQW
BBRy1A5l3zYT5+GY7FmRnVRm/vm6qTAfBgNVHSMEGDAWgBRy1A5l3zYT5+GY7FmR
nVRm/vm6qTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAI3CdZKG
u6/WC6PcNShIz/cIVvdfzDrhwbZwciRb3ovdsEndMboaaFADLSc55tfnU9uFKBsW
JJ/2U4sHqJrZOPOiWvwmKf4mgpriMX/NNNHBkj4GxNV7GspkRNzBtUdRdIi9ZVRz
gemI0b3c7AEURtzKKnzyNzRIq+asmb9Mkz8E
-----END CERTIFICATE-----

33
test/data/data.go Normal file
View file

@ -0,0 +1,33 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package data
import (
"path/filepath"
"runtime"
)
var packagePath string
func init() {
_, thisFile, _, _ := runtime.Caller(0)
packagePath = filepath.Dir(thisFile)
}
func FilePath(filePath string) string {
return filepath.Join(packagePath, filePath)
}

View file

@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICMTCCAZoCCQCI0sgI4VdhPjANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMRQwEgYDVQQDDAtuZmQtdGVzdC1jYTAeFw0xOTA0MDUxMzMxMTRa
Fw0yOTA0MDIxMzMxMTRaMF8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0
YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNVBAMM
D25mZC10ZXN0LW1hc3RlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4ZQO
O3uM/BlGhgtlUPxP0eeZEtmcKKXhqLclCkpQXds42EQV2/bfLetV4aSoewRg1yf/
+fHB50Jivqpnxw2+9kL7H4jog6rpWYVH3iSYvwjshc+Bf/ePKULE2lhve0/gNylr
hRfhiFBr9YHq2Baj6hu9kCJwqL8MisT+xkNttkkCAwEAATANBgkqhkiG9w0BAQsF
AAOBgQCQJEQbdDAZfBL/twzkQ5lbpeCaQ/bSrKLid3iwmsxO4hSQetdnieXGvgI+
VZB4EbtouIMcQiThBS9rUgZ5mDZwqVJhY/DZ/9LzPzovRG4Ptafay04tmVeqXFiC
MISkbKE+7JwrDxFjnDzfiYoPYCi5hjoVgU0YsYp5e/DW/TP3SA==
-----END CERTIFICATE-----

View file

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOGUDjt7jPwZRoYL
ZVD8T9HnmRLZnCil4ai3JQpKUF3bONhEFdv23y3rVeGkqHsEYNcn//nxwedCYr6q
Z8cNvvZC+x+I6IOq6VmFR94kmL8I7IXPgX/3jylCxNpYb3tP4Dcpa4UX4YhQa/WB
6tgWo+obvZAicKi/DIrE/sZDbbZJAgMBAAECgYEAvKHFQQJxA8LTEXZoE8/Zo4qK
m5OzHN6SFDaKV8+K4uFV6KsOqHEJcemwWE8LwEsJ/AFr8YOzhQIjdpMi0vZwrwWE
0wBTkKctYEpuKLCFROkIiDPV1c1m5i5+kjDpvHvhwnufIozgLz7rFcC5ucR5gSMq
Uy1V3sfF9DM0UBBuoX0CQQD3Ogmfgmffi8gCq1zsQcp99u5R3Yj/ApQjQgRz0k6g
IhbY1i3u+fY7pTc/nBO9ezbvy4SHFP0rkfVbINQ25mdnAkEA6ZVZxUmI0r3GnTsZ
Rrya2lYXA9KfhgLFvpx7eAaaejClQyCP+fpoyV3KXPlI9J9bWAazO4k0jbmeNEL9
F9DWzwJBAIdjfzWdQqlHcWcU1TSE6xGEkwq+GXIdxWZxluKev3QudviUgl8nAFO1
rMXnAWB5A6Laf19CfUrJCea32b+e+e0CQCdMW0gX8Q8ToqC9WqlN/feR2FlqTDBt
svs4tIUjB0ZbfNJoXhC+knaecvdlcWLGlMWgivMPSGo3umgshQxGtH0CQQDlTjdU
stoxEneM2vIv9doqmXo80zkoMIG4gdsaINnfcbpnh7Is+mEdDGll/eSrekgBDpGw
rk9C6sqYwFFCY3Re
-----END PRIVATE KEY-----

View file

@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICMTCCAZoCCQCI0sgI4VdhPzANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMRQwEgYDVQQDDAtuZmQtdGVzdC1jYTAeFw0xOTA0MDUxMzMxMzRa
Fw0yOTA0MDIxMzMxMzRaMF8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0
YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNVBAMM
D25mZC10ZXN0LXdvcmtlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5f4D
NErXtIW6GBJ5at/4HxJlQR0GFkaMErrKmYBmAxbolbBNux0lFTq6itNfZe+A61Gi
VdvBJPBaMWmS9iArQSjyQotTm04TpdiLThRVhG8drbqlAql+x5S6DrjUY61SVZhS
Aaa9IyKQQiKWH5v9oAb7n8r582qLTx8uZfq3ZcsCAwEAATANBgkqhkiG9w0BAQsF
AAOBgQA8WueokD59e0bzeGe1hPwuVXMnKoRHADbqbK/02KagoDBRnYTRRYM7hNDT
XMu++PHD0GkSfYs4XgX6BwdptaqQ0ww6BnX1OG1T+d9Ft/osneVyvkGv7fiGPF6D
5oXDz3xevUcKQzjux4P246bhWCIx/jrt8EVw5CXquS72qfGrXw==
-----END CERTIFICATE-----

View file

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOX+AzRK17SFuhgS
eWrf+B8SZUEdBhZGjBK6ypmAZgMW6JWwTbsdJRU6uorTX2XvgOtRolXbwSTwWjFp
kvYgK0Eo8kKLU5tOE6XYi04UVYRvHa26pQKpfseUug641GOtUlWYUgGmvSMikEIi
lh+b/aAG+5/K+fNqi08fLmX6t2XLAgMBAAECgYEAqsA7gMdP/iaKUvTkUASYIfl2
UzFJI6CcvgsP/4bkNcb8RqXuD81Dis9fT1I+sV9vR0YET9onO1V2oNjQ0wpvETjO
bk5veRfqFLOTavl64pAPGLEvOTWHSHQ9rtFZst1FFfehB1Vw69nBs9E40Zo2Y9yv
gkK+RIKUc2oPqMOigQECQQD8k2jxRX1COF+GO+pBTOTAr3pAmd0ahWAQGoqLwteQ
x+ARRZss1nuX0IGEyJ89hD6dHLv/FhhUxGE1R0xdQ31JAkEA6Rw5VYrAphATPCCX
h2gboAbHTOFAzwjnlW1pU6nlZI89kDAD3TF8d+eq906J8y7ji0YE89/G4HEzHqtQ
vMsucwJBAId2VAlauJRkga8PwVKmd+Vz98BgBTqtH9ljMr1EkbK/0EfTKieBHSZO
GLjrlKQ8ogxHlfh4lDIaZPxbMfSvNqkCQDkEfEmeHK0BtZK5bhbisg8cWVdGqXF6
fhqgnmimX8OO/cHs3KUX25gAhGLlRPzEdUe1orR8AcsYJSbVRHRJRl0CQQC7VBgp
04kaZzLFf61TmqMGVDoG2Wi5HwXYyzAEEEYFW61kwfZ6vuq3AP7NPMfW1F94welg
8LfkI2NBgjyKGiqn
-----END PRIVATE KEY-----