api: implement /compose/log

This commit is contained in:
Ondřej Budai 2019-12-19 10:02:55 +01:00 committed by Lars Karlitski
parent 665a7d81a8
commit 8c6f5016b0
3 changed files with 115 additions and 0 deletions

View file

@ -146,6 +146,25 @@ func TestRoute(t *testing.T, api API, external bool, method, path, body string,
}
}
func TestNonJsonRoute(t *testing.T, api API, external bool, method, path, body string, expectedStatus int, expectedResponse string) {
response := SendHTTP(api, external, method, path, body)
if response.StatusCode != expectedStatus {
t.Errorf("%s: expected status %v, but got %v", path, expectedStatus, response.StatusCode)
}
responseBodyBytes, err := ioutil.ReadAll(response.Body)
if err != nil {
t.Errorf("%s: could not read response body: %v", path, err)
}
responseBody := string(responseBodyBytes)
if responseBody != expectedResponse {
t.Errorf("%s: expected response \"%s\", but got \"%s\"", path, expectedResponse, responseBody)
}
}
func IgnoreDates() cmp.Option {
return cmp.Comparer(func(a, b time.Time) bool { return true })
}

View file

@ -98,6 +98,7 @@ func New(rpmmd rpmmd.RPMMD, arch string, distro distro.Distro, logger *log.Logge
api.router.GET("/api/v:version/compose/failed", api.composeFailedHandler)
api.router.GET("/api/v:version/compose/image/:uuid", api.composeImageHandler)
api.router.GET("/api/v:version/compose/logs/:uuid", api.composeLogsHandler)
api.router.GET("/api/v:version/compose/log/:uuid", api.composeLogHandler)
api.router.POST("/api/v:version/compose/uploads/schedule/:uuid", api.uploadsScheduleHandler)
api.router.DELETE("/api/v:version/upload/delete/:uuid", api.uploadsDeleteHandler)
@ -1623,6 +1624,75 @@ func (api *API) composeLogsHandler(writer http.ResponseWriter, request *http.Req
tw.WriteHeader(header)
io.Copy(tw, &fileContents)
tw.Close()
}
func (api *API) composeLogHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
// TODO: implement size param
if !verifyRequestVersion(writer, params, 0) {
return
}
uuidString := params.ByName("uuid")
id, err := uuid.Parse(uuidString)
if err != nil {
errors := responseError{
ID: "UnknownUUID",
Msg: fmt.Sprintf("%s is not a valid build uuid", uuidString),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
compose, exists := api.store.GetCompose(id)
if !exists {
errors := responseError{
ID: "UnknownUUID",
Msg: fmt.Sprintf("Compose %s doesn't exist", uuidString),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
if compose.QueueStatus == "WAITING" {
errors := responseError{
ID: "BuildInWrongState",
Msg: fmt.Sprintf("Build %s has not started yet. No logs to view.", uuidString),
}
statusResponseError(writer, http.StatusOK, errors) // weirdly, Lorax returns 200 in this case
return
}
if compose.QueueStatus == "RUNNING" {
fmt.Fprintf(writer, "Running...\n")
return
}
resultReader, err := api.store.GetComposeResult(id)
if err != nil {
errors := responseError{
ID: "ComposeError",
Msg: fmt.Sprintf("Opening log for compose %s failed", uuidString),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
var result ComposeResult
err = json.NewDecoder(resultReader).Decode(&result)
if err != nil {
errors := responseError{
ID: "ComposeError",
Msg: fmt.Sprintf("Parsing log for compose %s failed", uuidString),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
resultReader.Close()
result.WriteLog(writer)
}
func (api *API) composeFinishedHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {

View file

@ -514,6 +514,32 @@ func TestComposeLogs(t *testing.T) {
}
}
func TestComposeLog(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator
Method string
Path string
ExpectedStatus int
ExpectedResponse string
}{
{rpmmd_mock.BaseFixture, "GET", "/api/v0/compose/log/30000000-0000-0000-0000-000000000000", http.StatusOK, `{"status":false,"errors":[{"id":"BuildInWrongState","msg":"Build 30000000-0000-0000-0000-000000000000 has not started yet. No logs to view."}]}` + "\n"},
{rpmmd_mock.BaseFixture, "GET", "/api/v0/compose/log/30000000-0000-0000-0000-000000000001", http.StatusOK, `Running...` + "\n"},
{rpmmd_mock.BaseFixture, "GET", "/api/v0/compose/log/30000000-0000-0000-0000-000000000002", http.StatusOK, `The compose result is empty.` + "\n"},
{rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/log/30000000-0000-0000-0000-000000000002", http.StatusOK, `The compose result is empty.` + "\n"},
{rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/log/30000000-0000-0000-0000", http.StatusBadRequest, `{"status":false,"errors":[{"id":"UnknownUUID","msg":"30000000-0000-0000-0000 is not a valid build uuid"}]}` + "\n"},
{rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/log/42000000-0000-0000-0000-000000000000", http.StatusBadRequest, `{"status":false,"errors":[{"id":"UnknownUUID","msg":"Compose 42000000-0000-0000-0000-000000000000 doesn't exist"}]}` + "\n"},
}
if len(os.Getenv("OSBUILD_COMPOSER_TEST_EXTERNAL")) > 0 {
t.Skip("This test is for internal testing only")
}
for _, c := range cases {
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
test.TestNonJsonRoute(t, api, false, "GET", c.Path, "", c.ExpectedStatus, c.ExpectedResponse)
}
}
func TestComposeQueue(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator