Add Root List test and fs.Limited tests for single files

This commit is contained in:
Nick Craig-Wood 2014-07-31 21:24:52 +01:00
parent ff91698fb5
commit 3e27ff1b95
10 changed files with 147 additions and 38 deletions

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }

View File

@ -184,9 +184,10 @@ func Find(name string) (*FsInfo, error) {
// NewFs makes a new Fs object from the path // NewFs makes a new Fs object from the path
// //
// The path is of the form service://path // The path is of the form remote:path
// //
// Services are looked up in the config file // Remotes are looked up in the config file. If the remote isn't
// found then NotFoundInConfigFile will be returned.
func NewFs(path string) (Fs, error) { func NewFs(path string) (Fs, error) {
parts := matcher.FindStringSubmatch(path) parts := matcher.FindStringSubmatch(path)
fsName, configName, fsPath := "local", "local", path fsName, configName, fsPath := "local", "local", path

View File

@ -125,29 +125,53 @@ func RandomString(n int) string {
return string(out) return string(out)
} }
// Creates a temporary directory name for local remotes
func LocalRemote() (path string, err error) {
path, err = ioutil.TempDir("", "rclone")
if err == nil {
// Now remove the directory
err = os.Remove(path)
}
return
}
// Make a random bucket or subdirectory name
//
// Returns a random remote name plus the leaf name
func RandomRemoteName(remoteName string) (string, string, error) {
var err error
var leafName string
// Make a directory if remote name is null
if remoteName == "" {
remoteName, err = LocalRemote()
if err != nil {
return "", "", err
}
} else {
if !strings.HasSuffix(remoteName, ":") {
remoteName += "/"
}
leafName = RandomString(32)
remoteName += leafName
}
return remoteName, leafName, nil
}
// Make a random bucket or subdirectory on the remote // Make a random bucket or subdirectory on the remote
// //
// Call the finalise function returned to Purge the fs at the end (and // Call the finalise function returned to Purge the fs at the end (and
// the parent if necessary) // the parent if necessary)
func RandomRemote(remoteName string, subdir bool) (fs.Fs, func(), error) { func RandomRemote(remoteName string, subdir bool) (fs.Fs, func(), error) {
// Make a directory if remote name is null
rmdir := ""
var err error var err error
if remoteName == "" { var parentRemote fs.Fs
remoteName, err = ioutil.TempDir("", "rclone")
if err != nil { remoteName, _, err = RandomRemoteName(remoteName)
return nil, nil, err if err != nil {
} return nil, nil, err
rmdir = remoteName
} }
if !strings.HasSuffix(remoteName, ":") {
remoteName += "/"
}
remoteName += RandomString(32)
var parentRemote fs.Fs
if subdir { if subdir {
var err error
parentRemote, err = fs.NewFs(remoteName) parentRemote, err = fs.NewFs(remoteName)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -168,13 +192,6 @@ func RandomRemote(remoteName string, subdir bool) (fs.Fs, func(), error) {
log.Printf("Failed to purge %v: %v", parentRemote, err) log.Printf("Failed to purge %v: %v", parentRemote, err)
} }
} }
// Delete directory if we made one above
if rmdir != "" {
err := os.RemoveAll(rmdir)
if err != nil {
Fatalf("Failed to remove %q: %v", rmdir, err)
}
}
} }
return remote, finalise, nil return remote, finalise, nil
@ -191,7 +208,7 @@ func TestMkdir(remote fs.Fs) {
func TestPurge(remote fs.Fs) { func TestPurge(remote fs.Fs) {
err := fs.Purge(remote) err := fs.Purge(remote)
if err != nil { if err != nil {
log.Fatalf("Purge failed: %v", err) Fatalf("Purge failed: %v", err)
} }
CheckListing(remote, []Item{}) CheckListing(remote, []Item{})
} }

View File

@ -7,8 +7,11 @@ import (
"bytes" "bytes"
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"fmt"
"io" "io"
"log" "log"
"os"
"strings"
"testing" "testing"
"time" "time"
@ -17,11 +20,12 @@ import (
) )
var ( var (
remote fs.Fs remote fs.Fs
RemoteName = "" RemoteName = ""
remoteFinalise func() subRemoteName = ""
NilObject fs.Object subRemoteLeaf = ""
file1 = fstest.Item{ NilObject fs.Object
file1 = fstest.Item{
ModTime: fstest.Time("2001-02-03T04:05:06.499999999Z"), ModTime: fstest.Time("2001-02-03T04:05:06.499999999Z"),
Path: "file name.txt", Path: "file name.txt",
} }
@ -32,11 +36,22 @@ var (
) )
func TestInit(t *testing.T) { func TestInit(t *testing.T) {
var err error
fs.LoadConfig() fs.LoadConfig()
fs.Config.Verbose = false fs.Config.Verbose = false
fs.Config.Quiet = true fs.Config.Quiet = true
var err error if RemoteName == "" {
remote, remoteFinalise, err = fstest.RandomRemote(RemoteName, false) RemoteName, err = fstest.LocalRemote()
if err != nil {
log.Fatalf("Failed to create tmp dir: %v", err)
}
}
subRemoteName, subRemoteLeaf, err = fstest.RandomRemoteName(RemoteName)
if err != nil {
t.Fatalf("Couldn't make remote name: %v", err)
}
remote, err = fs.NewFs(subRemoteName)
if err == fs.NotFoundInConfigFile { if err == fs.NotFoundInConfigFile {
log.Printf("Didn't find %q in config file - skipping tests", RemoteName) log.Printf("Didn't find %q in config file - skipping tests", RemoteName)
return return
@ -160,6 +175,24 @@ func TestFsListDirFile2(t *testing.T) {
} }
} }
func TestFsListDirRoot(t *testing.T) {
skipIfNotOk(t)
rootRemote, err := fs.NewFs(RemoteName)
if err != nil {
t.Fatal("Failed to make remote %q: %v", RemoteName, err)
}
found := false
for obj := range rootRemote.ListDir() {
fmt.Printf("obj = %q\n", obj.Name)
if obj.Name == subRemoteLeaf {
found = true
}
}
if !found {
t.Errorf("Didn't find %q", subRemoteLeaf)
}
}
func TestFsListFile1(t *testing.T) { func TestFsListFile1(t *testing.T) {
skipIfNotOk(t) skipIfNotOk(t)
fstest.CheckListing(remote, []fstest.Item{file1, file2}) fstest.CheckListing(remote, []fstest.Item{file1, file2})
@ -312,6 +345,36 @@ func TestObjectStorable(t *testing.T) {
} }
} }
func TestLimitedFs(t *testing.T) {
skipIfNotOk(t)
remoteName := subRemoteName + "/" + file2.Path
file2Copy := file2
file2Copy.Path = "z.txt"
fileRemote, err := fs.NewFs(remoteName)
if err != nil {
t.Fatal("Failed to make remote %q: %v", remoteName, err)
}
fstest.CheckListing(fileRemote, []fstest.Item{file2Copy})
_, ok := fileRemote.(*fs.Limited)
if !ok {
t.Errorf("%v is not a fs.Limited", fileRemote)
}
}
func TestLimitedFsNotFound(t *testing.T) {
skipIfNotOk(t)
remoteName := subRemoteName + "/not found.txt"
fileRemote, err := fs.NewFs(remoteName)
if err != nil {
t.Fatal("Failed to make remote %q: %v", remoteName, err)
}
fstest.CheckListing(fileRemote, []fstest.Item{})
_, ok := fileRemote.(*fs.Limited)
if ok {
t.Errorf("%v is is a fs.Limited", fileRemote)
}
}
func TestObjectRemove(t *testing.T) { func TestObjectRemove(t *testing.T) {
skipIfNotOk(t) skipIfNotOk(t)
obj := findObject(t, file1.Path) obj := findObject(t, file1.Path)
@ -333,7 +396,11 @@ func TestObjectPurge(t *testing.T) {
func TestFinalise(t *testing.T) { func TestFinalise(t *testing.T) {
skipIfNotOk(t) skipIfNotOk(t)
if remoteFinalise != nil { if strings.HasPrefix(RemoteName, "/") {
remoteFinalise() // Remove temp directory
err := os.Remove(RemoteName)
if err != nil {
log.Printf("Failed to remove %q: %v\n", RemoteName, err)
}
} }
} }

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }

View File

@ -1,11 +1,17 @@
Change lsd command so it doesn't show -1 Change lsd command so it doesn't show -1
* Make sure all Fses show -1 for objects Zero for dates etc * Make sure all Fses show -1 for objects Zero for dates etc
* Make test?
Make unit tests for the fses Make a subdir test on an existing file (file2 say) (List and ListDir)
* Make them try to load a TestFSName config
* Then do a proper unit test of each one Put the TestRemote names into the Fs description
* If there is no TestFSName config it should exit quietly Make rclonetest use the TestRemote name automatically
* However the Local FS should default to a tmpdir Put rclonetest back into rclone as tests
Run errcheck and go vet in the make file
.. Also race detector?
Write developer manual
Todo Todo
* FIXME: More -dry-run checks for object transfer * FIXME: More -dry-run checks for object transfer

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }

View File

@ -29,6 +29,7 @@ func TestFsNewFsObjectNotFound(t *testing.T) { fstests.TestFsNewFsObjectNotFound
func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) } func TestFsPutFile1(t *testing.T) { fstests.TestFsPutFile1(t) }
func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) } func TestFsPutFile2(t *testing.T) { fstests.TestFsPutFile2(t) }
func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) } func TestFsListDirFile2(t *testing.T) { fstests.TestFsListDirFile2(t) }
func TestFsListDirRoot(t *testing.T) { fstests.TestFsListDirRoot(t) }
func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) } func TestFsListFile1(t *testing.T) { fstests.TestFsListFile1(t) }
func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) } func TestFsNewFsObject(t *testing.T) { fstests.TestFsNewFsObject(t) }
func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) } func TestFsListFile1and2(t *testing.T) { fstests.TestFsListFile1and2(t) }
@ -44,6 +45,8 @@ func TestObjectSize(t *testing.T) { fstests.TestObjectSize(t) }
func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) } func TestObjectOpen(t *testing.T) { fstests.TestObjectOpen(t) }
func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) } func TestObjectUpdate(t *testing.T) { fstests.TestObjectUpdate(t) }
func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) } func TestObjectStorable(t *testing.T) { fstests.TestObjectStorable(t) }
func TestLimitedFs(t *testing.T) { fstests.TestLimitedFs(t) }
func TestLimitedFsNotFound(t *testing.T) { fstests.TestLimitedFsNotFound(t) }
func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) } func TestObjectRemove(t *testing.T) { fstests.TestObjectRemove(t) }
func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) } func TestObjectPurge(t *testing.T) { fstests.TestObjectPurge(t) }
func TestFinalise(t *testing.T) { fstests.TestFinalise(t) } func TestFinalise(t *testing.T) { fstests.TestFinalise(t) }