Example #1
0
func TestLinkedSubscriptionUnsubscribesTargetOnLink(t *testing.T) {
	linked := NewLinkedSubscription()
	sub := NewGenericSubscription()
	linked.Dispose()
	assert.True(t, linked.Disposed())
	assert.False(t, sub.Disposed())
	linked.Link(sub)
	assert.True(t, linked.Disposed())
	assert.True(t, sub.Disposed())
}
Example #2
0
func TestLinkedSubscription(t *testing.T) {
	linked := NewLinkedSubscription()
	sub := NewGenericSubscription()
	assert.False(t, linked.Disposed())
	assert.False(t, sub.Disposed())
	linked.Link(sub)
	assert.Panics(t, func() { linked.Link(sub) })
	linked.Dispose()
	assert.True(t, sub.Disposed())
	assert.True(t, linked.Disposed())
}
Example #3
0
func TestCombinedShortFlags(t *testing.T) {
	app := newTestApp()
	a := app.Flag("short0", "").Short('0').Bool()
	b := app.Flag("short1", "").Short('1').Bool()
	c := app.Flag("short2", "").Short('2').Bool()
	_, err := app.Parse([]string{"-01"})
	assert.NoError(t, err)
	assert.True(t, *a)
	assert.True(t, *b)
	assert.False(t, *c)
}
Example #4
0
func TestChannelSubscription(t *testing.T) {
	done := make(chan bool)
	unsubscribed := false
	var s Subscription = NewChannelSubscription()
	events, ok := s.(SubscriptionEvents)
	assert.True(t, ok)
	events.OnUnsubscribe(func() { unsubscribed = true; done <- true })
	assert.False(t, s.Disposed())
	s.Dispose()
	assert.True(t, s.Disposed())
	<-done
	assert.True(t, unsubscribed)
}
Example #5
0
func TestDoOnComplete(t *testing.T) {
	complete := false
	a, err := EmptyInt().DoOnComplete(func() { complete = true }).ToArrayWithError()
	assert.NoError(t, err)
	assert.Equal(t, []int{}, a)
	assert.True(t, complete)
}
Example #6
0
func TestBool(t *testing.T) {
	app := newTestApp()
	b := app.Flag("b", "").Bool()
	_, err := app.Parse([]string{"--b"})
	assert.NoError(t, err)
	assert.True(t, *b)
}
Example #7
0
func TestShortFlag(t *testing.T) {
	app := newTestApp()
	f := app.Flag("long", "").Short('s').Bool()
	_, err := app.Parse([]string{"-s"})
	assert.NoError(t, err)
	assert.True(t, *f)
}
Example #8
0
func TestNestedCommandWithMergedFlags(t *testing.T) {
	app := New("app", "")
	cmd0 := app.Command("a", "")
	cmd0f0 := cmd0.Flag("aflag", "").Bool()
	// cmd1 := app.Command("b", "")
	// cmd1f0 := cmd0.Flag("bflag", "").Bool()
	cmd00 := cmd0.Command("aa", "")
	cmd00f0 := cmd00.Flag("aaflag", "").Bool()
	err := app.init()
	assert.NoError(t, err)
	context := tokenize(strings.Split("a aa --aflag --aaflag", " "), false)
	selected, err := parseAndExecute(app, context)
	assert.NoError(t, err)
	assert.True(t, *cmd0f0)
	assert.True(t, *cmd00f0)
	assert.Equal(t, "a aa", selected)
}
Example #9
0
func Test_Renewal(t *testing.T) {
	res := &http.Response{
		StatusCode: 400,
	}
	assert.True(t, needsRenewal(res, nil))

	res.StatusCode = 200
	assert.False(t, needsRenewal(res, nil))
}
Example #10
0
func TestTimeout(t *testing.T) {
	wg := sync.WaitGroup{}
	start := time.Now()
	wg.Add(1)
	actual, err := CreateInt(func(observer IntObserver, subscription Subscription) {
		observer.Next(1)
		time.Sleep(time.Millisecond * 500)
		assert.True(t, subscription.Disposed())
		wg.Done()
	}).
		Timeout(time.Millisecond * 250).
		ToArrayWithError()
	elapsed := time.Now().Sub(start)
	assert.Error(t, err)
	assert.Equal(t, ErrTimeout, err)
	assert.True(t, elapsed > time.Millisecond*250 && elapsed < time.Millisecond*500)
	assert.Equal(t, []int{1}, actual)
	wg.Wait()
}
Example #11
0
func TestDispatchCallbackIsCalled(t *testing.T) {
	dispatched := false
	c := newTestApp()
	c.Command("cmd", "").Action(func(*ParseContext) error {
		dispatched = true
		return nil
	})

	_, err := c.Parse([]string{"cmd"})
	assert.NoError(t, err)
	assert.True(t, dispatched)
}
Example #12
0
func Test_NewHealer(t *testing.T) {
	_, err := NewHealer("", "/dev/null")
	assert.Error(t, err)

	_, err = NewHealer("nope,/dev/null", "invalid")
	assert.Error(t, err)

	healer, err := NewHealer("archive,/dev/null", "invalid")
	assert.NoError(t, err)

	_, ok := healer.(*ArchiveHealer)
	assert.True(t, ok)
}
Example #13
0
func TestNestedCommandsWithArgs(t *testing.T) {
	app := New("app", "")
	cmd := app.Command("a", "").Command("b", "")
	a := cmd.Arg("a", "").String()
	b := cmd.Arg("b", "").String()
	context := tokenize([]string{"a", "b", "c", "d"}, false)
	selected, err := parseAndExecute(app, context)
	assert.NoError(t, err)
	assert.True(t, context.EOL())
	assert.Equal(t, "a b", selected)
	assert.Equal(t, "c", *a)
	assert.Equal(t, "d", *b)
}
Example #14
0
func Test_FanOut(t *testing.T) {
	t.Logf("Testing fail fast...")

	ts := &TestSink{
		FailingBlock: BlockLocation{
			FileIndex:  2,
			BlockIndex: 2,
		},
	}
	fos, err := NewFanOutSink(ts, 8)
	assert.NoError(t, err)

	fos.Start()

	hadError := false

	for i := 0; i < 8; i++ {
		for j := 0; j < 8; j++ {
			loc := BlockLocation{
				FileIndex:  int64(i),
				BlockIndex: int64(j),
			}
			sErr := fos.Store(loc, []byte{})
			if sErr != nil {
				hadError = true
			}
		}
	}

	assert.True(t, hadError)

	err = fos.Close()
	assert.NoError(t, err)

	t.Logf("Testing tail errors...")

	fos, err = NewFanOutSink(ts, 8)
	assert.NoError(t, err)

	fos.Start()

	// Store shouldn't err, just queue it...
	err = fos.Store(ts.FailingBlock, []byte{})
	assert.NoError(t, err)

	// but close should catch the error
	err = fos.Close()
	assert.NotNil(t, err)
}
Example #15
0
func TestNestedCommandsWithFlags(t *testing.T) {
	app := New("app", "")
	cmd := app.Command("a", "").Command("b", "")
	a := cmd.Flag("aaa", "").Short('a').String()
	b := cmd.Flag("bbb", "").Short('b').String()
	err := app.init()
	assert.NoError(t, err)
	context := tokenize(strings.Split("a b --aaa x -b x", " "), false)
	selected, err := parseAndExecute(app, context)
	assert.NoError(t, err)
	assert.True(t, context.EOL())
	assert.Equal(t, "a b", selected)
	assert.Equal(t, "x", *a)
	assert.Equal(t, "x", *b)
}
Example #16
0
func TestRetry(t *testing.T) {
	errored := false
	a := CreateInt(func(observer IntObserver, subscription Subscription) {
		observer.Next(1)
		observer.Next(2)
		observer.Next(3)
		if errored {
			observer.Complete()
		} else {
			observer.Error(errors.New("error"))
			errored = true
		}
	})
	b := a.Retry().ToArray()
	assert.Equal(t, []int{1, 2, 3, 1, 2, 3}, b)
	assert.True(t, errored)
}
Example #17
0
func TestArgMultipleRequired(t *testing.T) {
	terminated := false
	app := New("test", "")
	app.Version("0.0.0").Writer(ioutil.Discard)
	app.Arg("a", "").Required().String()
	app.Arg("b", "").Required().String()
	app.Terminate(func(int) { terminated = true })

	_, err := app.Parse([]string{})
	assert.Error(t, err)
	_, err = app.Parse([]string{"A"})
	assert.Error(t, err)
	_, err = app.Parse([]string{"A", "B"})
	assert.NoError(t, err)
	_, err = app.Parse([]string{"--version"})
	assert.True(t, terminated)
}
Example #18
0
func TestNestedCommands(t *testing.T) {
	app := New("app", "")
	sub1 := app.Command("sub1", "")
	sub1.Flag("sub1", "")
	subsub1 := sub1.Command("sub1sub1", "")
	subsub1.Command("sub1sub1end", "")

	sub2 := app.Command("sub2", "")
	sub2.Flag("sub2", "")
	sub2.Command("sub2sub1", "")

	context := tokenize([]string{"sub1", "sub1sub1", "sub1sub1end"}, false)
	selected, err := parseAndExecute(app, context)
	assert.NoError(t, err)
	assert.True(t, context.EOL())
	assert.Equal(t, "sub1 sub1sub1 sub1sub1end", selected)
}
Example #19
0
func TestFork(t *testing.T) {
	ch := make(chan int, 30)
	s := FromIntChannel(ch).Fork()
	a := []int{}
	b := []int{}
	sub := s.SubscribeNext(func(n int) { a = append(a, n) })
	s.SubscribeNext(func(n int) { b = append(b, n) })
	ch <- 1
	ch <- 2
	ch <- 3
	runtime.Gosched()
	sub.Dispose()
	assert.True(t, sub.Disposed())
	ch <- 4
	close(ch)
	s.Wait()
	assert.Equal(t, []int{1, 2, 3, 4}, b)
	assert.Equal(t, []int{1, 2, 3}, a)
}
Example #20
0
func runPatchingScenario(t *testing.T, scenario patchScenario) {
	log := func(format string, args ...interface{}) {
		t.Logf("[%s] %s", scenario.name, fmt.Sprintf(format, args...))
	}
	log("Scenario start")

	mainDir, err := ioutil.TempDir("", "patch-cycle")
	assert.NoError(t, err)
	assert.NoError(t, os.MkdirAll(mainDir, 0755))
	defer os.RemoveAll(mainDir)

	v1 := filepath.Join(mainDir, "v1")
	makeTestDir(t, v1, scenario.v1)

	v2 := filepath.Join(mainDir, "v2")
	makeTestDir(t, v2, scenario.v2)

	compression := &CompressionSettings{}
	compression.Algorithm = CompressionAlgorithm_NONE

	sourceContainer, err := tlc.WalkAny(v2, nil)
	assert.NoError(t, err)

	consumer := &state.Consumer{}
	patchBuffer := new(bytes.Buffer)
	signatureBuffer := new(bytes.Buffer)

	func() {
		targetContainer, dErr := tlc.WalkAny(v1, nil)
		assert.NoError(t, dErr)

		targetPool := fspool.New(targetContainer, v1)
		targetSignature, dErr := ComputeSignature(targetContainer, targetPool, consumer)
		assert.NoError(t, dErr)

		pool := fspool.New(sourceContainer, v2)

		dctx := &DiffContext{
			Compression: compression,
			Consumer:    consumer,

			SourceContainer: sourceContainer,
			Pool:            pool,

			TargetContainer: targetContainer,
			TargetSignature: targetSignature,
		}

		assert.NoError(t, dctx.WritePatch(patchBuffer, signatureBuffer))
	}()

	v1Before := filepath.Join(mainDir, "v1Before")
	cpDir(t, v1, v1Before)

	v1After := filepath.Join(mainDir, "v1After")

	woundsPath := filepath.Join(mainDir, "wounds.pww")

	if scenario.extraTests {
		log("Making sure before-path folder doesn't validate")
		signature, sErr := ReadSignature(bytes.NewReader(signatureBuffer.Bytes()))
		assert.NoError(t, sErr)
		assert.Error(t, AssertValid(v1Before, signature))

		runExtraTest := func(setup SetupFunc) error {
			assert.NoError(t, os.RemoveAll(woundsPath))
			assert.NoError(t, os.RemoveAll(v1Before))
			cpDir(t, v1, v1Before)

			actx := &ApplyContext{
				TargetPath: v1Before,
				OutputPath: v1Before,

				InPlace:  true,
				Consumer: consumer,
			}
			if setup != nil {
				setup(actx)
			}

			patchReader := bytes.NewReader(patchBuffer.Bytes())

			aErr := actx.ApplyPatch(patchReader)
			if aErr != nil {
				return aErr
			}

			if actx.Signature == nil {
				vErr := AssertValid(v1Before, signature)
				if vErr != nil {
					return vErr
				}
			}

			return nil
		}

		func() {
			log("In-place with failing vet")
			var NotVettingError = errors.New("not vetting this")
			pErr := runExtraTest(func(actx *ApplyContext) {
				actx.VetApply = func(actx *ApplyContext) error {
					return NotVettingError
				}
			})
			assert.Error(t, pErr)
			assert.True(t, errors.Is(pErr, NotVettingError))
		}()

		func() {
			log("In-place with signature (failfast, passing)")
			assert.NoError(t, runExtraTest(func(actx *ApplyContext) {
				actx.Signature = signature
			}))
		}()

		func() {
			log("In-place with signature (failfast, failing)")
			assert.Error(t, runExtraTest(func(actx *ApplyContext) {
				actx.Signature = signature
				makeTestDir(t, v1Before, *scenario.corruptions)
			}))
		}()

		func() {
			log("In-place with signature (wounds, passing)")
			assert.NoError(t, runExtraTest(func(actx *ApplyContext) {
				actx.Signature = signature
				actx.WoundsPath = woundsPath
			}))

			_, sErr := os.Lstat(woundsPath)
			assert.Error(t, sErr)
			assert.True(t, os.IsNotExist(sErr))
		}()

		func() {
			log("In-place with signature (wounds, failing)")
			assert.NoError(t, runExtraTest(func(actx *ApplyContext) {
				actx.Signature = signature
				actx.WoundsPath = woundsPath
				makeTestDir(t, v1Before, *scenario.corruptions)
			}))

			_, sErr := os.Lstat(woundsPath)
			assert.NoError(t, sErr)
		}()
	}

	log("Applying to other directory, with separate check")
	assert.NoError(t, os.RemoveAll(v1Before))
	cpDir(t, v1, v1Before)

	func() {
		actx := &ApplyContext{
			TargetPath: v1Before,
			OutputPath: v1After,

			Consumer: consumer,
		}

		patchReader := bytes.NewReader(patchBuffer.Bytes())

		aErr := actx.ApplyPatch(patchReader)
		assert.NoError(t, aErr)

		assert.Equal(t, 0, actx.Stats.DeletedFiles, "deleted files (other dir)")
		assert.Equal(t, 0, actx.Stats.DeletedDirs, "deleted dirs (other dir)")
		assert.Equal(t, 0, actx.Stats.DeletedSymlinks, "deleted symlinks (other dir)")
		assert.Equal(t, 0, actx.Stats.MovedFiles, "moved files (other dir)")
		assert.Equal(t, len(sourceContainer.Files), actx.Stats.TouchedFiles, "touched files (other dir)")
		assert.Equal(t, 0, actx.Stats.NoopFiles, "noop files (other dir)")

		signature, sErr := ReadSignature(bytes.NewReader(signatureBuffer.Bytes()))
		assert.NoError(t, sErr)

		assert.NoError(t, AssertValid(v1After, signature))
	}()

	log("Applying in-place")

	testAll := func(setup SetupFunc) {
		assert.NoError(t, os.RemoveAll(v1After))
		assert.NoError(t, os.RemoveAll(v1Before))
		cpDir(t, v1, v1Before)

		func() {
			actx := &ApplyContext{
				TargetPath: v1Before,
				OutputPath: v1Before,

				InPlace: true,

				Consumer: consumer,
			}
			if setup != nil {
				setup(actx)
			}

			patchReader := bytes.NewReader(patchBuffer.Bytes())

			aErr := actx.ApplyPatch(patchReader)
			assert.NoError(t, aErr)

			assert.Equal(t, scenario.deletedFiles, actx.Stats.DeletedFiles, "deleted files (in-place)")
			assert.Equal(t, scenario.deletedSymlinks, actx.Stats.DeletedSymlinks, "deleted symlinks (in-place)")
			assert.Equal(t, scenario.deletedDirs+scenario.leftDirs, actx.Stats.DeletedDirs, "deleted dirs (in-place)")
			assert.Equal(t, scenario.touchedFiles, actx.Stats.TouchedFiles, "touched files (in-place)")
			assert.Equal(t, scenario.movedFiles, actx.Stats.MovedFiles, "moved files (in-place)")
			assert.Equal(t, len(sourceContainer.Files)-scenario.touchedFiles-scenario.movedFiles, actx.Stats.NoopFiles, "noop files (in-place)")

			signature, sErr := ReadSignature(bytes.NewReader(signatureBuffer.Bytes()))
			assert.NoError(t, sErr)

			assert.NoError(t, AssertValid(v1Before, signature))
		}()

		if scenario.intermediate != nil {
			log("Applying in-place with %d intermediate files", len(scenario.intermediate.entries))

			assert.NoError(t, os.RemoveAll(v1After))
			assert.NoError(t, os.RemoveAll(v1Before))
			cpDir(t, v1, v1Before)

			makeTestDir(t, v1Before, *scenario.intermediate)

			func() {
				actx := &ApplyContext{
					TargetPath: v1Before,
					OutputPath: v1Before,

					InPlace: true,

					Consumer: consumer,
				}
				if setup != nil {
					setup(actx)
				}

				patchReader := bytes.NewReader(patchBuffer.Bytes())

				aErr := actx.ApplyPatch(patchReader)
				assert.NoError(t, aErr)

				assert.Equal(t, scenario.deletedFiles, actx.Stats.DeletedFiles, "deleted files (in-place w/intermediate)")
				assert.Equal(t, scenario.deletedDirs, actx.Stats.DeletedDirs, "deleted dirs (in-place w/intermediate)")
				assert.Equal(t, scenario.deletedSymlinks, actx.Stats.DeletedSymlinks, "deleted symlinks (in-place w/intermediate)")
				assert.Equal(t, scenario.touchedFiles, actx.Stats.TouchedFiles, "touched files (in-place w/intermediate)")
				assert.Equal(t, scenario.noopFiles, actx.Stats.NoopFiles, "noop files (in-place w/intermediate)")
				assert.Equal(t, scenario.leftDirs, actx.Stats.LeftDirs, "left dirs (in-place w/intermediate)")

				signature, sErr := ReadSignature(bytes.NewReader(signatureBuffer.Bytes()))
				assert.NoError(t, sErr)

				assert.NoError(t, AssertValid(v1Before, signature))
			}()
		}
	}

	testAll(nil)

	if scenario.testBrokenRename {
		testAll(func(actx *ApplyContext) {
			actx.debugBrokenRename = true
		})
	}
}
Example #21
0
func Test_WriterClose(t *testing.T) {
	dropSize := 16

	t.Logf("validation error on close")

	buf := make([]byte, dropSize)
	var validateError = errors.New("validation error")
	var underWriteError = errors.New("underlying write error")
	var underCloseError = errors.New("underlying close error")

	tw := &tracingWriter{}
	dw := &Writer{
		Buffer: buf,
		Validate: func(buf []byte) error {
			return validateError
		},
		Writer: tw,
	}

	_, wErr := dw.Write([]byte{1, 2, 3, 4})
	assert.NoError(t, wErr)

	cErr := dw.Close()
	assert.Error(t, cErr)
	assert.Equal(t, validateError, cErr)
	assert.True(t, tw.closeCall)

	t.Logf("underlying write error on close")

	tw = &tracingWriter{
		writeErr: underWriteError,
	}
	dw = &Writer{
		Buffer: buf,
		Validate: func(buf []byte) error {
			return nil
		},
		Writer: tw,
	}

	_, wErr = dw.Write([]byte{1, 2, 3, 4})
	assert.NoError(t, wErr)

	cErr = dw.Close()
	assert.Error(t, cErr)
	assert.Equal(t, underWriteError, cErr)
	assert.True(t, tw.closeCall)

	t.Logf("underlying close error on close")

	tw = &tracingWriter{
		closeErr: underCloseError,
	}
	dw = &Writer{
		Buffer: buf,
		Validate: func(buf []byte) error {
			return nil
		},
		Writer: tw,
	}

	_, wErr = dw.Write([]byte{1, 2, 3, 4})
	assert.NoError(t, wErr)

	cErr = dw.Close()
	assert.Error(t, cErr)
	assert.Equal(t, underCloseError, cErr)
	assert.True(t, tw.closeCall)
}
Example #22
0
func TestUnsubscribe(t *testing.T) {
	s := NewGenericSubscription()
	assert.False(t, s.Disposed())
	s.Dispose()
	assert.True(t, s.Disposed())
}