Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7 make rest only buildbinary #12

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@
# Go workspace file
go.work

# ignore the main exec
# ignore the binaries folder
/bin

dremio-stress
# code coverage output file that is often left behind
coverage.out

# vscode files
.vscode

# mac directory files

.DS_Store
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,31 @@ dremio-stress -user dremio -password dremio123 -url http://localhost:9047 -conf

## Run via ODBC

NOTE: I HIGHLY suggest using the Docker image to run this which already has unixODBC included and therefore will run on anything including the M series Mac with minimal fuss.

### Run via Docker on Mac or Windows
### Run via Docker

```bash
docker run -it -v $(pwd):/mnt ghcr.io/rsvihladremio/dremio-stress -protocol odbc -user dremio -password dremio123 -url "Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=host.docker.internal;Port=32010;useEncryption=false" -conf /mnt/stress.json
```

### Run ODBC Directly With a Binary

```bash
dremio-stress -protocol odbc -user dremio -password dremio123 -url "Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=localhost;Port=32010;useEncryption=false" -conf ./stress.json
```
#### Dependencies on Windows

* Dremio ODBC Driver
* X86\_64 (or AMD64) processor

#### Apple Silicon Mac Dependency Note
#### Dependencies on Mac and Linux

NOTE: it is highly recommended to use the Docker option.
* UnixODBC
* Dremio ODBC Driver
* X86\_64 (or AMD64) processor
* Apple Silicon not supported use the Docker option

To run this on an M series Mac (Apple Silicon) one needs to have UnixODBC installed for Intel so do the following:

* run the shell in x86_64 mode `arch -x86_64 zsh`
* install Homebrew `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
* install UnixODBC as `brew install unixodbc`
* install the Dremio ODBC driver
```bash
dremio-stress -protocol odbc -user dremio -password dremio123 -url "Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=localhost;Port=32010;useEncryption=false" -conf ./stress.json
```

## Example stress.json files

Expand Down
164 changes: 60 additions & 104 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import (
"strings"
"time"

"github.com/rsvihladremio/dremio-stress/pkg/args"
"github.com/rsvihladremio/dremio-stress/pkg/conf"
"github.com/rsvihladremio/dremio-stress/pkg/gen"
"github.com/rsvihladremio/dremio-stress/pkg/protocol"
"github.com/rsvihladremio/dremio-stress/pkg/querygen"
"github.com/rsvihladremio/dremio-stress/pkg/stress"
)

Expand All @@ -48,123 +49,85 @@ func (o OsFileReader) ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filename)
}

// ParseProtocol will convert a string to a AccessMethod type
func ParseProtocol(method string) (conf.Protocol, error) {
switch strings.ToLower(method) {
case "http":
return conf.HTTP, nil
case "odbc":
return conf.ODBC, nil
default:
return -1, fmt.Errorf("method: %v is not supported only 'ODBC' and 'HTTP' methods are currently supported", method)
}
}

// ParseArgs will attempt to read the args from flags passed to the cli. It also does validation of the arguments
func ParseArgs() (conf.Args, error) {
func ParseArgs() (args.Args, error) {
maxConcurrency := flag.Int("max-concurrency", 4, "max number of concurrent queries")
timeout := flag.Duration("timeout", 60*time.Second, "default timeout for queries")
duration := flag.Duration("duration", 10*time.Minute, "duration of dremio-stress run")
user := flag.String("user", "dremio", "user to use at login")
password := flag.String("password", "dremio123", "password to use at login")
url := flag.String("url", "http://localhost:9047", "http(s) URL used for '-protocol http' or a odbc connection string for '-protocol odbc'")
protocolResult := flag.String("protocol", "http", "communication protocol to use for stress http or odbc are available")
protocolMethod := flag.String("protocol", "http", "communication protocol to use for stress http or odbc are available")

verbose := flag.Bool("v", false, "add more verbose output")
skipSSL := flag.Bool("skip-ssl", false, "works with '-protocol http' when using https")
jsonConfigPath := flag.String("conf", "stress.json", "location of the stress.json to define the stress job. If one is not provided a default stress job is used")

//Set usage output
flag.Usage = func() {
fmt.Fprintf(os.Stderr, `## stress.json examples:

### Two queries will end up at more or less at 50%% usage each
{
"queries": [
{
"query": "select * FROM Samples.\"samples.dremio.com\".\"SF weather 2018-2019.csv LIMIT 50\"",
"frequency": 5
},
{
"query": "select * FROM Samples.\"samples.dremio.com\".\"SF weather 2018-2019.csv\" where \"DATE\" between ':start' and ':end'",
"frequency": 5,
"parameters": {
"start": ["2018-02-04","2018-02-05"],
"end": ["2018-02-14","2018-02-15"]
}
}
]
}
fmt.Fprintf(os.Stderr, `dremio-stress %s %s-%s

EXAMPLE stress.json:

## Using queryGroups to preform several ops in order, "schema" will be called roughly 10%% of the time.

### Using queryGroups to preform several ops in order, schemops will be called roughly 10%% of the time
{
"queryGroups": [
{
"name": "schemaops",
"queryGroups": [
{
"name": "schema",
"queries": [
"drop table if exists samples.\"samples.dremio.com\".\"A\"",
"create table samples.\"samples.dremio.com\".\"A\" STORE AS (type => 'iceberg') AS SELECT \"a\",\"b\" FROM (values('a', 'b')) as t(\"a\",\"b\")",
"select * from samples.\"samples.dremio.com\".\"A\""
]
}
],
"queries": [
"drop table if exists samples.\"samples.dremio.com\".\"A\"",
"create table samples.\"samples.dremio.com\".\"A\" STORE AS (type => 'iceberg') AS SELECT \"a\",\"b\" FROM (values('a', 'b')) as t(\"a\",\"b\")",
"select * from samples.\"samples.dremio.com\".\"A\""
{
"queryGroup": "schema",
"frequency": 1
},
{
"query": "select * FROM Samples.\"samples.dremio.com\".\"SF weather 2018-2019.csv\" where \"DATE\" between ':start' and ':end'",
"frequency": 9,
"parameters": {
"start": ["2018-02-04", "2018-02-05"],
"end": ["2018-02-14","2018-02-15"]
}
}
]
}
],
"queries": [
{
"queryGroup": "schemaops",
"frequency": 1
},
{
"query": "select * FROM Samples.\"samples.dremio.com\".\"SF weather 2018-2019.csv\" where \"DATE\" between ':start' and ':end'",
"frequency": 9,
"parameters": {
"start": ["2018-02-04", "2018-02-05"],
"end": ["2018-02-14","2018-02-15"]
}
}
]
}

Usage with http:

dremio-stress -user dremio -password dremio123 -url http://localhost:9047 -conf ./stress.json

Usage with odbc (using new Arrow Flight driver, default install and unixodbc):

dremio-stress -protocol odbc -user dremio -password dremio123 -url "Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=localhost;Port=32010;useEncryption=false" -conf ./stress.json

Usage with docker image on Mac or Windows against a localhost dremio - (all dependencies bundled)

docker run -it -v $(pwd):/mnt ghcr.io/rsvihladremio/dremio-stress-protocol odbc -user dremio -password dremio123 -url "Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=host.docker.internal;Port=32010;useEncryption=false" -conf /mnt/stress.json

`)

USAGE:
`, odbcDisabled, Version, GitSha)
for k, v := range examples {
fmt.Fprintf(os.Stderr, "%s:\n\n %s\n\n", k, v)
}
fmt.Fprint(os.Stderr, "flags:\n\n")
flag.PrintDefaults()
}
flag.Parse()
protocolMethod, err := ParseProtocol(*protocolResult)
if err != nil {
return conf.Args{}, err
}
return conf.Args{
ProtocolArgs: conf.ProtocolArgs{
return args.Args{
ProtocolArgs: args.ProtocolArgs{
User: *user,
Password: *password,
URL: *url,
SkipSSL: *skipSSL,
Timeout: *timeout,
},
StressArgs: conf.StressArgs{
StressArgs: args.StressArgs{
Duration: *duration,
MaxConcurrency: *maxConcurrency,
JSONConfigPath: *jsonConfigPath,
},
Protocol: protocolMethod,
Protocol: *protocolMethod,
Verbose: *verbose,
}, nil
}

// Execute is the entry point function after the args have been parsed
func Execute(args conf.Args) error {
func Execute(args args.Args) error {
fmt.Fprintf(os.Stdout, "dremio-stress %s %s-%s\n", odbcDisabled, Version, GitSha)
engine, err := GetEngine(args)
if err != nil {
return err
Expand All @@ -174,36 +137,19 @@ func Execute(args conf.Args) error {

// GetEngine is a function which returns a specific protocol engine
// based on the protocol specified in the passed configuration arguments.
func GetEngine(args conf.Args) (protocol.Engine, error) {
// Check if the protocol in the configuration arguments is HTTP.
// If so, initialize the HTTP protocol engine.
switch args.Protocol {
case conf.HTTP:
// Try to create a new HTTP protocol engine.
protocolEngine, err := protocol.NewHTTPEngine(args.ProtocolArgs)
if err != nil {
// If there was an error creating the HTTP protocol engine, return an error.
return nil, fmt.Errorf("unable to initialize HTTP protocol engine: %w", err)
}
// Return the created HTTP protocol engine.
return protocolEngine, nil
case conf.ODBC:
// If the protocol is not HTTP, check if it is ODBC.
// If so, initialize the ODBC protocol engine.
protocolEngine, err := protocol.NewODBCEngine(args.ProtocolArgs)
if err != nil {
// If there was an error creating the ODBC protocol engine, return an error.
return nil, fmt.Errorf("unable to initialize ODBC protocol engine: %w", err)
func GetEngine(args args.Args) (protocol.Engine, error) {
//loop through and match on available protocols
for name, factoryFunction := range conf.GetProtocols() {
if strings.ToLower(args.Protocol) == name {
return factoryFunction(args.ProtocolArgs)
}
// Return the created ODBC protocol engine.
return protocolEngine, nil
}
// If the protocol is neither HTTP nor ODBC, return an error.
return nil, fmt.Errorf("unknown protocol %v", args.Protocol)
}

// ExecuteWithEngine is the entry point function after the args have been parsed.
func ExecuteWithEngine(args conf.Args, protocolEngine protocol.Engine, fileReader FileReader) (err error) {
func ExecuteWithEngine(args args.Args, protocolEngine protocol.Engine, fileReader FileReader) (err error) {

defer func() {
if err := protocolEngine.Close(); err != nil {
Expand All @@ -219,6 +165,16 @@ func ExecuteWithEngine(args conf.Args, protocolEngine protocol.Engine, fileReade
if err != nil {
return err
}
queryGen := querygen.NewStressConfQueryGenerator(stressConf)
queryGen := gen.NewStressConfQueryGenerator(stressConf)
return stress.Run(args.Verbose, protocolEngine, queryGen, args.StressArgs)
}

var examples = make(map[string]string)
var odbcDisabled = "odbc disabled"
var GitSha = "unknown"
var Version = "dev"

func init() {
examples["Usage with http"] = "dremio-stress -user dremio -password dremio123 -url http://localhost:9047 -conf ./stress.json"
examples["Usage with docker against a localhost dremio - (all dependencies bundled)"] = "docker run -it -v $(pwd):/mnt ghcr.io/rsvihladremio/dremio-stress-protocol odbc -user dremio -password dremio123 -url \"Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=host.docker.internal;Port=32010;useEncryption=false\" -conf /mnt/stress.json"
}
22 changes: 22 additions & 0 deletions cmd/cmd_odbc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build odbc

// Copyright 2023 Dremio Corporation
//
// 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 cmd

func init() {
examples["ODBC (using new Arrow Flight driver)"] = "dremio-stress -protocol odbc -user dremio -password dremio123 -url \"Driver={Arrow Flight SQL ODBC Driver};ConnectionType=Direct;AuthenticationType=Plain;Host=localhost;Port=32010;useEncryption=false\" -conf ./stress.json"
odbcDisabled = "odbc enabled"
}
Loading
Loading