blob: dadf6168bf3f641cf6584388b63a10cb6b5f3c47 [file]
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package view
import (
"bytes"
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
"github.com/apache/skywalking-cli/pkg/contextkey"
)
func TestCoreURL(t *testing.T) {
cases := map[string]string{
"http://127.0.0.1:12800/graphql": "http://127.0.0.1:12800",
"https://oap.example.com/graphql/": "https://oap.example.com",
"http://[::1]:12800/graphql": "http://[::1]:12800",
"http://oap:12800": "http://oap:12800",
"not a url": "not a url",
}
for in, want := range cases {
if got := CoreURL(in); got != want {
t.Errorf("CoreURL(%q) = %q, want %q", in, got, want)
}
}
}
// server answers the route the way the OAP does: the document as JSON in several flushes or
// as YAML by Accept, a problem document for anything else, and 418 for a wrong request.
func server(t *testing.T, document []byte) *httptest.Server {
t.Helper()
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/ai-agent/conversations/c 1/v1/view" ||
r.URL.Query().Get("service") != "agent" || r.URL.Query().Get("instance") != "sender" {
w.WriteHeader(http.StatusTeapot)
return
}
if r.Header.Get("Authorization") != "Basic dTpw" {
w.WriteHeader(http.StatusUnauthorized)
return
}
switch r.Header.Get("Accept") {
case MediaTypeYAML:
w.Header().Set("Content-Type", MediaTypeYAML+"; version=1.0")
_, _ = w.Write([]byte("format: asz.view\n"))
case MediaTypeJSON:
w.Header().Set("Content-Type", MediaTypeJSON+"; version=1.0")
for i := 0; i < len(document); i += 8192 {
end := i + 8192
if end > len(document) {
end = len(document)
}
_, _ = w.Write(document[i:end])
w.(http.Flusher).Flush()
}
default:
w.Header().Set("Content-Type", "application/problem+json")
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte(`{"type":"about:blank","title":"Not Found","status":404,"detail":"no round"}`))
}
}))
}
func testContext(serverURL string) context.Context {
ctx := context.WithValue(context.Background(), contextkey.BaseURL{}, serverURL+"/graphql")
ctx = context.WithValue(ctx, contextkey.Username{}, "u")
return context.WithValue(ctx, contextkey.Password{}, "p")
}
func TestFetchStreamsTheDocument(t *testing.T) {
document := bytes.Repeat([]byte("{\"format\":\"asz.view\"}\n"), 4096)
srv := server(t, document)
defer srv.Close()
var out bytes.Buffer
contentType, err := Fetch(testContext(srv.URL), "c 1", "agent", "sender", false, &out)
if err != nil {
t.Fatal(err)
}
if contentType != MediaTypeJSON+"; version=1.0" || !bytes.Equal(out.Bytes(), document) {
t.Fatalf("content type %q, %d bytes", contentType, out.Len())
}
}
func TestFetchAsksForYAML(t *testing.T) {
srv := server(t, nil)
defer srv.Close()
var out bytes.Buffer
contentType, err := Fetch(testContext(srv.URL), "c 1", "agent", "sender", true, &out)
if err != nil || contentType != MediaTypeYAML+"; version=1.0" || out.String() != "format: asz.view\n" {
t.Fatalf("%v, content type %q, body %q", err, contentType, out.String())
}
}
func TestAProblemDocumentIsTheError(t *testing.T) {
srv := server(t, nil)
defer srv.Close()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, srv.URL+Path("c 1")+"?service=agent&instance=sender", http.NoBody)
req.Header.Set("Authorization", "Basic dTpw")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
var problem *Problem
if err := readError(resp, req.URL.String()); !errors.As(err, &problem) ||
problem.Status != 404 || problem.Detail != "no round" || problem.Title != "Not Found" {
t.Fatalf("problem: %v", err)
}
}