Пример #1
0
func TestUploadLogChunksAndCloseSuccessfully(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClient(ts.URL)

	ts.ExpectAndRespond("POST", "/buckets/", http.StatusOK, `{"Id": "foo"}`)
	ts.ExpectAndRespond("POST", "/buckets/foo/artifacts", http.StatusOK, `{"Name": "artifact"}`)

	b, _ := client.NewBucket("foo", "bar", 32)
	sa, err := b.NewChunkedArtifact("artifact")
	require.NotNil(t, sa)
	require.NoError(t, err)

	{
		// Content request might come later, even as late as Flush()
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact", 200, `{}`)
		err := sa.AppendLog("console contents")
		require.NoError(t, err)
	}

	{
		// Content request might come later, even as late as Flush()
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact", 200, `{}`)
		err := sa.AppendLog("more console contents")
		require.NoError(t, err)
	}

	{
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact/close", 200, `{}`)
		err := sa.Close()
		require.NoError(t, err)
	}
}
Пример #2
0
func TestPushLogChunkCancelledContext(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	ctx, cancel := context.WithCancel(context.Background())
	client := NewArtifactStoreClientWithContext(ts.URL, 100*time.Millisecond, ctx)

	ts.ExpectAndRespond("POST", "/buckets/", http.StatusOK, `{"Id": "foo"}`)
	ts.ExpectAndRespond("POST", "/buckets/foo/artifacts", http.StatusOK, `{"Name": "artifact"}`)

	b, _ := client.NewBucket("foo", "bar", 32)
	sa, err := b.NewChunkedArtifact("artifact")
	require.NotNil(t, sa)
	require.NoError(t, err)

	// Cancel the context to prevent any further requests
	cancel()

	{
		err := sa.AppendLog("console contents")
		require.NoError(t, err)
		err = sa.Close()
		require.Error(t, err)
		require.False(t, err.IsRetriable())
	}
}
Пример #3
0
func TestPushLogChunkServerSucceedOnRetry(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClient(ts.URL)

	ts.ExpectAndRespond("POST", "/buckets/", http.StatusOK, `{"Id": "foo"}`)
	ts.ExpectAndRespond("POST", "/buckets/foo/artifacts", http.StatusOK, `{"Name": "artifact"}`)

	b, _ := client.NewBucket("foo", "bar", 32)
	sa, err := b.NewChunkedArtifact("artifact")
	require.NotNil(t, sa)
	require.NoError(t, err)

	{
		// Fail with a retriable error first
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact", 500, `{}`)
		// Then succeed on retry
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact", 200, `{}`)
		err := sa.AppendLog("console contents")
		require.NoError(t, err)
	}

	{
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact/close", 200, `{}`)
		err := sa.Close()
		require.NoError(t, err)
	}
}
Пример #4
0
func TestGetBucketSuccessfully(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClient(ts.URL)

	ts.ExpectAndRespond("GET", "/buckets/foo", http.StatusOK, `{"Id": "foo"}`)

	b, err := client.GetBucket("foo")
	require.NotNil(t, b)
	require.NoError(t, err)
}
Пример #5
0
func TestGetBucketSuccessStateWithWrongName(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClient(ts.URL)

	ts.ExpectAndRespond("GET", "/buckets/foo", http.StatusOK, `{"Id": "1234"}`)

	b, err := client.GetBucket("foo")
	require.Nil(t, b)
	require.Error(t, err)
	require.False(t, err.IsRetriable(), "Error %s should not be retriable", err)
}
Пример #6
0
func TestNewStreamedArtifactSuccessfully(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClient(ts.URL)

	ts.ExpectAndRespond("POST", "/buckets/", http.StatusOK, `{"Id": "foo"}`)
	ts.ExpectAndRespond("POST", "/buckets/foo/artifacts", http.StatusOK, `{"Name": "artifact"}`)

	b, _ := client.NewBucket("foo", "bar", 32)
	sa, err := b.NewStreamedArtifact("artifact", 10)
	require.NotNil(t, sa)
	require.NoError(t, err)
}
Пример #7
0
func TestInitTimeout(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	r := &Reporter{deadline: 100 * time.Millisecond}
	artifactServer = ts.URL
	ts.ExpectAndHang("POST", "/buckets/")

	r.Init(&client.Config{JobstepID: "jobstep"})

	if !r.isDisabled() {
		t.Error("Init did not fail with deadline exceeded")
	}
}
Пример #8
0
func TestShutdownTimeout(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	r := &Reporter{deadline: 100 * time.Millisecond}
	artifactServer = ts.URL
	ts.ExpectAndRespond("POST", "/buckets/", 200, `{"Id": "jobstep"}`)

	r.Init(&client.Config{JobstepID: "jobstep"})
	if r.isDisabled() {
		t.Error("Init should not fail with deadline exceeded")
	}

	ts.ExpectAndHang("POST", "/buckets/jobstep/close")
	r.Shutdown()
	if !r.isDisabled() {
		t.Error("Shutdown did not fail with deadline exceeded")
	}
}
Пример #9
0
func TestPushLogChunkTimeout(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	r := &Reporter{deadline: 150 * time.Millisecond}
	artifactServer = ts.URL
	ts.ExpectAndRespond("POST", "/buckets/", 200, `{"Id": "jobstep"}`)

	r.Init(&client.Config{JobstepID: "jobstep"})
	if r.isDisabled() {
		t.Error("Init should not fail with deadline exceeded")
	}

	ts.ExpectAndHang("POST", "/buckets/jobstep/artifacts")
	r.PushLogChunk("console", []byte("console contents"))
	if !r.isDisabled() {
		t.Error("PushLogChunk did not fail with deadline exceeded")
	}

	// This call should not even create a new request. If it does, testserver will throw an error
	// about an unexpected request.
	r.PushLogChunk("console", []byte("console contents"))
}
Пример #10
0
func TestPushLogChunkServerFailWithTerminalError(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	client := NewArtifactStoreClientWithContext(ts.URL, 100*time.Millisecond, context.Background())

	ts.ExpectAndRespond("POST", "/buckets/", http.StatusOK, `{"Id": "foo"}`)
	ts.ExpectAndRespond("POST", "/buckets/foo/artifacts", http.StatusOK, `{"Name": "artifact"}`)

	b, _ := client.NewBucket("foo", "bar", 32)
	sa, err := b.NewChunkedArtifact("artifact")
	require.NotNil(t, sa)
	require.NoError(t, err)

	{
		// Fail with a terminal error
		ts.ExpectAndRespond("POST", "/buckets/foo/artifacts/artifact", 400, `{}`)
		err := sa.AppendLog("console contents")
		require.NoError(t, err)
		err = sa.Close()
		require.Error(t, err)
		require.False(t, err.IsRetriable())
	}
}
Пример #11
0
func TestPublishArtifactsTimeout(t *testing.T) {
	ts := testserver.NewTestServer(t)
	defer ts.CloseAndAssertExpectations()

	r := &Reporter{deadline: 100 * time.Millisecond}
	artifactServer = ts.URL
	ts.ExpectAndRespond("POST", "/buckets/", 200, `{"Id": "jobstep"}`)

	r.Init(&client.Config{JobstepID: "jobstep"})
	if r.isDisabled() {
		t.Error("Init should not fail with deadline exceeded")
	}

	ma := &mockAdapter{}
	ts.ExpectAndHang("POST", "/buckets/jobstep/artifacts")
	l := client.NewLog()
	go l.Drain()
	defer l.Close()
	r.PublishArtifacts(client.ConfigCmd{Artifacts: []string{"*hosts*"}}, ma, l)

	if !r.isDisabled() {
		t.Error("PublishArtifacts did not fail with deadline exceeded")
	}
}
Пример #12
0
func testErrorCombinations(t *testing.T,
	prerun func(*testserver.TestServer, *ArtifactStoreClient) interface{},
	method string,
	url string,
	test func(c *ArtifactStoreClient, obj interface{}) (interface{}, *ArtifactsError)) {
	{
		ts := testserver.NewTestServer(t)
		client := NewArtifactStoreClient(ts.URL)
		obj := prerun(ts, client)

		ts.CloseAndAssertExpectations()
		// Server is missing, network error
		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.True(t, err.IsRetriable(), "Error %s should be retriable", err)
	}

	{
		// Server threw internal error
		ts := testserver.NewTestServer(t)
		defer ts.CloseAndAssertExpectations()

		client := NewArtifactStoreClient(ts.URL)
		obj := prerun(ts, client)
		ts.ExpectAndRespond(method, url, http.StatusInternalServerError, `{"error": "Something bad happened"}`)

		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.True(t, err.IsRetriable(), "Error %s should be retriable", err)
	}

	{
		// Server indicated client error
		ts := testserver.NewTestServer(t)
		defer ts.CloseAndAssertExpectations()

		client := NewArtifactStoreClient(ts.URL)
		obj := prerun(ts, client)
		ts.ExpectAndRespond(method, url, http.StatusBadRequest, `{"error": "Bad client"}`)

		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.False(t, err.IsRetriable(), "Error %s should not be retriable", err)
	}

	{
		// Proxy error - server was unreachable
		ts := testserver.NewTestServer(t)
		defer ts.CloseAndAssertExpectations()

		client := NewArtifactStoreClient(ts.URL)
		obj := prerun(ts, client)
		ts.ExpectAndRespond(method, url, http.StatusBadGateway, `<html>Foo</html>`)

		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.True(t, err.IsRetriable(), "Error %s should be retriable", err)
	}

	{
		// Proxy/server error - mangled output
		ts := testserver.NewTestServer(t)
		defer ts.CloseAndAssertExpectations()

		client := NewArtifactStoreClient(ts.URL)
		obj := prerun(ts, client)
		ts.ExpectAndRespond(method, url, http.StatusOK, `<html></html>`)

		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.False(t, err.IsRetriable(), "Error %s should not be retriable", err)
	}

	{
		// Proxy/server hangs and times out
		ts := testserver.NewTestServer(t)
		defer ts.CloseAndAssertExpectations()
		client := NewArtifactStoreClientWithContext(ts.URL, 100*time.Millisecond, context.Background())
		obj := prerun(ts, client)
		ts.ExpectAndHang(method, url)

		op, err := test(client, obj)
		require.Nil(t, op)
		require.Error(t, err)
		require.True(t, err.IsRetriable(), "Error %s should be retriable", err)
	}
}