Skip to content

Commit

Permalink
Added ES document indexing (#50)
Browse files Browse the repository at this point in the history
* Added ES document indexing

After each test is finished if the elastic config is set
the process will read the file and Bulk index all the results to the ES
server

Signed-off-by: Vicente Zepeda Mas <[email protected]>

* Adding unit test for ES Indexer

Signed-off-by: Vicente Zepeda Mas <[email protected]>

* Adding support for lines bigger than buffer size

Signed-off-by: Vicente Zepeda Mas <[email protected]>

* Adding documentation

Signed-off-by: Vicente Zepeda Mas <[email protected]>
  • Loading branch information
chentex authored Apr 5, 2022
1 parent 65f059e commit 11a5671
Show file tree
Hide file tree
Showing 12 changed files with 924 additions and 227 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
name: GO checks
strategy:
matrix:
go-version: [1.15.x]
go-version: [1.17.x]
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ path as your binary, it will be autodetected and you could run by just calling i
--config-file string config file (default "config.yaml")
--cooldown int Cooldown time between tests in seconds. (default 10)
--duration int Duration of each individual run in minutes. (default 1)
--elastic-index string Elasticsearch index to store the documents
--elastic-password string Elasticsearch Password for authentication
--elastic-server string Elasticsearch cluster URL
--elastic-user string Elasticsearch User for authentication
--end-rate int Ending request per second rate. (E.g.: 5 would be 5 req/s)
--gateway-url string Gateway url to perform the test against (default "https://api.integration.openshift.com")
-h, --help help for ocm-api-load
Expand Down Expand Up @@ -91,6 +95,11 @@ path as your binary, it will be autodetected and you could run by just calling i
- client:
- id: OpenID client identifier.
- secret: OpenID client secret.
- aws:
- region: AWS region (default "us-west-1")
- access-key: AWS access key
- secret-access-key: AWS access secret
- account-id: AWS Account ID, is the 12-digit account number
- output-path: Path to output results.
- duration: Duration of each individual run in minutes. (default 1)
- cooldown: Cooldown time between tests in seconds. (default 10 s)
Expand All @@ -102,6 +111,11 @@ path as your binary, it will be autodetected and you could run by just calling i
- end-rate: Ending request per second rate. (E.g.: 5 would be 5 req/s)
- ramp-steps: Number of stepts to get from start rate to end rate. (Minimum 2 steps)
- tests: List of the tests to run. Empty list means all.
- elastic:
- server: Elasticsearch cluster URL
- user: Elasticsearch User for authentication
- password: Elasticsearch Password for authentication
- index: Elasticsearch index to store the documents

### Test options

Expand Down
50 changes: 42 additions & 8 deletions cmd/ocm-load-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ func init() {
rootCmd.Flags().BoolP("verbose", "v", false, "set this flag to activate verbose logging.")
rootCmd.Flags().Int("cooldown", 10, "Cooldown time between tests in seconds.")
rootCmd.Flags().StringSlice("test-names", []string{}, "Names for the tests to be run.")
//Elasticsearch Flags
rootCmd.Flags().String("elastic-server", "", "Elasticsearch cluster URL")
rootCmd.Flags().String("elastic-user", "", "Elasticsearch User for authentication")
rootCmd.Flags().String("elastic-password", "", "Elasticsearch Password for authentication")
rootCmd.Flags().String("elastic-index", "", "Elasticsearch index to store the documents")
//Ramping Flags
rootCmd.Flags().String("ramp-type", "", "Type of ramp to use for all tests. (linear, exponential)")
rootCmd.Flags().Int("start-rate", 0, "Starting request per second rate. (E.g.: 5 would be 5 req/s)")
Expand Down Expand Up @@ -109,12 +114,12 @@ func configTests() {
}

// configAWS decides wether to use Flags values or config file
func configAWS(ctx context.Context, logger *logging.GoLogger) {
func configAWS() error {
// Flag overrides config
// Selecting test passed in the Flag
// Selecting aws config passed by flags
if viper.GetString("aws-account-id") != "" {
if viper.GetString("aws-access-key") == "" || viper.GetString("aws-access-secret") == "" {
logger.Fatal(ctx, "AWS configuration not complete")
return fmt.Errorf("AWS configuration not complete")
}
config := []interface{}{map[interface{}]interface{}{
"region": viper.GetString("aws-region"),
Expand All @@ -125,15 +130,36 @@ func configAWS(ctx context.Context, logger *logging.GoLogger) {
viper.Set("aws", config)
}

// If no Flag or Config is passed all test should run
if len(viper.Get("aws").([]interface{})) < 1 {
logger.Fatal(ctx, "AWS configuration not provided")
// If no Flag or Config is passed test should fail
if !viper.IsSet("aws") || len(viper.Get("aws").([]interface{})) < 1 {
return fmt.Errorf("AWS configuration not provided")
}

// If multiple accounts are passed.
if len(viper.Get("aws").([]interface{})) > 1 {
logger.Fatal(ctx, "Multiple AWS accounts are not supported at the moment")
return fmt.Errorf("multiple AWS accounts are not supported at the moment")
}
return nil
}

// configES decides wether to use Flags values or config file
func configES() error {
// Flag overrides config
// Selecting ES config passed by flags
// If no Flag or Config is passed the test will not index the documents.
if viper.GetString("elastic-server") != "" {
if viper.GetString("elastic-index") == "" {
return fmt.Errorf("ES configuration needs an index set `elastic-index` flag")
}
config := map[string]interface{}{
"server": viper.GetString("elastic-server"),
"user": viper.GetString("elastic-user"),
"password": viper.GetString("elastic-password"),
"index": viper.GetString("elastic-index"),
}
viper.Set("elastic", config)
}
return nil
}

func run(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -167,7 +193,15 @@ func run(cmd *cobra.Command, args []string) error {

configTests()

configAWS(cmd.Context(), logger)
err = configAWS()
if err != nil {
logger.Fatal(cmd.Context(), "Configuring AWS: %s", err)
}

err = configES()
if err != nil {
logger.Fatal(cmd.Context(), "Configuring ES: %s", err)
}

runner := tests.NewRunner(
viper.GetString("test-id"),
Expand Down
137 changes: 137 additions & 0 deletions cmd/ocm-load-test_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package main

import (
"testing"

"github.com/spf13/viper"
)

func initConfigTests() {
viper.Reset()
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.SetConfigFile("test.yaml")
viper.AutomaticEnv()
}
func Test_configAWS(t *testing.T) {

t.Run("TestingFlags", func(t *testing.T) {
initConfigTests()
viper.Set("aws-region", "us-east-2")
viper.Set("aws-access-key", "THISISAKEY")
viper.Set("aws-access-secret", "THISISASECRET")
viper.Set("aws-account-id", "THEID")
configAWS()
aws := viper.Get("aws").([]interface{})[0].(map[interface{}]interface{})
if aws["region"] == "" {
t.Fatalf("Flags are set and `aws.0.region` should be set")
}
})

t.Run("TestingWithIncompleteFlags", func(t *testing.T) {
initConfigTests()
viper.Set("aws-region", "us-east-2")
viper.Set("aws-access-secret", "THISISASECRET")
viper.Set("aws-account-id", "THEID")
err := configAWS()
if err == nil {
t.Fatalf("Shold fail because of missing AWS config")
}
})

t.Run("TestingNoFlagsNoConfig", func(t *testing.T) {
initConfigTests()
err := configAWS()
if err == nil {
t.Fatalf("This test should fail because there is no configuraiton")
}
})

t.Run("TestingNoFlagsWithConfig", func(t *testing.T) {
initConfigTests()
config := []interface{}{map[interface{}]interface{}{
"region": "aws-region",
"access-key": "aws-access-key",
"secret-access-key": "aws-access-secret",
"account-id": "aws-account-id",
}}
viper.Set("aws", config)
err := configAWS()
if err != nil {
t.Fatalf("This test should not fail because there is a YAML config")
}
aws := viper.Get("aws").([]interface{})[0].(map[interface{}]interface{})
if aws["region"] == "" {
t.Fatalf("Config is set and `aws.0.region` should be set")
}
})

t.Run("TestingNoFlagsWithConfig", func(t *testing.T) {
initConfigTests()
config := []interface{}{map[interface{}]interface{}{
"region": "aws-region",
"access-key": "aws-access-key",
"secret-access-key": "aws-access-secret",
"account-id": "aws-account-id",
}, map[interface{}]interface{}{
"region": "aws-region-2",
"access-key": "aws-access-key-2",
"secret-access-key": "aws-access-secret-2",
"account-id": "aws-account-id-2",
}}
viper.Set("aws", config)
err := configAWS()
if err == nil {
t.Fatalf("This test should fail because there are multiple AWS configs")
}
})
}

func Test_configES(t *testing.T) {
t.Run("TestWithFlags", func(t *testing.T) {
initConfigTests()
viper.Set("elastic-server", "http://localhost:9200")
viper.Set("elastic-user", "user")
viper.Set("elastic-password", "password")
viper.Set("elastic-index", "es-index")
if err := configES(); (err != nil) != false {
if !viper.IsSet("elastic.server") {
t.Fatalf("Flags are set and `elastic.server` should be set")
}
}
})

t.Run("TestingNoFlagsNoConfig", func(t *testing.T) {
initConfigTests()
err := configES()
if err != nil {
t.Fatalf("This test not should fail even with empty config")
}
})

t.Run("TestingNoFlagsWithConfig", func(t *testing.T) {
initConfigTests()
config := map[string]interface{}{
"server": "https://localhost:9200",
"user": "user",
"password": "password",
"index": "elastic-index",
}
viper.Set("elastic", config)
err := configES()
if err != nil {
t.Fatalf("This test should not fail because there is a YAML config")
}
if viper.GetString("elastic.server") == "" {
t.Fatalf("Config is set `elastic.server` should be set")
}
})

t.Run("TestWithInclompleteFlags", func(t *testing.T) {
initConfigTests()
viper.Set("elastic-server", "http://localhost:9200")
if err := configES(); (err != nil) != true {
t.Fatalf("Should fail because of missing index.")
}
})
}
5 changes: 5 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ aws:
access-key: "ASD7ASFET65FFGHDFFS"
secret-access-key: "fjhgsadf6#$!@%&/dfghdfgdsdf"
account-id: "123434565665"
elastic:
server: "http://elastic.apps.perfscale.devcluster.openshift.com/"
user: "user"
password: "password"
index: "es-index"
duration: 2
cooldown: 10
output-path: "./results"
Expand Down
69 changes: 54 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,24 +1,63 @@
module github.com/cloud-bulldozer/ocm-api-load

go 1.15
go 1.17

require (
github.com/Rican7/retry v0.1.0
github.com/github-release/github-release v0.10.0 // indirect
github.com/influxdata/tdigest v0.0.1 // indirect
github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/onsi/ginkgo v1.15.0 // indirect
github.com/onsi/gomega v1.10.5 // indirect
github.com/openshift-online/ocm-sdk-go v0.1.175
github.com/Rican7/retry v0.3.1
github.com/opensearch-project/opensearch-go v1.1.0
github.com/openshift-online/ocm-sdk-go v0.1.252
github.com/satori/go.uuid v1.2.0
github.com/spf13/cobra v1.1.3
github.com/spf13/viper v1.7.0
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
github.com/tsenart/vegeta/v12 v12.8.4
github.com/voxelbrain/goptions v0.0.0-20180630082107-58cddc247ea2 // indirect
github.com/zgalor/weberr v0.6.0
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 // indirect
github.com/zgalor/weberr v0.7.0
)

require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/influxdata/tdigest v0.0.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/microcosm-cc/bluemonday v1.0.16 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.9.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.15.0 // indirect
github.com/prometheus/procfs v0.2.0 // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

replace (
Expand Down
Loading

0 comments on commit 11a5671

Please sign in to comment.