171 lines
4.1 KiB
Go
171 lines
4.1 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package diagnose
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/go-test/deep"
|
|
)
|
|
|
|
const getMoreCoffee = "You'll find more coffee in the freezer door, or consider buying more for the office."
|
|
|
|
func TestDiagnoseOtelResults(t *testing.T) {
|
|
expected := &Result{
|
|
Name: "make-coffee",
|
|
Status: ErrorStatus,
|
|
Warnings: []string{
|
|
"coffee getting low",
|
|
},
|
|
Advice: getMoreCoffee,
|
|
Children: []*Result{
|
|
{
|
|
Name: "prepare-kitchen",
|
|
Status: ErrorStatus,
|
|
Children: []*Result{
|
|
{
|
|
Name: "build-microwave",
|
|
Status: ErrorStatus,
|
|
Children: []*Result{
|
|
{
|
|
Name: "buy-parts",
|
|
Status: ErrorStatus,
|
|
Message: "no stores sell microwave parts, please buy a microwave instead.",
|
|
Warnings: []string{
|
|
"warning: you are about to try to build a microwave from scratch.",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "warm-milk",
|
|
Status: OkStatus,
|
|
},
|
|
{
|
|
Name: "brew-coffee",
|
|
Status: OkStatus,
|
|
},
|
|
{
|
|
Name: "pick-scone",
|
|
Status: ErrorStatus,
|
|
Message: "no scones",
|
|
},
|
|
{
|
|
Name: "dispose-grounds",
|
|
Status: SkippedStatus,
|
|
Message: "skipped as requested",
|
|
},
|
|
},
|
|
}
|
|
sess := New(os.Stdout)
|
|
sess.SkipFilters = []string{"dispose-grounds"}
|
|
ctx := Context(context.Background(), sess)
|
|
|
|
func() {
|
|
ctx, span := StartSpan(ctx, "make-coffee")
|
|
defer span.End()
|
|
|
|
makeCoffee(ctx)
|
|
}()
|
|
|
|
results := sess.Finalize(ctx)
|
|
results.ZeroTimes()
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
t.Fatalf("results mismatch: %s", strings.Join(deep.Equal(results, expected), "\n"))
|
|
}
|
|
results.Write(os.Stdout, 0)
|
|
}
|
|
|
|
const coffeeLeft = 3
|
|
|
|
func makeCoffee(ctx context.Context) error {
|
|
if coffeeLeft < 5 {
|
|
Warn(ctx, "coffee getting low")
|
|
Advise(ctx, getMoreCoffee)
|
|
}
|
|
|
|
// To mimic listener TLS checks, we'll see if we can nest a Test and add errors in the function
|
|
Test(ctx, "prepare-kitchen", func(ctx context.Context) error {
|
|
return Test(ctx, "build-microwave", func(ctx context.Context) error {
|
|
buildMicrowave(ctx)
|
|
return nil
|
|
})
|
|
})
|
|
|
|
Test(ctx, "warm-milk", func(ctx context.Context) error {
|
|
return warmMilk(ctx)
|
|
})
|
|
|
|
brewCoffee(ctx)
|
|
|
|
SpotCheck(ctx, "pick-scone", pickScone)
|
|
|
|
Test(ctx, "dispose-grounds", disposeGrounds)
|
|
return nil
|
|
}
|
|
|
|
// buildMicrowave will throw an error in the function itself to fail the span,
|
|
// but will return nil so the caller test doesn't necessarily throw an error.
|
|
// The intended behavior is that the superspan will detect the failed subspan
|
|
// and fail regardless. This happens when Fail is used to fail the span, but not
|
|
// when Error is used. See the comment in the function itself.
|
|
func buildMicrowave(ctx context.Context) error {
|
|
ctx, span := StartSpan(ctx, "buy-parts")
|
|
|
|
Fail(ctx, "no stores sell microwave parts, please buy a microwave instead.")
|
|
|
|
// The error line here does not actually yield an error in the output.
|
|
// TODO: Debug this. In the meantime, always use Fail over Error.
|
|
// Error(ctx, errors.New("no stores sell microwave parts, please buy a microwave instead."))
|
|
|
|
Warn(ctx, "warning: you are about to try to build a microwave from scratch.")
|
|
span.End()
|
|
return nil
|
|
}
|
|
|
|
func warmMilk(ctx context.Context) error {
|
|
// Always succeeds
|
|
return nil
|
|
}
|
|
|
|
func brewCoffee(ctx context.Context) error {
|
|
ctx, span := StartSpan(ctx, "brew-coffee")
|
|
defer span.End()
|
|
|
|
// Brewing happens here, successfully
|
|
return nil
|
|
}
|
|
|
|
func pickScone() error {
|
|
return errors.New("no scones")
|
|
}
|
|
|
|
func disposeGrounds(_ context.Context) error {
|
|
// Done!
|
|
return nil
|
|
}
|
|
|
|
func TestCapitalizeFirstLetter(t *testing.T) {
|
|
s := "this is a test."
|
|
if CapitalizeFirstLetter(s) != "This is a test." {
|
|
t.Fatalf("first word of string was not capitalized: got %s", CapitalizeFirstLetter(s))
|
|
}
|
|
s = "this"
|
|
if CapitalizeFirstLetter(s) != "This" {
|
|
t.Fatalf("first word of string was not capitalized: got %s", CapitalizeFirstLetter(s))
|
|
}
|
|
s = "."
|
|
if CapitalizeFirstLetter(s) != "." {
|
|
t.Fatalf("String without letters was not unchanged: got %s", CapitalizeFirstLetter(s))
|
|
}
|
|
}
|