// Test volume attachment by volume ID func volumeAttach( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("attaching volume") // Get next device name from executor nextDevice, err := client.Executor().NextDevice(context.Background().WithValue(context.ServiceKey, ebs.Name), utils.NewStore()) assert.NoError(t, err) if err != nil { t.Error("error getting next device name from executor") t.FailNow() } reply, token, err := client.API().VolumeAttach( nil, ebs.Name, volumeID, &types.VolumeAttachRequest{ NextDeviceName: &nextDevice, }) assert.NoError(t, err) if err != nil { t.Error("failed volumeAttach") t.FailNow() } apitests.LogAsJSON(reply, t) assert.NotEqual(t, token, "") return reply }
func TestVolumesWithAttachmentsMineWithNotMyInstanceID( t *testing.T) { tc, _, _, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { ctx := context.Background() iidm := types.InstanceIDMap{ "vfs": &types.InstanceID{ID: "none", Driver: "vfs"}, } ctx = ctx.WithValue(context.AllInstanceIDsKey, iidm) reply, err := client.API().Volumes(ctx, types.VolAttReqForInstance) if err != nil { t.Fatal(err) } assert.NotNil(t, reply["vfs"]["vfs-000"]) assert.NotNil(t, reply["vfs"]["vfs-001"]) assert.NotNil(t, reply["vfs"]["vfs-002"]) assert.Len(t, reply["vfs"]["vfs-000"].Attachments, 0) assert.Len(t, reply["vfs"]["vfs-001"].Attachments, 0) assert.Len(t, reply["vfs"]["vfs-002"].Attachments, 0) } apitests.RunWithClientType(t, types.ControllerClient, vfs.Name, tc, tf) }
func TestVolumeAttach(t *testing.T) { tf := func(config gofig.Config, client types.Client, t *testing.T) { nextDevice, err := client.Executor().NextDevice( context.Background().WithValue(context.ServiceKey, vfs.Name), utils.NewStore()) assert.NoError(t, err) if err != nil { t.FailNow() } request := &types.VolumeAttachRequest{ NextDeviceName: &nextDevice, } reply, attTokn, err := client.API().VolumeAttach( nil, vfs.Name, "vfs-002", request) assert.NoError(t, err) if reply == nil { t.FailNow() } assert.Equal(t, "/dev/xvdc", attTokn) assert.Equal(t, "vfs-002", reply.ID) assert.Equal(t, "/dev/xvdc", reply.Attachments[0].DeviceName) } apitests.Run(t, vfs.Name, newTestConfig(t), tf) }
func TestInstanceID(t *testing.T) { skipTest(t) iid, err := InstanceID(context.Background()) if !assert.NoError(t, err) { t.FailNow() } t.Logf("instanceID=%s", iid.String()) }
// Test is the APITestFunc for the NextDeviceTest. func (tt *NextDeviceTest) Test( config gofig.Config, client types.Client, t *testing.T) { ctx := context.Background().WithValue(context.ServiceKey, tt.Driver) val, err := client.Executor().NextDevice(ctx, utils.NewStore()) assert.NoError(t, err) assert.Equal(t, tt.Expected, val) }
func TestClient(t *testing.T) { apitests.Run(t, vfs.Name, newTestConfig(t), func(config gofig.Config, client types.Client, t *testing.T) { ctx := context.Background() iid, err := client.Executor().InstanceID( ctx.WithValue(context.ServiceKey, vfs.Name), utils.NewStore()) assert.NoError(t, err) assert.NotNil(t, iid) }) }
func newCLI(format, tpl string, tplTabs bool) *CLI { ctx := context.Background() if testing.Verbose() { context.SetLogLevel(ctx, log.DebugLevel) } else { context.SetLogLevel(ctx, log.WarnLevel) } return &CLI{ ctx: ctx, outputFormat: format, outputTemplate: tpl, outputTemplateTabs: tplTabs, } }
func TestStorageDriverVolumes(t *testing.T) { apitests.Run(t, vfs.Name, newTestConfig(t), func(config gofig.Config, client types.Client, t *testing.T) { vols, err := client.Storage().Volumes( context.Background().WithValue( context.ServiceKey, vfs.Name), &types.VolumesOpts{ Attachments: types.VolAttReqTrue, Opts: utils.NewStore()}) assert.NoError(t, err) assert.Len(t, vols, 2) }) }
func TestVolumeAttachWithControllerClient(t *testing.T) { tf := func(config gofig.Config, client types.Client, t *testing.T) { _, err := client.Executor().NextDevice( context.Background().WithValue(context.ServiceKey, vfs.Name), utils.NewStore()) assert.Error(t, err) assert.Equal(t, "unsupported op for client type", err.Error()) _, _, err = client.API().VolumeAttach( nil, vfs.Name, "vfs-002", &types.VolumeAttachRequest{}) assert.Error(t, err) assert.Equal(t, "unsupported op for client type", err.Error()) } apitests.RunWithClientType( t, types.ControllerClient, vfs.Name, newTestConfig(t), tf) }
// Test is the APITestFunc for the InstanceTest. func (tt *InstanceTest) Test( config gofig.Config, client types.Client, t *testing.T) { expectedBuf, err := json.Marshal(tt.Expected) assert.NoError(t, err) expectedJSON := string(expectedBuf) ctx := context.Background().WithValue(context.ServiceKey, tt.Driver) iid, err := client.Storage().InstanceInspect(ctx, utils.NewStore()) assert.NoError(t, err) iidBuf, err := json.Marshal(iid) assert.NoError(t, err) iidJSON := string(iidBuf) assert.Equal(t, expectedJSON, iidJSON) }
// Check if InstanceID metadata is properly returned by executor // and InstanceID.ID is filled out by InstanceInspect func TestInstanceID(t *testing.T) { if skipTests() { t.SkipNow() } // create storage driver sd, err := registry.NewStorageDriver(ebs.Name) if err != nil { t.Fatal(err) } // initialize storage driver ctx := context.Background() if err := sd.Init(ctx, registry.NewConfig()); err != nil { t.Fatal(err) } // Get Instance ID metadata from executor iid, err := ebsUtils.InstanceID(ctx) assert.NoError(t, err) if err != nil { t.Fatal(err) } // Fill in Instance ID's ID field with InstanceInspect ctx = ctx.WithValue(context.InstanceIDKey, iid) i, err := sd.InstanceInspect(ctx, utils.NewStore()) if err != nil { t.Fatal(err) } iid = i.InstanceID // test resulting InstanceID apitests.Run( t, ebs.Name, nil, (&apitests.InstanceIDTest{ Driver: ebs.Name, Expected: iid, }).Test) }
func TestInstanceID(t *testing.T) { //PASSES lowercase hidden for testing other stuff if skipTests() { t.SkipNow() } sd, err := registry.NewStorageDriver(rackspace.Name) if err != nil { t.Fatal(err) } ctx := context.Background() configR := registry.NewConfig() if err := configR.ReadConfig(bytes.NewReader(configYAML)); err != nil { panic(err) } if err := sd.Init(ctx, configR); err != nil { t.Fatal(err) } iid, err := rackspacex.InstanceID(configR) if err != nil { t.Fatal(err) } ctx = ctx.WithValue(context.InstanceIDKey, iid) i, err := sd.InstanceInspect(ctx, utils.NewStore()) if err != nil { t.Fatal(err) } iid = i.InstanceID apitests.Run( t, rackspace.Name, configYAML, (&apitests.InstanceIDTest{ Driver: rackspace.Name, Expected: iid, }).Test) }
func TestInstanceID(t *testing.T) { if skipTests() { t.SkipNow() } sd, err := registry.NewStorageDriver(efs.Name) if err != nil { t.Fatal(err) } ctx := context.Background() if err := sd.Init(ctx, registry.NewConfig()); err != nil { t.Fatal(err) } iid, err := efsx.InstanceID() assert.NoError(t, err) if err != nil { t.Error("failed TestInstanceID") t.FailNow() } assert.NotEqual(t, iid, "") ctx = ctx.WithValue(context.InstanceIDKey, iid) i, err := sd.InstanceInspect(ctx, utils.NewStore()) if err != nil { t.Fatal(err) } iid = i.InstanceID apitests.Run( t, efs.Name, configYAML, (&apitests.InstanceIDTest{ Driver: efs.Name, Expected: iid, }).Test) }
// Test is the APITestFunc for the LocalDevicesTest. func (tt *LocalDevicesTest) Test( config gofig.Config, client types.Client, t *testing.T) { expectedBuf, err := tt.Expected.MarshalText() assert.NoError(t, err) expectedText := string(expectedBuf) ctx := context.Background().WithValue(context.ServiceKey, tt.Driver) val, err := client.Executor().LocalDevices(ctx, &types.LocalDevicesOpts{ ScanType: types.DeviceScanQuick, Opts: utils.NewStore(), }) assert.NoError(t, err) buf, err := val.MarshalText() assert.NoError(t, err) actualText := string(buf) assert.Equal(t, expectedText, actualText) }
// Run the CLI. func Run() { updateLogLevel() var ( err error traceProfile *os.File cpuProfile *os.File ctx = context.Background() exit sync.Once ) onExit := func() { if traceProfile != nil { ctx.Info("stopping trace profile") trace.Stop() traceProfile.Close() ctx.Debug("stopped trace profile") } if cpuProfile != nil { ctx.Info("stopping cpu profile") pprof.StopCPUProfile() cpuProfile.Close() ctx.Debug("stopped cpu profile") } ctx.Info("exiting process") } core.RegisterSignalHandler(func(ctx apitypes.Context, s os.Signal) { if ok, _ := core.IsExitSignal(s); ok { ctx.Info("received exit signal") exit.Do(onExit) } }) if p := os.Getenv("REXRAY_TRACE_PROFILE"); p != "" { if traceProfile, err = os.Create(p); err != nil { panic(err) } if err = trace.Start(traceProfile); err != nil { panic(err) } ctx.WithField("path", traceProfile.Name()).Info("trace profile enabled") } if p := os.Getenv("REXRAY_CPU_PROFILE"); p != "" { if cpuProfile, err = os.Create(p); err != nil { panic(err) } if err = pprof.StartCPUProfile(cpuProfile); err != nil { panic(err) } ctx.WithField("path", cpuProfile.Name()).Info("cpu profile enabled") } if p := os.Getenv("REXRAY_PROFILE_ADDR"); p != "" { go http.ListenAndServe(p, http.DefaultServeMux) ctx.WithField("address", p).Info("http pprof enabled") } core.TrapSignals(ctx) ctx.Debug("trapped signals") cli.Execute(ctx) ctx.Debug("completed cli execution") exit.Do(onExit) ctx.Debug("completed onExit at end of program") }
// Run runs the executor CLI. func Run() { args := os.Args if len(args) < 3 { printUsageAndExit() } d, err := registry.NewStorageExecutor(args[1]) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } driverName := strings.ToLower(d.Name()) config, err := apiconfig.NewConfig() if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } apiconfig.UpdateLogLevel(config) ctx := context.Background() if err := d.Init(ctx, config); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } cmd := cmdRx.FindString(args[2]) if cmd == "" { printUsageAndExit() } store := utils.NewStore() var ( result interface{} op string exitCode int ) if strings.EqualFold(cmd, apitypes.LSXCmdSupported) { op = "supported" if dws, ok := d.(apitypes.StorageExecutorWithSupported); ok { opResult, opErr := dws.Supported(ctx, store) if opErr != nil { err = opErr } else { result = opResult } } else { err = apitypes.ErrNotImplemented } } else if strings.EqualFold(cmd, apitypes.LSXCmdInstanceID) { op = "instance ID" opResult, opErr := d.InstanceID(ctx, store) if opErr != nil { err = opErr } else { opResult.Driver = driverName result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdNextDevice) { op = "next device" opResult, opErr := d.NextDevice(ctx, store) if opErr != nil && opErr != apitypes.ErrNotImplemented { err = opErr } else { result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdLocalDevices) { if len(args) < 4 { printUsageAndExit() } op = "local devices" opResult, opErr := d.LocalDevices(ctx, &apitypes.LocalDevicesOpts{ ScanType: apitypes.ParseDeviceScanType(args[3]), Opts: store, }) opResult.Driver = driverName if opErr != nil { err = opErr } else { result = opResult } } else if strings.EqualFold(cmd, apitypes.LSXCmdWaitForDevice) { if len(args) < 5 { printUsageAndExit() } op = "wait" opts := &apitypes.WaitForDeviceOpts{ LocalDevicesOpts: apitypes.LocalDevicesOpts{ ScanType: apitypes.ParseDeviceScanType(args[3]), Opts: store, }, Token: strings.ToLower(args[4]), Timeout: utils.DeviceAttachTimeout(args[5]), } ldl := func() (bool, *apitypes.LocalDevices, error) { ldm, err := d.LocalDevices(ctx, &opts.LocalDevicesOpts) if err != nil { return false, nil, err } for k := range ldm.DeviceMap { if strings.ToLower(k) == opts.Token { return true, ldm, nil } } return false, ldm, nil } var ( found bool opErr error opResult *apitypes.LocalDevices timeoutC = time.After(opts.Timeout) tick = time.Tick(500 * time.Millisecond) ) TimeoutLoop: for { select { case <-timeoutC: exitCode = apitypes.LSXExitCodeTimedOut break TimeoutLoop case <-tick: if found, opResult, opErr = ldl(); found || opErr != nil { break TimeoutLoop } } } if opErr != nil { err = opErr } else { opResult.Driver = driverName result = opResult } } if err != nil { // if the function is not implemented then exit with // apitypes.LSXExitCodeNotImplemented to let callers // know that the function is unsupported on this system exitCode = 1 if strings.EqualFold(err.Error(), apitypes.ErrNotImplemented.Error()) { exitCode = apitypes.LSXExitCodeNotImplemented } fmt.Fprintf(os.Stderr, "error: error getting %s: %v\n", op, err) os.Exit(exitCode) } switch tr := result.(type) { case bool: fmt.Fprintf(os.Stdout, "%v", result) case string: fmt.Fprintln(os.Stdout, result) case encoding.TextMarshaler: buf, err := tr.MarshalText() if err != nil { fmt.Fprintf(os.Stderr, "error: error encoding %s: %v\n", op, err) os.Exit(1) } os.Stdout.Write(buf) default: buf, err := json.Marshal(result) if err != nil { fmt.Fprintf(os.Stderr, "error: error encoding %s: %v\n", op, err) os.Exit(1) } if isNullBuf(buf) { os.Stdout.Write(emptyJSONBuff) } else { os.Stdout.Write(buf) } } os.Exit(exitCode) }