github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/test_framework/mockDirectoryWrapper.go (about)

     1  package test_framework
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/balzaczyy/golucene/core/index"
     7  	"github.com/balzaczyy/golucene/core/store"
     8  	"github.com/balzaczyy/golucene/core/util"
     9  	. "github.com/balzaczyy/golucene/test_framework/util"
    10  	"io"
    11  	"log"
    12  	"math/rand"
    13  	"os"
    14  	"reflect"
    15  	"runtime"
    16  	"runtime/debug"
    17  	"sort"
    18  	// "strings"
    19  	"sync"
    20  )
    21  
    22  // store/MockDirectoryWrapper.java
    23  
    24  /*
    25  This is a Directory wrapper that adds methods intended to be used
    26  only by unit tests. It also adds a number of fatures useful for
    27  testing:
    28  
    29  1. Instances created by newDirectory() are tracked to ensure they are
    30  closed by the test.
    31  2. When a MockDirectoryWrapper is closed, it returns an error if it
    32  has any open files against it (with a stacktrace indicating where
    33  they were opened from)
    34  3. When a MockDirectoryWrapper is closed, it runs CheckIndex to test
    35  if the index was corrupted.
    36  4. MockDirectoryWrapper simulates some "features" of Windows, such as
    37  refusing to write/delete to open files.
    38  */
    39  type MockDirectoryWrapper struct {
    40  	*BaseDirectoryWrapperImpl
    41  	sync.Locker                     // simulate Java's synchronized keyword
    42  	myLockFactory store.LockFactory // overrides LockFactory
    43  
    44  	isLocked bool // workaround re-entrant lock
    45  
    46  	maxSize int64
    47  
    48  	// Max actual bytes used. This is set by MockRAMOutputStream
    49  	maxUsedSize           int64
    50  	randomErrorRate       float64
    51  	randomErrorRateOnOpen float64
    52  	randomState           *rand.Rand
    53  	noDeleteOpenFile      bool
    54  	preventDoubleWrite    bool
    55  	trackDiskUsage        bool
    56  	wrapLockFactory       bool
    57  	unSyncedFiles         map[string]bool
    58  	createdFiles          map[string]bool
    59  	openFilesForWrite     map[string]bool
    60  	openLocks             map[string]bool // synchronized
    61  	openLocksLock         sync.Locker
    62  	crashed               bool // volatile
    63  	throttledOutput       *ThrottledIndexOutput
    64  	throttling            Throttling
    65  
    66  	inputCloneCount int32 // atomic
    67  
    68  	// use this for tracking files for crash.
    69  	// additionally: provides debugging information in case you leave one open
    70  	openFileHandles map[io.Closer]error // synchronized
    71  
    72  	// NOTE: we cannot intialize the map here due to the order in which our
    73  	// constructor actually does this member initialization vs when it calls
    74  	// super. It seems like super is called, then our members are initialzed.
    75  	//
    76  	// Ian: it's not the case for golucene BUT I have no idea why it stays...
    77  	openFiles map[string]int
    78  
    79  	// Only tracked if noDeleteOpenFile is true: if an attempt is made to delete
    80  	// an open file, we entroll it here.
    81  	openFilesDeleted map[string]bool
    82  
    83  	failOnCreateOutput               bool
    84  	failOnOpenInput                  bool
    85  	assertNoUnreferencedFilesOnClose bool
    86  
    87  	failures []*Failure
    88  }
    89  
    90  func (mdw *MockDirectoryWrapper) init() {
    91  	if mdw.openFiles == nil {
    92  		mdw.openFiles = make(map[string]int)
    93  		mdw.openFilesDeleted = make(map[string]bool)
    94  	}
    95  
    96  	if mdw.createdFiles == nil {
    97  		mdw.createdFiles = make(map[string]bool)
    98  	}
    99  	if mdw.unSyncedFiles == nil {
   100  		mdw.unSyncedFiles = make(map[string]bool)
   101  	}
   102  }
   103  
   104  func NewMockDirectoryWrapper(random *rand.Rand, delegate store.Directory) *MockDirectoryWrapper {
   105  	ans := &MockDirectoryWrapper{
   106  		noDeleteOpenFile:                 true,
   107  		preventDoubleWrite:               true,
   108  		trackDiskUsage:                   false,
   109  		wrapLockFactory:                  true,
   110  		openFilesForWrite:                make(map[string]bool),
   111  		openLocks:                        make(map[string]bool),
   112  		openLocksLock:                    &sync.Mutex{},
   113  		throttling:                       THROTTLING_SOMETIMES,
   114  		inputCloneCount:                  0,
   115  		openFileHandles:                  make(map[io.Closer]error),
   116  		failOnCreateOutput:               true,
   117  		failOnOpenInput:                  true,
   118  		assertNoUnreferencedFilesOnClose: true,
   119  	}
   120  	ans.BaseDirectoryWrapperImpl = NewBaseDirectoryWrapper(delegate)
   121  	ans.Locker = &sync.Mutex{}
   122  	// must make a private random since our methods are called from different
   123  	// methods; else test failures may not be reproducible from the original
   124  	// seed
   125  	ans.randomState = rand.New(rand.NewSource(random.Int63()))
   126  	ans.throttledOutput = NewThrottledIndexOutput(
   127  		MBitsToBytes(40+ans.randomState.Intn(10)), 5+ans.randomState.Int63n(5), nil)
   128  	// force wrapping of LockFactory
   129  	ans.myLockFactory = newMockLockFactoryWrapper(ans, delegate.LockFactory())
   130  	ans.init()
   131  	return ans
   132  }
   133  
   134  // Controlling hard disk throttling
   135  // Set via setThrottling()
   136  // WARNING: can make tests very slow.
   137  type Throttling int
   138  
   139  const (
   140  	// always emulate a slow hard disk. Cold be very slow!
   141  	THROTTLING_ALWAYS = Throttling(1)
   142  	// sometimes (2% of the time) emulate a slow hard disk.
   143  	THROTTLING_SOMETIMES = Throttling(2)
   144  	// never throttle output
   145  	THROTTLING_NEVER = Throttling(3)
   146  )
   147  
   148  func (mdw *MockDirectoryWrapper) SetThrottling(throttling Throttling) {
   149  	mdw.throttling = throttling
   150  }
   151  
   152  /*
   153  Returns true if delegate must sync its files. Currently, only
   154  NRTCachingDirectory requires sync'ing its files because otherwise
   155  they are cached in an internal RAMDirectory. If other directories
   156  requires that too, they should be added to this method.
   157  */
   158  func (mdw *MockDirectoryWrapper) mustSync() bool {
   159  	var delegate = mdw.Directory
   160  	for {
   161  		if v, ok := delegate.(*store.RateLimitedDirectoryWrapper); ok {
   162  			delegate = v.Directory
   163  		} else if v, ok := delegate.(*store.TrackingDirectoryWrapper); ok {
   164  			delegate = v.Directory
   165  		} else {
   166  			break
   167  		}
   168  	}
   169  	_, ok := delegate.(*store.NRTCachingDirectory)
   170  	return ok
   171  }
   172  
   173  func (w *MockDirectoryWrapper) Sync(names []string) error {
   174  	w.Lock() // synchronized
   175  	defer w.Unlock()
   176  	w.maybeYield()
   177  	err := w.maybeThrowDeterministicException()
   178  	if err != nil {
   179  		return err
   180  	}
   181  	if w.crashed {
   182  		return errors.New("cannot sync after crash")
   183  	}
   184  	// don't wear out out hardware so much intests.
   185  	if Rarely(w.randomState) || w.mustSync() {
   186  		for _, name := range names {
   187  			// randomly fail with IOE on any file
   188  			err = w.maybeThrowIOException(name)
   189  			if err != nil {
   190  				return err
   191  			}
   192  			err = w.Directory.Sync([]string{name})
   193  			if err != nil {
   194  				return err
   195  			}
   196  			delete(w.unSyncedFiles, name)
   197  		}
   198  	} else {
   199  		for _, name := range names {
   200  			delete(w.unSyncedFiles, name)
   201  		}
   202  	}
   203  	return nil
   204  }
   205  
   206  func (w *MockDirectoryWrapper) String() string {
   207  	// NOTE: do not maybeYield here, since it consumes randomness and
   208  	// can thus (unexpectedly during debugging) change the behavior of
   209  	// a seed maybeYield()
   210  	return fmt.Sprintf("MockDirWrapper(%v)", w.Directory)
   211  }
   212  
   213  func (w *MockDirectoryWrapper) sizeInBytes() (int64, error) {
   214  	w.Lock()
   215  	defer w.Unlock()
   216  
   217  	// v, ok := w.Directory.(*store.RAMDirectory)
   218  	// if ok {
   219  	// 	return v.RamBytesUsed(), nil
   220  	// }
   221  	// hack
   222  	panic("not implemented yet")
   223  }
   224  
   225  // Simulates a crash of OS or machine by overwriting unsynced files.
   226  func (w *MockDirectoryWrapper) Crash() error {
   227  	w.Lock() // synchronized
   228  	defer w.Unlock()
   229  	return w._crash()
   230  }
   231  
   232  func (w *MockDirectoryWrapper) _crash() error {
   233  	panic("not implemented yet")
   234  	// w.crashed = true
   235  	// w.openFiles = make(map[string]int)
   236  	// w.openFilesForWrite = make(map[string]bool)
   237  	// w.openFilesDeleted = make(map[string]bool)
   238  	// files := w.unSyncedFiles
   239  	// w.unSyncedFiles = make(map[string]bool)
   240  	// // first force-close all files, so we can corrupt on windows etc.
   241  	// // clone the file map, as these guys want to remove themselves on close.
   242  	// m := make(map[io.Closer]error)
   243  	// for k, v := range w.openFileHandles {
   244  	// 	m[k] = v
   245  	// }
   246  	// for f, _ := range m {
   247  	// 	f.Close() // ignore error
   248  	// }
   249  
   250  	// for name, _ := range files {
   251  	// 	var action string
   252  	// 	var err error
   253  	// 	switch w.randomState.Intn(5) {
   254  	// 	case 0:
   255  	// 		action = "deleted"
   256  	// 		err = w.deleteFile(name, true)
   257  	// 	case 1:
   258  	// 		action = "zeroes"
   259  	// 		// Zero out file entirely
   260  	// 		var length int64
   261  	// 		length, err = w._fileLength(name)
   262  	// 		if err == nil {
   263  	// 			zeroes := make([]byte, 256)
   264  	// 			var upto int64 = 0
   265  	// 			var out store.IndexOutput
   266  	// 			out, err = w.BaseDirectoryWrapperImpl.CreateOutput(name, NewDefaultIOContext(w.randomState))
   267  	// 			if err == nil {
   268  	// 				for upto < length && err == nil {
   269  	// 					limit := length - upto
   270  	// 					if int64(len(zeroes)) < limit {
   271  	// 						limit = int64(len(zeroes))
   272  	// 					}
   273  	// 					err = out.WriteBytes(zeroes[:limit])
   274  	// 					upto += limit
   275  	// 				}
   276  	// 				if err == nil {
   277  	// 					err = out.Close()
   278  	// 				}
   279  	// 			}
   280  	// 		}
   281  	// 	case 2:
   282  	// 		action = "partially truncated"
   283  	// 		// Partially Truncate the file:
   284  
   285  	// 		// First, make temp file and copy only half this file over:
   286  	// 		var tempFilename string
   287  	// 		for {
   288  	// 			tempFilename = fmt.Sprintf("%v", w.randomState.Int())
   289  	// 			if !w.BaseDirectoryWrapperImpl.FileExists(tempFilename) {
   290  	// 				break
   291  	// 			}
   292  	// 		}
   293  	// 		var tempOut store.IndexOutput
   294  	// 		if tempOut, err = w.BaseDirectoryWrapperImpl.CreateOutput(tempFilename, NewDefaultIOContext(w.randomState)); err == nil {
   295  	// 			var ii store.IndexInput
   296  	// 			if ii, err = w.BaseDirectoryWrapperImpl.OpenInput(name, NewDefaultIOContext(w.randomState)); err == nil {
   297  	// 				if err = tempOut.CopyBytes(ii, ii.Length()/2); err == nil {
   298  	// 					if err = tempOut.Close(); err == nil {
   299  	// 						if err = ii.Close(); err == nil {
   300  	// 							// Delete original and copy bytes back:
   301  	// 							if err = w.deleteFile(name, true); err == nil {
   302  	// 								var out store.IndexOutput
   303  	// 								if out, err = w.BaseDirectoryWrapperImpl.CreateOutput(name, NewDefaultIOContext(w.randomState)); err == nil {
   304  	// 									if ii, err = w.BaseDirectoryWrapperImpl.OpenInput(tempFilename, NewDefaultIOContext(w.randomState)); err == nil {
   305  	// 										if err = out.CopyBytes(ii, ii.Length()); err == nil {
   306  	// 											if err = out.Close(); err == nil {
   307  	// 												if err = ii.Close(); err == nil {
   308  	// 													err = w.deleteFile(tempFilename, true)
   309  	// 												}
   310  	// 											}
   311  	// 										}
   312  	// 									}
   313  	// 								}
   314  	// 							}
   315  	// 						}
   316  	// 					}
   317  	// 				}
   318  	// 			}
   319  	// 		}
   320  	// 	case 3:
   321  	// 		// the file survived intact:
   322  	// 		action = "didn't change"
   323  	// 	default:
   324  	// 		action = "fully truncated"
   325  	// 		// totally truncate the file to zero bytes
   326  	// 		if err = w.deleteFile(name, true); err == nil {
   327  	// 			var out store.IndexOutput
   328  	// 			if out, err = w.BaseDirectoryWrapperImpl.CreateOutput(name, NewDefaultIOContext(w.randomState)); err == nil {
   329  	// 				if err = out.SetLength(0); err == nil {
   330  	// 					err = out.Close()
   331  	// 				}
   332  	// 			}
   333  	// 		}
   334  	// 	}
   335  	// 	if err != nil {
   336  	// 		return err
   337  	// 	}
   338  	// 	if VERBOSE {
   339  	// 		log.Printf("MockDirectoryWrapper: %v unsynced file: %v", action, name)
   340  	// 	}
   341  	// }
   342  	// return nil
   343  }
   344  
   345  func (w *MockDirectoryWrapper) maybeThrowIOException(message string) error {
   346  	if w.randomState.Float64() < w.randomErrorRate {
   347  		if message != "" {
   348  			message = fmt.Sprintf(" (%v)", message)
   349  		}
   350  		if VERBOSE {
   351  			log.Printf("MockDirectoryWrapper: now return random error%v", message)
   352  			debug.PrintStack()
   353  		}
   354  		return errors.New(fmt.Sprintf("a random IO error%v", message))
   355  	}
   356  	return nil
   357  }
   358  
   359  func (w *MockDirectoryWrapper) maybeThrowIOExceptionOnOpen(name string) error {
   360  	if w.randomState.Float64() < w.randomErrorRateOnOpen {
   361  		if VERBOSE {
   362  			log.Printf("MockDirectoryWrapper: now return random error during open file=%v", name)
   363  			debug.PrintStack()
   364  		}
   365  		if w.randomState.Intn(2) == 0 {
   366  			return errors.New(fmt.Sprintf("a random IO error (%v)", name))
   367  		}
   368  		return os.ErrNotExist
   369  	}
   370  	return nil
   371  }
   372  
   373  func (w *MockDirectoryWrapper) DeleteFile(name string) error {
   374  	w.maybeYield()
   375  	return w.deleteFile(name, false)
   376  }
   377  
   378  /*
   379  sets the cause of the incoming ioe to be the stack trace when the
   380  offending file name was opened
   381  */
   382  func (w *MockDirectoryWrapper) fillOpenTrace(err error, name string, input bool) error {
   383  	w.Lock()
   384  	defer w.Unlock()
   385  	return w._fillOpenTrace(err, name, input)
   386  }
   387  
   388  func (w *MockDirectoryWrapper) _fillOpenTrace(err error, name string, input bool) error {
   389  	for closer, cause := range w.openFileHandles {
   390  		v, ok := closer.(*MockIndexInputWrapper)
   391  		if input && ok && v.name == name {
   392  			err = mergeError(err, cause)
   393  			break
   394  		} else {
   395  			v2, ok := closer.(*MockIndexOutputWrapper)
   396  			if !input && ok && v2.name == name {
   397  				err = mergeError(err, cause)
   398  				break
   399  			}
   400  		}
   401  	}
   402  	return err
   403  }
   404  
   405  func mergeError(err, err2 error) error {
   406  	if err == nil {
   407  		return err2
   408  	} else {
   409  		return errors.New(fmt.Sprintf("%v\n  %v", err, err2))
   410  	}
   411  }
   412  
   413  func (w *MockDirectoryWrapper) maybeYield() {
   414  	if w.randomState.Intn(2) == 0 {
   415  		runtime.Gosched()
   416  	}
   417  }
   418  
   419  func (w *MockDirectoryWrapper) deleteFile(name string, forced bool) error {
   420  	if !w.isLocked {
   421  		w.Lock() // synchronized
   422  		defer w.Unlock()
   423  	}
   424  
   425  	w.maybeYield()
   426  
   427  	err := w.maybeThrowDeterministicException()
   428  	if err != nil {
   429  		return err
   430  	}
   431  
   432  	if w.crashed && !forced {
   433  		return errors.New("cannot delete after crash")
   434  	}
   435  
   436  	if _, ok := w.unSyncedFiles[name]; ok {
   437  		delete(w.unSyncedFiles, name)
   438  	}
   439  	if !forced && w.noDeleteOpenFile {
   440  		if _, ok := w.openFiles[name]; ok {
   441  			w.openFilesDeleted[name] = true
   442  			return w._fillOpenTrace(errors.New(fmt.Sprintf(
   443  				"MockDirectoryWrapper: file  '%v' is still open: cannot delete",
   444  				name)), name, true)
   445  		}
   446  		delete(w.openFilesDeleted, name)
   447  	}
   448  	return w.Directory.DeleteFile(name)
   449  }
   450  
   451  func (w *MockDirectoryWrapper) CreateOutput(name string, context store.IOContext) (store.IndexOutput, error) {
   452  	panic("not implemented yet")
   453  	// if !w.isLocked {
   454  	// 	w.Lock() // synchronized
   455  	// 	defer w.Unlock()
   456  	// }
   457  
   458  	// err := w.maybeThrowDeterministicException()
   459  	// if err != nil {
   460  	// 	return nil, err
   461  	// }
   462  	// err = w.maybeThrowIOExceptionOnOpen(name)
   463  	// if err != nil {
   464  	// 	return nil, err
   465  	// }
   466  	// w.maybeYield()
   467  	// if w.failOnCreateOutput {
   468  	// 	if err = w.maybeThrowDeterministicException(); err != nil {
   469  	// 		return nil, err
   470  	// 	}
   471  	// }
   472  	// if w.crashed {
   473  	// 	return nil, errors.New("cannot createOutput after crash")
   474  	// }
   475  	// w.init()
   476  	// if _, ok := w.createdFiles[name]; w.preventDoubleWrite && ok && name != "segments.gen" {
   477  	// 	return nil, errors.New(fmt.Sprintf("file %v was already written to", name))
   478  	// }
   479  	// if _, ok := w.openFiles[name]; w.noDeleteOpenFile && ok {
   480  	// 	return nil, errors.New(fmt.Sprintf("MockDirectoryWraper: file %v is still open: cannot overwrite", name))
   481  	// }
   482  
   483  	// if w.crashed {
   484  	// 	return nil, errors.New("cannot createOutput after crash")
   485  	// }
   486  	// w.unSyncedFiles[name] = true
   487  	// w.createdFiles[name] = true
   488  
   489  	// if ramdir, ok := w.Directory.(*store.RAMDirectory); ok {
   490  	// 	file := store.NewRAMFile(ramdir)
   491  	// 	existing := ramdir.GetRAMFile(name)
   492  
   493  	// 	// Enforce write once:
   494  	// 	if existing != nil && name != "segments.gen" && w.preventDoubleWrite {
   495  	// 		return nil, errors.New(fmt.Sprintf("file %v already exists", name))
   496  	// 	} else {
   497  	// 		if existing != nil {
   498  	// 			ramdir.ChangeSize(-existing.SizeInBytes())
   499  	// 			// existing.directory = nil
   500  	// 		}
   501  	// 		ramdir.PutRAMFile(name, file)
   502  	// 	}
   503  	// }
   504  	// log.Printf("MDW: create %v", name)
   505  	// delegateOutput, err := w.Directory.CreateOutput(name, NewIOContext(w.randomState, context))
   506  	// if err != nil {
   507  	// 	return nil, err
   508  	// }
   509  	// assert(delegateOutput != nil)
   510  	// if w.randomState.Intn(10) == 0 {
   511  	// 	// once ina while wrap the IO in a buffered IO with random buffer sizes
   512  	// 	delegateOutput = newBufferedIndexOutputWrapper(
   513  	// 		1+w.randomState.Intn(store.DEFAULT_BUFFER_SIZE), delegateOutput)
   514  	// 	assert(delegateOutput != nil)
   515  	// }
   516  	// io := newMockIndexOutputWrapper(w, name, delegateOutput)
   517  	// w._addFileHandle(io, name, HANDLE_OUTPUT)
   518  	// w.openFilesForWrite[name] = true
   519  
   520  	// // throttling REALLY slows down tests, so don't do it very often for SOMETIMES
   521  	// if _, ok := w.Directory.(*store.RateLimitedDirectoryWrapper); w.throttling == THROTTLING_ALWAYS ||
   522  	// 	(w.throttling == THROTTLING_SOMETIMES && w.randomState.Intn(50) == 0) && !ok {
   523  	// 	if VERBOSE {
   524  	// 		log.Println(fmt.Sprintf("MockDirectoryWrapper: throttling indexOutpu (%v)", name))
   525  	// 	}
   526  	// 	return w.throttledOutput.NewFromDelegate(io), nil
   527  	// }
   528  	// return io, nil
   529  }
   530  
   531  type Handle int
   532  
   533  const (
   534  	HANDLE_INPUT  = Handle(1)
   535  	HANDLE_OUTPUT = Handle(2)
   536  	HANDLE_SLICE  = Handle(3)
   537  )
   538  
   539  func handleName(handle Handle) string {
   540  	switch handle {
   541  	case HANDLE_INPUT:
   542  		return "Input"
   543  	case HANDLE_OUTPUT:
   544  		return "Output"
   545  	case HANDLE_SLICE:
   546  		return "Slice"
   547  	}
   548  	panic("should not be here")
   549  }
   550  
   551  func (w *MockDirectoryWrapper) addFileHandle(c io.Closer, name string, handle Handle) {
   552  	if !w.isLocked {
   553  		w.Lock() // synchronized
   554  		defer w.Unlock()
   555  	}
   556  	w._addFileHandle(c, name, handle)
   557  }
   558  
   559  func (w *MockDirectoryWrapper) _addFileHandle(c io.Closer, name string, handle Handle) {
   560  	if v, ok := w.openFiles[name]; ok {
   561  		w.openFiles[name] = v + 1
   562  	} else {
   563  		w.openFiles[name] = 1
   564  	}
   565  	w.openFileHandles[c] = errors.New(fmt.Sprintf("unclosed Index %v: %v", handleName(handle), name))
   566  }
   567  
   568  func (w *MockDirectoryWrapper) OpenInput(name string, context store.IOContext) (ii store.IndexInput, err error) {
   569  	panic("not implemented yet")
   570  	// if !w.isLocked {
   571  	// 	w.Lock() // synchronized
   572  	// 	defer w.Unlock()
   573  	// }
   574  
   575  	// if err = w.maybeThrowDeterministicException(); err != nil {
   576  	// 	return
   577  	// }
   578  	// if err = w.maybeThrowIOExceptionOnOpen(name); err != nil {
   579  	// 	return
   580  	// }
   581  	// w.maybeYield()
   582  	// if w.failOnOpenInput {
   583  	// 	if err = w.maybeThrowDeterministicException(); err != nil {
   584  	// 		return
   585  	// 	}
   586  	// }
   587  	// if !w.Directory.FileExists(name) {
   588  	// 	return nil, errors.New(fmt.Sprintf("%v in dir=%v", name, w.Directory))
   589  	// }
   590  
   591  	// // cannot open a file for input if it's still open for output,
   592  	// // except for segments.gen and segments_N
   593  	// if _, ok := w.openFilesForWrite[name]; ok && strings.HasPrefix(name, "segments") {
   594  	// 	err = w.fillOpenTrace(errors.New(fmt.Sprintf(
   595  	// 		"MockDirectoryWrapper: file '%v' is still open for writing", name)), name, false)
   596  	// 	return
   597  	// }
   598  
   599  	// var delegateInput store.IndexInput
   600  	// delegateInput, err = w.Directory.OpenInput(name, NewIOContext(w.randomState, context))
   601  	// if err != nil {
   602  	// 	return
   603  	// }
   604  
   605  	// randomInt := w.randomState.Intn(500)
   606  	// if randomInt == 0 {
   607  	// 	if VERBOSE {
   608  	// 		log.Printf("MockDirectoryWrapper: using SlowClosingMockIndexInputWrapper for file %v", name)
   609  	// 	}
   610  	// 	panic("not implemented yet")
   611  	// } else if randomInt == 1 {
   612  	// 	if VERBOSE {
   613  	// 		log.Printf("MockDirectoryWrapper: using SlowOpeningMockIndexInputWrapper for file %v", name)
   614  	// 	}
   615  	// 	panic("not implemented yet")
   616  	// } else {
   617  	// 	ii = newMockIndexInputWrapper(w, name, delegateInput)
   618  	// }
   619  	// w._addFileHandle(ii, name, HANDLE_INPUT)
   620  	// return ii, nil
   621  }
   622  
   623  // L594
   624  /*
   625  Like recomputeSizeInBytes(), but uses actual file lengths rather than
   626  buffer allocations (which are quantized up to nearest
   627  RAMOutputStream.BUFFER_SIZE (now 1024) bytes).
   628  */
   629  func (w *MockDirectoryWrapper) recomputeActualSizeInBytes() (int64, error) {
   630  	w.Lock()
   631  	defer w.Unlock()
   632  	// if _, ok := w.Directory.(store.RAMDirectory); !ok {
   633  	// 	return w.sizeInBytes()
   634  	// }
   635  	panic("not implemented yet")
   636  }
   637  
   638  func (w *MockDirectoryWrapper) Close() error {
   639  	w.Lock()
   640  	w.isLocked = true
   641  	defer func() {
   642  		w.isLocked = false
   643  		w.Unlock()
   644  	}()
   645  
   646  	// files that we tried to delete, but couldn't because reader were open
   647  	// all that matters is that we tried! (they will eventually go away)
   648  	pendingDeletions := make(map[string]bool)
   649  	for k, v := range w.openFilesDeleted {
   650  		pendingDeletions[k] = v
   651  	}
   652  
   653  	w.maybeYield()
   654  
   655  	if w.openFiles == nil {
   656  		w.openFiles = make(map[string]int)
   657  		w.openFilesDeleted = make(map[string]bool)
   658  	}
   659  	nOpenFiles := len(w.openFiles)
   660  
   661  	if w.noDeleteOpenFile && nOpenFiles > 0 {
   662  		// print the first one as its very verbose otherwise
   663  		var cause error
   664  		for _, v := range w.openFileHandles {
   665  			cause = v
   666  			break
   667  		}
   668  		panic(mergeError(errors.New(fmt.Sprintf(
   669  			"MockDirectoryWrapper: cannot close: there are still open files: %v",
   670  			w.openFiles)), cause))
   671  	}
   672  
   673  	nOpenLocks := func() int {
   674  		w.openLocksLock.Lock()
   675  		defer w.openLocksLock.Unlock()
   676  		return len(w.openLocks)
   677  	}()
   678  	if w.noDeleteOpenFile && nOpenLocks > 0 {
   679  		panic(fmt.Sprintf("MockDirectoryWrapper: cannot close: there are still open locks: %v", w.openLocks))
   680  	}
   681  
   682  	w.isOpen = false
   683  	if w.checkIndexOnClose {
   684  		w.randomErrorRate = 0
   685  		w.randomErrorRateOnOpen = 0
   686  		files, err := w._ListAll()
   687  		if err != nil {
   688  			return err
   689  		}
   690  		if index.IsIndexFileExists(files) {
   691  			fmt.Println("\nNOTE: MockDirectoryWrapper: now crash")
   692  			err = w._crash() // corrupt any unsynced-files
   693  			if err != nil {
   694  				return err
   695  			}
   696  			fmt.Println("\nNOTE: MockDirectoryWrapper: now run CheckIndex")
   697  			w.Unlock() // CheckIndex may access synchronized method
   698  			CheckIndex(w, w.crossCheckTermVectorsOnClose)
   699  			w.Lock() // CheckIndex may access synchronized method
   700  
   701  			// TODO: factor this out / share w/ TestIW.assertNoUnreferencedFiles
   702  			if w.assertNoUnreferencedFilesOnClose {
   703  				// now look for unreferenced files: discount ones that we tried to delete but could not
   704  				all, err := w._ListAll()
   705  				if err != nil {
   706  					return err
   707  				}
   708  				allFiles := make(map[string]bool)
   709  				for _, name := range all {
   710  					allFiles[name] = true
   711  				}
   712  				for name, _ := range pendingDeletions {
   713  					delete(allFiles, name)
   714  				}
   715  				startFiles := make([]string, 0, len(allFiles))
   716  				for k, _ := range allFiles {
   717  					startFiles = append(startFiles, k)
   718  				}
   719  				iwc := index.NewIndexWriterConfig(TEST_VERSION_CURRENT, nil)
   720  				iwc.SetIndexDeletionPolicy(index.NO_DELETION_POLICY)
   721  				iw, err := index.NewIndexWriter(w.Directory, iwc)
   722  				if err != nil {
   723  					return err
   724  				}
   725  				err = iw.Rollback()
   726  				if err != nil {
   727  					return err
   728  				}
   729  				endFiles, err := w.Directory.ListAll()
   730  				if err != nil {
   731  					return err
   732  				}
   733  
   734  				hasSegmentsGenFile := sort.SearchStrings(endFiles, index.INDEX_FILENAME_SEGMENTS_GEN) >= 0
   735  				if pendingDeletions["segments.gen"] && hasSegmentsGenFile {
   736  					panic("not implemented yet")
   737  				}
   738  
   739  				// its possible we cannot delete the segments_N on windows if someone has it open and
   740  				// maybe other files too, depending on timing. normally someone on windows wouldnt have
   741  				// an issue (IFD would nuke this stuff eventually), but we pass NoDeletionPolicy...
   742  				for _, file := range pendingDeletions {
   743  					log.Println(file)
   744  					panic("not implemented yet")
   745  				}
   746  
   747  				sort.Strings(startFiles)
   748  				startFiles = uniqueStrings(startFiles)
   749  				sort.Strings(endFiles)
   750  				endFiles = uniqueStrings(endFiles)
   751  
   752  				if !reflect.DeepEqual(startFiles, endFiles) {
   753  					panic("not implemented")
   754  				}
   755  
   756  				ir1, err := index.OpenDirectoryReader(w)
   757  				if err != nil {
   758  					return err
   759  				}
   760  				numDocs1 := ir1.NumDocs()
   761  				err = ir1.Close()
   762  				if err != nil {
   763  					return err
   764  				}
   765  				iw, err = index.NewIndexWriter(w, index.NewIndexWriterConfig(TEST_VERSION_CURRENT, nil))
   766  				if err != nil {
   767  					return err
   768  				}
   769  				err = iw.Close()
   770  				if err != nil {
   771  					return err
   772  				}
   773  				ir2, err := index.OpenDirectoryReader(w)
   774  				if err != nil {
   775  					return err
   776  				}
   777  				numDocs2 := ir2.NumDocs()
   778  				err = ir2.Close()
   779  				if err != nil {
   780  					return err
   781  				}
   782  				assert2(numDocs1 == numDocs2, fmt.Sprintf("numDocs changed after opening/closing IW: before=%v after=%v", numDocs1, numDocs2))
   783  			}
   784  		}
   785  	}
   786  	return w.Directory.Close()
   787  }
   788  
   789  func assert(ok bool) {
   790  	if !ok {
   791  		panic("assert fail")
   792  	}
   793  }
   794  
   795  func assert2(ok bool, msg string) {
   796  	if !ok {
   797  		panic(msg)
   798  	}
   799  }
   800  
   801  func uniqueStrings(a []string) []string {
   802  	ans := make([]string, 0, len(a)) // inefficient for fewer unique items
   803  	for _, v := range a {
   804  		if n := len(ans); n == 0 || ans[n-1] != v {
   805  			ans = append(ans, v)
   806  		}
   807  	}
   808  	return ans
   809  }
   810  
   811  func (w *MockDirectoryWrapper) removeOpenFile(c io.Closer, name string) {
   812  	w.Lock() // synchronized
   813  	defer w.Unlock()
   814  
   815  	w._removeOpenFile(c, name)
   816  }
   817  
   818  func (w *MockDirectoryWrapper) _removeOpenFile(c io.Closer, name string) {
   819  	if v, ok := w.openFiles[name]; ok {
   820  		if v == 1 {
   821  			delete(w.openFiles, name)
   822  		} else {
   823  			w.openFiles[name] = v - 1
   824  		}
   825  	}
   826  	delete(w.openFileHandles, c)
   827  }
   828  
   829  func (w *MockDirectoryWrapper) removeIndexOutput(out store.IndexOutput, name string) {
   830  	w.Lock() // synchronized
   831  	defer w.Unlock()
   832  
   833  	delete(w.openFilesForWrite, name)
   834  	w._removeOpenFile(out, name)
   835  }
   836  
   837  func (w *MockDirectoryWrapper) removeIndexInput(in store.IndexInput, name string) {
   838  	if !w.isLocked {
   839  		w.Lock() // synchronized
   840  		defer w.Unlock()
   841  	}
   842  
   843  	w._removeOpenFile(in, name)
   844  }
   845  
   846  /*
   847  Objects that represent fail-lable conditions. Objects of a derived
   848  class are created and registered with teh mock directory. After
   849  register, each object will be invoked once for each first write of a
   850  file, giving the object a chance to throw an IO error.
   851  */
   852  type Failure struct {
   853  	// eval is called on the first write of every new file
   854  	eval   func(dir *MockDirectoryWrapper) error
   855  	doFail bool
   856  }
   857  
   858  /*
   859  reset should set the state of the failure to its default (freshly
   860  constructed) state. Reset is convenient for tests that want to create
   861  one failure object and then reuse it in mutiple cases. This, combined
   862  with the fact that Failure subclasses are often anonymous classes
   863  makes reset difficult to do otherwise.
   864  
   865  A typical example of use is
   866  
   867  		failure := &Failure { eval: func(dir *MockDirectoryWrapper) { ... } }
   868  		...
   869  		mock.failOn(failure.reset())
   870  
   871  */
   872  func (f *Failure) Reset() *Failure { return f }
   873  func (f *Failure) SetDoFail()      { f.doFail = true }
   874  func (f *Failure) ClearDoFail()    { f.doFail = false }
   875  
   876  /*
   877  add a Failure object to the list of objects to be evaluated at every
   878  potential failure opint
   879  */
   880  func (w *MockDirectoryWrapper) failOn(fail *Failure) {
   881  	w.failures = append(w.failures, fail)
   882  }
   883  
   884  // Iterate through the failures list, giving each object a
   885  // chance to return an error
   886  func (w *MockDirectoryWrapper) maybeThrowDeterministicException() error {
   887  	for _, f := range w.failures {
   888  		if err := f.eval(w); err != nil {
   889  			return err
   890  		}
   891  	}
   892  	return nil
   893  }
   894  
   895  func (w *MockDirectoryWrapper) ListAll() ([]string, error) {
   896  	if !w.isLocked {
   897  		w.Lock() // synchronized
   898  		defer w.Unlock()
   899  	}
   900  	return w._ListAll()
   901  }
   902  
   903  func (w *MockDirectoryWrapper) _ListAll() ([]string, error) {
   904  	w.maybeYield()
   905  	return w.Directory.ListAll()
   906  }
   907  
   908  func (w *MockDirectoryWrapper) FileExists(name string) bool {
   909  	if !w.isLocked {
   910  		w.Lock() // synchronized
   911  		defer w.Unlock()
   912  	}
   913  
   914  	w.maybeYield()
   915  	return w.Directory.FileExists(name)
   916  }
   917  
   918  func (w *MockDirectoryWrapper) FileLength(name string) (int64, error) {
   919  	w.Lock() // synchronized
   920  	defer w.Unlock()
   921  
   922  	return w._fileLength(name)
   923  }
   924  
   925  func (w *MockDirectoryWrapper) _fileLength(name string) (int64, error) {
   926  	w.maybeYield()
   927  	return w.Directory.FileLength(name)
   928  }
   929  
   930  func (w *MockDirectoryWrapper) MakeLock(name string) store.Lock {
   931  	if !w.isLocked {
   932  		w.Lock() // synchronized
   933  		defer w.Unlock()
   934  	}
   935  
   936  	w.maybeYield()
   937  	return w.lockFactory().Make(name)
   938  }
   939  
   940  func (w *MockDirectoryWrapper) ClearLock(name string) error {
   941  	w.Lock() // synchronized
   942  	defer w.Unlock()
   943  
   944  	w.maybeYield()
   945  	return w.lockFactory().Clear(name)
   946  }
   947  
   948  func (w *MockDirectoryWrapper) SetLockFactory(lockFactory store.LockFactory) {
   949  	w.Lock() // synchronized
   950  	defer w.Unlock()
   951  
   952  	w.maybeYield()
   953  	// sneaky: we must pass the original this way to the dir, because
   954  	// some impls (e.g. FSDir) do instanceof here
   955  	w.Directory.SetLockFactory(lockFactory)
   956  	// now set out wrapped factory here
   957  	w.myLockFactory = newMockLockFactoryWrapper(w, w.Directory.LockFactory())
   958  }
   959  
   960  func (w *MockDirectoryWrapper) LockFactory() store.LockFactory {
   961  	w.Lock() // synchronized
   962  	defer w.Unlock()
   963  
   964  	return w.lockFactory()
   965  }
   966  
   967  func (w *MockDirectoryWrapper) lockFactory() store.LockFactory {
   968  	w.maybeYield()
   969  	if w.wrapLockFactory {
   970  		return w.myLockFactory
   971  	} else {
   972  		return w.Directory.LockFactory()
   973  	}
   974  }
   975  
   976  func (w *MockDirectoryWrapper) LockID() string {
   977  	w.Lock() // synchronized
   978  	defer w.Unlock()
   979  
   980  	w.maybeYield()
   981  	return w.Directory.LockID()
   982  }
   983  
   984  func (w *MockDirectoryWrapper) Copy(to store.Directory, src string, dest string, context store.IOContext) error {
   985  	w.Lock() // synchronized
   986  	w.isLocked = true
   987  	defer func() {
   988  		w.isLocked = false
   989  		w.Unlock()
   990  	}()
   991  
   992  	w.maybeYield()
   993  	// randomize the IOContext here?
   994  	return w.Directory.Copy(to, src, dest, context)
   995  }
   996  
   997  // func (w *MockDirectoryWrapper) CreateSlicer(name string,
   998  // 	context store.IOContext) (store.IndexInputSlicer, error) {
   999  
  1000  // 	if !w.isLocked {
  1001  // 		w.Lock() // synchronized
  1002  // 		defer w.Unlock()
  1003  // 	}
  1004  
  1005  // 	w.maybeYield()
  1006  // 	if !w.Directory.FileExists(name) {
  1007  // 		return nil, errors.New(fmt.Sprintf("File not found: %v", name))
  1008  // 	}
  1009  // 	// cannot open a file for input if it's still open for output,
  1010  // 	// except for segments.gen and segments_N
  1011  // 	if _, ok := w.openFilesForWrite[name]; ok && !strings.HasPrefix(name, "segments") {
  1012  // 		return nil, w.fillOpenTrace(errors.New(fmt.Sprintf(
  1013  // 			"MockDirectoryWrapper: file '%v' is still open for writing", name)), name, false)
  1014  // 	}
  1015  
  1016  // 	delegateHandle, err := w.Directory.CreateSlicer(name, context)
  1017  // 	if err != nil {
  1018  // 		return nil, err
  1019  // 	}
  1020  // 	handle := &myIndexInputSlicer{w, delegateHandle, name, false}
  1021  // 	w._addFileHandle(handle, name, HANDLE_SLICE)
  1022  // 	return handle, nil
  1023  // }
  1024  
  1025  // type myIndexInputSlicer struct {
  1026  // 	owner          *MockDirectoryWrapper
  1027  // 	delegateHandle store.IndexInputSlicer
  1028  // 	name           string
  1029  // 	isClosed       bool
  1030  // }
  1031  
  1032  // func (s *myIndexInputSlicer) Close() error {
  1033  // 	if !s.isClosed {
  1034  // 		err := s.delegateHandle.Close()
  1035  // 		if err != nil {
  1036  // 			return err
  1037  // 		}
  1038  // 		s.owner.removeOpenFile(s, s.name)
  1039  // 		s.isClosed = true
  1040  // 	}
  1041  // 	return nil
  1042  // }
  1043  
  1044  // func (s *myIndexInputSlicer) OpenSlice(desc string, offset, length int64) store.IndexInput {
  1045  // 	s.owner.maybeYield()
  1046  // 	slice := s.delegateHandle.OpenSlice(desc, offset, length)
  1047  // 	ii := newMockIndexInputWrapper(s.owner, s.name, slice)
  1048  // 	s.owner.addFileHandle(ii, s.name, HANDLE_INPUT)
  1049  // 	return ii
  1050  // }
  1051  
  1052  // func (s *myIndexInputSlicer) OpenFullSlice() store.IndexInput {
  1053  // 	s.owner.maybeYield()
  1054  // 	slice := s.delegateHandle.OpenFullSlice()
  1055  // 	ii := newMockIndexInputWrapper(s.owner, s.name, slice)
  1056  // 	s.owner.addFileHandle(ii, s.name, HANDLE_INPUT)
  1057  // 	return ii
  1058  // }
  1059  
  1060  // type BufferedIndexOutputWrapper struct {
  1061  // 	*store.BufferedIndexOutput
  1062  // 	io store.IndexOutput
  1063  // }
  1064  
  1065  // func newBufferedIndexOutputWrapper(bufferSize int, io store.IndexOutput) *BufferedIndexOutputWrapper {
  1066  // 	ans := &BufferedIndexOutputWrapper{}
  1067  // 	ans.BufferedIndexOutput = store.NewBufferedIndexOutput(bufferSize, ans)
  1068  // 	ans.io = io
  1069  // 	return ans
  1070  // }
  1071  
  1072  // func (w *BufferedIndexOutputWrapper) Length() (int64, error) {
  1073  // 	return w.io.Length()
  1074  // }
  1075  
  1076  // func (w *BufferedIndexOutputWrapper) FlushBuffer(buf []byte) error {
  1077  // 	return w.io.WriteBytes(buf)
  1078  // }
  1079  
  1080  // // func (w *BufferedIndexOutputWrapper) Flush() error {
  1081  // // 	defer w.io.Flush()
  1082  // // 	return w.BufferedIndexOutput.Flush()
  1083  // // }
  1084  
  1085  // func (w *BufferedIndexOutputWrapper) Close() error {
  1086  // 	defer w.io.Close()
  1087  // 	return w.BufferedIndexOutput.Close()
  1088  // }
  1089  
  1090  // store/MockLockFactoryWrapper.java
  1091  
  1092  // Used by MockDirectoryWrapper to wrap another factory and track
  1093  // open locks.
  1094  type MockLockFactoryWrapper struct {
  1095  	store.LockFactory
  1096  	dir *MockDirectoryWrapper
  1097  }
  1098  
  1099  func newMockLockFactoryWrapper(dir *MockDirectoryWrapper, delegate store.LockFactory) *MockLockFactoryWrapper {
  1100  	return &MockLockFactoryWrapper{delegate, dir}
  1101  }
  1102  
  1103  func (w *MockLockFactoryWrapper) Make(lockName string) store.Lock {
  1104  	return newMockLock(w.dir, w.LockFactory.Make(lockName), lockName)
  1105  }
  1106  
  1107  func (w *MockLockFactoryWrapper) Clear(lockName string) error {
  1108  	err := w.LockFactory.Clear(lockName)
  1109  	if err != nil {
  1110  		return err
  1111  	}
  1112  	w.dir.openLocksLock.Lock()
  1113  	defer w.dir.openLocksLock.Unlock()
  1114  	delete(w.dir.openLocks, lockName)
  1115  	return nil
  1116  }
  1117  
  1118  func (w *MockLockFactoryWrapper) String() string {
  1119  	return fmt.Sprintf("MockLockFactoryWrapper(%v)", w.LockFactory)
  1120  }
  1121  
  1122  type MockLock struct {
  1123  	*store.LockImpl
  1124  	delegate store.Lock
  1125  	name     string
  1126  	dir      *MockDirectoryWrapper
  1127  }
  1128  
  1129  func newMockLock(dir *MockDirectoryWrapper, delegate store.Lock, name string) *MockLock {
  1130  	panic("not implemented yet")
  1131  	// assert(name != "")
  1132  	// ans := &MockLock{
  1133  	// 	delegate: delegate,
  1134  	// 	name:     name,
  1135  	// 	dir:      dir,
  1136  	// }
  1137  	// ans.LockImpl = store.NewLockImpl(ans)
  1138  	// return ans
  1139  }
  1140  
  1141  func (lock *MockLock) Obtain() (ok bool, err error) {
  1142  	ok, err = lock.delegate.Obtain()
  1143  	if err != nil {
  1144  		return
  1145  	}
  1146  	if ok {
  1147  		lock.dir.openLocksLock.Lock()
  1148  		defer lock.dir.openLocksLock.Unlock()
  1149  		lock.dir.openLocks[lock.name] = true
  1150  	}
  1151  	return ok, nil
  1152  }
  1153  
  1154  func (lock *MockLock) Close() error {
  1155  	panic("not implemented yet")
  1156  	// if err := lock.delegate.Release(); err != nil {
  1157  	// 	return err
  1158  	// }
  1159  	// lock.dir.openLocksLock.Lock()
  1160  	// defer lock.dir.openLocksLock.Unlock()
  1161  	// delete(lock.dir.openLocks, lock.name)
  1162  	// return nil
  1163  }
  1164  
  1165  func (lock *MockLock) IsLocked() bool {
  1166  	return lock.delegate.IsLocked()
  1167  }
  1168  
  1169  // store/MockIndexInputWrapper.java
  1170  
  1171  /*
  1172  Used by MockDirectoryWrapper to create an input stream that keeps
  1173  track of when it's been closed.
  1174  */
  1175  type MockIndexInputWrapper struct {
  1176  	*store.IndexInputImpl
  1177  	dir      *MockDirectoryWrapper
  1178  	delegate store.IndexInput
  1179  	name     string
  1180  	isClone  bool
  1181  	closed   bool
  1182  }
  1183  
  1184  func newMockIndexInputWrapper(dir *MockDirectoryWrapper,
  1185  	name string, delegate store.IndexInput) *MockIndexInputWrapper {
  1186  	ans := &MockIndexInputWrapper{nil, dir, delegate, name, false, false}
  1187  	ans.IndexInputImpl = store.NewIndexInputImpl(fmt.Sprintf(
  1188  		"MockIndexInputWrapper(name=%v delegate=%v)",
  1189  		name, delegate), ans)
  1190  	return ans
  1191  }
  1192  
  1193  func (w *MockIndexInputWrapper) Close() (err error) {
  1194  	panic("not implemented yet")
  1195  	// defer func() {
  1196  	// 	w.closed = true
  1197  	// 	err2 := w.delegate.Close()
  1198  	// 	err = mergeError(err, err2)
  1199  	// 	if err2 == nil {
  1200  	// 		// Pending resolution on LUCENE-686 we may want to remove the
  1201  	// 		// conditional check so we also track that all clones get closed:
  1202  	// 		if !w.isClone {
  1203  	// 			w.dir.removeIndexInput(w, w.name)
  1204  	// 		}
  1205  	// 	}
  1206  	// }()
  1207  	// // turn on the following to look for leaks closing inputs, after
  1208  	// // fixing TestTransactions
  1209  	// // return w.dir.maybeThrowDeterministicException()
  1210  	// return nil
  1211  }
  1212  
  1213  func (w *MockIndexInputWrapper) ensureOpen() {
  1214  	assert2(!w.closed, "Abusing closed IndexInput!")
  1215  }
  1216  
  1217  func (w *MockIndexInputWrapper) Clone() store.IndexInput {
  1218  	panic("not implemented yet")
  1219  }
  1220  
  1221  func (w *MockIndexInputWrapper) FilePointer() int64 {
  1222  	w.ensureOpen()
  1223  	return w.delegate.FilePointer()
  1224  }
  1225  
  1226  func (w *MockIndexInputWrapper) Seek(pos int64) error {
  1227  	w.ensureOpen()
  1228  	return w.delegate.Seek(pos)
  1229  }
  1230  
  1231  func (w *MockIndexInputWrapper) Length() int64 {
  1232  	w.ensureOpen()
  1233  	return w.delegate.Length()
  1234  }
  1235  
  1236  func (w *MockIndexInputWrapper) ReadByte() (byte, error) {
  1237  	w.ensureOpen()
  1238  	return w.delegate.ReadByte()
  1239  }
  1240  
  1241  func (w *MockIndexInputWrapper) ReadBytes(buf []byte) error {
  1242  	w.ensureOpen()
  1243  	return w.delegate.ReadBytes(buf)
  1244  }
  1245  
  1246  func (w *MockIndexInputWrapper) ReadShort() (int16, error) {
  1247  	w.ensureOpen()
  1248  	return w.delegate.ReadShort()
  1249  }
  1250  
  1251  func (w *MockIndexInputWrapper) ReadInt() (int32, error) {
  1252  	w.ensureOpen()
  1253  	return w.delegate.ReadInt()
  1254  }
  1255  
  1256  func (w *MockIndexInputWrapper) ReadLong() (int64, error) {
  1257  	w.ensureOpen()
  1258  	return w.delegate.ReadLong()
  1259  }
  1260  
  1261  func (w *MockIndexInputWrapper) ReadString() (string, error) {
  1262  	w.ensureOpen()
  1263  	return w.delegate.ReadString()
  1264  }
  1265  
  1266  func (w *MockIndexInputWrapper) ReadStringStringMap() (map[string]string, error) {
  1267  	w.ensureOpen()
  1268  	return w.delegate.ReadStringStringMap()
  1269  }
  1270  
  1271  func (w *MockIndexInputWrapper) ReadVInt() (int32, error) {
  1272  	w.ensureOpen()
  1273  	return w.delegate.ReadVInt()
  1274  }
  1275  
  1276  func (w *MockIndexInputWrapper) ReadVLong() (int64, error) {
  1277  	w.ensureOpen()
  1278  	return w.delegate.ReadVLong()
  1279  }
  1280  
  1281  func (w *MockIndexInputWrapper) String() string {
  1282  	return fmt.Sprintf("MockIndexInputWrapper(%v)", w.delegate)
  1283  }
  1284  
  1285  // store/MockIndexOutputWrapper.java
  1286  
  1287  /*
  1288  Used by MockRAMDirectory to create an output stream that will throw
  1289  an error on fake disk full, track max disk space actually used, and
  1290  maybe throw random IO errors.
  1291  */
  1292  type MockIndexOutputWrapper struct {
  1293  	*store.IndexOutputImpl
  1294  	dir        *MockDirectoryWrapper
  1295  	delegate   store.IndexOutput
  1296  	first      bool
  1297  	name       string
  1298  	singleByte []byte
  1299  }
  1300  
  1301  func newMockIndexOutputWrapper(dir *MockDirectoryWrapper, name string, delegate store.IndexOutput) *MockIndexOutputWrapper {
  1302  	assert(delegate != nil)
  1303  	ans := &MockIndexOutputWrapper{
  1304  		dir:        dir,
  1305  		name:       name,
  1306  		delegate:   delegate,
  1307  		first:      true,
  1308  		singleByte: make([]byte, 1),
  1309  	}
  1310  	ans.IndexOutputImpl = store.NewIndexOutput(ans)
  1311  	return ans
  1312  }
  1313  
  1314  func (w *MockIndexOutputWrapper) checkCrashed() error {
  1315  	// If MockRAMDir crashed since we were opened, then don't write anything
  1316  	if w.dir.crashed {
  1317  		return errors.New(fmt.Sprintf("MockRAMDirectory was crashed; cannot write to %v", w.name))
  1318  	}
  1319  	return nil
  1320  }
  1321  
  1322  func (w *MockIndexOutputWrapper) checkDiskFull(buf []byte, in util.DataInput) (err error) {
  1323  	panic("not implemented yet")
  1324  	// var freeSpace int64 = 0
  1325  	// if w.dir.maxSize > 0 {
  1326  	// 	sizeInBytes, err := w.dir.sizeInBytes()
  1327  	// 	if err != nil {
  1328  	// 		return err
  1329  	// 	}
  1330  	// 	freeSpace = w.dir.maxSize - sizeInBytes
  1331  	// }
  1332  	// var realUsage int64 = 0
  1333  
  1334  	// // Enforce disk full:
  1335  	// if w.dir.maxSize > 0 && freeSpace <= int64(len(buf)) {
  1336  	// 	// Compute the real disk free. This will greatly slow down our
  1337  	// 	// test but makes it more accurate:
  1338  	// 	realUsage, err = w.dir.recomputeActualSizeInBytes()
  1339  	// 	if err != nil {
  1340  	// 		return err
  1341  	// 	}
  1342  	// 	freeSpace = w.dir.maxSize - realUsage
  1343  	// }
  1344  
  1345  	// if w.dir.maxSize > 0 && freeSpace <= int64(len(buf)) {
  1346  	// 	if freeSpace > 0 {
  1347  	// 		realUsage += freeSpace
  1348  	// 		if buf != nil {
  1349  	// 			w.delegate.WriteBytes(buf[:freeSpace])
  1350  	// 		} else {
  1351  	// 			w.CopyBytes(in, int64(len(buf)))
  1352  	// 		}
  1353  	// 	}
  1354  	// 	if realUsage > w.dir.maxUsedSize {
  1355  	// 		w.dir.maxUsedSize = realUsage
  1356  	// 	}
  1357  	// 	n, err := w.dir.recomputeActualSizeInBytes()
  1358  	// 	if err != nil {
  1359  	// 		return err
  1360  	// 	}
  1361  	// 	fLen, err := w.delegate.Length()
  1362  	// 	if err != nil {
  1363  	// 		return err
  1364  	// 	}
  1365  	// 	message := fmt.Sprintf("fake disk full at %v bytes when writing %v (file length=%v",
  1366  	// 		n, w.name, fLen)
  1367  	// 	if freeSpace > 0 {
  1368  	// 		message += fmt.Sprintf("; wrote %v of %v bytes", freeSpace, len(buf))
  1369  	// 	}
  1370  	// 	message += ")"
  1371  	// 	if VERBOSE {
  1372  	// 		log.Println("MDW: now throw fake disk full")
  1373  	// 		debug.PrintStack()
  1374  	// 	}
  1375  	// 	return errors.New(message)
  1376  	// }
  1377  	// return nil
  1378  }
  1379  
  1380  func (w *MockIndexOutputWrapper) Close() (err error) {
  1381  	panic("not implemented yet")
  1382  	// defer func() {
  1383  	// 	err2 := w.delegate.Close()
  1384  	// 	if err2 != nil {
  1385  	// 		err = mergeError(err, err2)
  1386  	// 		return
  1387  	// 	}
  1388  	// 	if w.dir.trackDiskUsage {
  1389  	// 		// Now compute actual disk usage & track the maxUsedSize
  1390  	// 		// in the MDW:
  1391  	// 		size, err2 := w.dir.recomputeActualSizeInBytes()
  1392  	// 		if err2 != nil {
  1393  	// 			err = mergeError(err, err2)
  1394  	// 			return
  1395  	// 		}
  1396  	// 		if size > w.dir.maxUsedSize {
  1397  	// 			w.dir.maxUsedSize = size
  1398  	// 		}
  1399  	// 	}
  1400  	// 	w.dir.removeIndexOutput(w, w.name)
  1401  	// }()
  1402  	// return w.dir.maybeThrowDeterministicException()
  1403  }
  1404  
  1405  func (w *MockIndexOutputWrapper) Flush() error {
  1406  	panic("not implemented yet")
  1407  	// defer w.delegate.Flush()
  1408  	// return w.dir.maybeThrowDeterministicException()
  1409  }
  1410  
  1411  func (w *MockIndexOutputWrapper) WriteByte(b byte) error {
  1412  	w.singleByte[0] = b
  1413  	return w.WriteBytes(w.singleByte)
  1414  }
  1415  
  1416  func (w *MockIndexOutputWrapper) WriteBytes(buf []byte) error {
  1417  	assert(w.delegate != nil)
  1418  	err := w.checkCrashed()
  1419  	if err != nil {
  1420  		return err
  1421  	}
  1422  	err = w.checkDiskFull(buf, nil)
  1423  	if err != nil {
  1424  		return err
  1425  	}
  1426  
  1427  	if w.dir.randomState.Intn(200) == 0 {
  1428  		half := len(buf) / 2
  1429  		err = w.delegate.WriteBytes(buf[:half])
  1430  		if err != nil {
  1431  			return err
  1432  		}
  1433  		runtime.Gosched()
  1434  		err = w.delegate.WriteBytes(buf[half:])
  1435  		if err != nil {
  1436  			return err
  1437  		}
  1438  	} else {
  1439  		err = w.delegate.WriteBytes(buf)
  1440  		if err != nil {
  1441  			return err
  1442  		}
  1443  	}
  1444  
  1445  	if w.first {
  1446  		// Maybe throw random error; only do this on first write to a new file:
  1447  		w.first = false
  1448  		err = w.dir.maybeThrowIOException(w.name)
  1449  		if err != nil {
  1450  			return err
  1451  		}
  1452  	}
  1453  	return nil
  1454  }
  1455  
  1456  func (w *MockIndexOutputWrapper) FilePointer() int64 {
  1457  	return w.delegate.FilePointer()
  1458  }
  1459  
  1460  func (w *MockIndexOutputWrapper) Length() (int64, error) {
  1461  	panic("not implemented yet")
  1462  	// return w.delegate.Length()
  1463  }
  1464  
  1465  func (w *MockIndexOutputWrapper) CopyBytes(input util.DataInput, numBytes int64) error {
  1466  	panic("not implemented yet")
  1467  }
  1468  
  1469  func (w *MockIndexOutputWrapper) String() string {
  1470  	return fmt.Sprintf("MockIndexOutputWrapper(%v,%v)", reflect.TypeOf(w.delegate), w.delegate)
  1471  }