Skip to content

Commit

Permalink
added in logger support
Browse files Browse the repository at this point in the history
and early HAR code (not ready yet)

Signed-off-by: quobix <dave@quobix.com>
  • Loading branch information
daveshanley committed Nov 30, 2023
1 parent e4630fb commit 9fe587f
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 18 deletions.
79 changes: 78 additions & 1 deletion cmd/root_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"log/slog"
"net/url"
"os"
"path/filepath"
Expand Down Expand Up @@ -67,6 +68,11 @@ var (
certKey = keyFlag
}
base, _ := cmd.Flags().GetString("base")

har, _ := cmd.Flags().GetString("har")
harValidate, _ := cmd.Flags().GetBool("har-validate")

debug, _ := cmd.Flags().GetBool("debug")
mockMode, _ = cmd.Flags().GetBool("mock-mode")
hardError, _ = cmd.Flags().GetBool("hard-validation")
hardErrorCode, _ = cmd.Flags().GetInt("hard-validation-code")
Expand Down Expand Up @@ -169,6 +175,12 @@ var (
if base != config.Base {
config.Base = base
}
if har != config.HAR {
config.HAR = har
}
if harValidate != config.HARValidate {
config.HARValidate = harValidate
}

} else {

Expand All @@ -180,6 +192,8 @@ var (
if base != "" {
config.Base = base
}
config.HAR = har
config.HARValidate = harValidate
}

if spec == "" {
Expand All @@ -200,7 +214,7 @@ var (
return nil
}

if !mockMode && redirectURL == "" {
if !mockMode && redirectURL == "" && har == "" {
pterm.Println()
pterm.Error.Println("No redirect URL provided. " +
"Please provide a URL to redirect API traffic to using the --url or -u flags.")
Expand Down Expand Up @@ -340,6 +354,66 @@ var (
pterm.Println()
}

// check if we're using a HAR file instead of sniffing traffic.
if config.HAR != "" {
pterm.Printf("📦 Loading HAR file: %s\n", pterm.LightMagenta(config.HAR))
// can we read the har file?
_, err := os.Stat(config.HAR)
if err != nil {
pterm.Error.Printf("Cannot read HAR file: %s (%s)\n", config.HAR, err.Error())
return nil
}
pterm.Println()

}

// check if we want to validate the HAR file against the OpenAPI spec.
// but only if we're not in mock mode and there is a spec provided
if config.HARValidate && !config.MockMode && config.Contract != "" {
pterm.Printf("🔍 Validating HAR file against OpenAPI specification: %s\n", pterm.LightMagenta(config.Contract))
pterm.Println()
} else {
// we can't use this mode, print an error and return
if config.HARValidate && config.MockMode {
pterm.Println()
pterm.Error.Println("Cannot validate HAR file against OpenAPI specification in mock mode!")
pterm.Println()
return nil
}

// if there is no spec, print an error
if config.HARValidate && config.Contract == "" {
pterm.Println()
pterm.Error.Println("Cannot validate HAR file against OpenAPI specification, no specification provided, use '-s'")
pterm.Println()
return nil
}

}

// lets create a logger first.
logLevel := pterm.LogLevelError
if debug {
logLevel = pterm.LogLevelDebug
}

ptermLog := &pterm.Logger{
Formatter: pterm.LogFormatterColorful,
Writer: os.Stdout,
Level: logLevel,
ShowTime: true,
TimeFormat: "2006-01-02 15:04:05",
MaxWidth: 180,
KeyStyles: map[string]pterm.Style{
"error": *pterm.NewStyle(pterm.FgRed, pterm.Bold),
"err": *pterm.NewStyle(pterm.FgRed, pterm.Bold),
"caller": *pterm.NewStyle(pterm.FgGray, pterm.Bold),
},
}

handler := pterm.NewSlogHandler(ptermLog)
config.Logger = slog.New(handler)

// ready to boot, let's go!
_, pErr := runWiretapService(&config)

Expand Down Expand Up @@ -379,6 +453,9 @@ func Execute(version, commit, date string, fs embed.FS) {
rootCmd.Flags().StringP("config", "c", "",
"Location of wiretap configuration file to use (default is .wiretap in current directory)")
rootCmd.Flags().StringP("base", "b", "", "Set a base path to resolve relative file references from, or a overriding base URL to resolve remote references from")
rootCmd.Flags().BoolP("debug", "l", false, "Enable debug logging")
rootCmd.Flags().StringP("har", "z", "", "Load a HAR file instead of sniffing traffic")
rootCmd.Flags().BoolP("har-validate", "v", false, "Load a HAR file instead of sniffing traffic, and validate against the OpenAPI specification (requires -s)")

if err := rootCmd.Execute(); err != nil {
os.Exit(1)
Expand Down
37 changes: 20 additions & 17 deletions mock/mock_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,23 +250,26 @@ func TestNewMockEngine_BuildResponse_SimpleValid(t *testing.T) {
assert.Equal(t, 19.99, decoded[0]["price"])
}

func TestNewMockEngine_BuildResponse_SimpleInvalid_BadContentType(t *testing.T) {
doc := resetGiftshopState()
me := NewMockEngine(doc, false)

request, _ := http.NewRequest(http.MethodGet, "https://api.pb33f.io/wiretap/giftshop/products", nil)
request.Header.Set(helpers.ContentTypeHeader, "cup/tea")
b, status, err := me.GenerateResponse(request)

assert.NoError(t, err)
assert.Equal(t, 415, status)

var decoded map[string]any
_ = json.Unmarshal(b, &decoded)

assert.Equal(t, "Media type not supported (415)", decoded["title"])
assert.Equal(t, "The media type requested 'cup/tea' is not supported by this operation", decoded["detail"])
}
// test disabled because I have updated the mock engine to drop down to 'application/json' if the content type is not
// found.

//func TestNewMockEngine_BuildResponse_SimpleInvalid_BadContentType(t *testing.T) {
// doc := resetGiftshopState()
// me := NewMockEngine(doc, false)
//
// request, _ := http.NewRequest(http.MethodGet, "https://api.pb33f.io/wiretap/giftshop/products", nil)
// request.Header.Set(helpers.ContentTypeHeader, "cup/tea")
// b, status, err := me.GenerateResponse(request)
//
// assert.NoError(t, err)
// assert.Equal(t, 415, status)
//
// var decoded map[string]any
// _ = json.Unmarshal(b, &decoded)
//
// assert.Equal(t, "Media type not supported (415)", decoded["title"])
// assert.Equal(t, "The media type requested 'cup/tea' is not supported by this operation", decoded["detail"])
//}

func TestNewMockEngine_BuildResponse_SimpleValid_Pretty(t *testing.T) {
doc := resetGiftshopState()
Expand Down
4 changes: 4 additions & 0 deletions shared/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"embed"
"fmt"
"github.com/gobwas/glob"
"log/slog"
"regexp"
)

Expand Down Expand Up @@ -38,12 +39,15 @@ type WiretapConfiguration struct {
MockMode bool `json:"mockMode,omitempty" yaml:"mockMode,omitempty"`
MockModePretty bool `json:"mockModePretty,omitempty" yaml:"mockModePretty,omitempty"`
Base string `json:"base,omitempty" yaml:"base,omitempty"`
HAR string `json:"har,omitempty" yaml:"har,omitempty"`
HARValidate bool `json:"harValidate,omitempty" yaml:"harValidate,omitempty"`
CompiledPathDelays map[string]*CompiledPathDelay `json:"-" yaml:"-"`
CompiledVariables map[string]*CompiledVariable `json:"-" yaml:"-"`
Version string `json:"-" yaml:"-"`
StaticPathsCompiled []glob.Glob `json:"-" yaml:"-"`
CompiledPaths map[string]*CompiledPath `json:"-"`
FS embed.FS `json:"-"`
Logger *slog.Logger
}

func (wtc *WiretapConfiguration) CompilePaths() {
Expand Down

0 comments on commit 9fe587f

Please sign in to comment.