fix golint issues in test/e2e_node

This commit is contained in:
SataQiu 2019-11-07 11:59:05 +08:00
parent 41757d673e
commit d2bdf89a8b
44 changed files with 104 additions and 101 deletions

View File

@ -536,7 +536,6 @@ staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder
test/e2e/common
test/e2e/lifecycle/bootstrap
test/e2e/storage/vsphere
test/e2e_node
test/e2e_node/remote
test/e2e_node/runner/remote
test/utils

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"bytes"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"
@ -36,7 +36,9 @@ import (
)
const (
// TimeSeriesTag is the tag for time series.
TimeSeriesTag = "[Result:TimeSeries]"
// TimeSeriesEnd is the end tag for time series.
TimeSeriesEnd = "[Finish:TimeSeries]"
)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"time"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"path/filepath"
@ -96,8 +96,8 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
podRECMD := "devs=$(ls /tmp/ | egrep '^Dev-[0-9]+$') && echo stub devices: $devs"
pod1 := f.PodClient().CreateSync(makeBusyboxPod(resourceName, podRECMD))
deviceIDRE := "stub devices: (Dev-[0-9]+)"
devId1 := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
gomega.Expect(devId1).To(gomega.Not(gomega.Equal("")))
devID1 := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
gomega.Expect(devID1).To(gomega.Not(gomega.Equal("")))
podResources, err := getNodeDevices()
var resourcesForOurPod *kubeletpodresourcesv1alpha1.PodResources
@ -125,8 +125,8 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
ensurePodContainerRestart(f, pod1.Name, pod1.Name)
ginkgo.By("Confirming that device assignment persists even after container restart")
devIdAfterRestart := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIdAfterRestart, devId1)
devIDAfterRestart := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIDAfterRestart, devID1)
restartTime := time.Now()
ginkgo.By("Restarting Kubelet")
@ -164,8 +164,8 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
ensurePodContainerRestart(f, pod1.Name, pod1.Name)
ginkgo.By("Confirming that after a kubelet restart, fake-device assignement is kept")
devIdRestart1 := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart1, devId1)
devIDRestart1 := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart1, devID1)
ginkgo.By("Waiting for resource to become available on the local node after re-registration")
gomega.Eventually(func() bool {
@ -179,9 +179,9 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
pod2 := f.PodClient().CreateSync(makeBusyboxPod(resourceName, podRECMD))
ginkgo.By("Checking that pod got a different fake device")
devId2 := parseLog(f, pod2.Name, pod2.Name, deviceIDRE)
devID2 := parseLog(f, pod2.Name, pod2.Name, deviceIDRE)
gomega.Expect(devId1).To(gomega.Not(gomega.Equal(devId2)))
gomega.Expect(devID1).To(gomega.Not(gomega.Equal(devID2)))
ginkgo.By("By deleting the pods and waiting for container removal")
err = f.ClientSet.CoreV1().Pods(metav1.NamespaceSystem).Delete(dp.Name, &deleteOptions)
@ -197,12 +197,12 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
ginkgo.By("Checking that scheduled pods can continue to run even after we delete device plugin.")
ensurePodContainerRestart(f, pod1.Name, pod1.Name)
devIdRestart1 = parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart1, devId1)
devIDRestart1 = parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart1, devID1)
ensurePodContainerRestart(f, pod2.Name, pod2.Name)
devIdRestart2 := parseLog(f, pod2.Name, pod2.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart2, devId2)
devIDRestart2 := parseLog(f, pod2.Name, pod2.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart2, devID2)
ginkgo.By("Re-register resources")
devicePluginPod, err = f.ClientSet.CoreV1().Pods(metav1.NamespaceSystem).Create(dp)

View File

@ -14,6 +14,5 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// e2e_node contains e2e tests specific to the node
// TODO: rename this package e2e-node
package e2e_node // import "k8s.io/kubernetes/test/e2e_node"
// Package e2enode contains e2e tests specific to the node
package e2enode // import "k8s.io/kubernetes/test/e2e_node"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"context"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"crypto/md5"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -18,7 +18,7 @@ limitations under the License.
// To run tests in this suite
// NOTE: This test suite requires password-less sudo capabilities to run the kubelet and kube-apiserver.
package e2e_node
package e2enode
import (
"bytes"
@ -305,7 +305,7 @@ func getNode(c *clientset.Clientset) (*v1.Node, error) {
nodes, err := c.CoreV1().Nodes().List(metav1.ListOptions{})
framework.ExpectNoError(err, "should be able to list nodes.")
if nodes == nil {
return nil, fmt.Errorf("the node list is nil.")
return nil, fmt.Errorf("the node list is nil")
}
gomega.Expect(len(nodes.Items) > 1).NotTo(gomega.BeTrue(), "the number of nodes is more than 1.")
if len(nodes.Items) == 0 {

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,10 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import "github.com/onsi/ginkgo"
// SIGDescribe annotates the test with the SIG label.
func SIGDescribe(text string, body func()) bool {
return ginkgo.Describe("[sig-node] "+text, body)
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"
@ -78,16 +78,16 @@ var _ = framework.KubeDescribe("GarbageCollect [Serial][NodeFeature:GarbageColle
// They differentiate pods from one another, and allow filtering
// by names to identify which containers belong to which pods
// They must be unique, and must not end in a number
first_suffix := "one-container-no-restarts"
second_suffix := "many-containers-many-restarts-one-pod"
third_suffix := "many-containers-many-restarts-"
firstSuffix := "one-container-no-restarts"
secondSuffix := "many-containers-many-restarts-one-pod"
thirdSuffix := "many-containers-many-restarts-"
tests := []testRun{
{
testName: "One Non-restarting Container",
testPods: []*testPodSpec{
{
podName: podNamePrefix + first_suffix,
containerPrefix: containerNamePrefix + first_suffix,
podName: podNamePrefix + firstSuffix,
containerPrefix: containerNamePrefix + firstSuffix,
restartCount: 0,
numContainers: 1,
},
@ -97,8 +97,8 @@ var _ = framework.KubeDescribe("GarbageCollect [Serial][NodeFeature:GarbageColle
testName: "Many Restarting Containers",
testPods: []*testPodSpec{
{
podName: podNamePrefix + second_suffix,
containerPrefix: containerNamePrefix + second_suffix,
podName: podNamePrefix + secondSuffix,
containerPrefix: containerNamePrefix + secondSuffix,
restartCount: 4,
numContainers: 4,
},
@ -108,20 +108,20 @@ var _ = framework.KubeDescribe("GarbageCollect [Serial][NodeFeature:GarbageColle
testName: "Many Pods with Many Restarting Containers",
testPods: []*testPodSpec{
{
podName: podNamePrefix + third_suffix + "one",
containerPrefix: containerNamePrefix + third_suffix + "one",
podName: podNamePrefix + thirdSuffix + "one",
containerPrefix: containerNamePrefix + thirdSuffix + "one",
restartCount: 3,
numContainers: 4,
},
{
podName: podNamePrefix + third_suffix + "two",
containerPrefix: containerNamePrefix + third_suffix + "two",
podName: podNamePrefix + thirdSuffix + "two",
containerPrefix: containerNamePrefix + thirdSuffix + "two",
restartCount: 2,
numContainers: 6,
},
{
podName: podNamePrefix + third_suffix + "three",
containerPrefix: containerNamePrefix + third_suffix + "three",
podName: podNamePrefix + thirdSuffix + "three",
containerPrefix: containerNamePrefix + thirdSuffix + "three",
restartCount: 3,
numContainers: 5,
},

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"bytes"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"os/exec"
@ -79,7 +79,7 @@ var _ = framework.KubeDescribe("NVIDIA GPU Device Plugin [Feature:GPUDevicePlugi
p1 := f.PodClient().CreateSync(makeBusyboxPod(gpu.NVIDIAGPUResourceName, podRECMD))
deviceIDRE := "gpu devices: (nvidia[0-9]+)"
devId1 := parseLog(f, p1.Name, p1.Name, deviceIDRE)
devID1 := parseLog(f, p1.Name, p1.Name, deviceIDRE)
p1, err := f.PodClient().Get(p1.Name, metav1.GetOptions{})
framework.ExpectNoError(err)
@ -88,8 +88,8 @@ var _ = framework.KubeDescribe("NVIDIA GPU Device Plugin [Feature:GPUDevicePlugi
ginkgo.By("Confirming that after a kubelet and pod restart, GPU assignment is kept")
ensurePodContainerRestart(f, p1.Name, p1.Name)
devIdRestart1 := parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart1, devId1)
devIDRestart1 := parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart1, devID1)
ginkgo.By("Restarting Kubelet and creating another pod")
restartKubelet()
@ -100,9 +100,9 @@ var _ = framework.KubeDescribe("NVIDIA GPU Device Plugin [Feature:GPUDevicePlugi
p2 := f.PodClient().CreateSync(makeBusyboxPod(gpu.NVIDIAGPUResourceName, podRECMD))
ginkgo.By("Checking that pods got a different GPU")
devId2 := parseLog(f, p2.Name, p2.Name, deviceIDRE)
devID2 := parseLog(f, p2.Name, p2.Name, deviceIDRE)
framework.ExpectEqual(devId1, devId2)
framework.ExpectEqual(devID1, devID2)
ginkgo.By("Deleting device plugin.")
f.ClientSet.CoreV1().Pods(metav1.NamespaceSystem).Delete(devicePluginPod.Name, &metav1.DeleteOptions{})
@ -114,21 +114,21 @@ var _ = framework.KubeDescribe("NVIDIA GPU Device Plugin [Feature:GPUDevicePlugi
}, 10*time.Minute, framework.Poll).Should(gomega.BeTrue())
ginkgo.By("Checking that scheduled pods can continue to run even after we delete device plugin.")
ensurePodContainerRestart(f, p1.Name, p1.Name)
devIdRestart1 = parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart1, devId1)
devIDRestart1 = parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart1, devID1)
ensurePodContainerRestart(f, p2.Name, p2.Name)
devIdRestart2 := parseLog(f, p2.Name, p2.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart2, devId2)
devIDRestart2 := parseLog(f, p2.Name, p2.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart2, devID2)
ginkgo.By("Restarting Kubelet.")
restartKubelet()
ginkgo.By("Checking that scheduled pods can continue to run even after we delete device plugin and restart Kubelet.")
ensurePodContainerRestart(f, p1.Name, p1.Name)
devIdRestart1 = parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart1, devId1)
devIDRestart1 = parseLog(f, p1.Name, p1.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart1, devID1)
ensurePodContainerRestart(f, p2.Name, p2.Name)
devIdRestart2 = parseLog(f, p2.Name, p2.Name, deviceIDRE)
framework.ExpectEqual(devIdRestart2, devId2)
devIDRestart2 = parseLog(f, p2.Name, p2.Name, deviceIDRE)
framework.ExpectEqual(devIDRestart2, devID2)
logDevicePluginMetrics()
// Cleanup

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"k8s.io/api/core/v1"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"
@ -133,7 +133,7 @@ func getPuller() (puller, error) {
return nil, fmt.Errorf("can't prepull images, unknown container runtime %q", runtime)
}
// Pre-fetch all images tests depend on so that we don't fail in an actual test.
// PrePullAllImages pre-fetches all images tests depend on so that we don't fail in an actual test.
func PrePullAllImages() error {
puller, err := getPuller()
if err != nil {

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"github.com/onsi/ginkgo"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
goerrors "errors"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"strings"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"bytes"
@ -64,6 +64,8 @@ var (
systemContainers map[string]string
)
// ResourceCollector is a collector object which collects
// resource usage periodically from Cadvisor.
type ResourceCollector struct {
client *cadvisorclient.Client
request *cadvisorapiv2.RequestOptions
@ -439,7 +441,7 @@ func newTestPods(numPods int, volume bool, imageName, podType string) []*v1.Pod
return pods
}
// GetResourceSeriesWithLabels gets the time series of resource usage of each container.
// GetResourceTimeSeries gets the time series of resource usage of each container.
func (r *ResourceCollector) GetResourceTimeSeries() map[string]*perftype.ResourceSeries {
resourceSeries := make(map[string]*perftype.ResourceSeries)
for key, name := range systemContainers {
@ -461,12 +463,12 @@ const kubeletProcessName = "kubelet"
func getPidsForProcess(name, pidFile string) ([]int, error) {
if len(pidFile) > 0 {
if pid, err := getPidFromPidFile(pidFile); err == nil {
pid, err := getPidFromPidFile(pidFile)
if err == nil {
return []int{pid}, nil
} else {
// log the error and fall back to pidof
runtime.HandleError(err)
}
// log the error and fall back to pidof
runtime.HandleError(err)
}
return procfs.PidOf(name)
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"
@ -72,19 +72,19 @@ var _ = framework.KubeDescribe("ResourceMetricsAPI", func() {
matchV1alpha1Expectations := gstruct.MatchAllKeys(gstruct.Keys{
"scrape_error": gstruct.Ignore(),
"node_cpu_usage_seconds_total": gstruct.MatchAllElements(nodeId, gstruct.Elements{
"node_cpu_usage_seconds_total": gstruct.MatchAllElements(nodeID, gstruct.Elements{
"": boundedSample(1, 1e6),
}),
"node_memory_working_set_bytes": gstruct.MatchAllElements(nodeId, gstruct.Elements{
"node_memory_working_set_bytes": gstruct.MatchAllElements(nodeID, gstruct.Elements{
"": boundedSample(10*volume.Mb, memoryLimit),
}),
"container_cpu_usage_seconds_total": gstruct.MatchElements(containerId, gstruct.IgnoreExtras, gstruct.Elements{
"container_cpu_usage_seconds_total": gstruct.MatchElements(containerID, gstruct.IgnoreExtras, gstruct.Elements{
fmt.Sprintf("%s::%s::%s", f.Namespace.Name, pod0, "busybox-container"): boundedSample(0, 100),
fmt.Sprintf("%s::%s::%s", f.Namespace.Name, pod1, "busybox-container"): boundedSample(0, 100),
}),
"container_memory_working_set_bytes": gstruct.MatchAllElements(containerId, gstruct.Elements{
"container_memory_working_set_bytes": gstruct.MatchAllElements(containerID, gstruct.Elements{
fmt.Sprintf("%s::%s::%s", f.Namespace.Name, pod0, "busybox-container"): boundedSample(10*volume.Kb, 80*volume.Mb),
fmt.Sprintf("%s::%s::%s", f.Namespace.Name, pod1, "busybox-container"): boundedSample(10*volume.Kb, 80*volume.Mb),
}),
@ -114,11 +114,11 @@ func getV1alpha1ResourceMetrics() (metrics.KubeletMetrics, error) {
return metrics.GrabKubeletMetricsWithoutProxy(framework.TestContext.NodeName+":10255", "/metrics/resource/"+kubeletresourcemetricsv1alpha1.Version)
}
func nodeId(element interface{}) string {
func nodeID(element interface{}) string {
return ""
}
func containerId(element interface{}) string {
func containerID(element interface{}) string {
el := element.(*model.Sample)
return fmt.Sprintf("%s::%s::%s", el.Metric["namespace"], el.Metric["pod"], el.Metric["container"])
}

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"
@ -33,9 +33,9 @@ import (
"github.com/onsi/gomega"
)
// waitForPods waits for timeout duration, for pod_count.
// waitForPods waits for timeout duration, for podCount.
// If the timeout is hit, it returns the list of currently running pods.
func waitForPods(f *framework.Framework, pod_count int, timeout time.Duration) (runningPods []*v1.Pod) {
func waitForPods(f *framework.Framework, podCount int, timeout time.Duration) (runningPods []*v1.Pod) {
for start := time.Now(); time.Since(start) < timeout; time.Sleep(10 * time.Second) {
podList, err := f.PodClient().List(metav1.ListOptions{})
if err != nil {
@ -51,7 +51,7 @@ func waitForPods(f *framework.Framework, pod_count int, timeout time.Duration) (
runningPods = append(runningPods, &pod)
}
framework.Logf("Running pod count %d", len(runningPods))
if len(runningPods) >= pod_count {
if len(runningPods) >= podCount {
break
}
}
@ -92,7 +92,7 @@ var _ = framework.KubeDescribe("Restart [Serial] [Slow] [Disruptive] [NodeFeatur
framework.Failf("Failed to start %d pods, cannot test that restarting container runtime doesn't leak IPs", minPods)
}
for i := 0; i < restartCount; i += 1 {
for i := 0; i < restartCount; i++ {
ginkgo.By(fmt.Sprintf("Killing container runtime iteration %d", i))
// Wait for container runtime to be running
var pid int

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"time"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"encoding/json"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"path/filepath"

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
func isXfs(dir string) bool {
return false

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e_node
package e2enode
import (
"time"