Example #1
0
func TestClient_Start(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	socketFile, l := createSocketServer(t)
	defer l.Close()

	var startContent string
	readChan := setupReadRequest(t, l, &startContent, "REQUEST OK\n")

	client := New(socketFile)
	err := client.Start(
		"echo", []string{"123"}, "dir", []string{"FOO=bar"},
		"/a", "/b", "123", "456", time.Second,
	)
	tt.TestExpectSuccess(t, err)

	select {
	case <-readChan:
	case <-time.After(time.Second):
		tt.Fatalf(t, "Expected to have read client response within 1 second")
	}

	expectedRequest := "1\n6\n2\n5\nSTART4\necho1\n3\n1231\n3\ndir1\n7\nFOO=bar2\n2\n/a2\n/b2\n3\n1233\n456"
	tt.TestEqual(t, startContent, expectedRequest)
}
Example #2
0
func TestClient_Exec(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	socketFile, l := createSocketServer(t)
	defer l.Close()

	var execContent string
	readChan := setupReadRequest(t, l, &execContent, "REQUEST OK\n")

	client := New(socketFile)
	err := client.Exec(
		[]string{"/sbin/init", "foo"}, []string{"FOO=bar"}, "/a", "/b", time.Second,
	)
	tt.TestExpectSuccess(t, err)

	select {
	case <-readChan:
	case <-time.After(time.Second):
		tt.Fatalf(t, "Expected to have read client response within 1 second")
	}

	expectedRequest := "1\n4\n1\n4\nEXEC2\n10\n/sbin/init3\nfoo1\n7\nFOO=bar2\n2\n/a2\n/b"
	tt.TestEqual(t, execContent, expectedRequest)
}
Example #3
0
func TestEnvMap(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	expected := []string{
		"START_COMMAND=XYZ",
		"TEST_CROSSREF1=cross_pkg2",
		"TEST_CROSSREF2=cross_pkg1",
		"TEST_CROSSREF_VAL1=cross_pkg1",
		"TEST_CROSSREF_VAL2=cross_pkg2",
		"TEST_ENV_VARIABLE=TEST_ENV_CONTENT",
		"TEST_MERGE_UNDEFINED=undef:",
		"TEST_MERGE_VARIABLE=pkg2:pkg1:",
		"TEST_OVERRIDE_VARIABLE=pkg2",
	}

	root := NewEnvMap()
	root.Set("TEST_ENV_VARIABLE", "TEST_ENV_CONTENT")
	root.Set("TEST_MERGE_VARIABLE", "pkg1:$TEST_MERGE_VARIABLE")
	root.Set("TEST_MERGE_UNDEFINED", "undef:$TEST_NOT_SET")
	root.Set("TEST_OVERRIDE_VARIABLE", "pkg1")
	root.Set("TEST_CROSSREF1", "$TEST_CROSSREF_VAL2")
	root.Set("TEST_CROSSREF_VAL1", "cross_pkg1")
	root.Set("START_COMMAND", "XYZ")

	c1 := root.NewChild()
	c1.Set("TEST_MERGE_VARIABLE", "pkg2:$TEST_MERGE_VARIABLE")
	c1.Set("TEST_OVERRIDE_VARIABLE", "pkg2")
	c1.Set("TEST_CROSSREF2", "$TEST_CROSSREF_VAL1")
	c1.Set("TEST_CROSSREF_VAL2", "cross_pkg2")
	c1.Set("START_COMMAND", "XYZ")

	envstrs := c1.Strings()

	// Sort the two list just in case.
	sort.Sort(sort.StringSlice(envstrs))
	sort.Sort(sort.StringSlice(expected))

	msg := make([]string, 0, len(envstrs))
	failed := false
	a := func(fmtstr string, args ...interface{}) {
		msg = append(msg, fmt.Sprintf(fmtstr, args...))
	}
	for i := 0; i < len(expected) || i < len(envstrs); i++ {
		if i >= len(expected) {
			a("\t'' > '%s'", envstrs[i])
		} else if i >= len(envstrs) {
			a("\t'%s' < ''", expected[i])
		} else if expected[i] != envstrs[i] {
			a("\t'%s' != '%s'", expected[i], envstrs[i])
		} else {
			a("\t'%s' == '%s'", expected[i], envstrs[i])
			continue
		}
		failed = true
	}
	if failed == true {
		tt.Fatalf(t, "results are not the same:\n%s", strings.Join(msg, "\n"))
	}
}
Example #4
0
func TestEnvMapSimple(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	// Simple case.
	e := NewEnvMap()
	e.Set("A", "$A")
	m := e.Map()
	if len(m) != 1 {
		tt.Fatalf(t, "Invlid number of environment variables set.")
	} else if v, ok := m["A"]; ok == false {
		tt.Fatalf(t, "$A was not defined.")
	} else if v != "" {
		tt.Fatalf(t, "$A has a bad value: %s", v)
	}
}
Example #5
0
func TestClient_Stop(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	// To effectively test stop, we also want to ensure a request is inflight and
	// that it makes that request return.

	socketFile, l := createSocketServer(t)
	defer l.Close()

	setupRequestThatNeverReturns(t, l)

	stopReadyCh := make(chan bool)
	waitDoneCh := make(chan bool)

	client := New(socketFile)

	go func() {
		close(stopReadyCh)
		defer close(waitDoneCh)
		err := client.Wait(time.Minute)
		if err == nil {
			t.Errorf("wait should have returned an error about the client stopping")
			return
		}
		if err.Error() != "client is stopped." {
			t.Errorf("client should have returned an error that the client was stopping, but got: %v", err)
		}
	}()

	select {
	case <-stopReadyCh:
	case <-time.After(5 * time.Second):
		tt.Fatalf(t, "the wait goroutine wasn't setup within 5 seconds")
	}

	tt.TestEqual(t, client.Stopped(), false)
	client.Stop()
	tt.TestEqual(t, client.Stopped(), true)

	select {
	case <-waitDoneCh:
	case <-time.After(5 * time.Second):
		tt.Fatalf(t, "the wait goroutine should have unblocked within 5 seconds")
	}
}
Example #6
0
func TestEnvMapGetRaw(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	root := NewEnvMap()
	root.Set("VARIABLE", "foo bar $STR")
	root.Set("VAR1", "abc 123 $VAR2")
	root.Set("VAR2", "xyz")

	if v, _ := root.Get("VARIABLE"); v != "foo bar " {
		tt.Fatalf(t, "Get(VARIABLE) should have blanked out STR: %q", v)
	}
	if v, _ := root.GetRaw("VARIABLE"); v != "foo bar $STR" {
		tt.Fatalf(t, "GetRaw(VARIABLE) should include raw $STR: %q", v)
	}

	if v, _ := root.Get("VAR1"); v != "abc 123 xyz" {
		tt.Fatalf(t, "Get(VAR1) should have parsed mentioned variables: %q", v)
	}
	if v, _ := root.GetRaw("VAR1"); v != "abc 123 $VAR2" {
		tt.Fatalf(t, "GetRaw(VAR1) should be the raw string: %q", v)
	}
}
Example #7
0
func TestClient_StopAndWaitRace(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	// This test is going to monkey with the internals. The goal is to get Wait()
	// to start before calling Stop(), but to then have the request flow begin
	// until after Stop() is done. The goal is test a race around the combination
	// of the two.
	//
	// This is done by triggering the Stop() call immediately after
	// l.Accept(). The Wait() call is a request that will never return with a 1
	// minute timeout, and we validate the response from Wait() is about stopping
	// rather than hitting the timeout.

	socketFile, l := createSocketServer(t)
	defer l.Close()

	client := New(socketFile)

	waitDoneCh := make(chan bool)

	go func() {
		l.Accept()
		client.Stop()
	}()

	go func() {
		defer close(waitDoneCh)
		err := client.Wait(5 * time.Second)
		if err == nil {
			t.Errorf("wait should have returned an error about the client stopping")
			return
		}
		if err.Error() != "client is stopped." {
			t.Errorf("client should have returned an error that the client was stopping, but got: %v", err)
		}
	}()

	select {
	case <-waitDoneCh:
	case <-time.After(6 * time.Second):
		tt.Fatalf(t, "the wait goroutine should have unblocked within 5 seconds")
	}
}
Example #8
0
func TestClient_Wait(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	socketFile, l := createSocketServer(t)
	defer l.Close()

	var waitContent string
	readChan := setupReadRequest(t, l, &waitContent, "REQUEST OK\n")

	client := New(socketFile)
	err := client.Wait(time.Second)
	tt.TestExpectSuccess(t, err)

	select {
	case <-readChan:
	case <-time.After(time.Second):
		tt.Fatalf(t, "Expected to have read client response within 1 second")
	}

	expectedRequest := "1\n1\n1\n4\nWAIT"
	tt.TestEqual(t, waitContent, expectedRequest)
}
Example #9
0
func TestClient_Status(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	socketFile, l := createSocketServer(t)
	defer l.Close()

	var statusContent string
	readChan := setupReadRequest(t, l, &statusContent, "REQUEST OK\nfoo\nrunning\nbar\nexit(1)\nend\n")

	client := New(socketFile)
	status, err := client.Status(time.Second)
	tt.TestExpectSuccess(t, err)

	select {
	case <-readChan:
	case <-time.After(time.Second):
		tt.Fatalf(t, "Expected to have read client response within 1 second")
	}

	expectedStatus := map[string]string{"foo": "running", "bar": "exit(1)"}
	tt.TestEqual(t, status, expectedStatus)
}
Example #10
0
func TestClient_Mount(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	socketFile, l := createSocketServer(t)
	defer l.Close()

	var startContent string
	readChan := setupReadRequest(t, l, &startContent, "REQUEST OK\n")

	client := New(socketFile)
	err := client.Mount("/src", "/dst", "ext4", 0, "", time.Second)
	tt.TestExpectSuccess(t, err)

	select {
	case <-readChan:
	case <-time.After(time.Second):
		tt.Fatalf(t, "Expected to have read client response within 1 second")
	}

	expectedRequest := "1\n2\n3\n5\nMOUNT4\n/src4\n/dst3\n4\next41\n00\n"
	tt.TestEqual(t, startContent, expectedRequest)
}
Example #11
0
func TestParseSimpleProcFile(t *testing.T) {
	tt.StartTest(t)
	defer tt.FinishTest(t)

	// Test 1: Success.
	lines := []string{
		"aelm0 aelm1\taelm2",
		" belm0  belm1\t belm2\t\t\t",
		"",
		"delm0"}
	f := tt.WriteTempFile(t, strings.Join(lines, "\n"))
	err := ParseSimpleProcFile(
		f,
		func(index int, line string) error {
			if index > len(lines) {
				tt.Fatalf(t, "Too many lines read: %d", index)
			} else if line != lines[index] {
				tt.Fatalf(t, "Invalid line read: %s", line)
			}
			return nil
		},
		func(line int, index int, elm string) error {
			switch {
			case line == 0 && index == 0 && elm == "aelm0":
			case line == 0 && index == 1 && elm == "aelm1":
			case line == 0 && index == 2 && elm == "aelm2":
			case line == 1 && index == 0 && elm == "belm0":
			case line == 1 && index == 1 && elm == "belm1":
			case line == 1 && index == 2 && elm == "belm2":
			case line == 3 && index == 0 && elm == "delm0":
			default:
				tt.Fatalf(
					t, "Unknown element read: %d, %d, %s", line, index, elm)
			}
			return nil
		})
	if err != nil {
		tt.Fatalf(t, "Unexpected error from ParseSimpleProcFile()")
	}

	// Test 2: No function defined. This should be successful.
	err = ParseSimpleProcFile(f, nil, nil)
	if err != nil {
		tt.Fatalf(t, "Unexpected error from ParseSimpleProcFile()")
	}

	// Test 3: ef returns an error.
	err = ParseSimpleProcFile(
		f,
		func(index int, line string) error {
			return fmt.Errorf("error.")
		},
		nil)
	if err == nil {
		tt.Fatalf(t, "Expected error not returned.")
	}

	// Test 4: lf returns an error.
	err = ParseSimpleProcFile(
		f,
		nil,
		func(line int, index int, elm string) error {
			return fmt.Errorf("error.")
		})
	if err == nil {
		tt.Fatalf(t, "Expected error not returned.")
	}

	// Test 6: last case lf operation.
	err = ParseSimpleProcFile(
		f,
		func(index int, line string) error {
			if line == "delm0" {
				return fmt.Errorf("error")
			}
			return nil
		},
		nil)

	// Test 5: last case lf operation.
	err = ParseSimpleProcFile(
		f,
		nil,
		func(line int, index int, elm string) error {
			if elm == "delm0" {
				return fmt.Errorf("error")
			}
			return nil
		})
}