api: implement /compose/log
This commit is contained in:
parent
665a7d81a8
commit
8c6f5016b0
3 changed files with 115 additions and 0 deletions
|
|
@ -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 })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue