Skip to content

Commit

Permalink
the neat way to create CITF instance.
Browse files Browse the repository at this point in the history
- Introduced package `citfoptions` which Contains struct `CreateOptions`
and a few functions to speedup the creation.
- NewCITF will now take a `citfoptions.CreateOptions` which will specify
which parts of CITF should be created.
- Updated `ReadMe.md` with some information about changes and updated example with new changes.
- Put same example in a new directory `example` and excluded it from test.

Changes committed:
	modified:   README.md
	modified:   citf.go
	new file:   citf_options/citf_options.go
	new file:   example/example_test.go
	new file:   example/nginx-rc.yaml
	modified:   test.sh
	modified:   utils/k8s/general.go

Signed-off-by: Abhishek Kashyap <[email protected]>
  • Loading branch information
Abhishek Kashyap authored and satyamz committed Jul 30, 2018
1 parent 50e4c8e commit fa95811
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 53 deletions.
70 changes: 57 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ OpenEBS/project
## Instantiation

Developer has to instantiate CITF using `NewCITF(configFilePath)` which will initialize it with all the required configurations.
Developer has to instantiate CITF using `citf.NewCITF` function, which will initialize it with all the configurations specified by `citfoptions.CreateOptions` passed to it.

> You should not pass `K8sInclude` in `citfoptions.CreateOptions` if your environment is not yet set. otherwise it will through error.
> If you want all options except `K8sInclude` in `CreateOptions` to set to `true`; you may use `citfoptions.CreateOptionsIncludeAllButK8s` function.
> If you want all options in `CreateOptions` to set to `true` you may use `citfoptions.CreateOptionsIncludeAll` function.
CITF struct has four fields:-
- Environment - To Setup or TearDown the platform such as minikube, GKE, AWS etc.
Expand Down Expand Up @@ -88,8 +94,9 @@ Once integration test is completed, developer can delete the setup using `TearDo
<details>
<summary><b>Example</b></summary>

```go
## example_test.go

```go
package example

import (
Expand All @@ -99,33 +106,38 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/openebs/CITF"
"github.com/openebs/CITF/utils/k8s"
citfoptions "github.com/openebs/CITF/citf_options"
)

var CitfInstance citf.CITF

func TestIntegrationExample(t *testing.T) {
RegisterFailHandler(Fail)

var err error
// Initializing CITF without config file.
// Also We should not include K8S as currently we don't have kubernetes environment setup
CitfInstance, err = citf.NewCITF(citfoptions.CreateOptionsIncludeAllButK8s(""))
Expect(err).NotTo(HaveOccurred())

RunSpecs(t, "Integration Test Suite")
}

// Initializing CITF without config file.
var CitfInstance, err = citf.NewCITF("")

var _ = BeforeSuite(func() {

// Setting up the default Platform i.e minikube
err = CitfInstance.Environment.Setup()
err := CitfInstance.Environment.Setup()
Expect(err).NotTo(HaveOccurred())

// if you are using minikube version greater than 0.24.1
// then you have to update the K8s config
// We're working to remove this step in upcoming changes.
CitfInstance.K8S, err = k8s.NewK8S()
// You have to update the K8s config when environment has been set up
// this extra step will be unsolicited in upcoming changes.
err = CitfInstance.Reload(citfoptions.CreateOptionsIncludeAll(""))
Expect(err).NotTo(HaveOccurred())

// Wait until platform is up
time.Sleep(30 * time.Second)

err = CitfInstance.K8S.YAMLApply("./nginx-pod.yaml")
err = CitfInstance.K8S.YAMLApply("./nginx-rc.yaml")
Expect(err).NotTo(HaveOccurred())

// Wait until the pod is up and running
Expand All @@ -135,7 +147,7 @@ var _ = BeforeSuite(func() {
var _ = AfterSuite(func() {

// Tear Down the Platform
err = CitfInstance.Environment.Teardown()
err := CitfInstance.Environment.Teardown()
Expect(err).NotTo(HaveOccurred())
})

Expand All @@ -145,6 +157,9 @@ var _ = Describe("Integration Test", func() {
pods, err := CitfInstance.K8S.GetPods("default", "nginx")
Expect(err).NotTo(HaveOccurred())

// Give pods some time to generate logs
time.Sleep(2 * time.Second)

// Assuming that only 1 nginx pod is running
for _, v := range pods {
log, err := CitfInstance.K8S.GetLog(v.GetName(), "default")
Expand All @@ -158,4 +173,33 @@ var _ = Describe("Integration Test", func() {
```

Above example is using [Ginkgo](https://github.com/onsi/ginkgo) and [Gomega](https://github.com/onsi/gomega) framework for handling the tests.

`nginx-rc.yaml` which is used in above example is below.

## nginx-rc.yaml
```yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 1
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
args: [/bin/sh, -c,
'echo "started the controller"']
ports:
- containerPort: 80
```
> **Note:** Above yaml is compatible with kubernetes 1.9, you may need to modify it if your kubernetes version is different.
</details>
70 changes: 46 additions & 24 deletions citf.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package citf
import (
"fmt"

"github.com/golang/glog"
citfoptions "github.com/openebs/CITF/citf_options"
"github.com/openebs/CITF/common"
"github.com/openebs/CITF/config"
"github.com/openebs/CITF/environments"
Expand All @@ -26,6 +26,8 @@ import (
"github.com/openebs/CITF/utils/log"
)

var logger log.Logger

// CITF is a struct which will be the driver for all functionalities of this framework
type CITF struct {
Environment environments.Environment
Expand All @@ -35,34 +37,54 @@ type CITF struct {
Logger log.Logger
}

// NewCITF returns CITF struct. One need this in order to use any functionality of this framework.
func NewCITF(confFilePath string) (CITF, error) {
var environment environments.Environment
if err := config.LoadConf(confFilePath); err != nil {
// Log this here
// Here, we don't want to return fatal error since we want to continue
// executing the function with default configuration even if it fails
glog.Errorf("error loading config file. Error: %+v", err)
}

// getEnvironment returns the environment according to the config
func getEnvironment() (environments.Environment, error) {
switch config.Environment() {
case common.Minikube:
environment = minikube.NewMinikube()
return minikube.NewMinikube(), nil
default:
// Exit with Error
return CITF{}, fmt.Errorf("platform: %q is not suppported by CITF", config.Environment())
return nil, fmt.Errorf("platform: %q is not suppported by CITF", config.Environment())
}
}

// Reload reloads all the fields of citfInstance according to supplied `citfCreateOptions`
func (citfInstance *CITF) Reload(citfCreateOptions *citfoptions.CreateOptions) error {
// Here, we don't want to return fatal error since we want to continue
// executing the function with default configuration even if it fails
// so we simply log any error and continue
logger.LogError(config.LoadConf(citfCreateOptions.ConfigPath), "error loading config file")

if citfCreateOptions.EnvironmentInclude {
environ, err := getEnvironment()
if err != nil {
return err
}
citfInstance.Environment = environ
}

k8sInstance, err := k8s.NewK8S()
if err != nil {
return CITF{}, err
if citfCreateOptions.K8SInclude {
k8sInstance, err := k8s.NewK8S()
if err != nil {
return err
}
citfInstance.K8S = k8sInstance
}

return CITF{
K8S: k8sInstance,
Environment: environment,
Docker: docker.NewDocker(),
DebugEnabled: config.Debug(),
Logger: log.Logger{},
}, nil
if citfCreateOptions.DockerInclude {
citfInstance.Docker = docker.NewDocker()
}

if citfCreateOptions.LoggerInclude {
citfInstance.Logger = log.Logger{}
}

citfInstance.DebugEnabled = config.Debug()
return nil
}

// NewCITF returns CITF struct filled according to supplied `citfCreateOptions`.
// One need this in order to use any functionality of this framework.
func NewCITF(citfCreateOptions *citfoptions.CreateOptions) (citfInstance CITF, err error) {
err = citfInstance.Reload(citfCreateOptions)
return
}
53 changes: 53 additions & 0 deletions citf_options/citf_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package citfoptions

// CreateOptions specifies which fields of CITF should be included when created or reloadedd
type CreateOptions struct {
ConfigPath string
EnvironmentInclude bool
K8SInclude bool
DockerInclude bool
LoggerInclude bool
}

// CreateOptionsIncludeAll returns CreateOptions where all fields are set to `true` and ConfigPath is set to configPath
func CreateOptionsIncludeAll(configPath string) *CreateOptions {
var citfCreateOptions CreateOptions
citfCreateOptions.ConfigPath = configPath
citfCreateOptions.EnvironmentInclude = true
citfCreateOptions.K8SInclude = true
citfCreateOptions.DockerInclude = true
citfCreateOptions.LoggerInclude = true
return &citfCreateOptions
}

// CreateOptionsIncludeAllButEnvironment returns CreateOptions where all fields except `Environment` are set to `true` and ConfigPath is set to configPath
func CreateOptionsIncludeAllButEnvironment(configPath string) *CreateOptions {
citfCreateOptions := CreateOptionsIncludeAll(configPath)

citfCreateOptions.EnvironmentInclude = false
return citfCreateOptions
}

// CreateOptionsIncludeAllButK8s returns CreateOptions where all fields except `K8S` are set to `true` and ConfigPath is set to configPath
func CreateOptionsIncludeAllButK8s(configPath string) *CreateOptions {
citfCreateOptions := CreateOptionsIncludeAll(configPath)

citfCreateOptions.K8SInclude = false
return citfCreateOptions
}

// CreateOptionsIncludeAllButDocker returns CreateOptions where all fields except `Docker` are set to `true` and ConfigPath is set to configPath
func CreateOptionsIncludeAllButDocker(configPath string) *CreateOptions {
citfCreateOptions := CreateOptionsIncludeAll(configPath)

citfCreateOptions.DockerInclude = false
return citfCreateOptions
}

// CreateOptionsIncludeAllButLogger returns CreateOptions where all fields except `Logger` are set to `true` and ConfigPath is set to configPath
func CreateOptionsIncludeAllButLogger(configPath string) *CreateOptions {
citfCreateOptions := CreateOptionsIncludeAll(configPath)

citfCreateOptions.LoggerInclude = false
return citfCreateOptions
}
73 changes: 73 additions & 0 deletions example/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package example

import (
"testing"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/openebs/CITF"
citfoptions "github.com/openebs/CITF/citf_options"
)

var CitfInstance citf.CITF

func TestIntegrationExample(t *testing.T) {
RegisterFailHandler(Fail)

var err error
// Initializing CITF without config file.
// Also We should not include K8S as currently we don't have kubernetes environment setup
CitfInstance, err = citf.NewCITF(citfoptions.CreateOptionsIncludeAllButK8s(""))
Expect(err).NotTo(HaveOccurred())

RunSpecs(t, "Integration Test Suite")
}

var _ = BeforeSuite(func() {

// Setting up the default Platform i.e minikube
err := CitfInstance.Environment.Setup()
Expect(err).NotTo(HaveOccurred())

// You have to update the K8s config when environment has been set up
// this extra step will be unsolicited in upcoming changes.
err = CitfInstance.Reload(citfoptions.CreateOptionsIncludeAll(""))
Expect(err).NotTo(HaveOccurred())

// Wait until platform is up
time.Sleep(30 * time.Second)

err = CitfInstance.K8S.YAMLApply("./nginx-rc.yaml")
Expect(err).NotTo(HaveOccurred())

// Wait until the pod is up and running
time.Sleep(30 * time.Second)
})

var _ = AfterSuite(func() {

// Tear Down the Platform
err := CitfInstance.Environment.Teardown()
Expect(err).NotTo(HaveOccurred())
})

var _ = Describe("Integration Test", func() {
When("We check the log", func() {
It("has `started the controller` in the log", func() {
pods, err := CitfInstance.K8S.GetPods("default", "nginx")
Expect(err).NotTo(HaveOccurred())

// Give pods some time to generate logs
time.Sleep(2 * time.Second)

// Assuming that only 1 nginx pod is running
for _, v := range pods {
log, err := CitfInstance.K8S.GetLog(v.GetName(), "default")
Expect(err).NotTo(HaveOccurred())

Expect(log).Should(ContainSubstring("started the controller"))
}
})
})
})
21 changes: 21 additions & 0 deletions example/nginx-rc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 1
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
args: [/bin/sh, -c,
'echo "started the controller"']
ports:
- containerPort: 80
2 changes: 1 addition & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

set -e
echo "" > coverage.txt
PACKAGES=$(go list ./... | grep -v '/vendor/')
PACKAGES=$(go list ./... | grep -Ev 'example|/vendor/')
for d in $PACKAGES; do
go test -coverprofile=profile.out -covermode=atomic $d
if [ -f profile.out ]; then
Expand Down
Loading

0 comments on commit fa95811

Please sign in to comment.