osbuild: add source type

This represents the sources objects, for now only org.osbuild.files
is supported.

Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
Tom Gundersen 2020-02-03 00:07:28 +01:00 committed by msehnout
parent fefe5db4ce
commit 3b774e0e6d
3 changed files with 148 additions and 0 deletions

View file

@ -0,0 +1,8 @@
package osbuild
// The FilesSourceOptions specifies a custom script to run in the image
type FilesSource struct {
URLs map[string]string `json:"urls"`
}
func (FilesSource) isSource() {}

View file

@ -0,0 +1,43 @@
package osbuild
import (
"encoding/json"
"errors"
)
// A Sources map contains all the sources made available to an osbuild run
type Sources map[string]Source
// Source specifies the operations of a given source-type.
type Source interface {
isSource()
}
type rawSources map[string]json.RawMessage
// UnmarshalJSON unmarshals JSON into a Source object. Each type of source has
// a custom unmarshaller for its options, selected based on the source name.
func (sources *Sources) UnmarshalJSON(data []byte) error {
var rawSources rawSources
err := json.Unmarshal(data, &rawSources)
if err != nil {
return err
}
*sources = make(map[string]Source)
for name, rawSource := range rawSources {
var source Source
switch name {
case "org.osbuild.files":
source = new(FilesSource)
default:
return errors.New("unexpected suorce name" + name)
}
err = json.Unmarshal(rawSource, source)
if err != nil {
return err
}
(*sources)[name] = source
}
return nil
}

View file

@ -0,0 +1,97 @@
package osbuild
import (
"bytes"
"encoding/json"
"reflect"
"testing"
)
func TestSource_UnmarshalJSON(t *testing.T) {
type fields struct {
Name string
Source Source
}
type args struct {
data []byte
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "invalid json",
args: args{
data: []byte(`{"name":"org.osbuild.foo","options":{"bar":null}`),
},
wantErr: true,
},
{
name: "unknown source",
args: args{
data: []byte(`{"name":"org.osbuild.foo","options":{"bar":null}}`),
},
wantErr: true,
},
{
name: "missing options",
args: args{
data: []byte(`{"name":"org.osbuild.files"}`),
},
wantErr: true,
},
{
name: "missing name",
args: args{
data: []byte(`{"foo":null,"options":{"bar":null}}`),
},
wantErr: true,
},
{
name: "files-empty",
fields: fields{
Name: "org.osbuild.files",
Source: &FilesSource{URLs: map[string]string{}},
},
args: args{
data: []byte(`{"org.osbuild.files":{"urls":{}}}`),
},
},
{
name: "files",
fields: fields{
Name: "org.osbuild.files",
Source: &FilesSource{URLs: map[string]string{"checksum1": "url1", "checksum2": "url2"}},
},
args: args{
data: []byte(`{"org.osbuild.files":{"urls":{"checksum1":"url1","checksum2":"url2"}}}`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sources := &Sources{
tt.fields.Name: tt.fields.Source,
}
var gotSources Sources
if err := gotSources.UnmarshalJSON(tt.args.data); (err != nil) != tt.wantErr {
t.Errorf("Sources.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantErr {
return
}
gotBytes, err := json.Marshal(sources)
if err != nil {
t.Errorf("Could not marshal source: %v", err)
}
if bytes.Compare(gotBytes, tt.args.data) != 0 {
t.Errorf("Expected '%v', got '%v'", string(tt.args.data), string(gotBytes))
}
if !reflect.DeepEqual(&gotSources, sources) {
t.Errorf("got '%v', expected '%v'", &gotSources, sources)
}
})
}
}