charts, common, tests/*: add skeleton for load test
This commit is contained in:
parent
83e681c947
commit
756ba4772f
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package charts
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
chartBasePath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
chartBasePath = filepath.Join(os.Getenv("CURDIR"), "benchmark/kubernetes")
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package charts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/getamis/istanbul-tools/genesis"
|
||||
)
|
||||
|
||||
type GenesisChart struct {
|
||||
name string
|
||||
chartPath string
|
||||
genesisFile string
|
||||
args []string
|
||||
}
|
||||
|
||||
func NewGenesisChart(addrs []common.Address, gasLimit uint64) *GenesisChart {
|
||||
chartPath := filepath.Join(chartBasePath, "genesis-block")
|
||||
genesisPath := filepath.Join(chartPath, ".genesis")
|
||||
err := os.MkdirAll(genesisPath, 0700)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
chart := &GenesisChart{
|
||||
name: "genesis-block",
|
||||
chartPath: chartPath,
|
||||
genesisFile: genesis.NewFileAt(
|
||||
genesisPath,
|
||||
false,
|
||||
genesis.Validators(addrs...),
|
||||
genesis.GasLimit(gasLimit),
|
||||
),
|
||||
}
|
||||
|
||||
relPath := strings.Replace(chart.genesisFile, chartPath+"/", "", 1)
|
||||
chart.Override("genesisFileName", relPath)
|
||||
|
||||
return chart
|
||||
}
|
||||
|
||||
func (chart *GenesisChart) Override(key, value string) {
|
||||
chart.args = append(chart.args, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
|
||||
func (chart *GenesisChart) Install(debug bool) error {
|
||||
defer os.RemoveAll(filepath.Dir(chart.genesisFile))
|
||||
|
||||
return installRelease(
|
||||
chart.name,
|
||||
chart.args,
|
||||
chart.chartPath,
|
||||
debug,
|
||||
)
|
||||
}
|
||||
|
||||
func (chart *GenesisChart) Uninstall() error {
|
||||
return uninstallRelease(chart.name)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package charts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/getamis/istanbul-tools/common"
|
||||
)
|
||||
|
||||
type StaticNodesChart struct {
|
||||
name string
|
||||
chartPath string
|
||||
staticNodesFile string
|
||||
args []string
|
||||
}
|
||||
|
||||
func NewStaticNodesChart(nodekeys []string, ipAddrs []string) *StaticNodesChart {
|
||||
chartPath := filepath.Join(chartBasePath, "static-nodes")
|
||||
staticNodesPath := filepath.Join(chartPath, ".static-nodes")
|
||||
err := os.MkdirAll(staticNodesPath, 0700)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(nodekeys) != len(ipAddrs) {
|
||||
log.Println("The number of nodekeys and the number of IP address should be equal")
|
||||
return nil
|
||||
}
|
||||
|
||||
chart := &StaticNodesChart{
|
||||
name: "static-nodes",
|
||||
chartPath: chartPath,
|
||||
staticNodesFile: common.GenerateStaticNodesAt(staticNodesPath, nodekeys, ipAddrs),
|
||||
}
|
||||
|
||||
relPath := strings.Replace(chart.staticNodesFile, chartPath+"/", "", 1)
|
||||
chart.Override("fileName", relPath)
|
||||
|
||||
return chart
|
||||
}
|
||||
|
||||
func (chart *StaticNodesChart) Override(key, value string) {
|
||||
chart.args = append(chart.args, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
|
||||
func (chart *StaticNodesChart) Install(debug bool) error {
|
||||
defer os.RemoveAll(filepath.Dir(chart.staticNodesFile))
|
||||
|
||||
return installRelease(
|
||||
chart.name,
|
||||
chart.args,
|
||||
chart.chartPath,
|
||||
debug,
|
||||
)
|
||||
}
|
||||
|
||||
func (chart *StaticNodesChart) Uninstall() error {
|
||||
return uninstallRelease(chart.name)
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package charts
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func newInstallCommand() *exec.Cmd {
|
||||
return exec.Command("helm", "install")
|
||||
}
|
||||
|
||||
func newUninstallCommand() *exec.Cmd {
|
||||
return exec.Command("helm", "delete", "--purge")
|
||||
}
|
||||
|
||||
func installRelease(name string, args []string, path string, debug bool) error {
|
||||
cmd := newInstallCommand()
|
||||
|
||||
if name != "" {
|
||||
cmd.Args = append(cmd.Args, "--name")
|
||||
cmd.Args = append(cmd.Args, name)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
cmd.Args = append(cmd.Args, "--set")
|
||||
cmd.Args = append(cmd.Args, strings.Join(args, ","))
|
||||
}
|
||||
|
||||
cmd.Args = append(cmd.Args, path)
|
||||
|
||||
if debug {
|
||||
cmd.Args = append(cmd.Args, "--dry-run")
|
||||
cmd.Args = append(cmd.Args, "--debug")
|
||||
}
|
||||
|
||||
cmd.Args = append(cmd.Args, "--wait")
|
||||
|
||||
if debug {
|
||||
fmt.Println(cmd.Args)
|
||||
}
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(err, string(output))
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
return nil
|
||||
}
|
||||
|
||||
func uninstallRelease(release string) error {
|
||||
cmd := newUninstallCommand()
|
||||
|
||||
if release != "" {
|
||||
cmd.Args = append(cmd.Args, release)
|
||||
} else {
|
||||
return errors.New("Unknown release name")
|
||||
}
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListCharts() {
|
||||
cmd := exec.Command("helm", "list")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package charts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type ValidatorChart struct {
|
||||
name string
|
||||
chartPath string
|
||||
args []string
|
||||
}
|
||||
|
||||
func NewValidatorChart(name string, args []string) *ValidatorChart {
|
||||
chartPath := filepath.Join(chartBasePath, "validator")
|
||||
|
||||
chart := &ValidatorChart{
|
||||
name: "validator-" + name,
|
||||
args: args,
|
||||
chartPath: chartPath,
|
||||
}
|
||||
|
||||
return chart
|
||||
}
|
||||
|
||||
func (chart *ValidatorChart) Override(key, value string) {
|
||||
chart.args = append(chart.args, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
|
||||
func (chart *ValidatorChart) Install(debug bool) error {
|
||||
return installRelease(
|
||||
chart.name,
|
||||
chart.args,
|
||||
chart.chartPath,
|
||||
debug,
|
||||
)
|
||||
}
|
||||
|
||||
func (chart *ValidatorChart) Uninstall() error {
|
||||
return uninstallRelease(chart.name)
|
||||
}
|
||||
|
||||
func (chart *ValidatorChart) Name() string {
|
||||
return chart.name
|
||||
}
|
|
@ -19,13 +19,17 @@ package common
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/getamis/go-ethereum/p2p/discover"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
|
@ -35,6 +39,14 @@ const (
|
|||
nodekeyFileName = "nodekey"
|
||||
)
|
||||
|
||||
func GenerateIPs(num int) (ips []string) {
|
||||
for i := 0; i < num; i++ {
|
||||
ips = append(ips, fmt.Sprintf("10.1.1.%d", i+2))
|
||||
}
|
||||
|
||||
return ips
|
||||
}
|
||||
|
||||
func GenerateRandomDir() (string, error) {
|
||||
err := os.MkdirAll(filepath.Join(defaultLocalDir), 0700)
|
||||
if err != nil {
|
||||
|
@ -83,6 +95,44 @@ func SaveNodeKey(key *ecdsa.PrivateKey, dataDir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func GenerateStaticNodesAt(dir string, nodekeys []string, ipAddrs []string) (filename string) {
|
||||
var nodes []string
|
||||
|
||||
for i, nodekey := range nodekeys {
|
||||
key, err := crypto.HexToECDSA(nodekey)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create key, err: %v\n", err)
|
||||
return ""
|
||||
}
|
||||
node := discover.NewNode(
|
||||
discover.PubkeyID(&key.PublicKey),
|
||||
net.ParseIP(ipAddrs[i]),
|
||||
0,
|
||||
uint16(30303))
|
||||
|
||||
nodes = append(nodes, node.String())
|
||||
}
|
||||
|
||||
filename = filepath.Join(dir, "static-nodes.json")
|
||||
bytes, _ := json.Marshal(nodes)
|
||||
if err := ioutil.WriteFile(filename, bytes, 0644); err != nil {
|
||||
log.Printf("Failed to write '%s', err: %v\n", filename, err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return filename
|
||||
}
|
||||
|
||||
func GenerateStaticNodes(nodekeys []string, ipAddrs []string) (filename string) {
|
||||
dir, err := GenerateRandomDir()
|
||||
if err != nil {
|
||||
log.Printf("Failed to generate directory, err: %v\n", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return GenerateStaticNodesAt(dir, nodekeys, ipAddrs)
|
||||
}
|
||||
|
||||
func RandomHex() string {
|
||||
b, _ := RandomBytes(32)
|
||||
return common.BytesToHash(b).Hex()
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package tests
|
||||
|
||||
type ChartInstaller interface {
|
||||
Install(bool) error
|
||||
Uninstall() error
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package load
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/getamis/istanbul-tools/charts"
|
||||
"github.com/getamis/istanbul-tools/common"
|
||||
|
||||
"github.com/getamis/istanbul-tools/tests"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("TPS-01: Large amount of transactions", func() {
|
||||
tests.CaseTable("with number of validators",
|
||||
func(numberOfValidators int) {
|
||||
tests.CaseTable("with gas limit",
|
||||
func(gaslimit int) {
|
||||
tests.CaseTable("with txpool size",
|
||||
func(txpoolSize int) {
|
||||
runTests(numberOfValidators, gaslimit, txpoolSize)
|
||||
},
|
||||
|
||||
tests.Case("2048", 2048),
|
||||
tests.Case("10240", 10240),
|
||||
)
|
||||
},
|
||||
|
||||
tests.Case("21000*1000", 21000*1000),
|
||||
tests.Case("21000*3000", 21000*3000),
|
||||
)
|
||||
},
|
||||
|
||||
tests.Case("4 validators", 4),
|
||||
tests.Case("7 validators", 7),
|
||||
tests.Case("10 validators", 10),
|
||||
)
|
||||
})
|
||||
|
||||
func runTests(numberOfValidators int, gaslimit int, txpoolSize int) {
|
||||
Describe("", func() {
|
||||
var (
|
||||
genesisChart tests.ChartInstaller
|
||||
staticNodesChart tests.ChartInstaller
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
_, nodekeys, addrs := common.GenerateKeys(numberOfValidators)
|
||||
genesisChart = charts.NewGenesisChart(addrs, uint64(gaslimit))
|
||||
Expect(genesisChart.Install(false)).To(BeNil())
|
||||
|
||||
staticNodesChart = charts.NewStaticNodesChart(nodekeys, common.GenerateIPs(len(nodekeys)))
|
||||
Expect(staticNodesChart.Install(false)).To(BeNil())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(genesisChart.Uninstall()).To(BeNil())
|
||||
Expect(staticNodesChart.Uninstall()).To(BeNil())
|
||||
})
|
||||
|
||||
It("", func() {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func IstanbulLoadTest(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Istanbul Load Test Suite")
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2017 AMIS Technologies
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
)
|
||||
|
||||
func CaseTable(description string, itBody interface{}, entries ...tableEntry) bool {
|
||||
caseTable(description, itBody, entries, false, false)
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
You can focus a table with `FCaseTable`.
|
||||
*/
|
||||
func FCaseTable(description string, itBody interface{}, entries ...tableEntry) bool {
|
||||
caseTable(description, itBody, entries, false, true)
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
You can mark a table as pending with `PCaseTable`.
|
||||
*/
|
||||
func PCaseTable(description string, itBody interface{}, entries ...tableEntry) bool {
|
||||
caseTable(description, itBody, entries, true, false)
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
You can mark a table as pending with `XCaseTable`.
|
||||
*/
|
||||
func XCaseTable(description string, itBody interface{}, entries ...tableEntry) bool {
|
||||
caseTable(description, itBody, entries, true, false)
|
||||
return true
|
||||
}
|
||||
|
||||
func caseTable(description string, itBody interface{}, entries []tableEntry, pending bool, focused bool) {
|
||||
itBodyValue := reflect.ValueOf(itBody)
|
||||
if itBodyValue.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("DescribeTable expects a function, got %#v", itBody))
|
||||
}
|
||||
|
||||
if pending {
|
||||
ginkgo.PDescribe(description, func() {
|
||||
for _, entry := range entries {
|
||||
entry.generate(itBodyValue, entries, pending, focused)
|
||||
}
|
||||
})
|
||||
} else if focused {
|
||||
ginkgo.FDescribe(description, func() {
|
||||
for _, entry := range entries {
|
||||
entry.generate(itBodyValue, entries, pending, focused)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ginkgo.Describe(description, func() {
|
||||
for _, entry := range entries {
|
||||
entry.generate(itBodyValue, entries, pending, focused)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
)
|
||||
|
||||
/*
|
||||
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
|
||||
*/
|
||||
type tableEntry struct {
|
||||
Description string
|
||||
Parameters []interface{}
|
||||
Pending bool
|
||||
Focused bool
|
||||
}
|
||||
|
||||
func (t tableEntry) generate(itBody reflect.Value, entries []tableEntry, pending bool, focused bool) {
|
||||
if t.Pending {
|
||||
ginkgo.PDescribe(t.Description, func() {
|
||||
for _, entry := range entries {
|
||||
entry.generate(itBody, entries, pending, focused)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
values := []reflect.Value{}
|
||||
for i, param := range t.Parameters {
|
||||
var value reflect.Value
|
||||
|
||||
if param == nil {
|
||||
inType := itBody.Type().In(i)
|
||||
value = reflect.Zero(inType)
|
||||
} else {
|
||||
value = reflect.ValueOf(param)
|
||||
}
|
||||
|
||||
values = append(values, value)
|
||||
}
|
||||
|
||||
body := func() {
|
||||
itBody.Call(values)
|
||||
}
|
||||
|
||||
if t.Focused {
|
||||
ginkgo.FDescribe(t.Description, body)
|
||||
} else {
|
||||
ginkgo.Describe(t.Description, body)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Entry constructs a tableEntry.
|
||||
|
||||
The first argument is a required description (this becomes the content of the generated Ginkgo `It`).
|
||||
Subsequent parameters are saved off and sent to the callback passed in to `DescribeTable`.
|
||||
|
||||
Each Entry ends up generating an individual Ginkgo It.
|
||||
*/
|
||||
func Case(description string, parameters ...interface{}) tableEntry {
|
||||
return tableEntry{description, parameters, false, false}
|
||||
}
|
||||
|
||||
/*
|
||||
You can focus a particular entry with FEntry. This is equivalent to FIt.
|
||||
*/
|
||||
func FCase(description string, parameters ...interface{}) tableEntry {
|
||||
return tableEntry{description, parameters, false, true}
|
||||
}
|
||||
|
||||
/*
|
||||
You can mark a particular entry as pending with PEntry. This is equivalent to PIt.
|
||||
*/
|
||||
func PCase(description string, parameters ...interface{}) tableEntry {
|
||||
return tableEntry{description, parameters, true, false}
|
||||
}
|
||||
|
||||
/*
|
||||
You can mark a particular entry as pending with XEntry. This is equivalent to XIt.
|
||||
*/
|
||||
func XCase(description string, parameters ...interface{}) tableEntry {
|
||||
return tableEntry{description, parameters, true, false}
|
||||
}
|
Loading…
Reference in New Issue