From 1039800fa98f222c188aeee53cef6cecc733ce3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=85=95=E8=96=87=E7=96=AF=E9=AD=94?= Date: Mon, 11 Mar 2019 09:28:35 +0800 Subject: [PATCH] 1. Migration for policy manager. 2. Clear test database after run test. 3. UT for policy manager and dao. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 慕薇疯魔 --- .../postgresql/0006_ng_replication.up.sql | 23 +- src/replication/ng/dao/dao_test.go | 16 +- src/replication/ng/dao/policy_test.go | 311 ++++++++++++++++++ src/replication/ng/policy/manager_test.go | 187 +++++++++++ 4 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 src/replication/ng/dao/policy_test.go create mode 100644 src/replication/ng/policy/manager_test.go diff --git a/make/migrations/postgresql/0006_ng_replication.up.sql b/make/migrations/postgresql/0006_ng_replication.up.sql index 792d6007a..693c83241 100644 --- a/make/migrations/postgresql/0006_ng_replication.up.sql +++ b/make/migrations/postgresql/0006_ng_replication.up.sql @@ -12,4 +12,25 @@ CREATE TABLE registry ( creation_time timestamp default CURRENT_TIMESTAMP, update_time timestamp default CURRENT_TIMESTAMP, CONSTRAINT unique_registry_name UNIQUE (name) -); \ No newline at end of file +); + +CREATE TABLE "replication_policy_ng" ( + "id" SERIAL PRIMARY KEY NOT NULL, + "name" varchar(256), + "description" text, + "creator" varchar(256), + "src_registry_id" int4, + "src_namespaces" varchar(256), + "dest_registry_id" int4, + "dest_namespace" varchar(256), + "override" bool NOT NULL DEFAULT false, + "enabled" bool NOT NULL DEFAULT true, + "cron_str" varchar(256), + "filters" varchar(1024), + "replicate_deletion" bool NOT NULL DEFAULT false, + "start_time" timestamp(6), + "deleted" bool NOT NULL DEFAULT false, + "creation_time" timestamp(6) DEFAULT now(), + "update_time" timestamp(6) DEFAULT now(), + CONSTRAINT unique_policy_ng_name UNIQUE ("name") +); diff --git a/src/replication/ng/dao/dao_test.go b/src/replication/ng/dao/dao_test.go index eb5e9bbb9..d27c52f37 100644 --- a/src/replication/ng/dao/dao_test.go +++ b/src/replication/ng/dao/dao_test.go @@ -23,5 +23,19 @@ import ( func TestMain(m *testing.M) { dao.PrepareTestForPostgresSQL() - os.Exit(m.Run()) + + var code = m.Run() + + // clear test database + var clearSqls = []string{ + `DROP TABLE "access", "access_log", "admin_job", "alembic_version", "clair_vuln_timestamp", + "harbor_label", "harbor_resource_label", "harbor_user", "img_scan_job", "img_scan_overview", + "job_log", "project", "project_member", "project_metadata", "properties", "registry", + "replication_immediate_trigger", "replication_job", "replication_policy", "replication_policy_ng", + "replication_target", "repository", "robot", "role", "schema_migrations", "user_group";`, + `DROP FUNCTION "update_update_time_at_column"();`, + } + dao.PrepareTestData(clearSqls, nil) + + os.Exit(code) } diff --git a/src/replication/ng/dao/policy_test.go b/src/replication/ng/dao/policy_test.go new file mode 100644 index 000000000..91a8bcac4 --- /dev/null +++ b/src/replication/ng/dao/policy_test.go @@ -0,0 +1,311 @@ +package dao + +import ( + "testing" + + "github.com/astaxie/beego/orm" + "github.com/goharbor/harbor/src/replication/ng/dao/models" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + testPolic1 = &models.RepPolicy{ + // ID: 999, + Name: "Policy Test 1", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: "ns1,ns2,ns3", + DestRegistryID: 456, + DestNamespace: "target_ns", + ReplicateDeletion: true, + Override: true, + Enabled: true, + Trigger: "{\"type\":\"\",\"trigger_settings\":null}", + Filters: "[{\"type\":\"registry\",\"value\":\"abc\"}]", + } + + testPolic2 = &models.RepPolicy{ + // ID: 999, + Name: "Policy Test 2", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: "ns1,ns2,ns3", + DestRegistryID: 456, + DestNamespace: "target_ns", + ReplicateDeletion: true, + Override: true, + Enabled: true, + Trigger: "{\"type\":\"\",\"trigger_settings\":null}", + Filters: "[{\"type\":\"registry\",\"value\":\"abc\"}]", + } + + testPolic3 = &models.RepPolicy{ + // ID: 999, + Name: "Policy Test 3", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: "ns1,ns2,ns3", + DestRegistryID: 456, + DestNamespace: "target_ns", + ReplicateDeletion: true, + Override: true, + Enabled: true, + Trigger: "{\"type\":\"\",\"trigger_settings\":null}", + Filters: "[{\"type\":\"registry\",\"value\":\"abc\"}]", + } +) + +func TestAddRepPolicy(t *testing.T) { + tests := []struct { + name string + policy *models.RepPolicy + want int64 + wantErr bool + }{ + {name: "AddRepPolicy 1", policy: testPolic1, want: 1}, + {name: "AddRepPolicy 2", policy: testPolic2, want: 2}, + {name: "AddRepPolicy 3", policy: testPolic3, want: 3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := AddRepPolicy(tt.policy) + + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestGetTotalOfRepPolicies(t *testing.T) { + type args struct { + name string + namespace string + } + tests := []struct { + name string + args args + want int64 + wantErr bool + }{ + {name: "GetTotalOfRepPolicies 1", args: args{name: "Test 1"}, want: 1}, + {name: "GetTotalOfRepPolicies 2", args: args{name: "Test"}, want: 3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetTotalOfRepPolicies(tt.args.name, tt.args.namespace) + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestGetPolicies(t *testing.T) { + type args struct { + name string + namespace string + page int64 + pageSize int64 + } + tests := []struct { + name string + args args + wantPolicies []*models.RepPolicy + wantErr bool + }{ + {name: "GetTotalOfRepPolicies nil", args: args{name: "Test 0"}, wantPolicies: []*models.RepPolicy{}}, + {name: "GetTotalOfRepPolicies 1", args: args{name: "Test 1"}, wantPolicies: []*models.RepPolicy{testPolic1}}, + {name: "GetTotalOfRepPolicies 2", args: args{name: "Test", page: 1, pageSize: 2}, wantPolicies: []*models.RepPolicy{testPolic1, testPolic2}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotPolicies, err := GetPolicies(tt.args.name, tt.args.namespace, tt.args.page, tt.args.pageSize) + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + for i, gotPolicy := range gotPolicies { + assert.Equal(t, tt.wantPolicies[i].Name, gotPolicy.Name) + assert.Equal(t, tt.wantPolicies[i].Description, gotPolicy.Description) + assert.Equal(t, tt.wantPolicies[i].Creator, gotPolicy.Creator) + assert.Equal(t, tt.wantPolicies[i].SrcRegistryID, gotPolicy.SrcRegistryID) + assert.Equal(t, tt.wantPolicies[i].SrcNamespaces, gotPolicy.SrcNamespaces) + assert.Equal(t, tt.wantPolicies[i].DestRegistryID, gotPolicy.DestRegistryID) + assert.Equal(t, tt.wantPolicies[i].DestNamespace, gotPolicy.DestNamespace) + assert.Equal(t, tt.wantPolicies[i].ReplicateDeletion, gotPolicy.ReplicateDeletion) + assert.Equal(t, tt.wantPolicies[i].Override, gotPolicy.Override) + assert.Equal(t, tt.wantPolicies[i].Enabled, gotPolicy.Enabled) + assert.Equal(t, tt.wantPolicies[i].Trigger, gotPolicy.Trigger) + assert.Equal(t, tt.wantPolicies[i].Filters, gotPolicy.Filters) + } + }) + } +} + +func TestGetRepPolicy(t *testing.T) { + tests := []struct { + name string + id int64 + wantPolicy *models.RepPolicy + wantErr bool + }{ + {name: "GetRepPolicy 1", id: 1, wantPolicy: testPolic1}, + {name: "GetRepPolicy 2", id: 2, wantPolicy: testPolic2}, + {name: "GetRepPolicy 3", id: 3, wantPolicy: testPolic3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotPolicy, err := GetRepPolicy(tt.id) + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + assert.Equal(t, tt.wantPolicy.Name, gotPolicy.Name) + assert.Equal(t, tt.wantPolicy.Description, gotPolicy.Description) + assert.Equal(t, tt.wantPolicy.Creator, gotPolicy.Creator) + assert.Equal(t, tt.wantPolicy.SrcRegistryID, gotPolicy.SrcRegistryID) + assert.Equal(t, tt.wantPolicy.SrcNamespaces, gotPolicy.SrcNamespaces) + assert.Equal(t, tt.wantPolicy.DestRegistryID, gotPolicy.DestRegistryID) + assert.Equal(t, tt.wantPolicy.DestNamespace, gotPolicy.DestNamespace) + assert.Equal(t, tt.wantPolicy.ReplicateDeletion, gotPolicy.ReplicateDeletion) + assert.Equal(t, tt.wantPolicy.Override, gotPolicy.Override) + assert.Equal(t, tt.wantPolicy.Enabled, gotPolicy.Enabled) + assert.Equal(t, tt.wantPolicy.Trigger, gotPolicy.Trigger) + assert.Equal(t, tt.wantPolicy.Filters, gotPolicy.Filters) + }) + } +} + +func TestGetRepPolicyByName(t *testing.T) { + type args struct { + name string + } + tests := []struct { + name string + args args + wantPolicy *models.RepPolicy + wantErr bool + }{ + {name: "GetRepPolicyByName 1", args: args{name: testPolic1.Name}, wantPolicy: testPolic1}, + {name: "GetRepPolicyByName 2", args: args{name: testPolic2.Name}, wantPolicy: testPolic2}, + {name: "GetRepPolicyByName 3", args: args{name: testPolic3.Name}, wantPolicy: testPolic3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotPolicy, err := GetRepPolicyByName(tt.args.name) + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + assert.Equal(t, tt.wantPolicy.Name, gotPolicy.Name) + assert.Equal(t, tt.wantPolicy.Description, gotPolicy.Description) + assert.Equal(t, tt.wantPolicy.Creator, gotPolicy.Creator) + assert.Equal(t, tt.wantPolicy.SrcRegistryID, gotPolicy.SrcRegistryID) + assert.Equal(t, tt.wantPolicy.SrcNamespaces, gotPolicy.SrcNamespaces) + assert.Equal(t, tt.wantPolicy.DestRegistryID, gotPolicy.DestRegistryID) + assert.Equal(t, tt.wantPolicy.DestNamespace, gotPolicy.DestNamespace) + assert.Equal(t, tt.wantPolicy.ReplicateDeletion, gotPolicy.ReplicateDeletion) + assert.Equal(t, tt.wantPolicy.Override, gotPolicy.Override) + assert.Equal(t, tt.wantPolicy.Enabled, gotPolicy.Enabled) + assert.Equal(t, tt.wantPolicy.Trigger, gotPolicy.Trigger) + assert.Equal(t, tt.wantPolicy.Filters, gotPolicy.Filters) + }) + } +} + +func TestUpdateRepPolicy(t *testing.T) { + type args struct { + policy *models.RepPolicy + props []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "UpdateRepPolicy Want Error", args: args{policy: nil}, wantErr: true}, + { + name: "UpdateRepPolicy 1", + args: args{ + policy: &models.RepPolicy{ID: 1, Description: "Policy Description 1", Creator: "Someone 1"}, + props: []string{"description", "creator"}, + }, + }, + { + name: "UpdateRepPolicy 2", + args: args{ + policy: &models.RepPolicy{ID: 2, Description: "Policy Description 2", Creator: "Someone 2"}, + props: []string{"description", "creator"}, + }, + }, + { + name: "UpdateRepPolicy 3", + args: args{ + policy: &models.RepPolicy{ID: 3, Description: "Policy Description 3", Creator: "Someone 3"}, + props: []string{"description", "creator"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := UpdateRepPolicy(tt.args.policy, tt.args.props...) + + if tt.wantErr { + require.NotNil(t, err, "Error: %s", err) + return + } + + require.Nil(t, err) + gotPolicy, err := GetRepPolicy(tt.args.policy.ID) + + require.Nil(t, err) + assert.Equal(t, tt.args.policy.Description, gotPolicy.Description) + assert.Equal(t, tt.args.policy.Creator, gotPolicy.Creator) + }) + } +} + +func TestDeleteRepPolicy(t *testing.T) { + tests := []struct { + name string + id int64 + wantErr bool + }{ + {name: "DeleteRepPolicy 1", id: 1, wantErr: false}, + {name: "DeleteRepPolicy 2", id: 2, wantErr: false}, + {name: "DeleteRepPolicy 3", id: 3, wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := DeleteRepPolicy(tt.id) + if tt.wantErr { + require.NotNil(t, err, "wantErr: %s", err) + return + } + + require.Nil(t, err) + _, err = GetRepPolicy(tt.id) + require.NotNil(t, err) + assert.Equal(t, err, orm.ErrNoRows) + }) + } +} diff --git a/src/replication/ng/policy/manager_test.go b/src/replication/ng/policy/manager_test.go new file mode 100644 index 000000000..3b5a64579 --- /dev/null +++ b/src/replication/ng/policy/manager_test.go @@ -0,0 +1,187 @@ +// Copyright Project Harbor Authors +// +// Licensed 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 policy + +import ( + "reflect" + "testing" + + persist_models "github.com/goharbor/harbor/src/replication/ng/dao/models" + "github.com/goharbor/harbor/src/replication/ng/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_convertFromPersistModel(t *testing.T) { + tests := []struct { + name string + from *persist_models.RepPolicy + want *model.Policy + wantErr bool + }{ + {name: "Nil Persist Model", from: nil, want: &model.Policy{}}, + { + name: "parse Filters Error", + from: &persist_models.RepPolicy{Filters: "abc"}, + want: &model.Policy{}, wantErr: true, + }, + { + name: "parse Trigger Error", + from: &persist_models.RepPolicy{Trigger: "abc"}, + want: &model.Policy{}, wantErr: true, + }, + { + name: "Persist Model", from: &persist_models.RepPolicy{ + ID: 999, + Name: "Policy Test", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: "ns1,ns2,ns3", + DestRegistryID: 456, + DestNamespace: "target_ns", + ReplicateDeletion: true, + Override: true, + Enabled: true, + Trigger: "", + Filters: "[]", + }, want: &model.Policy{ + ID: 999, + Name: "Policy Test", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: []string{"ns1", "ns2", "ns3"}, + DestRegistryID: 456, + DestNamespace: "target_ns", + Deletion: true, + Override: true, + Enabled: true, + Trigger: nil, + Filters: []*model.Filter{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := convertFromPersistModel(tt.from) + + if tt.wantErr { + require.NotNil(t, err) + return + } + + require.Nil(t, err, tt.name) + assert.Equal(t, tt.want.ID, got.ID) + assert.Equal(t, tt.want.Name, got.Name) + assert.Equal(t, tt.want.Description, got.Description) + assert.Equal(t, tt.want.Creator, got.Creator) + assert.Equal(t, tt.want.SrcRegistryID, got.SrcRegistryID) + assert.Equal(t, tt.want.SrcNamespaces, got.SrcNamespaces) + assert.Equal(t, tt.want.DestRegistryID, got.DestRegistryID) + assert.Equal(t, tt.want.DestNamespace, got.DestNamespace) + assert.Equal(t, tt.want.Deletion, got.Deletion) + assert.Equal(t, tt.want.Override, got.Override) + assert.Equal(t, tt.want.Enabled, got.Enabled) + assert.Equal(t, tt.want.Trigger, got.Trigger) + assert.Equal(t, tt.want.Filters, got.Filters) + + }) + } +} + +func Test_convertToPersistModel(t *testing.T) { + tests := []struct { + name string + from *model.Policy + want *persist_models.RepPolicy + wantErr bool + }{ + {name: "Nil Model", from: nil, want: nil, wantErr: true}, + { + name: "Persist Model", from: &model.Policy{ + ID: 999, + Name: "Policy Test", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: []string{"ns1", "ns2", "ns3"}, + DestRegistryID: 456, + DestNamespace: "target_ns", + Deletion: true, + Override: true, + Enabled: true, + Trigger: &model.Trigger{}, + Filters: []*model.Filter{{Type: "registry", Value: "abc"}}, + }, want: &persist_models.RepPolicy{ + ID: 999, + Name: "Policy Test", + Description: "Policy Description", + Creator: "someone", + SrcRegistryID: 123, + SrcNamespaces: "ns1,ns2,ns3", + DestRegistryID: 456, + DestNamespace: "target_ns", + ReplicateDeletion: true, + Override: true, + Enabled: true, + Trigger: "{\"type\":\"\",\"trigger_settings\":null}", + Filters: "[{\"type\":\"registry\",\"value\":\"abc\"}]", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := convertToPersistModel(tt.from) + + if tt.wantErr { + assert.Equal(t, err, errNilPolicyModel) + return + } + + require.Nil(t, err, tt.name) + assert.Equal(t, tt.want.ID, got.ID) + assert.Equal(t, tt.want.Name, got.Name) + assert.Equal(t, tt.want.Description, got.Description) + assert.Equal(t, tt.want.Creator, got.Creator) + assert.Equal(t, tt.want.SrcRegistryID, got.SrcRegistryID) + assert.Equal(t, tt.want.SrcNamespaces, got.SrcNamespaces) + assert.Equal(t, tt.want.DestRegistryID, got.DestRegistryID) + assert.Equal(t, tt.want.DestNamespace, got.DestNamespace) + assert.Equal(t, tt.want.ReplicateDeletion, got.ReplicateDeletion) + assert.Equal(t, tt.want.Override, got.Override) + assert.Equal(t, tt.want.Enabled, got.Enabled) + assert.Equal(t, tt.want.Trigger, got.Trigger) + assert.Equal(t, tt.want.Filters, got.Filters) + + }) + } +} + +func TestNewDefaultManager(t *testing.T) { + tests := []struct { + name string + want *DefaultManager + }{ + {want: &DefaultManager{}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewDefaultManager(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewDefaultManager() = %v, want %v", got, tt.want) + } + }) + } +}